392 lines
10 KiB
Nim
392 lines
10 KiB
Nim
|
# beacon_chain
|
||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||
|
# Licensed and distributed under either of
|
||
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||
|
|
||
|
# import ../interpreter # included to be able to use "suiteReport"
|
||
|
|
||
|
proc setup_finality_02(): tuple[fork_choice: ForkChoice, ops: seq[Operation]] =
|
||
|
var balances = @[Gwei(1), Gwei(1)]
|
||
|
let GenesisRoot = fakeHash(0)
|
||
|
|
||
|
# Initialize the fork choice context
|
||
|
result.fork_choice = initForkChoice(
|
||
|
finalized_block_slot = Slot(0), # Metadata unused in fork choice
|
||
|
finalized_block_state_root = default(Eth2Digest), # Metadata unused in fork choice
|
||
|
justified_epoch = Epoch(1),
|
||
|
finalized_epoch = Epoch(1),
|
||
|
finalized_root = GenesisRoot
|
||
|
).get()
|
||
|
|
||
|
# ----------------------------------
|
||
|
|
||
|
# Head should be genesis
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(1),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(1),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: GenesisRoot
|
||
|
)
|
||
|
|
||
|
# Build the following tree.
|
||
|
#
|
||
|
# 0
|
||
|
# / \
|
||
|
# just: 0, fin: 0 -> 1 2 <- just: 0, fin: 0
|
||
|
# | |
|
||
|
# just: 1, fin: 0 -> 3 4 <- just: 0, fin: 0
|
||
|
# | |
|
||
|
# just: 1, fin: 0 -> 5 6 <- just: 0, fin: 0
|
||
|
# | |
|
||
|
# just: 1, fin: 0 -> 7 8 <- just: 1, fin: 0
|
||
|
# | |
|
||
|
# just: 2, fin: 0 -> 9 10 <- just: 2, fin: 0
|
||
|
|
||
|
# Left branch
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(1),
|
||
|
parent_root: GenesisRoot,
|
||
|
blk_justified_epoch: Epoch(0),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(3),
|
||
|
parent_root: fakeHash(1),
|
||
|
blk_justified_epoch: Epoch(1),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(5),
|
||
|
parent_root: fakeHash(3),
|
||
|
blk_justified_epoch: Epoch(1),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(7),
|
||
|
parent_root: fakeHash(5),
|
||
|
blk_justified_epoch: Epoch(1),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(9),
|
||
|
parent_root: fakeHash(7),
|
||
|
blk_justified_epoch: Epoch(2),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
|
||
|
# Build the following tree.
|
||
|
#
|
||
|
# 0
|
||
|
# / \
|
||
|
# just: 0, fin: 0 -> 1 2 <- just: 0, fin: 0
|
||
|
# | |
|
||
|
# just: 1, fin: 0 -> 3 4 <- just: 0, fin: 0
|
||
|
# | |
|
||
|
# just: 1, fin: 0 -> 5 6 <- just: 0, fin: 0
|
||
|
# | |
|
||
|
# just: 1, fin: 0 -> 7 8 <- just: 1, fin: 0
|
||
|
# | |
|
||
|
# just: 2, fin: 0 -> 9 10 <- just: 2, fin: 0
|
||
|
|
||
|
# Right branch
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(2),
|
||
|
parent_root: GenesisRoot,
|
||
|
blk_justified_epoch: Epoch(0),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(4),
|
||
|
parent_root: fakeHash(2),
|
||
|
blk_justified_epoch: Epoch(0),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(6),
|
||
|
parent_root: fakeHash(4),
|
||
|
blk_justified_epoch: Epoch(0),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(8),
|
||
|
parent_root: fakeHash(6),
|
||
|
blk_justified_epoch: Epoch(1),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessBlock,
|
||
|
root: fakeHash(10),
|
||
|
parent_root: fakeHash(8),
|
||
|
blk_justified_epoch: Epoch(2),
|
||
|
blk_finalized_epoch: Epoch(0)
|
||
|
)
|
||
|
|
||
|
# Ensure that if we start at 0 we find 10 (just: 0, fin: 0).
|
||
|
#
|
||
|
# 0 <-- start
|
||
|
# / \
|
||
|
# 1 2
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# 9 10 <-- head
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(0),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(10)
|
||
|
)
|
||
|
|
||
|
# Same with justified_epoch 2
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(2),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(10)
|
||
|
)
|
||
|
|
||
|
# Justified epoch 3 is invalid
|
||
|
result.ops.add Operation(
|
||
|
kind: InvalidFindHead,
|
||
|
justified_epoch: Epoch(3), # <--- Wrong epoch
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances
|
||
|
)
|
||
|
|
||
|
# Add a vote to 1.
|
||
|
#
|
||
|
# 0
|
||
|
# / \
|
||
|
# +1 vote -> 1 2
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# 9 10
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessAttestation,
|
||
|
validator_index: ValidatorIndex(0),
|
||
|
block_root: fake_hash(1),
|
||
|
target_epoch: Epoch(0)
|
||
|
)
|
||
|
|
||
|
# Ensure that if we start at 0 we find 9 (just: 0, fin: 0).
|
||
|
#
|
||
|
# 0 <-- start
|
||
|
# / \
|
||
|
# 1 2
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# head -> 9 10
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(0),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(9)
|
||
|
)
|
||
|
|
||
|
# Same with justified_epoch 2
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(2),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(9)
|
||
|
)
|
||
|
|
||
|
# Justified epoch 3 is invalid
|
||
|
result.ops.add Operation(
|
||
|
kind: InvalidFindHead,
|
||
|
justified_epoch: Epoch(3), # <--- Wrong epoch
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances
|
||
|
)
|
||
|
|
||
|
# Add a vote to 2.
|
||
|
#
|
||
|
# 0
|
||
|
# / \
|
||
|
# 1 2 <- +1 vote
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# 9 10
|
||
|
result.ops.add Operation(
|
||
|
kind: ProcessAttestation,
|
||
|
validator_index: ValidatorIndex(1),
|
||
|
block_root: fake_hash(2),
|
||
|
target_epoch: Epoch(0)
|
||
|
)
|
||
|
|
||
|
# Ensure that if we start at 0 we find 10 again (just: 0, fin: 0).
|
||
|
#
|
||
|
# 0 <-- start
|
||
|
# / \
|
||
|
# 1 2
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# 9 10 <-- head
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(0),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(10)
|
||
|
)
|
||
|
|
||
|
# Same with justified_epoch 2
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(2),
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(10)
|
||
|
)
|
||
|
|
||
|
# Justified epoch 3 is invalid
|
||
|
result.ops.add Operation(
|
||
|
kind: InvalidFindHead,
|
||
|
justified_epoch: Epoch(3), # <--- Wrong epoch
|
||
|
justified_root: GenesisRoot,
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances
|
||
|
)
|
||
|
|
||
|
# Ensure that if we start at 1 (instead of 0) we find 9 (just: 0, fin: 0).
|
||
|
#
|
||
|
# 0
|
||
|
# / \
|
||
|
# start-> 1 2
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# head -> 9 10
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(0),
|
||
|
justified_root: fakeHash(1),
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(9)
|
||
|
)
|
||
|
|
||
|
# Same with justified_epoch 2
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(2),
|
||
|
justified_root: fakeHash(1),
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(9)
|
||
|
)
|
||
|
|
||
|
# Justified epoch 3 is invalid
|
||
|
result.ops.add Operation(
|
||
|
kind: InvalidFindHead,
|
||
|
justified_epoch: Epoch(3), # <--- Wrong epoch
|
||
|
justified_root: fakeHash(1),
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances
|
||
|
)
|
||
|
|
||
|
# Ensure that if we start at 2 (instead of 0) we find 10 (just: 0, fin: 0).
|
||
|
#
|
||
|
# 0
|
||
|
# / \
|
||
|
# 1 2 <- start
|
||
|
# | |
|
||
|
# 3 4
|
||
|
# | |
|
||
|
# 5 6
|
||
|
# | |
|
||
|
# 7 8
|
||
|
# | |
|
||
|
# 9 10 <- head
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(0),
|
||
|
justified_root: fakeHash(2),
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(10)
|
||
|
)
|
||
|
|
||
|
# Same with justified_epoch 2
|
||
|
result.ops.add Operation(
|
||
|
kind: FindHead,
|
||
|
justified_epoch: Epoch(2),
|
||
|
justified_root: fakeHash(2),
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances,
|
||
|
expected_head: fakeHash(10)
|
||
|
)
|
||
|
|
||
|
# Justified epoch 3 is invalid
|
||
|
result.ops.add Operation(
|
||
|
kind: InvalidFindHead,
|
||
|
justified_epoch: Epoch(3), # <--- Wrong epoch
|
||
|
justified_root: fakeHash(2),
|
||
|
finalized_epoch: Epoch(0),
|
||
|
justified_state_balances: balances
|
||
|
)
|
||
|
|
||
|
proc test_ffg02() =
|
||
|
timedTest "fork_choice - testing finality #02":
|
||
|
# for i in 0 ..< 12:
|
||
|
# echo " block (", i, ") hash: ", fakeHash(i)
|
||
|
# echo " ------------------------------------------------------"
|
||
|
|
||
|
var (ctx, ops) = setup_finality_02()
|
||
|
ctx.run(ops)
|
||
|
|
||
|
test_ffg02()
|