cryptarchia: drop note evolution

This commit is contained in:
David Rusu 2025-03-21 02:47:55 +04:00
parent 17bec9b570
commit 69464eb5a5
6 changed files with 116 additions and 139 deletions

View File

@ -159,10 +159,6 @@ class Note:
def encode_pk(self) -> bytes: def encode_pk(self) -> bytes:
return int.to_bytes(self.pk, length=32, byteorder="big") return int.to_bytes(self.pk, length=32, byteorder="big")
def evolve(self) -> "Note":
evolved_nonce = Hash(b"coin-evolve", self.encode_sk(), self.nonce)
return Note(nonce=evolved_nonce, sk=self.sk, value=self.value)
def commitment(self) -> Hash: def commitment(self) -> Hash:
value_bytes = int.to_bytes(self.value, length=32, byteorder="big") value_bytes = int.to_bytes(self.value, length=32, byteorder="big")
return Hash( return Hash(

View File

@ -26,7 +26,6 @@ class TestNode:
parent = self.follower.tip_id() parent = self.follower.tip_id()
epoch_state = self.epoch_state(slot) epoch_state = self.epoch_state(slot)
if leader_proof := self.leader.try_prove_slot_leader(epoch_state, slot, parent): if leader_proof := self.leader.try_prove_slot_leader(epoch_state, slot, parent):
self.leader.note = self.leader.note.evolve()
return BlockHeader( return BlockHeader(
parent=parent, parent=parent,
slot=slot, slot=slot,
@ -89,5 +88,4 @@ def mk_chain(
block = mk_block(parent=parent, slot=s, note=note) block = mk_block(parent=parent, slot=s, note=note)
chain.append(block) chain.append(block)
parent = block parent = block
note = note.evolve() return chain
return chain, note

View File

@ -174,18 +174,18 @@ class TestForkChoice(TestCase):
genesis = mk_genesis_state([]).block genesis = mk_genesis_state([]).block
short_note, long_note = Note(sk=0, value=100), Note(sk=1, value=100) short_note, long_note = Note(sk=0, value=100), Note(sk=1, value=100)
common, long_note = mk_chain(parent=genesis, note=long_note, slots=range(50)) common = mk_chain(parent=genesis, note=long_note, slots=range(50))
long_chain_sparse_ext, long_note = mk_chain( long_chain_sparse_ext = mk_chain(
parent=common[-1], note=long_note, slots=range(50, 100, 2) parent=common[-1], note=long_note, slots=range(50, 100, 2)
) )
short_chain_dense_ext, _ = mk_chain( short_chain_dense_ext = mk_chain(
parent=common[-1], note=short_note, slots=range(50, 100) parent=common[-1], note=short_note, slots=range(50, 100)
) )
# add more blocks to the long chain to ensure the long chain is indeed longer # add more blocks to the long chain to ensure the long chain is indeed longer
long_chain_further_ext, _ = mk_chain( long_chain_further_ext = mk_chain(
parent=long_chain_sparse_ext[-1], note=long_note, slots=range(100, 126) parent=long_chain_sparse_ext[-1], note=long_note, slots=range(100, 126)
) )
@ -214,16 +214,16 @@ class TestForkChoice(TestCase):
def test_fork_choice_long_dense_chain(self): def test_fork_choice_long_dense_chain(self):
# The longest chain is also the densest after the fork # The longest chain is also the densest after the fork
short_note, long_note = Note(sk=0, value=100), Note(sk=1, value=100) short_note, long_note = Note(sk=0, value=100), Note(sk=1, value=100)
common, long_note = mk_chain( common = mk_chain(
parent=mk_genesis_state([]).block, parent=mk_genesis_state([]).block,
note=long_note, note=long_note,
slots=range(1, 50), slots=range(1, 50),
) )
long_chain_dense_ext, _ = mk_chain( long_chain_dense_ext = mk_chain(
parent=common[-1], note=long_note, slots=range(50, 100) parent=common[-1], note=long_note, slots=range(50, 100)
) )
short_chain_sparse_ext, _ = mk_chain( short_chain_sparse_ext = mk_chain(
parent=common[-1], note=short_note, slots=range(50, 100, 2) parent=common[-1], note=short_note, slots=range(50, 100, 2)
) )
@ -246,7 +246,7 @@ class TestForkChoice(TestCase):
genesis = mk_genesis_state(notes) genesis = mk_genesis_state(notes)
follower = Follower(genesis, config) follower = Follower(genesis, config)
b1, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b1 = mk_block(genesis.block, 1, n_a)
follower.on_block(b1) follower.on_block(b1)
@ -262,8 +262,8 @@ class TestForkChoice(TestCase):
# b3 # b3
# #
b2, n_a = mk_block(b1, 2, n_a), n_a.evolve() b2 = mk_block(b1, 2, n_a)
b3, n_b = mk_block(b1, 2, n_b), n_b.evolve() b3 = mk_block(b1, 2, n_b)
follower.on_block(b2) follower.on_block(b2)
follower.on_block(b3) follower.on_block(b3)
@ -280,7 +280,7 @@ class TestForkChoice(TestCase):
# b3 - b4 == tip # b3 - b4 == tip
# #
b4, n_b = mk_block(b3, 3, n_b), n_a.evolve() b4 = mk_block(b3, 3, n_b)
follower.on_block(b4) follower.on_block(b4)
assert follower.tip_id() == b4.id() assert follower.tip_id() == b4.id()

View File

@ -32,7 +32,7 @@ class TestLedgerStateUpdate(TestCase):
assert len(follower.ledger_state) == 2 assert len(follower.ledger_state) == 2
assert len(follower.forks) == 0 assert len(follower.forks) == 0
def test_ledger_state_prevents_note_reuse(self): def test_ledger_state_allows_note_reuse(self):
leader_note = Note(sk=0, value=100) leader_note = Note(sk=0, value=100)
genesis = mk_genesis_state([leader_note]) genesis = mk_genesis_state([leader_note])
@ -45,16 +45,12 @@ class TestLedgerStateUpdate(TestCase):
assert len(list(iter_chain(follower.tip_id(), follower.ledger_state))) == 2 assert len(list(iter_chain(follower.tip_id(), follower.ledger_state))) == 2
assert follower.tip() == block assert follower.tip() == block
# Follower should have updated their ledger state to mark the leader note as spent
assert follower.tip_state().verify_unspent(leader_note.nullifier()) == False
reuse_note_block = mk_block(slot=1, parent=block, note=leader_note) reuse_note_block = mk_block(slot=1, parent=block, note=leader_note)
with self.assertRaises(InvalidLeaderProof): follower.on_block(reuse_note_block)
follower.on_block(reuse_note_block)
# Follower should *not* have accepted the block # Follower should have accepted the block
assert len(list(iter_chain(follower.tip_id(), follower.ledger_state))) == 2 assert len(list(iter_chain(follower.tip_id(), follower.ledger_state))) == 3
assert follower.tip() == block assert follower.tip() == reuse_note_block
def test_ledger_state_is_properly_updated_on_reorg(self): def test_ledger_state_is_properly_updated_on_reorg(self):
note = [Note(sk=0, value=100), Note(sk=1, value=100), Note(sk=2, value=100)] note = [Note(sk=0, value=100), Note(sk=1, value=100), Note(sk=2, value=100)]
@ -72,7 +68,6 @@ class TestLedgerStateUpdate(TestCase):
follower.on_block(block_1) follower.on_block(block_1)
assert follower.tip() == block_1 assert follower.tip() == block_1
assert not follower.tip_state().verify_unspent(note[0].nullifier())
# 3) then sees block 2, but sticks with block_1 as the tip # 3) then sees block 2, but sticks with block_1 as the tip
@ -87,9 +82,6 @@ class TestLedgerStateUpdate(TestCase):
# the follower should have switched over to the block_2 fork # the follower should have switched over to the block_2 fork
assert follower.tip() == block_3 assert follower.tip() == block_3
# and the original note[0] should now be removed from the spent pool
assert follower.tip_state().verify_unspent(note[0].nullifier())
def test_fork_creation(self): def test_fork_creation(self):
notes = [Note(sk=i, value=100) for i in range(7)] notes = [Note(sk=i, value=100) for i in range(7)]
genesis = mk_genesis_state(notes) genesis = mk_genesis_state(notes)
@ -177,15 +169,15 @@ class TestLedgerStateUpdate(TestCase):
with self.assertRaises(InvalidLeaderProof): with self.assertRaises(InvalidLeaderProof):
follower.on_block(block_4) follower.on_block(block_4)
assert follower.tip() == block_3 assert follower.tip() == block_3
# then we add the note to "spendable commitments" associated with slot 9 # then we add the note to "commitments" associated with slot 9
follower.ledger_state[block_2.id()].commitments_spend.add( follower.ledger_state[block_2.id()].commitments.add(
Note(sk=4, value=100).commitment() Note(sk=4, value=100).commitment()
) )
follower.on_block(block_4) follower.on_block(block_4)
assert follower.tip() == block_4 assert follower.tip() == block_4
assert follower.tip().slot.epoch(config).epoch == 2 assert follower.tip().slot.epoch(config).epoch == 2
def test_evolved_note_is_eligible_for_leadership(self): def test_note_added_after_stake_freeze_is_ineligible_for_leadership(self):
note = Note(sk=0, value=100) note = Note(sk=0, value=100)
genesis = mk_genesis_state([note]) genesis = mk_genesis_state([note])
@ -197,16 +189,19 @@ class TestLedgerStateUpdate(TestCase):
follower.on_block(block_1) follower.on_block(block_1)
assert follower.tip() == block_1 assert follower.tip() == block_1
# note can't be reused to win following slots: # note can be reused to win following slots:
block_2_reuse = mk_block(slot=1, parent=block_1, note=note) block_2 = mk_block(slot=1, parent=block_1, note=note)
with self.assertRaises(InvalidLeaderProof): follower.on_block(block_2)
follower.on_block(block_2_reuse) assert follower.tip() == block_2
assert follower.tip() == block_1
# but the evolved note is eligible # but the a new note is ineligible
block_2_evolve = mk_block(slot=1, parent=block_1, note=note.evolve()) note_new = Note(sk=1, value=10)
follower.on_block(block_2_evolve) follower.tip_state().commitments.add(note_new.commitment())
assert follower.tip() == block_2_evolve block_3_new = mk_block(slot=2, parent=block_2, note=note_new)
with self.assertRaises(InvalidLeaderProof):
follower.on_block(block_3_new)
assert follower.tip() == block_2
def test_new_notes_becoming_eligible_after_stake_distribution_stabilizes(self): def test_new_notes_becoming_eligible_after_stake_distribution_stabilizes(self):
note = Note(sk=0, value=100) note = Note(sk=0, value=100)
@ -225,9 +220,7 @@ class TestLedgerStateUpdate(TestCase):
# mint a new note to be used for leader elections in upcoming epochs # mint a new note to be used for leader elections in upcoming epochs
note_new = Note(sk=1, value=10) note_new = Note(sk=1, value=10)
follower.ledger_state[block_0_0.id()].commitments_spend.add( follower.ledger_state[block_0_0.id()].commitments.add(note_new.commitment())
note_new.commitment()
)
# the new note is not yet eligible for elections # the new note is not yet eligible for elections
block_0_1_attempt = mk_block(slot=1, parent=block_0_0, note=note_new) block_0_1_attempt = mk_block(slot=1, parent=block_0_0, note=note_new)
@ -235,30 +228,20 @@ class TestLedgerStateUpdate(TestCase):
follower.on_block(block_0_1_attempt) follower.on_block(block_0_1_attempt)
assert follower.tip() == block_0_0 assert follower.tip() == block_0_0
# whereas the evolved note from genesis can be spent immediately
block_0_1 = mk_block(slot=1, parent=block_0_0, note=note.evolve())
follower.on_block(block_0_1)
assert follower.tip() == block_0_1
# ---- EPOCH 1 ---- # ---- EPOCH 1 ----
# The newly minted note is still not eligible in the following epoch since the # The newly minted note is still not eligible in the following epoch since the
# stake distribution snapshot is taken at the beginning of the previous epoch # stake distribution snapshot is taken at the beginning of the previous epoch
block_1_0 = mk_block(slot=20, parent=block_0_1, note=note_new) block_1_0_attempt = mk_block(slot=20, parent=block_0_0, note=note_new)
with self.assertRaises(InvalidLeaderProof): with self.assertRaises(InvalidLeaderProof):
follower.on_block(block_1_0) follower.on_block(block_1_0_attempt)
assert follower.tip() == block_0_1 assert follower.tip() == block_0_0
# ---- EPOCH 2 ---- # ---- EPOCH 2 ----
# The note is finally eligible 2 epochs after it was first minted # The note is finally eligible 2 epochs after it was first minted
block_2_0 = mk_block(slot=40, parent=block_0_1, note=note_new) block_2_0 = mk_block(slot=40, parent=block_0_0, note=note_new)
follower.on_block(block_2_0) follower.on_block(block_2_0)
assert follower.tip() == block_2_0 assert follower.tip() == block_2_0
# And now the minted note can freely use the evolved note for subsequent blocks
block_2_1 = mk_block(slot=40, parent=block_2_0, note=note_new.evolve())
follower.on_block(block_2_1)
assert follower.tip() == block_2_1

View File

@ -32,7 +32,7 @@ class TestStakeRelativization(TestCase):
assert follower.tip_state().leader_count == 1 assert follower.tip_state().leader_count == 1
# continuing the chain increments the leader count # continuing the chain increments the leader count
b2 = mk_block(b1, slot=2, note=n_a.evolve()) b2 = mk_block(b1, slot=2, note=n_a)
follower.on_block(b2) follower.on_block(b2)
assert follower.tip_state().block == b2 assert follower.tip_state().block == b2
assert follower.tip_state().leader_count == 2 assert follower.tip_state().leader_count == 2

View File

@ -13,10 +13,10 @@ class TestSync(TestCase):
config = mk_config([note]) config = mk_config([note])
genesis = mk_genesis_state([note]) genesis = mk_genesis_state([note])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, note = mk_block(genesis.block, 1, note), note.evolve() b0 = mk_block(genesis.block, 1, note)
b1, note = mk_block(b0, 2, note), note.evolve() b1 = mk_block(b0, 2, note)
b2, note = mk_block(b1, 3, note), note.evolve() b2 = mk_block(b1, 3, note)
b3, note = mk_block(b2, 4, note), note.evolve() b3 = mk_block(b2, 4, note)
for b in [b0, b1, b2, b3]: for b in [b0, b1, b2, b3]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b3) self.assertEqual(peer.tip(), b3)
@ -36,10 +36,10 @@ class TestSync(TestCase):
config = mk_config([note]) config = mk_config([note])
genesis = mk_genesis_state([note]) genesis = mk_genesis_state([note])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, note = mk_block(genesis.block, 1, note), note.evolve() b0 = mk_block(genesis.block, 1, note)
b1, note = mk_block(b0, 2, note), note.evolve() b1 = mk_block(b0, 2, note)
b2, note = mk_block(b1, 3, note), note.evolve() b2 = mk_block(b1, 3, note)
b3, note = mk_block(b2, 4, note), note.evolve() b3 = mk_block(b2, 4, note)
for b in [b0, b1, b2, b3]: for b in [b0, b1, b2, b3]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b3) self.assertEqual(peer.tip(), b3)
@ -65,12 +65,12 @@ class TestSync(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_a = mk_block(b1, 3, n_a), n_a.evolve() b2 = mk_block(b1, 3, n_a)
b3, n_b = mk_block(b0, 2, n_b), n_b.evolve() b3 = mk_block(b0, 2, n_b)
b4, n_b = mk_block(b3, 3, n_b), n_b.evolve() b4 = mk_block(b3, 3, n_b)
b5, n_a = mk_block(b2, 4, n_a), n_a.evolve() b5 = mk_block(b2, 4, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -92,12 +92,12 @@ class TestSync(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_a = mk_block(b1, 3, n_a), n_a.evolve() b2 = mk_block(b1, 3, n_a)
b3, n_b = mk_block(b0, 2, n_b), n_b.evolve() b3 = mk_block(b0, 2, n_b)
b4, n_b = mk_block(b3, 3, n_b), n_b.evolve() b4 = mk_block(b3, 3, n_b)
b5, n_a = mk_block(b2, 4, n_a), n_a.evolve() b5 = mk_block(b2, 4, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -125,12 +125,12 @@ class TestSync(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_a = mk_block(b1, 3, n_a), n_a.evolve() b2 = mk_block(b1, 3, n_a)
b3, n_b = mk_block(b0, 2, n_b), n_b.evolve() b3 = mk_block(b0, 2, n_b)
b4, n_b = mk_block(b3, 3, n_b), n_b.evolve() b4 = mk_block(b3, 3, n_b)
b5, n_a = mk_block(b2, 4, n_a), n_a.evolve() b5 = mk_block(b2, 4, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -159,12 +159,12 @@ class TestSync(TestCase):
n_a, n_b = Note(sk=0, value=10), Note(sk=1, value=10) n_a, n_b = Note(sk=0, value=10), Note(sk=1, value=10)
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_a = mk_block(b1, 3, n_a), n_a.evolve() b2 = mk_block(b1, 3, n_a)
b3, n_b = mk_block(b0, 2, n_b), n_b.evolve() b3 = mk_block(b0, 2, n_b)
b4, n_b = mk_block(b3, 3, n_b), n_b.evolve() b4 = mk_block(b3, 3, n_b)
b5, n_a = mk_block(b2, 4, n_a), n_a.evolve() b5 = mk_block(b2, 4, n_a)
peer0 = Follower(genesis, config) peer0 = Follower(genesis, config)
for b in [b0, b1, b2, b5]: for b in [b0, b1, b2, b5]:
peer0.on_block(b) peer0.on_block(b)
@ -204,10 +204,10 @@ class TestSync(TestCase):
config = mk_config([note]) config = mk_config([note])
genesis = mk_genesis_state([note]) genesis = mk_genesis_state([note])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, note = mk_block(genesis.block, 1, note), note.evolve() b0 = mk_block(genesis.block, 1, note)
b1, note = mk_block(b0, 2, note), note.evolve() b1 = mk_block(b0, 2, note)
b2, note = mk_block(b1, 3, note), note.evolve() b2 = mk_block(b1, 3, note)
b3, note = mk_block(b2, 4, note), note.evolve() b3 = mk_block(b2, 4, note)
for b in [b0, b1, b2, b3]: for b in [b0, b1, b2, b3]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b3) self.assertEqual(peer.tip(), b3)
@ -215,8 +215,8 @@ class TestSync(TestCase):
# And deliberately, add invalid blocks (b4 ~ b5): # And deliberately, add invalid blocks (b4 ~ b5):
fake_note = Note(sk=1, value=10) fake_note = Note(sk=1, value=10)
b4, fake_note = mk_block(b3, 5, fake_note), fake_note.evolve() b4 = mk_block(b3, 5, fake_note)
b5, fake_note = mk_block(b4, 6, fake_note), fake_note.evolve() b5 = mk_block(b4, 6, fake_note)
apply_invalid_block_to_ledger_state(peer, b4) apply_invalid_block_to_ledger_state(peer, b4)
apply_invalid_block_to_ledger_state(peer, b5) apply_invalid_block_to_ledger_state(peer, b5)
# the tip shouldn't be changed. # the tip shouldn't be changed.
@ -243,12 +243,12 @@ class TestSync(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_b = mk_block(b0, 2, n_b), n_b.evolve() b2 = mk_block(b0, 2, n_b)
b3, n_a = mk_block(b1, 3, n_a), n_a.evolve() b3 = mk_block(b1, 3, n_a)
b4, n_a = mk_block(b3, 4, n_a), n_a.evolve() b4 = mk_block(b3, 4, n_a)
b5, n_a = mk_block(b4, 5, n_a), n_a.evolve() b5 = mk_block(b4, 5, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -256,8 +256,8 @@ class TestSync(TestCase):
# And deliberately, add invalid blocks (b6 ~ b7): # And deliberately, add invalid blocks (b6 ~ b7):
fake_note = Note(sk=2, value=10) fake_note = Note(sk=2, value=10)
b6, fake_note = mk_block(b2, 3, fake_note), fake_note.evolve() b6 = mk_block(b2, 3, fake_note)
b7, fake_note = mk_block(b6, 4, fake_note), fake_note.evolve() b7 = mk_block(b6, 4, fake_note)
apply_invalid_block_to_ledger_state(peer, b6) apply_invalid_block_to_ledger_state(peer, b6)
apply_invalid_block_to_ledger_state(peer, b7) apply_invalid_block_to_ledger_state(peer, b7)
# the tip shouldn't be changed. # the tip shouldn't be changed.
@ -291,10 +291,10 @@ class TestSyncFromCheckpoint(TestCase):
config = mk_config([note]) config = mk_config([note])
genesis = mk_genesis_state([note]) genesis = mk_genesis_state([note])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, note = mk_block(genesis.block, 1, note), note.evolve() b0 = mk_block(genesis.block, 1, note)
b1, note = mk_block(b0, 2, note), note.evolve() b1 = mk_block(b0, 2, note)
b2, note = mk_block(b1, 3, note), note.evolve() b2 = mk_block(b1, 3, note)
b3, note = mk_block(b2, 4, note), note.evolve() b3 = mk_block(b2, 4, note)
for b in [b0, b1, b2, b3]: for b in [b0, b1, b2, b3]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b3) self.assertEqual(peer.tip(), b3)
@ -328,12 +328,12 @@ class TestSyncFromCheckpoint(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_a = mk_block(b1, 3, n_a), n_a.evolve() b2 = mk_block(b1, 3, n_a)
b3, n_b = mk_block(b0, 2, n_b), n_b.evolve() b3 = mk_block(b0, 2, n_b)
b4, n_b = mk_block(b3, 3, n_b), n_b.evolve() b4 = mk_block(b3, 3, n_b)
b5, n_a = mk_block(b2, 4, n_a), n_a.evolve() b5 = mk_block(b2, 4, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -366,12 +366,12 @@ class TestSyncFromCheckpoint(TestCase):
n_a, n_b = Note(sk=0, value=10), Note(sk=1, value=10) n_a, n_b = Note(sk=0, value=10), Note(sk=1, value=10)
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_a = mk_block(b1, 3, n_a), n_a.evolve() b2 = mk_block(b1, 3, n_a)
b3, n_b = mk_block(b0, 2, n_b), n_b.evolve() b3 = mk_block(b0, 2, n_b)
b4, n_b = mk_block(b3, 3, n_b), n_b.evolve() b4 = mk_block(b3, 3, n_b)
b5, n_a = mk_block(b2, 4, n_a), n_a.evolve() b5 = mk_block(b2, 4, n_a)
peer0 = Follower(genesis, config) peer0 = Follower(genesis, config)
for b in [b0, b1, b2, b5]: for b in [b0, b1, b2, b5]:
peer0.on_block(b) peer0.on_block(b)
@ -411,12 +411,12 @@ class TestSyncFromCheckpoint(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_b = mk_block(b0, 2, n_b), n_b.evolve() b2 = mk_block(b0, 2, n_b)
b3, n_a = mk_block(b1, 3, n_a), n_a.evolve() b3 = mk_block(b1, 3, n_a)
b4, n_a = mk_block(b3, 4, n_a), n_a.evolve() b4 = mk_block(b3, 4, n_a)
b5, n_a = mk_block(b4, 5, n_a), n_a.evolve() b5 = mk_block(b4, 5, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -424,8 +424,8 @@ class TestSyncFromCheckpoint(TestCase):
# And deliberately, add invalid blocks (b6 ~ b7): # And deliberately, add invalid blocks (b6 ~ b7):
fake_note = Note(sk=2, value=10) fake_note = Note(sk=2, value=10)
b6, fake_note = mk_block(b2, 3, fake_note), fake_note.evolve() b6 = mk_block(b2, 3, fake_note)
b7, fake_note = mk_block(b6, 4, fake_note), fake_note.evolve() b7 = mk_block(b6, 4, fake_note)
apply_invalid_block_to_ledger_state(peer, b6) apply_invalid_block_to_ledger_state(peer, b6)
apply_invalid_block_to_ledger_state(peer, b7) apply_invalid_block_to_ledger_state(peer, b7)
# the tip shouldn't be changed. # the tip shouldn't be changed.
@ -461,12 +461,12 @@ class TestSyncFromCheckpoint(TestCase):
config = mk_config([n_a, n_b]) config = mk_config([n_a, n_b])
genesis = mk_genesis_state([n_a, n_b]) genesis = mk_genesis_state([n_a, n_b])
peer = Follower(genesis, config) peer = Follower(genesis, config)
b0, n_a = mk_block(genesis.block, 1, n_a), n_a.evolve() b0 = mk_block(genesis.block, 1, n_a)
b1, n_a = mk_block(b0, 2, n_a), n_a.evolve() b1 = mk_block(b0, 2, n_a)
b2, n_b = mk_block(b0, 2, n_b), n_b.evolve() b2 = mk_block(b0, 2, n_b)
b3, n_a = mk_block(b1, 3, n_a), n_a.evolve() b3 = mk_block(b1, 3, n_a)
b4, n_a = mk_block(b3, 4, n_a), n_a.evolve() b4 = mk_block(b3, 4, n_a)
b5, n_a = mk_block(b4, 5, n_a), n_a.evolve() b5 = mk_block(b4, 5, n_a)
for b in [b0, b1, b2, b3, b4, b5]: for b in [b0, b1, b2, b3, b4, b5]:
peer.on_block(b) peer.on_block(b)
self.assertEqual(peer.tip(), b5) self.assertEqual(peer.tip(), b5)
@ -474,8 +474,8 @@ class TestSyncFromCheckpoint(TestCase):
# And deliberately, add invalid blocks (b6 ~ b7): # And deliberately, add invalid blocks (b6 ~ b7):
fake_note = Note(sk=2, value=10) fake_note = Note(sk=2, value=10)
b6, fake_note = mk_block(b2, 3, fake_note), fake_note.evolve() b6 = mk_block(b2, 3, fake_note)
b7, fake_note = mk_block(b6, 4, fake_note), fake_note.evolve() b7 = mk_block(b6, 4, fake_note)
apply_invalid_block_to_ledger_state(peer, b6) apply_invalid_block_to_ledger_state(peer, b6)
apply_invalid_block_to_ledger_state(peer, b7) apply_invalid_block_to_ledger_state(peer, b7)
# the tip shouldn't be changed. # the tip shouldn't be changed.