diff --git a/tests/test_beacon_chain_db.nim b/tests/test_beacon_chain_db.nim index 79bc8c91b..772e05e09 100644 --- a/tests/test_beacon_chain_db.nim +++ b/tests/test_beacon_chain_db.nim @@ -75,6 +75,13 @@ proc getElectraStateRef(db: BeaconChainDB, root: Eth2Digest): if db.getState(root, res[], noRollback): return res +proc getFuluStateRef(db: BeaconChainDB, root: Eth2Digest): + fulu.NilableBeaconStateRef = + # load beaconstate the way the block pool does it - into an existence instance + let res = (fulu.BeaconStateRef)() + if db.getState(root, res[], noRollback): + return res + func withDigest(blck: phase0.TrustedBeaconBlock): phase0.TrustedSignedBeaconBlock = phase0.TrustedSignedBeaconBlock( @@ -117,6 +124,13 @@ func withDigest(blck: electra.TrustedBeaconBlock): root: hash_tree_root(blck) ) +func withDigest(blck: fulu.TrustedBeaconBlock): + fulu.TrustedSignedBeaconBlock = + fulu.TrustedSignedBeaconBlock( + message: blck, + root: hash_tree_root(blck) + ) + proc getTestStates(consensusFork: ConsensusFork): auto = let db = makeTestDB(SLOTS_PER_EPOCH) @@ -138,12 +152,15 @@ let testStatesCapella = getTestStates(ConsensusFork.Capella) testStatesDeneb = getTestStates(ConsensusFork.Deneb) testStatesElectra = getTestStates(ConsensusFork.Electra) + testStatesFulu = getTestStates(ConsensusFork.Fulu) + doAssert len(testStatesPhase0) > 8 doAssert len(testStatesAltair) > 8 doAssert len(testStatesBellatrix) > 8 doAssert len(testStatesCapella) > 8 doAssert len(testStatesDeneb) > 8 doAssert len(testStatesElectra) > 8 +doAssert len(testStatesFulu) > 8 suite "Beacon chain DB" & preset(): test "empty database" & preset(): @@ -187,6 +204,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, phase0.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, phase0.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, phase0.TrustedSignedBeaconBlock) @@ -220,6 +238,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, altair.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, altair.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, altair.TrustedSignedBeaconBlock) @@ -236,6 +255,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, altair.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, altair.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, altair.TrustedSignedBeaconBlock) @@ -269,6 +289,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, bellatrix.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, bellatrix.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, bellatrix.TrustedSignedBeaconBlock) @@ -285,6 +306,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, bellatrix.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, bellatrix.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, bellatrix.TrustedSignedBeaconBlock) @@ -317,6 +339,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.containsBlock(root, capella.TrustedSignedBeaconBlock) db.getBlock(root, capella.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, capella.TrustedSignedBeaconBlock) @@ -334,6 +357,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, capella.TrustedSignedBeaconBlock).isErr() not db.getBlockSSZ(root, tmp, capella.TrustedSignedBeaconBlock) not db.getBlockSZ(root, tmp2, capella.TrustedSignedBeaconBlock) @@ -367,6 +391,7 @@ suite "Beacon chain DB" & preset(): not db.containsBlock(root, capella.TrustedSignedBeaconBlock) db.containsBlock(root, deneb.TrustedSignedBeaconBlock) not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) db.getBlock(root, deneb.TrustedSignedBeaconBlock).get() == signedBlock db.getBlockSSZ(root, tmp, deneb.TrustedSignedBeaconBlock) db.getBlockSZ(root, tmp2, deneb.TrustedSignedBeaconBlock) @@ -447,6 +472,57 @@ suite "Beacon chain DB" & preset(): db.close() + test "sanity check Fulu blocks" & preset(): + let db = BeaconChainDB.new("", inMemory = true) + + let + signedBlock = withDigest((fulu.TrustedBeaconBlock)()) + root = hash_tree_root(signedBlock.message) + + db.putBlock(signedBlock) + + var tmp, tmp2: seq[byte] + check: + db.containsBlock(root) + not db.containsBlock(root, phase0.TrustedSignedBeaconBlock) + not db.containsBlock(root, altair.TrustedSignedBeaconBlock) + not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) + not db.containsBlock(root, capella.TrustedSignedBeaconBlock) + not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + db.containsBlock(root, fulu.TrustedSignedBeaconBlock) + db.getBlock(root, fulu.TrustedSignedBeaconBlock).get() == signedBlock + db.getBlockSSZ(root, tmp, fulu.TrustedSignedBeaconBlock) + db.getBlockSZ(root, tmp2, fulu.TrustedSignedBeaconBlock) + tmp == SSZ.encode(signedBlock) + tmp2 == encodeFramed(tmp) + uncompressedLenFramed(tmp2).isSome + + check: + db.delBlock(ConsensusFork.Fulu, root) + not db.containsBlock(root) + not db.containsBlock(root, phase0.TrustedSignedBeaconBlock) + not db.containsBlock(root, altair.TrustedSignedBeaconBlock) + not db.containsBlock(root, bellatrix.TrustedSignedBeaconBlock) + not db.containsBlock(root, capella.TrustedSignedBeaconBlock) + not db.containsBlock(root, deneb.TrustedSignedBeaconBlock) + not db.containsBlock(root, electra.TrustedSignedBeaconBlock) + not db.containsBlock(root, fulu.TrustedSignedBeaconBlock) + db.getBlock(root, fulu.TrustedSignedBeaconBlock).isErr() + not db.getBlockSSZ(root, tmp, fulu.TrustedSignedBeaconBlock) + not db.getBlockSZ(root, tmp2, fulu.TrustedSignedBeaconBlock) + + db.putStateRoot(root, signedBlock.message.slot, root) + var root2 = root + root2.data[0] = root.data[0] + 1 + db.putStateRoot(root, signedBlock.message.slot + 1, root2) + + check: + db.getStateRoot(root, signedBlock.message.slot).get() == root + db.getStateRoot(root, signedBlock.message.slot + 1).get() == root2 + + db.close() + test "sanity check phase 0 states" & preset(): let db = makeTestDB(SLOTS_PER_EPOCH) @@ -555,6 +631,24 @@ suite "Beacon chain DB" & preset(): db.close() + test "sanity check Fulu states" & preset(): + let db = makeTestDB(SLOTS_PER_EPOCH) + + for state in testStatesFulu: + let root = state[].fuluData.root + db.putState(root, state[].fuluData.data) + + check: + db.containsState(root) + hash_tree_root(db.getFuluStateRef(root)[]) == root + + db.delState(ConsensusFork.Fulu, root) + check: + not db.containsState(root) + db.getFuluStateRef(root).isNil + + db.close() + test "sanity check phase 0 states, reusing buffers" & preset(): let db = makeTestDB(SLOTS_PER_EPOCH) let stateBuffer = (phase0.BeaconStateRef)() @@ -675,6 +769,26 @@ suite "Beacon chain DB" & preset(): db.close() + test "sanity check Fulu states, reusing buffers" & preset(): + let db = makeTestDB(SLOTS_PER_EPOCH) + let stateBuffer = (fulu.BeaconStateRef)() + + for state in testStatesFulu: + let root = state[].fuluData.root + db.putState(root, state[].fuluData.data) + + check: + db.getState(root, stateBuffer[], noRollback) + db.containsState(root) + hash_tree_root(stateBuffer[]) == root + + db.delState(ConsensusFork.Fulu, root) + check: + not db.containsState(root) + not db.getState(root, stateBuffer[], noRollback) + + db.close() + test "sanity check phase 0 getState rollback" & preset(): var db = makeTestDB(SLOTS_PER_EPOCH) @@ -828,6 +942,32 @@ suite "Beacon chain DB" & preset(): state[].kind == ConsensusFork.Phase0 state[].phase0Data.data.slot != 10.Slot + test "sanity check Fulu and cross-fork getState rollback" & preset(): + var + db = makeTestDB(SLOTS_PER_EPOCH) + validatorMonitor = newClone(ValidatorMonitor.init()) + dag = init(ChainDAGRef, defaultRuntimeConfig, db, validatorMonitor, {}) + state = (ref ForkedHashedBeaconState)( + kind: ConsensusFork.Fulu, + fuluData: fulu.HashedBeaconState(data: fulu.BeaconState( + slot: 10.Slot))) + root = Eth2Digest() + + db.putCorruptState(ConsensusFork.Fulu, root) + + let restoreAddr = addr dag.headState + + func restore() = + assign(state[], restoreAddr[]) + + check: + state[].fuluData.data.slot == 10.Slot + not db.getState(root, state[].fuluData.data, restore) + + # assign() has switched the case object fork + state[].kind == ConsensusFork.Phase0 + state[].phase0Data.data.slot != 10.Slot + test "find ancestors" & preset(): var db = BeaconChainDB.new("", inMemory = true) diff --git a/tests/test_light_client.nim b/tests/test_light_client.nim index 7f3090d79..7ad26c134 100644 --- a/tests/test_light_client.nim +++ b/tests/test_light_client.nim @@ -25,13 +25,14 @@ suite "Light client" & preset(): headPeriod = 4.SyncCommitteePeriod let cfg = block: # Fork schedule so that each `LightClientDataFork` is covered - static: doAssert ConsensusFork.high == ConsensusFork.Electra + static: doAssert ConsensusFork.high == ConsensusFork.Fulu var res = defaultRuntimeConfig res.ALTAIR_FORK_EPOCH = 1.Epoch res.BELLATRIX_FORK_EPOCH = 2.Epoch res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch res.ELECTRA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 3).Epoch + res.FULU_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 4).Epoch res altairStartSlot = cfg.ALTAIR_FORK_EPOCH.start_slot diff --git a/tests/test_light_client_processor.nim b/tests/test_light_client_processor.nim index 213ffaf11..5f9c06034 100644 --- a/tests/test_light_client_processor.nim +++ b/tests/test_light_client_processor.nim @@ -28,13 +28,14 @@ suite "Light client processor" & preset(): highPeriod = 6.SyncCommitteePeriod let cfg = block: # Fork schedule so that each `LightClientDataFork` is covered - static: doAssert ConsensusFork.high == ConsensusFork.Electra + static: doAssert ConsensusFork.high == ConsensusFork.Fulu var res = defaultRuntimeConfig res.ALTAIR_FORK_EPOCH = 1.Epoch res.BELLATRIX_FORK_EPOCH = 2.Epoch res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch res.ELECTRA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 3).Epoch + res.FULU_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 4).Epoch res const numValidators = SLOTS_PER_EPOCH diff --git a/tests/test_remote_keystore.nim b/tests/test_remote_keystore.nim index dec0cacd8..a635772fd 100644 --- a/tests/test_remote_keystore.nim +++ b/tests/test_remote_keystore.nim @@ -138,6 +138,7 @@ suite "Remove keystore testing suite": check keystore.provenBlockProperties[0].capellaIndex == some GeneralizedIndex(401) check keystore.provenBlockProperties[0].denebIndex == some GeneralizedIndex(801) check keystore.provenBlockProperties[0].electraIndex == some GeneralizedIndex(801) + check keystore.provenBlockProperties[0].fuluIndex == some GeneralizedIndex(801) test "Verifying Signer / Many remotes": for version in [3]: @@ -186,4 +187,5 @@ suite "Remove keystore testing suite": check keystore.provenBlockProperties.len == 1 check keystore.provenBlockProperties[0].capellaIndex == some GeneralizedIndex(401) check keystore.provenBlockProperties[0].denebIndex == some GeneralizedIndex(801) - check keystore.provenBlockProperties[0].electraIndex == some GeneralizedIndex(801) \ No newline at end of file + check keystore.provenBlockProperties[0].electraIndex == some GeneralizedIndex(801) + check keystore.provenBlockProperties[0].fuluIndex == some GeneralizedIndex(801) \ No newline at end of file diff --git a/tests/test_signing_node.nim b/tests/test_signing_node.nim index 8b0541ee2..e99d4ee8d 100644 --- a/tests/test_signing_node.nim +++ b/tests/test_signing_node.nim @@ -105,6 +105,9 @@ proc getBlock( of ConsensusFork.Electra: debugComment "electra test signing node getblock" raiseAssert "electra unsupported" + of ConsensusFork.Fulu: + debugFuluComment "electra test signing node getblock" + raiseAssert "fulu unsupported" except ValueError: # https://github.com/nim-lang/Nim/pull/23356 raiseAssert "Arguments match the format string" @@ -128,6 +131,10 @@ func init(t: typedesc[Web3SignerForkedBeaconBlock], Web3SignerForkedBeaconBlock( kind: ConsensusFork.Electra, data: forked.electraData.toBeaconBlockHeader) + of ConsensusFork.Fulu: + Web3SignerForkedBeaconBlock( + kind: ConsensusFork.Fulu, + data: forked.fuluData.toBeaconBlockHeader) proc createKeystore(dataDir, pubkey, store, password: string): Result[void, string] = @@ -260,6 +267,7 @@ func getRemoteKeystoreData(data: string, basePort: int, provenBlockProperties: @[ ProvenProperty( path: ".execution_payload.fee_recipient", + fuluIndex: some GeneralizedIndex(801), electraIndex: some GeneralizedIndex(801), denebIndex: some GeneralizedIndex(801), capellaIndex: some GeneralizedIndex(401) diff --git a/tests/test_toblindedblock.nim b/tests/test_toblindedblock.nim index 934e6db31..c60f70c91 100644 --- a/tests/test_toblindedblock.nim +++ b/tests/test_toblindedblock.nim @@ -12,7 +12,8 @@ import # Beacon chain internals ../beacon_chain/spec/helpers, ../beacon_chain/spec/datatypes/[bellatrix, capella], - ../beacon_chain/spec/mev/[bellatrix_mev, capella_mev, deneb_mev, electra_mev], + ../beacon_chain/spec/mev/[bellatrix_mev, capella_mev, deneb_mev, electra_mev, + fulu_mev], # Test utilities unittest2 @@ -130,6 +131,17 @@ template electra_steps() = default(ConsolidationRequest)) do_check +template fulu_steps() = + check: b.message.body.execution_requests.deposits.add( + default(DepositRequest)) + do_check + check: b.message.body.execution_requests.withdrawals.add( + default(WithdrawalRequest)) + do_check + check: b.message.body.execution_requests.consolidations.add( + default(ConsolidationRequest)) + do_check + suite "Blinded block conversions": withAll(ConsensusFork): when consensusFork >= ConsensusFork.Bellatrix: @@ -143,4 +155,6 @@ suite "Blinded block conversions": deneb_steps when consensusFork >= ConsensusFork.Electra: electra_steps - static: doAssert high(ConsensusFork) == ConsensusFork.Electra + when consensusFork >= ConsensusFork.Fulu: + fulu_steps + static: doAssert high(ConsensusFork) == ConsensusFork.Fulu diff --git a/tests/test_validator_change_pool.nim b/tests/test_validator_change_pool.nim index 9beb63658..51c273d30 100644 --- a/tests/test_validator_change_pool.nim +++ b/tests/test_validator_change_pool.nim @@ -79,6 +79,7 @@ suite "Validator change pool testing suite": tmp.CAPELLA_FORK_EPOCH = Epoch(tmp.SHARD_COMMITTEE_PERIOD) + 2 tmp.DENEB_FORK_EPOCH = Epoch(tmp.SHARD_COMMITTEE_PERIOD) + 3 tmp.ELECTRA_FORK_EPOCH = Epoch(tmp.SHARD_COMMITTEE_PERIOD) + 4 + tmp.FULU_FORK_EPOCH = Epoch(tmp.SHARD_COMMITTEE_PERIOD) + 5 tmp validatorMonitor = newClone(ValidatorMonitor.init()) diff --git a/tests/testdbutil.nim b/tests/testdbutil.nim index 48df0f222..7a7c39cf9 100644 --- a/tests/testdbutil.nim +++ b/tests/testdbutil.nim @@ -31,6 +31,11 @@ proc makeTestDB*( cfg.CAPELLA_FORK_EPOCH = 90000.Epoch if cfg.DENEB_FORK_EPOCH == FAR_FUTURE_EPOCH: cfg.DENEB_FORK_EPOCH = 100000.Epoch + if cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH: + cfg.ELECTRA_FORK_EPOCH = 110000.Epoch + if cfg.FULU_FORK_EPOCH == FAR_FUTURE_EPOCH: + cfg.FULU_FORK_EPOCH = 120000.Epoch + var genState = (ref ForkedHashedBeaconState)( kind: ConsensusFork.Phase0, diff --git a/tests/teststateutil.nim b/tests/teststateutil.nim index e97b284be..6e93147fe 100644 --- a/tests/teststateutil.nim +++ b/tests/teststateutil.nim @@ -91,7 +91,7 @@ proc getTestStates*( if consensusFork >= ConsensusFork.Electra: cfg.ELECTRA_FORK_EPOCH = 5.Epoch if consensusFork >= ConsensusFork.Fulu: - cfg.ELECTRA_FORK_EPOCH = 6.Epoch + cfg.FULU_FORK_EPOCH = 6.Epoch for i, epoch in stateEpochs: let slot = epoch.Epoch.start_slot