-
Notifications
You must be signed in to change notification settings - Fork 12
test: nuke int; move state transition tests to state transition module #166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0b64074
b167eea
7ac3b3e
c17ec5e
318ce49
f180d8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,3 +52,18 @@ pub fn becomesNewEth1Data(allocator: std.mem.Allocator, state: *BeaconState, new | |
|
|
||
| return false; | ||
| } | ||
|
|
||
| const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; | ||
| const Node = @import("persistent_merkle_tree").Node; | ||
|
|
||
| test "process eth1 data - sanity" { | ||
| const allocator = std.testing.allocator; | ||
| var pool = try Node.Pool.init(allocator, 1024); | ||
| defer pool.deinit(); | ||
|
|
||
| var test_state = try TestCachedBeaconState.init(allocator, &pool, 256); | ||
| defer test_state.deinit(); | ||
|
|
||
| const block = types.electra.BeaconBlock.default_value; | ||
| try processEth1Data(allocator, test_state.cached_state, &block.body.eth1_data); | ||
| } | ||
|
Comment on lines
+59
to
+69
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to other new sanity tests, this one could be strengthened by asserting post-conditions. The References
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,14 +3,15 @@ const Allocator = std.mem.Allocator; | |
| const CachedBeaconState = @import("../cache/state_cache.zig").CachedBeaconState; | ||
| const types = @import("consensus_types"); | ||
| const preset = @import("preset").preset; | ||
| const ForkSeq = @import("config").ForkSeq; | ||
| const config = @import("config"); | ||
| const ForkSeq = config.ForkSeq; | ||
| const SignedBlock = @import("../types/block.zig").SignedBlock; | ||
| const Body = @import("../types/block.zig").Body; | ||
| const ExecutionPayloadStatus = @import("../state_transition.zig").ExecutionPayloadStatus; | ||
| const ExecutionPayloadHeader = @import("../types/execution_payload.zig").ExecutionPayloadHeader; | ||
| const SignedBlindedBeaconBlock = @import("../types/beacon_block.zig").SignedBlindedBeaconBlock; | ||
| const BlockExternalData = @import("../state_transition.zig").BlockExternalData; | ||
| const BeaconConfig = @import("config").BeaconConfig; | ||
| const BeaconConfig = config.BeaconConfig; | ||
| const isMergeTransitionComplete = @import("../utils/execution.zig").isMergeTransitionComplete; | ||
| const computeEpochAtSlot = @import("../utils/epoch.zig").computeEpochAtSlot; | ||
| const getRandaoMix = @import("../utils/seed.zig").getRandaoMix; | ||
|
|
@@ -29,8 +30,8 @@ pub fn processExecutionPayload( | |
| external_data: BlockExternalData, | ||
| ) !void { | ||
| const state = cached_state.state; | ||
| const beacon_config = cached_state.config; | ||
| const epoch_cache = cached_state.getEpochCache(); | ||
| const config = epoch_cache.config; | ||
| var partial_payload = PartialPayload{}; | ||
| switch (body) { | ||
| .regular => |b| { | ||
|
|
@@ -72,12 +73,12 @@ pub fn processExecutionPayload( | |
| // def compute_timestamp_at_slot(state: BeaconState, slot: Slot) -> uint64: | ||
| // slots_since_genesis = slot - GENESIS_SLOT | ||
| // return uint64(state.genesis_time + slots_since_genesis * SECONDS_PER_SLOT) | ||
| if (partial_payload.timestamp != (try state.genesisTime()) + (try state.slot()) * config.chain.SECONDS_PER_SLOT) { | ||
| if (partial_payload.timestamp != (try state.genesisTime() + try state.slot() * beacon_config.chain.SECONDS_PER_SLOT)) { | ||
| return error.InvalidExecutionPayloadTimestamp; | ||
| } | ||
|
|
||
| if (state.forkSeq().gte(.deneb)) { | ||
| const max_blobs_per_block = config.getMaxBlobsPerBlock(computeEpochAtSlot(try state.slot())); | ||
| const max_blobs_per_block = beacon_config.getMaxBlobsPerBlock(computeEpochAtSlot(try state.slot())); | ||
| if (body.blobKzgCommitmentsLen() > max_blobs_per_block) { | ||
| return error.BlobKzgCommitmentsExceedsLimit; | ||
| } | ||
|
|
@@ -105,3 +106,37 @@ pub fn processExecutionPayload( | |
|
|
||
| try state.setLatestExecutionPayloadHeader(&payload_header); | ||
| } | ||
|
|
||
| const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; | ||
| const Block = @import("../types/block.zig").Block; | ||
| const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; | ||
| const Node = @import("persistent_merkle_tree").Node; | ||
|
|
||
| test "process execution payload - sanity" { | ||
| const allocator = std.testing.allocator; | ||
|
|
||
| var pool = try Node.Pool.init(allocator, 1024); | ||
| defer pool.deinit(); | ||
|
|
||
| var test_state = try TestCachedBeaconState.init(allocator, &pool, 256); | ||
| defer test_state.deinit(); | ||
|
|
||
| var execution_payload: types.electra.ExecutionPayload.Type = types.electra.ExecutionPayload.default_value; | ||
| const beacon_config = test_state.cached_state.config; | ||
| execution_payload.timestamp = try test_state.cached_state.state.genesisTime() + try test_state.cached_state.state.slot() * beacon_config.chain.SECONDS_PER_SLOT; | ||
| var body: types.electra.BeaconBlockBody.Type = types.electra.BeaconBlockBody.default_value; | ||
| body.execution_payload = execution_payload; | ||
|
|
||
| var message: types.electra.BeaconBlock.Type = types.electra.BeaconBlock.default_value; | ||
| message.body = body; | ||
|
|
||
| const beacon_block = BeaconBlock{ .electra = &message }; | ||
| const block = Block{ .regular = beacon_block }; | ||
|
|
||
| try processExecutionPayload( | ||
| allocator, | ||
| test_state.cached_state, | ||
| block.beaconBlockBody(), | ||
| .{ .execution_payload_status = .valid, .data_availability_status = .available }, | ||
| ); | ||
| } | ||
|
Comment on lines
+115
to
+142
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test correctly sets up a valid timestamp to pass the check within References
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,10 @@ | ||
| const std = @import("std"); | ||
| const CachedBeaconState = @import("../cache/state_cache.zig").CachedBeaconState; | ||
| const types = @import("consensus_types"); | ||
| const preset = @import("preset").preset; | ||
| const config = @import("config"); | ||
| const ForkSeq = config.ForkSeq; | ||
| const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; | ||
| const Body = @import("../types/block.zig").Body; | ||
| const Bytes32 = types.primitive.Bytes32.Type; | ||
| const getRandaoMix = @import("../utils/seed.zig").getRandaoMix; | ||
|
|
@@ -40,3 +44,33 @@ fn xor(a: *const [32]u8, b: *const [32]u8, out: *[32]u8) void { | |
| out_i.* = a_i ^ b_i; | ||
| } | ||
| } | ||
|
|
||
| const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; | ||
| const Block = @import("../types/block.zig").Block; | ||
| const Node = @import("persistent_merkle_tree").Node; | ||
|
|
||
| test "process randao - sanity" { | ||
| const allocator = std.testing.allocator; | ||
|
|
||
| var pool = try Node.Pool.init(allocator, 1024); | ||
| defer pool.deinit(); | ||
|
|
||
| var test_state = try TestCachedBeaconState.init(allocator, &pool, 256); | ||
| const slot = config.mainnet.chain_config.ELECTRA_FORK_EPOCH * preset.SLOTS_PER_EPOCH + 2025 * preset.SLOTS_PER_EPOCH - 1; | ||
| defer test_state.deinit(); | ||
|
|
||
| const proposers = test_state.cached_state.getEpochCache().proposers; | ||
|
|
||
| var message: types.electra.BeaconBlock.Type = types.electra.BeaconBlock.default_value; | ||
| const proposer_index = proposers[slot % preset.SLOTS_PER_EPOCH]; | ||
| var header = try test_state.cached_state.state.latestBlockHeader(); | ||
| const header_parent_root = try header.hashTreeRoot(); | ||
|
|
||
| message.slot = slot; | ||
| message.proposer_index = proposer_index; | ||
| message.parent_root = header_parent_root.*; | ||
|
|
||
| const beacon_block = BeaconBlock{ .electra = &message }; | ||
| const block = Block{ .regular = beacon_block }; | ||
| try processRandao(test_state.cached_state, block.beaconBlockBody(), block.proposerIndex(), false); | ||
| } | ||
|
Comment on lines
+52
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sanity test is good for ensuring the function runs without errors on a valid state. To improve it, you could add an assertion to check that the References
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,3 +110,15 @@ pub fn processEffectiveBalanceUpdates(allocator: Allocator, cached_state: *Cache | |
| cache.next_epoch_total_active_balance_by_increment = next_epoch_total_active_balance_by_increment; | ||
| return num_update; | ||
| } | ||
|
|
||
| test "processEffectiveBalanceUpdates - sanity" { | ||
| try @import("../test_utils/test_runner.zig").TestRunner( | ||
| processEffectiveBalanceUpdates, | ||
| .{ | ||
| .alloc = true, | ||
| .err_return = true, | ||
| .void_return = false, | ||
| }, | ||
| ).testProcessEpochFn(); | ||
| defer @import("../state_transition.zig").deinitStateTransition(); | ||
| } | ||
|
Comment on lines
+114
to
+124
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a Consider adding a dedicated test that sets up a validator with a balance that would trigger the hysteresis update, then call References
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sanity test is a good start, but it only verifies that
processBlockHeaderdoesn't return an error. To make the test more robust, it should also assert that the function has the intended side effects on the state.Specifically,
processBlockHeaderupdates thelatest_block_headerin the state. You could add assertions to verify that the header has been updated correctly with the new block's data.Additionally, the style guide (line 296) recommends adding a comment at the top of tests to explain their goal and methodology. Adding a brief description would improve clarity for future readers.
References