From 91f87b55b4774588c8e8132ffe3669ca6f80bd18 Mon Sep 17 00:00:00 2001 From: Joao Gabriel Carvalho Date: Sat, 29 Feb 2020 12:15:44 -0300 Subject: [PATCH] SignedBeaconBlock in state_transition (#773) * using SignedBeaconBlock in state_transition --- beacon_chain/beacon_node.nim | 16 +++++++-------- beacon_chain/block_pool.nim | 10 +++++----- beacon_chain/state_transition.nim | 20 +++++++++---------- beacon_chain/sync_protocol.nim | 2 +- nbench/scenarios.nim | 4 ++-- ncli/ncli_transition.nim | 2 +- research/state_sim.nim | 6 +++--- tests/mocking/mock_attestations.nim | 2 +- tests/mocking/mock_blocks.nim | 2 +- tests/official/test_fixture_sanity_blocks.nim | 4 ++-- tests/test_beacon_chain_db.nim | 12 +++++------ tests/test_state_transition.nim | 6 +++--- tests/testblockutil.nim | 2 +- 13 files changed, 44 insertions(+), 44 deletions(-) diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index 0f8268d65..f643974de 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -61,7 +61,7 @@ type mainchainMonitor: MainchainMonitor beaconClock: BeaconClock -proc onBeaconBlock*(node: BeaconNode, blck: SignedBeaconBlock) {.gcsafe.} +proc onBeaconBlock*(node: BeaconNode, signedBlock: SignedBeaconBlock) {.gcsafe.} proc updateHead(node: BeaconNode): BlockRef proc saveValidatorKey(keyName, key: string, conf: BeaconNodeConf) = @@ -412,7 +412,7 @@ proc proposeBlock(node: BeaconNode, parent_root: head.root, body: blockBody)) tmpState = hashedState - discard state_transition(tmpState, newBlock.message, {skipValidation}) + discard state_transition(tmpState, newBlock, {skipValidation}) # TODO only enable in fast-fail debugging situations # otherwise, bad attestations can bring down network # doAssert ok # TODO: err, could this fail somehow? @@ -492,19 +492,19 @@ proc onAttestation(node: BeaconNode, attestation: Attestation) = node.attestationPool.add(attestation) -proc onBeaconBlock(node: BeaconNode, blck: SignedBeaconBlock) = +proc onBeaconBlock(node: BeaconNode, signedBlock: SignedBeaconBlock) = # We received a block but don't know much about it yet - in particular, we # don't know if it's part of the chain we're currently building. - let blockRoot = hash_tree_root(blck.message) + let blockRoot = hash_tree_root(signedBlock.message) debug "Block received", - blck = shortLog(blck.message), + signedBlock = shortLog(signedBlock.message), blockRoot = shortLog(blockRoot), cat = "block_listener", pcs = "receive_block" beacon_blocks_received.inc() - if node.blockPool.add(blockRoot, blck).isNil: + if node.blockPool.add(blockRoot, signedBlock).isNil: return # The block we received contains attestations, and we might not yet know about @@ -514,8 +514,8 @@ proc onBeaconBlock(node: BeaconNode, blck: SignedBeaconBlock) = # TODO shouldn't add attestations if the block turns out to be invalid.. let currentSlot = node.beaconClock.now.toSlot if currentSlot.afterGenesis and - blck.message.slot.epoch + 1 >= currentSlot.slot.epoch: - for attestation in blck.message.body.attestations: + signedBlock.message.slot.epoch + 1 >= currentSlot.slot.epoch: + for attestation in signedBlock.message.body.attestations: node.onAttestation(attestation) proc handleAttestations(node: BeaconNode, head: BlockRef, slot: Slot) = diff --git a/beacon_chain/block_pool.nim b/beacon_chain/block_pool.nim index c1a67b646..b6415245f 100644 --- a/beacon_chain/block_pool.nim +++ b/beacon_chain/block_pool.nim @@ -374,7 +374,7 @@ proc add*( # but maybe we should use it as a hint that our clock is wrong? updateStateData(pool, pool.tmpState, BlockSlot(blck: parent, slot: blck.slot - 1)) - if not state_transition(pool.tmpState.data, blck, {}): + if not state_transition(pool.tmpState.data, signedBlock, {}): # TODO find a better way to log all this block data notice "Invalid block", blck = shortLog(blck), @@ -570,12 +570,12 @@ proc skipAndUpdateState( afterUpdate(state) proc skipAndUpdateState( - state: var HashedBeaconState, blck: BeaconBlock, flags: UpdateFlags, + state: var HashedBeaconState, signedBlock: SignedBeaconBlock, flags: UpdateFlags, afterUpdate: proc (state: HashedBeaconState)): bool = - skipAndUpdateState(state, blck.slot - 1, afterUpdate) + skipAndUpdateState(state, signedBlock.message.slot - 1, afterUpdate) - let ok = state_transition(state, blck, flags) + let ok = state_transition(state, signedBlock, flags) afterUpdate(state) @@ -713,7 +713,7 @@ proc updateStateData*(pool: BlockPool, state: var StateData, bs: BlockSlot) = for i in countdown(ancestors.len - 1, 0): let ok = skipAndUpdateState(state.data, - ancestors[i].data.message, + ancestors[i].data, {skipValidation}) do (state: HashedBeaconState): pool.maybePutState(state, ancestors[i].refs) doAssert ok, "Blocks in database should never fail to apply.." diff --git a/beacon_chain/state_transition.nim b/beacon_chain/state_transition.nim index fa1f1698d..d860ce122 100644 --- a/beacon_chain/state_transition.nim +++ b/beacon_chain/state_transition.nim @@ -113,7 +113,7 @@ proc verifyStateRoot(state: BeaconState, blck: BeaconBlock): bool = true proc state_transition*( - state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool {.nbench.}= + state: var BeaconState, signedBlock: SignedBeaconBlock, flags: UpdateFlags): bool {.nbench.}= ## Time in the beacon chain moves by slots. Every time (haha.) that happens, ## we will update the beacon state. Normally, the state updates will be driven ## by the contents of a new block, but it may happen that the block goes @@ -147,7 +147,7 @@ proc state_transition*( var old_state = state # These should never fail. - process_slots(state, blck.slot) + process_slots(state, signedBlock.message.slot) # Block updates - these happen when there's a new block being suggested # by the block proposer. Every actor in the network will update its state @@ -157,11 +157,11 @@ proc state_transition*( # https://github.com/ethereum/eth2.0-specs/issues/293 var per_epoch_cache = get_empty_per_epoch_cache() - if processBlock(state, blck, flags, per_epoch_cache): + if processBlock(state, signedBlock.message, flags, per_epoch_cache): # This is a bit awkward - at the end of processing we verify that the # state we arrive at is what the block producer thought it would be - # meaning that potentially, it could fail verification - if skipValidation in flags or verifyStateRoot(state, blck): + if skipValidation in flags or verifyStateRoot(state, signedBlock.message): # TODO: allow skipping just verifyStateRoot for mocking # instead of both processBlock and verifyStateRoot # https://github.com/status-im/nim-beacon-chain/issues/407 @@ -220,23 +220,23 @@ proc process_slots*(state: var HashedBeaconState, slot: Slot) = state.root = hash_tree_root(state.data) proc state_transition*( - state: var HashedBeaconState, blck: BeaconBlock, flags: UpdateFlags): bool = + state: var HashedBeaconState, signedBlock: SignedBeaconBlock, flags: UpdateFlags): bool = # Save for rollback var old_state = state - process_slots(state, blck.slot) + process_slots(state, signedBlock.message.slot) var per_epoch_cache = get_empty_per_epoch_cache() - if processBlock(state.data, blck, flags, per_epoch_cache): - if skipValidation in flags or verifyStateRoot(state.data, blck): + if processBlock(state.data, signedBlock.message, flags, per_epoch_cache): + if skipValidation in flags or verifyStateRoot(state.data, signedBlock.message): # State root is what it should be - we're done! # TODO when creating a new block, state_root is not yet set.. comparing # with zero hash here is a bit fragile however, but this whole thing # should go away with proper hash caching state.root = - if blck.state_root == Eth2Digest(): hash_tree_root(state.data) - else: blck.state_root + if signedBlock.message.state_root == Eth2Digest(): hash_tree_root(state.data) + else: signedBlock.message.state_root return true diff --git a/beacon_chain/sync_protocol.nim b/beacon_chain/sync_protocol.nim index 72ca79afc..8f386a12e 100644 --- a/beacon_chain/sync_protocol.nim +++ b/beacon_chain/sync_protocol.nim @@ -22,7 +22,7 @@ type else: index: uint32 - BeaconBlockCallback* = proc(blck: SignedBeaconBlock) {.gcsafe.} + BeaconBlockCallback* = proc(signedBlock: SignedBeaconBlock) {.gcsafe.} BeaconSyncNetworkState* = ref object blockPool*: BlockPool forkVersion*: array[4, byte] diff --git a/nbench/scenarios.nim b/nbench/scenarios.nim index 855ea8c31..1da1fbbb8 100644 --- a/nbench/scenarios.nim +++ b/nbench/scenarios.nim @@ -148,10 +148,10 @@ proc runFullTransition*(dir, preState, blocksPrefix: string, blocksQty: int, ski let blockPath = dir / blocksPrefix & $i & ".ssz" echo "Processing: ", blockPath - let blck = parseSSZ(blockPath, SignedBeaconBlock) + let signedBlock = parseSSZ(blockPath, SignedBeaconBlock) let flags = if skipBLS: {skipValidation} # TODO: this also skips state root verification else: {} - let success = state_transition(state[], blck.message, flags) + let success = state_transition(state[], signedBlock.message, flags) echo "State transition status: ", if success: "SUCCESS ✓" else: "FAILURE ⚠️" proc runProcessSlots*(dir, preState: string, numSlots: uint64) = diff --git a/ncli/ncli_transition.nim b/ncli/ncli_transition.nim index 02a735b1e..8a42f805f 100644 --- a/ncli/ncli_transition.nim +++ b/ncli/ncli_transition.nim @@ -6,7 +6,7 @@ import cli do(pre: string, blck: string, post: string, verifyStateRoot = false): let stateX = SSZ.loadFile(pre, BeaconState) - blckX = SSZ.loadFile(blck, BeaconBlock) + blckX = SSZ.loadFile(blck, SignedBeaconBlock) flags = if verifyStateRoot: {skipValidation} else: {} var stateY = HashedBeaconState(data: stateX, root: hash_tree_root(stateX)) diff --git a/research/state_sim.nim b/research/state_sim.nim index 2022ecca6..e3bbc3b53 100644 --- a/research/state_sim.nim +++ b/research/state_sim.nim @@ -91,7 +91,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6, timers: array[Timers, RunningStat] attesters: RunningStat r: Rand - blck: SignedBeaconBlock + signedBlock: SignedBeaconBlock cache = get_empty_per_epoch_cache() proc maybeWrite(last: bool) = @@ -133,9 +133,9 @@ cli do(slots = SLOTS_PER_EPOCH * 6, else: tBlock withTimer(timers[t]): - blck = addBlock(state, latest_block_root, body, flags) + signedBlock = addBlock(state, latest_block_root, body, flags) latest_block_root = withTimerRet(timers[tHashBlock]): - hash_tree_root(blck.message) + hash_tree_root(signedBlock.message) if attesterRatio > 0.0: # attesterRatio is the fraction of attesters that actually do their diff --git a/tests/mocking/mock_attestations.nim b/tests/mocking/mock_attestations.nim index 8472f3c7b..22a264480 100644 --- a/tests/mocking/mock_attestations.nim +++ b/tests/mocking/mock_attestations.nim @@ -148,4 +148,4 @@ proc add*(state: var BeaconState, attestation: Attestation, slot: Slot) = # TODO: we can skip just VerifyStateRoot doAssert state_transition( - state, signedBlock.message, flags = {skipValidation}) + state, signedBlock, flags = {skipValidation}) diff --git a/tests/mocking/mock_blocks.nim b/tests/mocking/mock_blocks.nim index 89d60ded8..666c12218 100644 --- a/tests/mocking/mock_blocks.nim +++ b/tests/mocking/mock_blocks.nim @@ -99,4 +99,4 @@ proc applyEmptyBlock*(state: var BeaconState) = let signedBlock = mockBlock(state, state.slot, flags = {}) # TODO: we only need to skip verifyStateRoot validation # processBlock validation should work - doAssert state_transition(state, signedBlock.message, {skipValidation}) + doAssert state_transition(state, signedBlock, {skipValidation}) diff --git a/tests/official/test_fixture_sanity_blocks.nim b/tests/official/test_fixture_sanity_blocks.nim index ad993a2e0..ef785ac92 100644 --- a/tests/official/test_fixture_sanity_blocks.nim +++ b/tests/official/test_fixture_sanity_blocks.nim @@ -49,11 +49,11 @@ proc runTest(identifier: string) = let blck = parseTest(testDir/"blocks_" & $i & ".ssz", SSZ, SignedBeaconBlock) if postRef.isNil: - let success = state_transition(stateRef[], blck.message, flags = {}) + let success = state_transition(stateRef[], blck, flags = {}) doAssert not success, "We didn't expect this invalid block to be processed" else: # TODO: The EF is using invalid BLS keys so we can't verify them - let success = state_transition(stateRef[], blck.message, flags = {skipValidation}) + let success = state_transition(stateRef[], blck, flags = {skipValidation}) doAssert success, "Failure when applying block " & $i # check: stateRef.hash_tree_root() == postRef.hash_tree_root() diff --git a/tests/test_beacon_chain_db.nim b/tests/test_beacon_chain_db.nim index 367bebb13..91b4a527a 100644 --- a/tests/test_beacon_chain_db.nim +++ b/tests/test_beacon_chain_db.nim @@ -30,18 +30,18 @@ suite "Beacon chain DB" & preset(): db = init(BeaconChainDB, kvStore MemoryStoreRef.init()) let - blck = SignedBeaconBlock() - root = hash_tree_root(blck.message) + signedBlock = SignedBeaconBlock() + root = hash_tree_root(signedBlock.message) - db.putBlock(blck) + db.putBlock(signedBlock) check: db.containsBlock(root) - db.getBlock(root).get() == blck + db.getBlock(root).get() == signedBlock - db.putStateRoot(root, blck.message.slot, root) + db.putStateRoot(root, signedBlock.message.slot, root) check: - db.getStateRoot(root, blck.message.slot).get() == root + db.getStateRoot(root, signedBlock.message.slot).get() == root timedTest "sanity check states" & preset(): var diff --git a/tests/test_state_transition.nim b/tests/test_state_transition.nim index 5f3cc7bc4..a2c1b210f 100644 --- a/tests/test_state_transition.nim +++ b/tests/test_state_transition.nim @@ -40,7 +40,7 @@ suite "Block processing" & preset(): previous_block_root = hash_tree_root(genesisBlock.message) new_block = makeBlock(state, previous_block_root, BeaconBlockBody()) - let block_ok = state_transition(state, new_block.message, {}) + let block_ok = state_transition(state, new_block, {}) check: block_ok @@ -64,7 +64,7 @@ suite "Block processing" & preset(): for i in 1..SLOTS_PER_EPOCH.int: var new_block = makeBlock(state, previous_block_root, BeaconBlockBody()) - let block_ok = state_transition(state, new_block.message, {}) + let block_ok = state_transition(state, new_block, {}) check: block_ok @@ -98,7 +98,7 @@ suite "Block processing" & preset(): new_block = makeBlock(state, previous_block_root, BeaconBlockBody( attestations: @[attestation] )) - discard state_transition(state, new_block.message, {}) + discard state_transition(state, new_block, {}) check: # TODO epoch attestations can get multiplied now; clean up paths to diff --git a/tests/testblockutil.nim b/tests/testblockutil.nim index 4d6675231..2427b1d0f 100644 --- a/tests/testblockutil.nim +++ b/tests/testblockutil.nim @@ -111,7 +111,7 @@ proc addBlock*( ) ) - let block_ok = state_transition(state, new_block.message, {skipValidation}) + let block_ok = state_transition(state, new_block, {skipValidation}) doAssert block_ok # Ok, we have the new state as it would look with the block applied - now we