From bddaa40d632b8a9220fd95f5280c930a817829e0 Mon Sep 17 00:00:00 2001 From: David Rusu Date: Tue, 6 Feb 2024 22:19:08 +0400 Subject: [PATCH] test coin minting and stake stabilizing --- cryptarchia/test_ledger_state_update.py | 67 +++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/cryptarchia/test_ledger_state_update.py b/cryptarchia/test_ledger_state_update.py index 349db47..c56e1b0 100644 --- a/cryptarchia/test_ledger_state_update.py +++ b/cryptarchia/test_ledger_state_update.py @@ -176,17 +176,78 @@ class TestLedgerStateUpdate(TestCase): # coin wins the first slot block_1 = mk_block(slot=0, parent=genesis.block, coin=coin) follower.on_block(block_1) - assert follower.tip_id() == block_1.id() # coin can't be reused to win following slots: block_2_reuse = mk_block(slot=1, parent=block_1.id(), coin=coin) follower.on_block(block_2_reuse) - assert follower.tip_id() == block_1.id() # but the evolved coin is eligible block_2_evolve = mk_block(slot=1, parent=block_1.id(), coin=coin.evolve()) follower.on_block(block_2_evolve) - assert follower.tip_id() == block_2_evolve.id() + + def test_new_coins_becoming_eligible_after_stake_distribution_stabilizes(self): + coin = Coin(sk=0, value=100) + genesis = mk_genesis_state([coin]) + + # An epoch will be 10 slots long, with stake distribution snapshot taken at the start of the epoch + # and nonce snapshot before slot 7 + config = Config( + k=1, + active_slot_coeff=1, + epoch_stake_distribution_stabilization=4, + epoch_period_nonce_buffer=3, + epoch_period_nonce_stabilization=3, + time=TimeConfig(slot_duration=1, chain_start_time=0), + ) + + follower = Follower(genesis, config) + + # ---- EPOCH 0 ---- + + block_0_0 = mk_block(slot=0, parent=genesis.block, coin=coin) + follower.on_block(block_0_0) + assert follower.tip() == block_0_0 + + # mint a new coin to be used for leader elections in upcoming epochs + coin_new = Coin(sk=1, value=10) + follower.ledger_state[block_0_0.id()].commitments_spend.add( + coin_new.commitment() + ) + + # the new coin is not yet eligible for elections + + block_0_1_attempt = mk_block(slot=1, parent=block_0_0.id(), coin=coin_new) + follower.on_block(block_0_1_attempt) + assert follower.tip() == block_0_0 + + # whereas the evolved coin from genesis can be spent immediately + + block_0_1 = mk_block(slot=1, parent=block_0_0.id(), coin=coin.evolve()) + follower.on_block(block_0_1) + assert follower.tip() == block_0_1 + + # ---- EPOCH 1 ---- + + # The newly minted coin is still not eligible in the following epoch since the + # stake distribution snapshot is taken at the beginning of the previous epoch + + block_1_0 = mk_block(slot=10, parent=block_0_1.id(), coin=coin_new) + follower.on_block(block_1_0) + assert follower.tip() == block_0_1 + + # ---- EPOCH 2 ---- + + # The coin is finally eligible 2 epochs after it was first minted + + block_2_0 = mk_block(slot=20, parent=block_0_1.id(), coin=coin_new) + follower.on_block(block_2_0) + assert follower.tip() == block_2_0 + + # And now the minted coin can freely use the evolved coin for subsequent blocks + + block_2_1 = mk_block(slot=20, parent=block_2_0.id(), coin=coin_new.evolve()) + follower.on_block(block_2_1) + assert follower.tip() == block_2_1