From d6c76f6b2f0e500fc6f8a0874b4722c7a941c61a Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Tue, 5 May 2020 11:18:44 +0200 Subject: [PATCH] re-enable all but the finalization tests for block pool in mainnet presets --- AllTests-mainnet.md | 13 +- tests/test_block_pool.nim | 320 +++++++++++++++++++------------------- 2 files changed, 170 insertions(+), 163 deletions(-) diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index 6d89a556a..f243fc52c 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -30,6 +30,17 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 + Smoke test initialize_beacon_state_from_eth1 [Preset: mainnet] OK ``` OK: 1/1 Fail: 0/1 Skip: 0/1 +## Block pool processing [Preset: mainnet] +```diff ++ Can add same block twice [Preset: mainnet] OK ++ Reverse order block add & get [Preset: mainnet] OK ++ Simple block add&get [Preset: mainnet] OK ++ getRef returns nil for missing blocks OK ++ loadTailState gets genesis block on first load [Preset: mainnet] OK ++ updateHead updates head and headState [Preset: mainnet] OK ++ updateStateData sanity [Preset: mainnet] OK +``` +OK: 7/7 Fail: 0/7 Skip: 0/7 ## Block processing [Preset: mainnet] ```diff + Attestation gets processed at epoch [Preset: mainnet] OK @@ -242,4 +253,4 @@ OK: 4/4 Fail: 0/4 Skip: 0/4 OK: 8/8 Fail: 0/8 Skip: 0/8 ---TOTAL--- -OK: 149/152 Fail: 3/152 Skip: 0/152 +OK: 156/159 Fail: 3/159 Skip: 0/159 diff --git a/tests/test_block_pool.nim b/tests/test_block_pool.nim index 6fce3126f..08d5c5256 100644 --- a/tests/test_block_pool.nim +++ b/tests/test_block_pool.nim @@ -8,10 +8,10 @@ {.used.} import - unittest, chronicles, - ./testutil, - ../beacon_chain/spec/datatypes, - ../beacon_chain/[beacon_node_types, block_pool, ssz] + chronicles, options, sequtils, unittest, + ./testutil, ./testblockutil, + ../beacon_chain/spec/[datatypes, digest, helpers], + ../beacon_chain/[beacon_node_types, block_pool, state_transition, ssz] suiteReport "BlockRef and helpers" & preset(): timedTest "isAncestorOf sanity" & preset(): @@ -82,211 +82,207 @@ suiteReport "BlockSlot and helpers" & preset(): s24.parent == BlockSlot(blck: s2, slot: Slot(3)) s24.parent.parent == s22 -when const_preset == "minimal": # Too much stack space used on mainnet - import - options, sequtils, - ./testblockutil, - ../beacon_chain/state_transition, - ../beacon_chain/spec/[digest, helpers, validator] +suiteReport "Block pool processing" & preset(): + setup: + var + db = makeTestDB(SLOTS_PER_EPOCH) + pool = BlockPool.init(db) + stateData = newClone(pool.loadTailState()) + b1 = addTestBlock(stateData.data.data, pool.tail.root) + b1Root = hash_tree_root(b1.message) + b2 = addTestBlock(stateData.data.data, b1Root) + b2Root {.used.} = hash_tree_root(b2.message) - suiteReport "Block pool processing" & preset(): - setup: - var - db = makeTestDB(SLOTS_PER_EPOCH) - pool = BlockPool.init(db) - state = newClone(pool.loadTailState().data) - b1 = addTestBlock(state.data, pool.tail.root) - b1Root = hash_tree_root(b1.message) - b2 = addTestBlock(state.data, b1Root) - b2Root {.used.} = hash_tree_root(b2.message) + # addTestBlock(...) operates on BeaconState, so doesn't update root + # TODO fix addTestBlock to work on HashedBeaconState directly + stateData.data.root = hash_tree_root(stateData.data.data) - # addTestBlock(...) operates on BeaconState, so doesn't update root - # TODO fix addTestBlock to work on HashedBeaconState directly - state.root = hash_tree_root(state.data) + timedTest "getRef returns nil for missing blocks": + check: + pool.getRef(default Eth2Digest) == nil - timedTest "getRef returns nil for missing blocks": - check: - pool.getRef(default Eth2Digest) == nil + timedTest "loadTailState gets genesis block on first load" & preset(): + let + b0 = pool.get(pool.tail.root) - timedTest "loadTailState gets genesis block on first load" & preset(): - let - b0 = pool.get(pool.tail.root) + check: + b0.isSome() - check: - b0.isSome() + timedTest "Simple block add&get" & preset(): + let + b1Add = pool.add(b1Root, b1) + b1Get = pool.get(b1Root) - timedTest "Simple block add&get" & preset(): - let - b1Add = pool.add(b1Root, b1) - b1Get = pool.get(b1Root) + check: + b1Get.isSome() + b1Get.get().refs.root == b1Root + b1Add.root == b1Get.get().refs.root + pool.heads.len == 1 + pool.heads[0].blck == b1Add - check: - b1Get.isSome() - b1Get.get().refs.root == b1Root - b1Add.root == b1Get.get().refs.root - pool.heads.len == 1 - pool.heads[0].blck == b1Add + let + b2Add = pool.add(b2Root, b2) + b2Get = pool.get(b2Root) - let - b2Add = pool.add(b2Root, b2) - b2Get = pool.get(b2Root) + check: + b2Get.isSome() + b2Get.get().refs.root == b2Root + b2Add.root == b2Get.get().refs.root + pool.heads.len == 1 + pool.heads[0].blck == b2Add - check: - b2Get.isSome() - b2Get.get().refs.root == b2Root - b2Add.root == b2Get.get().refs.root - pool.heads.len == 1 - pool.heads[0].blck == b2Add + # Skip one slot to get a gap + process_slots(stateData.data, stateData.data.data.slot + 1) - # Skip one slot to get a gap - process_slots(state[], state.data.slot + 1) + let + b4 = addTestBlock(stateData.data.data, b2Root) + b4Root = hash_tree_root(b4.message) + b4Add = pool.add(b4Root, b4) + # TODO fix addTestBlock to work on HashedBeaconState + stateData.data.root = hash_tree_root(stateData.data.data) - let - b4 = addTestBlock(state.data, b2Root) - b4Root = hash_tree_root(b4.message) - b4Add = pool.add(b4Root, b4) - # TODO fix addTestBlock to work on HashedBeaconState - state.root = hash_tree_root(state.data) + check: + b4Add.parent == b2Add - check: - b4Add.parent == b2Add + pool.updateHead(b4Add) - pool.updateHead(b4Add) + var blocks: array[3, BlockRef] - var blocks: array[3, BlockRef] + check: + pool.getBlockRange(Slot(0), 1, blocks.toOpenArray(0, 0)) == 0 + blocks[0..<1] == [pool.tail] - check: - pool.getBlockRange(Slot(0), 1, blocks.toOpenArray(0, 0)) == 0 - blocks[0..<1] == [pool.tail] + pool.getBlockRange(Slot(0), 1, blocks.toOpenArray(0, 1)) == 0 + blocks[0..<2] == [pool.tail, b1Add] - pool.getBlockRange(Slot(0), 1, blocks.toOpenArray(0, 1)) == 0 - blocks[0..<2] == [pool.tail, b1Add] + pool.getBlockRange(Slot(0), 2, blocks.toOpenArray(0, 1)) == 0 + blocks[0..<2] == [pool.tail, b2Add] - pool.getBlockRange(Slot(0), 2, blocks.toOpenArray(0, 1)) == 0 - blocks[0..<2] == [pool.tail, b2Add] + pool.getBlockRange(Slot(0), 3, blocks.toOpenArray(0, 1)) == 1 + blocks[0..<2] == [nil, pool.tail] # block 3 is missing! - pool.getBlockRange(Slot(0), 3, blocks.toOpenArray(0, 1)) == 1 - blocks[0..<2] == [nil, pool.tail] # block 3 is missing! + pool.getBlockRange(Slot(2), 2, blocks.toOpenArray(0, 1)) == 0 + blocks[0..<2] == [b2Add, b4Add] # block 3 is missing! - pool.getBlockRange(Slot(2), 2, blocks.toOpenArray(0, 1)) == 0 - blocks[0..<2] == [b2Add, b4Add] # block 3 is missing! + # empty length + pool.getBlockRange(Slot(2), 2, blocks.toOpenArray(0, -1)) == 0 - # empty length - pool.getBlockRange(Slot(2), 2, blocks.toOpenArray(0, -1)) == 0 + # No blocks in sight + pool.getBlockRange(Slot(5), 1, blocks.toOpenArray(0, 1)) == 2 - # No blocks in sight - pool.getBlockRange(Slot(5), 1, blocks.toOpenArray(0, 1)) == 2 + # No blocks in sight either due to gaps + pool.getBlockRange(Slot(3), 2, blocks.toOpenArray(0, 1)) == 2 + blocks[0..<2] == [BlockRef nil, nil] # block 3 is missing! - # No blocks in sight either due to gaps - pool.getBlockRange(Slot(3), 2, blocks.toOpenArray(0, 1)) == 2 - blocks[0..<2] == [BlockRef nil, nil] # block 3 is missing! + timedTest "Reverse order block add & get" & preset(): + discard pool.add(b2Root, b2) - timedTest "Reverse order block add & get" & preset(): - discard pool.add(b2Root, b2) + check: + pool.get(b2Root).isNone() # Unresolved, shouldn't show up + FetchRecord(root: b1Root, historySlots: 1) in pool.checkMissing() - check: - pool.get(b2Root).isNone() # Unresolved, shouldn't show up - FetchRecord(root: b1Root, historySlots: 1) in pool.checkMissing() + discard pool.add(b1Root, b1) - discard pool.add(b1Root, b1) + let + b1Get = pool.get(b1Root) + b2Get = pool.get(b2Root) - let - b1Get = pool.get(b1Root) - b2Get = pool.get(b2Root) + check: + b1Get.isSome() + b2Get.isSome() - check: - b1Get.isSome() - b2Get.isSome() + b1Get.get().refs.children[0] == b2Get.get().refs + b2Get.get().refs.parent == b1Get.get().refs - b1Get.get().refs.children[0] == b2Get.get().refs - b2Get.get().refs.parent == b1Get.get().refs + pool.updateHead(b2Get.get().refs) - pool.updateHead(b2Get.get().refs) + # The heads structure should have been updated to contain only the new + # b2 head + check: + pool.heads.mapIt(it.blck) == @[b2Get.get().refs] - # The heads structure should have been updated to contain only the new - # b2 head - check: - pool.heads.mapIt(it.blck) == @[b2Get.get().refs] + # check that init also reloads block graph + var + pool2 = BlockPool.init(db) - # check that init also reloads block graph - var - pool2 = BlockPool.init(db) + check: + # ensure we loaded the correct head state + pool2.head.blck.root == b2Root + hash_tree_root(pool2.headState.data.data) == b2.message.state_root + pool2.get(b1Root).isSome() + pool2.get(b2Root).isSome() + pool2.heads.len == 1 + pool2.heads[0].blck.root == b2Root - check: - # ensure we loaded the correct head state - pool2.head.blck.root == b2Root - hash_tree_root(pool2.headState.data.data) == b2.message.state_root - pool2.get(b1Root).isSome() - pool2.get(b2Root).isSome() - pool2.heads.len == 1 - pool2.heads[0].blck.root == b2Root + timedTest "Can add same block twice" & preset(): + let + b10 = pool.add(b1Root, b1) + b11 = pool.add(b1Root, b1) - timedTest "Can add same block twice" & preset(): - let - b10 = pool.add(b1Root, b1) - b11 = pool.add(b1Root, b1) + check: + b10 == b11 + not b10.isNil - check: - b10 == b11 - not b10.isNil + timedTest "updateHead updates head and headState" & preset(): + let + b1Add = pool.add(b1Root, b1) - timedTest "updateHead updates head and headState" & preset(): - let - b1Add = pool.add(b1Root, b1) + pool.updateHead(b1Add) - pool.updateHead(b1Add) + check: + pool.head.blck == b1Add + pool.headState.data.data.slot == b1Add.slot - check: - pool.head.blck == b1Add - pool.headState.data.data.slot == b1Add.slot + timedTest "updateStateData sanity" & preset(): + let + b1Add = pool.add(b1Root, b1) + b2Add = pool.add(b2Root, b2) + bs1 = BlockSlot(blck: b1Add, slot: b1.message.slot) + bs1_3 = b1Add.atSlot(3.Slot) + bs2_3 = b2Add.atSlot(3.Slot) - timedTest "updateStateData sanity" & preset(): - let - b1Add = pool.add(b1Root, b1) - b2Add = pool.add(b2Root, b2) - bs1 = BlockSlot(blck: b1Add, slot: b1.message.slot) - bs1_3 = b1Add.atSlot(3.Slot) - bs2_3 = b2Add.atSlot(3.Slot) + var tmpState = newClone(pool.headState) - var tmpState = newClone(pool.headState) + # move to specific block + pool.updateStateData(tmpState[], bs1) - # move to specific block - pool.updateStateData(tmpState[], bs1) + check: + tmpState.blck == b1Add + tmpState.data.data.slot == bs1.slot - check: - tmpState.blck == b1Add - tmpState.data.data.slot == bs1.slot + # Skip slots + pool.updateStateData(tmpState[], bs1_3) # skip slots - # Skip slots - pool.updateStateData(tmpState[], bs1_3) # skip slots + check: + tmpState.blck == b1Add + tmpState.data.data.slot == bs1_3.slot - check: - tmpState.blck == b1Add - tmpState.data.data.slot == bs1_3.slot + # Move back slots, but not blocks + pool.updateStateData(tmpState[], bs1_3.parent()) + check: + tmpState.blck == b1Add + tmpState.data.data.slot == bs1_3.parent().slot - # Move back slots, but not blocks - pool.updateStateData(tmpState[], bs1_3.parent()) - check: - tmpState.blck == b1Add - tmpState.data.data.slot == bs1_3.parent().slot + # Move to different block and slot + pool.updateStateData(tmpState[], bs2_3) + check: + tmpState.blck == b2Add + tmpState.data.data.slot == bs2_3.slot - # Move to different block and slot - pool.updateStateData(tmpState[], bs2_3) - check: - tmpState.blck == b2Add - tmpState.data.data.slot == bs2_3.slot + # Move back slot and block + pool.updateStateData(tmpState[], bs1) + check: + tmpState.blck == b1Add + tmpState.data.data.slot == bs1.slot - # Move back slot and block - pool.updateStateData(tmpState[], bs1) - check: - tmpState.blck == b1Add - tmpState.data.data.slot == bs1.slot + # Move back to genesis + pool.updateStateData(tmpState[], bs1.parent()) + check: + tmpState.blck == b1Add.parent + tmpState.data.data.slot == bs1.parent.slot - # Move back to genesis - pool.updateStateData(tmpState[], bs1.parent()) - check: - tmpState.blck == b1Add.parent - tmpState.data.data.slot == bs1.parent.slot +when const_preset == "minimal": # These require some minutes in mainnet + import ../beacon_chain/spec/validator suiteReport "BlockPool finalization tests" & preset(): setup: