From 0b64074ab733ff933c75ace165aba23c7c02846e Mon Sep 17 00:00:00 2001 From: bing Date: Mon, 12 Jan 2026 19:12:23 +0800 Subject: [PATCH 1/6] test: nuke int; move state transition tests to state transition module In a similar vein with moving the `ssz` tests to the ssz module, we move the state transition tests to `state_transition` because they aren't actually integration tests, and with that we nuke `int` entirely. We rename `int_slow` to `int` - technically our era tests are the only 'integration' tests anyway! Why this re-organization: - `int` was a ambiguous test directory name to begin with - there were some tests spread between their own module and within the `int` directory, despite the tests actually not being integration in nature. This was clearer in the `ssz` tests refactored in #162. - we can now test each module independently. Previously, if we made changes to `ssz`, we're forced to do both `zig build test:ssz` and `zig build test:int` because our tests were scattered. It also unnecessarily runs the `state_transition` tests since they're both put in `int`. With this structure we can test only the module we are working on and made changes in. - test locality - it's obvious right away if a certain key procedure does not have tests, if the tests are located in proximity with the implementation. --- build.zig | 34 +---- .../block/process_blob_kzg_commitments.zig | 7 + .../block/process_block_header.zig | 31 ++++- .../block/process_eth1_data.zig | 15 +++ .../block/process_execution_payload.zig | 37 +++++- .../block/process_operations.zig | 16 +++ src/state_transition/block/process_randao.zig | 31 +++++ .../block/process_sync_committee.zig | 37 ++++++ .../block/process_withdrawals.zig | 22 ++++ .../process_effective_balance_updates.zig | 12 ++ src/state_transition/epoch/process_epoch.zig | 9 ++ .../epoch/process_eth1_data_reset.zig | 9 ++ .../process_historical_summaries_update.zig | 9 ++ .../epoch/process_inactivity_updates.zig | 9 ++ ...process_justification_and_finalization.zig | 9 ++ .../process_participation_flag_updates.zig | 18 +++ .../epoch/process_pending_consolidations.zig | 9 ++ .../epoch/process_pending_deposits.zig | 9 ++ .../epoch/process_proposer_lookahead.zig | 10 ++ .../epoch/process_randao_mixes_reset.zig | 9 ++ .../epoch/process_registry_updates.zig | 9 ++ .../epoch/process_rewards_and_penalties.zig | 9 ++ .../epoch/process_slashings.zig | 9 ++ .../epoch/process_slashings_reset.zig | 9 ++ .../epoch/process_sync_committee_updates.zig | 13 ++ src/state_transition/state_transition.zig | 55 ++++++++ .../test_utils}/test_runner.zig | 8 +- .../process_effective_balance_updates.zig | 19 --- test/int/epoch/process_epoch.zig | 16 --- test/int/epoch/process_eth1_data_reset.zig | 16 --- .../process_historical_summaries_update.zig | 16 --- test/int/epoch/process_inactivity_updates.zig | 16 --- ...process_justification_and_finalization.zig | 16 --- .../process_participation_flag_updates.zig | 21 --- .../epoch/process_pending_consolidations.zig | 16 --- test/int/epoch/process_pending_deposits.zig | 19 --- test/int/epoch/process_proposer_lookahead.zig | 13 -- test/int/epoch/process_randao_mixes_reset.zig | 19 --- test/int/epoch/process_registry_updates.zig | 16 --- .../epoch/process_rewards_and_penalties.zig | 16 --- test/int/epoch/process_slashings.zig | 16 --- test/int/epoch/process_slashings_reset.zig | 16 --- .../epoch/process_sync_committee_updates.zig | 23 ---- test/int/era/root.zig | 123 ++++++++++++++++++ test/int/process_blob_kzg_commitments.zig | 8 -- test/int/process_block_header.zig | 38 ------ test/int/process_eth1_data.zig | 23 ---- test/int/process_execution_payload.zig | 41 ------ test/int/process_operations.zig | 26 ---- test/int/process_randao.zig | 42 ------ test/int/process_sync_aggregate.zig | 57 -------- test/int/process_withdrawals.zig | 38 ------ test/int/root.zig | 48 ------- test/int/state_transition.zig | 69 ---------- test/int_slow/era/root.zig | 117 ----------------- test/int_slow/root.zig | 5 - zbuild.zon | 16 --- 57 files changed, 536 insertions(+), 843 deletions(-) rename {test/int/epoch => src/state_transition/test_utils}/test_runner.zig (89%) delete mode 100644 test/int/epoch/process_effective_balance_updates.zig delete mode 100644 test/int/epoch/process_epoch.zig delete mode 100644 test/int/epoch/process_eth1_data_reset.zig delete mode 100644 test/int/epoch/process_historical_summaries_update.zig delete mode 100644 test/int/epoch/process_inactivity_updates.zig delete mode 100644 test/int/epoch/process_justification_and_finalization.zig delete mode 100644 test/int/epoch/process_participation_flag_updates.zig delete mode 100644 test/int/epoch/process_pending_consolidations.zig delete mode 100644 test/int/epoch/process_pending_deposits.zig delete mode 100644 test/int/epoch/process_proposer_lookahead.zig delete mode 100644 test/int/epoch/process_randao_mixes_reset.zig delete mode 100644 test/int/epoch/process_registry_updates.zig delete mode 100644 test/int/epoch/process_rewards_and_penalties.zig delete mode 100644 test/int/epoch/process_slashings.zig delete mode 100644 test/int/epoch/process_slashings_reset.zig delete mode 100644 test/int/epoch/process_sync_committee_updates.zig create mode 100644 test/int/era/root.zig delete mode 100644 test/int/process_blob_kzg_commitments.zig delete mode 100644 test/int/process_block_header.zig delete mode 100644 test/int/process_eth1_data.zig delete mode 100644 test/int/process_execution_payload.zig delete mode 100644 test/int/process_operations.zig delete mode 100644 test/int/process_randao.zig delete mode 100644 test/int/process_sync_aggregate.zig delete mode 100644 test/int/process_withdrawals.zig delete mode 100644 test/int/root.zig delete mode 100644 test/int/state_transition.zig delete mode 100644 test/int_slow/era/root.zig delete mode 100644 test/int_slow/root.zig diff --git a/build.zig b/build.zig index adcfd7640..740a4c075 100644 --- a/build.zig +++ b/build.zig @@ -772,27 +772,6 @@ pub fn build(b: *std.Build) void { tls_run_test_int.dependOn(&run_test_int.step); tls_run_test.dependOn(&run_test_int.step); - const module_int_slow = b.createModule(.{ - .root_source_file = b.path("test/int_slow/root.zig"), - .target = target, - .optimize = optimize, - }); - b.modules.put(b.dupe("int_slow"), module_int_slow) catch @panic("OOM"); - - const test_int_slow = b.addTest(.{ - .name = "int_slow", - .root_module = module_int_slow, - .filters = b.option([][]const u8, "int_slow.filters", "int_slow test filters") orelse &[_][]const u8{}, - }); - const install_test_int_slow = b.addInstallArtifact(test_int_slow, .{}); - const tls_install_test_int_slow = b.step("build-test:int_slow", "Install the int_slow test"); - tls_install_test_int_slow.dependOn(&install_test_int_slow.step); - - const run_test_int_slow = b.addRunArtifact(test_int_slow); - const tls_run_test_int_slow = b.step("test:int_slow", "Run the int_slow test"); - tls_run_test_int_slow.dependOn(&run_test_int_slow.step); - tls_run_test.dependOn(&run_test_int_slow.step); - const module_spec_tests = b.createModule(.{ .root_source_file = b.path("test/spec/root.zig"), .target = target, @@ -952,18 +931,9 @@ pub fn build(b: *std.Build) void { module_bench_process_epoch.addImport("download_era_options", options_module_download_era_options); module_bench_process_epoch.addImport("era", module_era); - module_int.addImport("build_options", options_module_build_options); - module_int.addImport("state_transition", module_state_transition); module_int.addImport("config", module_config); - module_int.addImport("consensus_types", module_consensus_types); - module_int.addImport("preset", module_preset); - module_int.addImport("constants", module_constants); - module_int.addImport("blst", dep_blst.module("blst")); - module_int.addImport("persistent_merkle_tree", module_persistent_merkle_tree); - - module_int_slow.addImport("config", module_config); - module_int_slow.addImport("download_era_options", options_module_download_era_options); - module_int_slow.addImport("era", module_era); + module_int.addImport("download_era_options", options_module_download_era_options); + module_int.addImport("era", module_era); module_spec_tests.addImport("spec_test_options", options_module_spec_test_options); module_spec_tests.addImport("consensus_types", module_consensus_types); diff --git a/src/state_transition/block/process_blob_kzg_commitments.zig b/src/state_transition/block/process_blob_kzg_commitments.zig index 63220f412..1d7e34af4 100644 --- a/src/state_transition/block/process_blob_kzg_commitments.zig +++ b/src/state_transition/block/process_blob_kzg_commitments.zig @@ -9,3 +9,10 @@ pub fn processBlobKzgCommitments(external_data: BlockExternalData) !void { else => {}, } } + +test "process blob kzg commitments - sanity" { + try processBlobKzgCommitments(.{ + .execution_payload_status = .valid, + .data_availability_status = .available, + }); +} diff --git a/src/state_transition/block/process_block_header.zig b/src/state_transition/block/process_block_header.zig index 46fe49c33..4b29bd8e2 100644 --- a/src/state_transition/block/process_block_header.zig +++ b/src/state_transition/block/process_block_header.zig @@ -3,7 +3,8 @@ const Allocator = std.mem.Allocator; const types = @import("consensus_types"); const CachedBeaconState = @import("../cache/state_cache.zig").CachedBeaconState; const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; -const BeaconConfig = @import("config").BeaconConfig; +const config = @import("config"); +const BeaconConfig = config.BeaconConfig; const BeaconBlockHeader = types.phase0.BeaconBlockHeader.Type; const Root = types.primitive.Root; const SignedBlock = @import("../types/block.zig").SignedBlock; @@ -66,3 +67,31 @@ pub fn blockToHeader(allocator: Allocator, signed_block: SignedBlock, out: *Beac out.state_root = block.stateRoot(); try block.hashTreeRoot(allocator, &out.body_root); } + +const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const preset = @import("preset").preset; + +test "process block header - sanity" { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 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_parent_root: [32]u8 = undefined; + try types.phase0.BeaconBlockHeader.hashTreeRoot(test_state.cached_state.state.latestBlockHeader(), &header_parent_root); + + 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 processBlockHeader(allocator, test_state.cached_state, block); +} diff --git a/src/state_transition/block/process_eth1_data.zig b/src/state_transition/block/process_eth1_data.zig index 2f41e1073..585881a16 100644 --- a/src/state_transition/block/process_eth1_data.zig +++ b/src/state_transition/block/process_eth1_data.zig @@ -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); +} diff --git a/src/state_transition/block/process_execution_payload.zig b/src/state_transition/block/process_execution_payload.zig index 5b7db7fa8..1d21b1cbb 100644 --- a/src/state_transition/block/process_execution_payload.zig +++ b/src/state_transition/block/process_execution_payload.zig @@ -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; @@ -30,7 +31,7 @@ pub fn processExecutionPayload( ) !void { const state = cached_state.state; const epoch_cache = cached_state.getEpochCache(); - const config = epoch_cache.config; + const epoch_cache_config = epoch_cache.config; var partial_payload = PartialPayload{}; switch (body) { .regular => |b| { @@ -72,7 +73,7 @@ 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 != state.genesisTime() + state.slot() * config.chain.SECONDS_PER_SLOT) { return error.InvalidExecutionPayloadTimestamp; } @@ -105,3 +106,31 @@ pub fn processExecutionPayload( try state.setLatestExecutionPayloadHeader(&payload_header); } + +const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; +const Block = @import("../types/block.zig").Block; +const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +test "process execution payload - sanity" { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + defer test_state.deinit(); + + var execution_payload: types.electra.ExecutionPayload.Type = types.electra.ExecutionPayload.default_value; + execution_payload.timestamp = test_state.cached_state.state.genesisTime() + test_state.cached_state.state.slot() * config.mainnet.chain_config.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 }, + ); +} diff --git a/src/state_transition/block/process_operations.zig b/src/state_transition/block/process_operations.zig index 540ad2480..03182cdab 100644 --- a/src/state_transition/block/process_operations.zig +++ b/src/state_transition/block/process_operations.zig @@ -78,3 +78,19 @@ pub fn processOperations( } } } + +const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const Block = @import("../types/block.zig").Block; +const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; +test "process operations" { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + defer test_state.deinit(); + + const electra_block = types.electra.BeaconBlock.default_value; + const beacon_block = BeaconBlock{ .electra = &electra_block }; + + const block = Block{ .regular = beacon_block }; + try processOperations(allocator, test_state.cached_state, block.beaconBlockBody(), .{}); +} diff --git a/src/state_transition/block/process_randao.zig b/src/state_transition/block/process_randao.zig index 517128a02..67261108c 100644 --- a/src/state_transition/block/process_randao.zig +++ b/src/state_transition/block/process_randao.zig @@ -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,30 @@ fn xor(a: *const [32]u8, b: *const [32]u8, out: *[32]u8) void { out_i.* = a_i ^ b_i; } } + +const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const Block = @import("../types/block.zig").Block; + +test "process randao - sanity" { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 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_parent_root: [32]u8 = undefined; + try types.phase0.BeaconBlockHeader.hashTreeRoot(test_state.cached_state.state.latestBlockHeader(), &header_parent_root); + + 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); +} diff --git a/src/state_transition/block/process_sync_committee.zig b/src/state_transition/block/process_sync_committee.zig index d23d9481f..a16ccb5d4 100644 --- a/src/state_transition/block/process_sync_committee.zig +++ b/src/state_transition/block/process_sync_committee.zig @@ -163,3 +163,40 @@ pub fn getSyncCommitteeSignatureSet(allocator: Allocator, cached_state: *CachedB .signature = signature, }; } + +const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const test_utils = @import("../test_utils/root.zig"); + +test "process sync aggregate - sanity" { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + defer test_state.deinit(); + + const state = test_state.cached_state.state; + const config = test_state.cached_state.config; + const previous_slot = state.slot() - 1; + const root_signed = try getBlockRootAtSlot(state, previous_slot); + const domain = try config.getDomain(state.slot(), c.DOMAIN_SYNC_COMMITTEE, previous_slot); + var signing_root: Root = undefined; + try computeSigningRoot(types.primitive.Root, &root_signed, domain, &signing_root); + + const committee_indices = @as(*const [preset.SYNC_COMMITTEE_SIZE]ValidatorIndex, @ptrCast(test_state.cached_state.getEpochCache().current_sync_committee_indexed.get().getValidatorIndices())); + // validator 0 signs + const sig0 = try test_utils.interopSign(committee_indices[0], &signing_root); + // validator 1 signs + const sig1 = try test_utils.interopSign(committee_indices[1], &signing_root); + const agg_sig = try blst.AggregateSignature.aggregate(&.{ sig0, sig1 }, true); + + var sync_aggregate: types.electra.SyncAggregate.Type = types.electra.SyncAggregate.default_value; + sync_aggregate.sync_committee_signature = agg_sig.toSignature().compress(); + try sync_aggregate.sync_committee_bits.set(0, true); + // don't set bit 1 yet + + const res = processSyncAggregate(allocator, test_state.cached_state, &sync_aggregate, true); + try std.testing.expect(res == error.SyncCommitteeSignatureInvalid); + + // now set bit 1 + try sync_aggregate.sync_committee_bits.set(1, true); + try processSyncAggregate(allocator, test_state.cached_state, &sync_aggregate, true); +} diff --git a/src/state_transition/block/process_withdrawals.zig b/src/state_transition/block/process_withdrawals.zig index f0f618502..b435f3470 100644 --- a/src/state_transition/block/process_withdrawals.zig +++ b/src/state_transition/block/process_withdrawals.zig @@ -218,3 +218,25 @@ pub fn getExpectedWithdrawals( withdrawals_result.sampled_validators = n; withdrawals_result.processed_partial_withdrawals_count = processed_partial_withdrawals_count; } +const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +test "process withdrawals - sanity" { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + defer test_state.deinit(); + var withdrawals_result = WithdrawalsResult{ + .withdrawals = try Withdrawals.initCapacity( + allocator, + preset.MAX_WITHDRAWALS_PER_PAYLOAD, + ), + }; + defer withdrawals_result.withdrawals.deinit(allocator); + var withdrawal_balances = std.AutoHashMap(ValidatorIndex, usize).init(allocator); + defer withdrawal_balances.deinit(); + + var root: Root = undefined; + try types.capella.Withdrawals.hashTreeRoot(allocator, &withdrawals_result.withdrawals, &root); + + try getExpectedWithdrawals(allocator, &withdrawals_result, &withdrawal_balances, test_state.cached_state); + try processWithdrawals(allocator, test_state.cached_state, withdrawals_result, root); +} diff --git a/src/state_transition/epoch/process_effective_balance_updates.zig b/src/state_transition/epoch/process_effective_balance_updates.zig index 7b60ed604..6efd1e959 100644 --- a/src/state_transition/epoch/process_effective_balance_updates.zig +++ b/src/state_transition/epoch/process_effective_balance_updates.zig @@ -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(); +} diff --git a/src/state_transition/epoch/process_epoch.zig b/src/state_transition/epoch/process_epoch.zig index 78655eeb9..3ce55ea0d 100644 --- a/src/state_transition/epoch/process_epoch.zig +++ b/src/state_transition/epoch/process_epoch.zig @@ -69,3 +69,12 @@ pub fn processEpoch(allocator: std.mem.Allocator, cached_state: *CachedBeaconSta try processProposerLookahead(allocator, cached_state, cache); } } + +test "processEpoch - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processEpoch, .{ + .alloc = true, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_eth1_data_reset.zig b/src/state_transition/epoch/process_eth1_data_reset.zig index 0e8bfda2c..38d3d0ccc 100644 --- a/src/state_transition/epoch/process_eth1_data_reset.zig +++ b/src/state_transition/epoch/process_eth1_data_reset.zig @@ -14,3 +14,12 @@ pub fn processEth1DataReset(cached_state: *CachedBeaconState, cache: *const Epoc try state.resetEth1DataVotes(); } } + +test "processEth1DataReset - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processEth1DataReset, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_historical_summaries_update.zig b/src/state_transition/epoch/process_historical_summaries_update.zig index e5a5b0af5..16033d4f3 100644 --- a/src/state_transition/epoch/process_historical_summaries_update.zig +++ b/src/state_transition/epoch/process_historical_summaries_update.zig @@ -21,3 +21,12 @@ pub fn processHistoricalSummariesUpdate(cached_state: *CachedBeaconState, cache: try historical_summaries.pushValue(&new_historical_summary); } } + +test "processHistoricalSummariesUpdate - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processHistoricalSummariesUpdate, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_inactivity_updates.zig b/src/state_transition/epoch/process_inactivity_updates.zig index 1e326279f..a4ac5eecc 100644 --- a/src/state_transition/epoch/process_inactivity_updates.zig +++ b/src/state_transition/epoch/process_inactivity_updates.zig @@ -45,3 +45,12 @@ pub fn processInactivityUpdates(cached_state: *CachedBeaconState, cache: *const } } } + +test "processInactivityUpdates - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processInactivityUpdates, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_justification_and_finalization.zig b/src/state_transition/epoch/process_justification_and_finalization.zig index 44c46ca70..5100e504d 100644 --- a/src/state_transition/epoch/process_justification_and_finalization.zig +++ b/src/state_transition/epoch/process_justification_and_finalization.zig @@ -84,3 +84,12 @@ pub fn weighJustificationAndFinalization(cached_state: *CachedBeaconState, total try state.setFinalizedCheckpoint(&old_current_justified_checkpoint); } } + +test "processJustificationAndFinalization - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processJustificationAndFinalization, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_participation_flag_updates.zig b/src/state_transition/epoch/process_participation_flag_updates.zig index 2f7f009fe..644446f9f 100644 --- a/src/state_transition/epoch/process_participation_flag_updates.zig +++ b/src/state_transition/epoch/process_participation_flag_updates.zig @@ -7,3 +7,21 @@ pub fn processParticipationFlagUpdates(cached_state: *CachedBeaconState) !void { if (state.forkSeq().lt(.altair)) return; try state.rotateEpochParticipation(); } + +const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; +const Node = @import("persistent_merkle_tree").Node; + +test "processParticipationFlagUpdates - sanity" { + const allocator = std.testing.allocator; + const validator_count_arr = &.{ 256, 10_000 }; + + var pool = try Node.Pool.init(allocator, 1024); + defer pool.deinit(); + + inline for (validator_count_arr) |validator_count| { + var test_state = try TestCachedBeaconState.init(allocator, &pool, validator_count); + defer test_state.deinit(); + try processParticipationFlagUpdates(test_state.cached_state); + } + defer @import("../root.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_pending_consolidations.zig b/src/state_transition/epoch/process_pending_consolidations.zig index 31b8c1749..b72d4c688 100644 --- a/src/state_transition/epoch/process_pending_consolidations.zig +++ b/src/state_transition/epoch/process_pending_consolidations.zig @@ -51,3 +51,12 @@ pub fn processPendingConsolidations(cached_state: *CachedBeaconState, cache: *Ep try state.setPendingConsolidations(new_pending_consolidations); } } + +test "processPendingConsolidations - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processPendingConsolidations, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_pending_deposits.zig b/src/state_transition/epoch/process_pending_deposits.zig index 69a357feb..fd55d91b2 100644 --- a/src/state_transition/epoch/process_pending_deposits.zig +++ b/src/state_transition/epoch/process_pending_deposits.zig @@ -150,3 +150,12 @@ fn applyPendingDeposit(allocator: Allocator, cached_state: *CachedBeaconState, d } } } + +test "processPendingDeposits - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processPendingDeposits, .{ + .alloc = true, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_proposer_lookahead.zig b/src/state_transition/epoch/process_proposer_lookahead.zig index 378d12a90..88831a372 100644 --- a/src/state_transition/epoch/process_proposer_lookahead.zig +++ b/src/state_transition/epoch/process_proposer_lookahead.zig @@ -60,3 +60,13 @@ pub fn processProposerLookahead( try state.setProposerLookahead(proposer_lookahead); } + +test "processProposerLookahead sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processProposerLookahead, .{ + .alloc = true, + .err_return = true, + .void_return = true, + .fulu = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_randao_mixes_reset.zig b/src/state_transition/epoch/process_randao_mixes_reset.zig index 6834138dd..232f6ce70 100644 --- a/src/state_transition/epoch/process_randao_mixes_reset.zig +++ b/src/state_transition/epoch/process_randao_mixes_reset.zig @@ -18,3 +18,12 @@ pub fn processRandaoMixesReset(cached_state: *CachedBeaconState, cache: *const E try old.clone(.{}), ); } + +test "processRandaoMixesReset - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processRandaoMixesReset, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_registry_updates.zig b/src/state_transition/epoch/process_registry_updates.zig index a39e58b75..2d3987014 100644 --- a/src/state_transition/epoch/process_registry_updates.zig +++ b/src/state_transition/epoch/process_registry_updates.zig @@ -48,3 +48,12 @@ pub fn processRegistryUpdates(cached_state: *CachedBeaconState, cache: *const Ep try validator.set("activation_epoch", activation_epoch); } } + +test "processRegistryUpdates - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processRegistryUpdates, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_rewards_and_penalties.zig b/src/state_transition/epoch/process_rewards_and_penalties.zig index c2dfd91a8..43a8e72aa 100644 --- a/src/state_transition/epoch/process_rewards_and_penalties.zig +++ b/src/state_transition/epoch/process_rewards_and_penalties.zig @@ -46,3 +46,12 @@ pub fn getRewardsAndPenalties( else try getRewardsAndPenaltiesAltair(allocator, cached_state, cache, rewards, penalties); } + +test "processRewardsAndPenalties - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processRewardsAndPenalties, .{ + .alloc = true, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_slashings.zig b/src/state_transition/epoch/process_slashings.zig index 7691ed1bc..c9b9638b3 100644 --- a/src/state_transition/epoch/process_slashings.zig +++ b/src/state_transition/epoch/process_slashings.zig @@ -67,3 +67,12 @@ pub fn getTotalSlashingsByIncrement(state: *BeaconState) !u64 { return total_slashings_by_increment; } + +test "processSlashings - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processSlashings, .{ + .alloc = true, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_slashings_reset.zig b/src/state_transition/epoch/process_slashings_reset.zig index 97334c268..d8a366f84 100644 --- a/src/state_transition/epoch/process_slashings_reset.zig +++ b/src/state_transition/epoch/process_slashings_reset.zig @@ -20,3 +20,12 @@ pub fn processSlashingsReset(cached_state: *CachedBeaconState, cache: *const Epo try slashings.set(slash_index, 0); epoch_cache.total_slashings_by_increment = @max(0, epoch_cache.total_slashings_by_increment - old_slashing_value_by_increment); } + +test "processSlashingsReset - sanity" { + try @import("../test_utils/test_runner.zig").TestRunner(processSlashingsReset, .{ + .alloc = false, + .err_return = true, + .void_return = true, + }).testProcessEpochFn(); + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/epoch/process_sync_committee_updates.zig b/src/state_transition/epoch/process_sync_committee_updates.zig index b58377e40..a5b9ad23e 100644 --- a/src/state_transition/epoch/process_sync_committee_updates.zig +++ b/src/state_transition/epoch/process_sync_committee_updates.zig @@ -28,3 +28,16 @@ pub fn processSyncCommitteeUpdates(allocator: Allocator, cached_state: *CachedBe try epoch_cache.rotateSyncCommitteeIndexed(allocator, &next_sync_committee_info.indices); } } + +test "processSyncCommitteeUpdates - sanity" { + const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; + const allocator = std.testing.allocator; + const validator_count_arr = &.{ 256, 10_000 }; + + inline for (validator_count_arr) |validator_count| { + var test_state = try TestCachedBeaconStateAllForks.init(allocator, validator_count); + defer test_state.deinit(); + try processSyncCommitteeUpdates(allocator, test_state.cached_state); + } + defer @import("../state_transition.zig").deinitStateTransition(); +} diff --git a/src/state_transition/state_transition.zig b/src/state_transition/state_transition.zig index 547489d32..c6030e8f6 100644 --- a/src/state_transition/state_transition.zig +++ b/src/state_transition/state_transition.zig @@ -208,3 +208,58 @@ pub fn stateTransition( pub fn deinitStateTransition() void { deinitReusedEpochTransitionCache(); } + +const TestCase = struct { + transition_opt: TransitionOpt, + expect_error: bool, +}; + +const TestCachedBeaconStateAllForks = @import("test_utils/root.zig").TestCachedBeaconStateAllForks; +const generateElectraBlock = @import("test_utils/generate_block.zig").generateElectraBlock; +const testing = std.testing; + +test "state transition - electra block" { + const test_cases = [_]TestCase{ + .{ .transition_opt = .{ .verify_signatures = true }, .expect_error = true }, + .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = true }, .expect_error = true }, + .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = false, .verify_state_root = true }, .expect_error = true }, + // this runs through epoch transition + process block without verifications + .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = false, .verify_state_root = false }, .expect_error = false }, + }; + inline for (test_cases) |tc| { + const allocator = std.testing.allocator; + + var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + defer test_state.deinit(); + const electra_block_ptr = try allocator.create(types.electra.SignedBeaconBlock.Type); + try generateElectraBlock(allocator, test_state.cached_state, electra_block_ptr); + defer { + types.electra.SignedBeaconBlock.deinit(allocator, electra_block_ptr); + allocator.destroy(electra_block_ptr); + } + + const signed_beacon_block = SignedBeaconBlock{ .electra = electra_block_ptr }; + const signed_block = SignedBlock{ .regular = signed_beacon_block }; + + // this returns the error so no need to handle returned post_state + // TODO: if blst can publish BlstError.BadEncoding, can just use testing.expectError + // testing.expectError(blst.c.BLST_BAD_ENCODING, stateTransition(allocator, test_state.cached_state, signed_block, .{ .verify_signatures = true })); + const res = stateTransition(allocator, test_state.cached_state, signed_block, tc.transition_opt); + if (tc.expect_error) { + if (res) |_| { + try testing.expect(false); + } else |_| {} + } else { + if (res) |post_state| { + defer { + post_state.deinit(); + allocator.destroy(post_state); + } + } else |_| { + try testing.expect(false); + } + } + } + + defer deinitStateTransition(); +} diff --git a/test/int/epoch/test_runner.zig b/src/state_transition/test_utils/test_runner.zig similarity index 89% rename from test/int/epoch/test_runner.zig rename to src/state_transition/test_utils/test_runner.zig index 524456b27..a53df8f1b 100644 --- a/test/int/epoch/test_runner.zig +++ b/src/state_transition/test_utils/test_runner.zig @@ -1,8 +1,8 @@ const std = @import("std"); const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const EpochTransitionCache = state_transition.EpochTransitionCache; +const upgradeStateToFulu = @import("../slot/upgrade_state_to_fulu.zig").upgradeStateToFulu; +const TestCachedBeaconState = @import("generate_state.zig").TestCachedBeaconState; +const EpochTransitionCache = @import("../cache/epoch_transition_cache.zig").EpochTransitionCache; const Node = @import("persistent_merkle_tree").Node; pub const TestOpt = struct { @@ -26,7 +26,7 @@ pub fn TestRunner(process_epoch_fn: anytype, opt: TestOpt) type { defer test_state.deinit(); if (opt.fulu) { - try state_transition.upgradeStateToFulu(allocator, test_state.cached_state); + try upgradeStateToFulu(allocator, test_state.cached_state); } var epoch_transition_cache = try EpochTransitionCache.init( diff --git a/test/int/epoch/process_effective_balance_updates.zig b/test/int/epoch/process_effective_balance_updates.zig deleted file mode 100644 index d6e49379d..000000000 --- a/test/int/epoch/process_effective_balance_updates.zig +++ /dev/null @@ -1,19 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processEffectiveBalanceUpdates - sanity" { - try TestRunner( - state_transition.processEffectiveBalanceUpdates, - .{ - .alloc = true, - .err_return = true, - .void_return = false, - }, - ).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_epoch.zig b/test/int/epoch/process_epoch.zig deleted file mode 100644 index 19d8ada28..000000000 --- a/test/int/epoch/process_epoch.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processEpoch - sanity" { - try TestRunner(state_transition.processEpoch, .{ - .alloc = true, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_eth1_data_reset.zig b/test/int/epoch/process_eth1_data_reset.zig deleted file mode 100644 index 08a15586a..000000000 --- a/test/int/epoch/process_eth1_data_reset.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processEth1DataReset - sanity" { - try TestRunner(state_transition.processEth1DataReset, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_historical_summaries_update.zig b/test/int/epoch/process_historical_summaries_update.zig deleted file mode 100644 index d97ec814e..000000000 --- a/test/int/epoch/process_historical_summaries_update.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processHistoricalSummariesUpdate - sanity" { - try TestRunner(state_transition.processHistoricalSummariesUpdate, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_inactivity_updates.zig b/test/int/epoch/process_inactivity_updates.zig deleted file mode 100644 index cd8035328..000000000 --- a/test/int/epoch/process_inactivity_updates.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processInactivityUpdates - sanity" { - try TestRunner(state_transition.processInactivityUpdates, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_justification_and_finalization.zig b/test/int/epoch/process_justification_and_finalization.zig deleted file mode 100644 index e374a1a99..000000000 --- a/test/int/epoch/process_justification_and_finalization.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processJustificationAndFinalization - sanity" { - try TestRunner(state_transition.processJustificationAndFinalization, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_participation_flag_updates.zig b/test/int/epoch/process_participation_flag_updates.zig deleted file mode 100644 index 7c046afe3..000000000 --- a/test/int/epoch/process_participation_flag_updates.zig +++ /dev/null @@ -1,21 +0,0 @@ -const std = @import("std"); -const state_transition = @import("state_transition"); -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const processParticipationFlagUpdates = state_transition.processParticipationFlagUpdates; -const Node = @import("persistent_merkle_tree").Node; -// this function runs without EpochTransionCache so cannot use getTestProcessFn - -test "processParticipationFlagUpdates - sanity" { - const allocator = std.testing.allocator; - const validator_count_arr = &.{ 256, 10_000 }; - - var pool = try Node.Pool.init(allocator, 1024); - defer pool.deinit(); - - inline for (validator_count_arr) |validator_count| { - var test_state = try TestCachedBeaconState.init(allocator, &pool, validator_count); - defer test_state.deinit(); - try processParticipationFlagUpdates(test_state.cached_state); - } - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_pending_consolidations.zig b/test/int/epoch/process_pending_consolidations.zig deleted file mode 100644 index 45ca2feb4..000000000 --- a/test/int/epoch/process_pending_consolidations.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processPendingConsolidations - sanity" { - try TestRunner(state_transition.processPendingConsolidations, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_pending_deposits.zig b/test/int/epoch/process_pending_deposits.zig deleted file mode 100644 index 20eb5896b..000000000 --- a/test/int/epoch/process_pending_deposits.zig +++ /dev/null @@ -1,19 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processPendingDeposits - sanity" { - try TestRunner(state_transition.processPendingDeposits, .{ - // .no_alloc = false, - .alloc = true, - // .no_err_return = false, - .err_return = true, - // .no_void_return = false, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_proposer_lookahead.zig b/test/int/epoch/process_proposer_lookahead.zig deleted file mode 100644 index 8d44958e1..000000000 --- a/test/int/epoch/process_proposer_lookahead.zig +++ /dev/null @@ -1,13 +0,0 @@ -const std = @import("std"); -const state_transition = @import("state_transition"); -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processProposerLookahead sanity" { - try TestRunner(state_transition.processProposerLookahead, .{ - .alloc = true, - .err_return = true, - .void_return = true, - .fulu = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_randao_mixes_reset.zig b/test/int/epoch/process_randao_mixes_reset.zig deleted file mode 100644 index 45a1c156d..000000000 --- a/test/int/epoch/process_randao_mixes_reset.zig +++ /dev/null @@ -1,19 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processRandaoMixesReset - sanity" { - try TestRunner( - state_transition.processRandaoMixesReset, - .{ - .alloc = false, - .err_return = true, - .void_return = true, - }, - ).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_registry_updates.zig b/test/int/epoch/process_registry_updates.zig deleted file mode 100644 index 84971bab7..000000000 --- a/test/int/epoch/process_registry_updates.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processRegistryUpdates - sanity" { - try TestRunner(state_transition.processRegistryUpdates, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_rewards_and_penalties.zig b/test/int/epoch/process_rewards_and_penalties.zig deleted file mode 100644 index d54878771..000000000 --- a/test/int/epoch/process_rewards_and_penalties.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processRewardsAndPenalties - sanity" { - try TestRunner(state_transition.processRewardsAndPenalties, .{ - .alloc = true, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_slashings.zig b/test/int/epoch/process_slashings.zig deleted file mode 100644 index 85c778e18..000000000 --- a/test/int/epoch/process_slashings.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processSlashings - sanity" { - try TestRunner(state_transition.processSlashings, .{ - .alloc = true, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_slashings_reset.zig b/test/int/epoch/process_slashings_reset.zig deleted file mode 100644 index 8b6cae591..000000000 --- a/test/int/epoch/process_slashings_reset.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const ReusedEpochTransitionCache = state_transition.ReusedEpochTransitionCache; -const EpochTransitionCache = state_transition.EpochTransitionCache; -const TestRunner = @import("./test_runner.zig").TestRunner; - -test "processSlashingsReset - sanity" { - try TestRunner(state_transition.processSlashingsReset, .{ - .alloc = false, - .err_return = true, - .void_return = true, - }).testProcessEpochFn(); - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/epoch/process_sync_committee_updates.zig b/test/int/epoch/process_sync_committee_updates.zig deleted file mode 100644 index 09bbc5cee..000000000 --- a/test/int/epoch/process_sync_committee_updates.zig +++ /dev/null @@ -1,23 +0,0 @@ -const std = @import("std"); -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const state_transition = @import("state_transition"); -const EpochTransitionCache = state_transition.EpochTransitionCache; -const processSyncCommitteeUpdates = state_transition.processSyncCommitteeUpdates; -const Node = @import("persistent_merkle_tree").Node; -// this function runs without EpochTransionCache so cannot use getTestProcessFn - -test "processSyncCommitteeUpdates - sanity" { - const allocator = std.testing.allocator; - const validator_count_arr = &.{ 256, 10_000 }; - - var pool = try Node.Pool.init(allocator, 1024); - defer pool.deinit(); - - inline for (validator_count_arr) |validator_count| { - var test_state = try TestCachedBeaconState.init(allocator, &pool, validator_count); - defer test_state.deinit(); - try processSyncCommitteeUpdates(allocator, test_state.cached_state); - } - defer state_transition.deinitStateTransition(); -} diff --git a/test/int/era/root.zig b/test/int/era/root.zig new file mode 100644 index 000000000..5aa0df9ca --- /dev/null +++ b/test/int/era/root.zig @@ -0,0 +1,123 @@ +<<<<<<< Conflict 1 of 1 +%%%%%%% Changes from base to side #1 + const std = @import("std"); + const era = @import("era"); + const download_era_options = @import("download_era_options"); + const c = @import("config"); + + const allocator = std.testing.allocator; + + test "validate an existing era file" { + const era_path = try std.fs.path.join( + allocator, + &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, + ); + defer allocator.free(era_path); + + // First check that the era file exists + if (std.fs.cwd().openFile(era_path, .{})) |f| { + f.close(); + } else |_| { + return error.SkipZigTest; + } + + var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); + defer reader.close(allocator); + + // Main validation + try reader.validate(allocator); + } + + test "write an era file from an existing era file" { + const era_path = try std.fs.path.join( + allocator, + &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, + ); + defer allocator.free(era_path); + + // First check that the era file exists + if (std.fs.cwd().openFile(era_path, .{})) |f| { + f.close(); + } else |_| { + return error.SkipZigTest; + } + + // Read known-good era file + var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); + defer reader.close(allocator); + + var tmp_dir = std.testing.tmpDir(.{}); + defer tmp_dir.cleanup(); + + const tmp_dir_path = try tmp_dir.dir.realpathAlloc(allocator, "."); + defer allocator.free(tmp_dir_path); + const out_path = try std.fs.path.join(allocator, &[_][]const u8{ tmp_dir_path, "out.era" }); + defer allocator.free(out_path); + + // Write known-good era to a new era file + var writer = try era.Writer.open(c.mainnet.config, out_path, reader.era_number); + + const blocks_index = reader.group_indices[0].blocks_index orelse return error.NoBlockIndex; + for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { + const block = try reader.readBlock(allocator, slot) orelse continue; + defer block.deinit(allocator); + + try writer.writeBlock(allocator, block); + } + var state = try reader.readState(allocator, null); +- defer state.deinit(allocator); ++ defer state.deinit(); + + try writer.writeState(allocator, state); + + const final_out_path = try writer.finish(allocator); + defer allocator.free(final_out_path); + + // Now check that the two era files are equivalent + + // Compare file names + if (!std.mem.eql(u8, std.fs.path.basename(final_out_path), std.fs.path.basename(era_path))) { + return error.IncorrectWrittenEraFileName; + } + var out_reader = try era.Reader.open(allocator, c.mainnet.config, final_out_path); + defer out_reader.close(allocator); + + // Compare struct fields + if (out_reader.era_number != reader.era_number) { + return error.IncorrectWrittenEraNumber; + } + if (!std.mem.eql(u8, &reader.short_historical_root, &out_reader.short_historical_root)) { + return error.IncorrectWrittenShortHistoricalRoot; + } + // We can't directly compare bytes or offsets (snappy compression isn't deterministic across implementations) + // if (!std.mem.eql(u8, std.mem.sliceAsBytes(reader.groups), std.mem.sliceAsBytes(out_reader.groups))) { + // return error.IncorrectWrittenEraIndices; + // } + + // Compare blocks + for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { + const block = try reader.readSerializedBlock(allocator, slot) orelse continue; + const out_block = try out_reader.readSerializedBlock(allocator, slot) orelse return error.MissingBlock; + defer allocator.free(block); + defer allocator.free(out_block); + + if (!std.mem.eql(u8, block, out_block)) { + return error.IncorrectWrittenBlock; + } + } + // Compare state + var out_state = try out_reader.readState(allocator, null); +- defer out_state.deinit(allocator); ++ defer out_state.deinit(); + + const serialized = try state.serialize(allocator); + defer allocator.free(serialized); + const out_serialized = try out_state.serialize(allocator); + defer allocator.free(out_serialized); + + if (!std.mem.eql(u8, serialized, out_serialized)) { + return error.IncorrectWrittenState; + } + } ++++++++ Contents of side #2 +>>>>>>> Conflict 1 of 1 ends diff --git a/test/int/process_blob_kzg_commitments.zig b/test/int/process_blob_kzg_commitments.zig deleted file mode 100644 index adff72a90..000000000 --- a/test/int/process_blob_kzg_commitments.zig +++ /dev/null @@ -1,8 +0,0 @@ -test "process blob kzg commitments - sanity" { - try processBlobKzgCommitments(.{ - .execution_payload_status = .valid, - .data_availability_status = .available, - }); -} - -const processBlobKzgCommitments = @import("state_transition").processBlobKzgCommitments; diff --git a/test/int/process_block_header.zig b/test/int/process_block_header.zig deleted file mode 100644 index 24917a353..000000000 --- a/test/int/process_block_header.zig +++ /dev/null @@ -1,38 +0,0 @@ -test "process block header - 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 latest_header_view = try test_state.cached_state.state.latestBlockHeader(); - const header_parent_root = try latest_header_view.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 processBlockHeader(allocator, test_state.cached_state, block); -} - -const std = @import("std"); -const types = @import("consensus_types"); -const config = @import("config"); -const state_transition = @import("state_transition"); -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const preset = @import("preset").preset; -const processBlockHeader = state_transition.processBlockHeader; -const Block = state_transition.Block; -const BeaconBlock = state_transition.BeaconBlock; -const Node = @import("persistent_merkle_tree").Node; diff --git a/test/int/process_eth1_data.zig b/test/int/process_eth1_data.zig deleted file mode 100644 index e89236b01..000000000 --- a/test/int/process_eth1_data.zig +++ /dev/null @@ -1,23 +0,0 @@ -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); -} - -const std = @import("std"); -const types = @import("consensus_types"); - -const state_transition = @import("state_transition"); -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const processEth1Data = state_transition.processEth1Data; -const SignedBlock = state_transition.SignedBlock; -const SignedBeaconBlock = state_transition.SignedBeaconBlock; diff --git a/test/int/process_execution_payload.zig b/test/int/process_execution_payload.zig deleted file mode 100644 index d41e08768..000000000 --- a/test/int/process_execution_payload.zig +++ /dev/null @@ -1,41 +0,0 @@ -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; - execution_payload.timestamp = (try test_state.cached_state.state.genesisTime()) + (try test_state.cached_state.state.slot()) * config.mainnet.chain_config.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 }, - ); -} - -const std = @import("std"); -const types = @import("consensus_types"); -const config = @import("config"); - -const state_transition = @import("state_transition"); -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const processExecutionPayload = state_transition.processExecutionPayload; -const SignedBlock = state_transition.SignedBlock; -const Block = state_transition.Block; -const SignedBeaconBlock = state_transition.SignedBeaconBlock; -const BeaconBlock = state_transition.BeaconBlock; diff --git a/test/int/process_operations.zig b/test/int/process_operations.zig deleted file mode 100644 index 906e0c742..000000000 --- a/test/int/process_operations.zig +++ /dev/null @@ -1,26 +0,0 @@ -const Node = @import("persistent_merkle_tree").Node; - -test "process operations" { - 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 electra_block = types.electra.BeaconBlock.default_value; - const beacon_block = BeaconBlock{ .electra = &electra_block }; - - const block = Block{ .regular = beacon_block }; - try processOperations(allocator, test_state.cached_state, block.beaconBlockBody(), .{}); -} - -const std = @import("std"); -const types = @import("consensus_types"); - -const state_transition = @import("state_transition"); -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const processOperations = state_transition.processOperations; -const Block = state_transition.Block; -const BeaconBlock = state_transition.BeaconBlock; diff --git a/test/int/process_randao.zig b/test/int/process_randao.zig deleted file mode 100644 index 549666dae..000000000 --- a/test/int/process_randao.zig +++ /dev/null @@ -1,42 +0,0 @@ -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 latest_header_view = try test_state.cached_state.state.latestBlockHeader(); - const header_parent_root = try latest_header_view.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); -} - -const std = @import("std"); -const types = @import("consensus_types"); -const config = @import("config"); - -const Allocator = std.mem.Allocator; -const state_transition = @import("state_transition"); -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; - -const preset = @import("preset").preset; - -const processRandao = state_transition.processRandao; -const Block = state_transition.Block; -const BeaconBlock = state_transition.BeaconBlock; diff --git a/test/int/process_sync_aggregate.zig b/test/int/process_sync_aggregate.zig deleted file mode 100644 index a5ce74737..000000000 --- a/test/int/process_sync_aggregate.zig +++ /dev/null @@ -1,57 +0,0 @@ -test "process sync aggregate - 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 state = test_state.cached_state.state; - const config = test_state.cached_state.config; - const previous_slot = (try state.slot()) - 1; - const root_signed = try state_transition.getBlockRootAtSlot(state, previous_slot); - const domain = try config.getDomain(try state.slot(), c.DOMAIN_SYNC_COMMITTEE, previous_slot); - var signing_root: Root = undefined; - try computeSigningRoot(types.primitive.Root, root_signed, domain, &signing_root); - - const committee_indices = @as(*const [preset.SYNC_COMMITTEE_SIZE]ValidatorIndex, @ptrCast(test_state.cached_state.getEpochCache().current_sync_committee_indexed.get().getValidatorIndices())); - // validator 0 signs - const sig0 = try state_transition.test_utils.interopSign(committee_indices[0], &signing_root); - // validator 1 signs - const sig1 = try state_transition.test_utils.interopSign(committee_indices[1], &signing_root); - const agg_sig = try blst.AggregateSignature.aggregate(&.{ sig0, sig1 }, true); - - var sync_aggregate: types.electra.SyncAggregate.Type = types.electra.SyncAggregate.default_value; - sync_aggregate.sync_committee_signature = agg_sig.toSignature().compress(); - try sync_aggregate.sync_committee_bits.set(0, true); - // don't set bit 1 yet - - const res = processSyncAggregate(allocator, test_state.cached_state, &sync_aggregate, true); - try std.testing.expect(res == error.SyncCommitteeSignatureInvalid); - - // now set bit 1 - try sync_aggregate.sync_committee_bits.set(1, true); - try processSyncAggregate(allocator, test_state.cached_state, &sync_aggregate, true); -} - -const std = @import("std"); -const types = @import("consensus_types"); -const blst = @import("blst"); -const preset = @import("preset").preset; -const c = @import("constants"); - -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = @import("state_transition").test_utils.TestCachedBeaconState; -const Node = @import("persistent_merkle_tree").Node; - -const state_transition = @import("state_transition"); -const processSyncAggregate = state_transition.processSyncAggregate; -const Root = types.primitive.Root.Type; -const ValidatorIndex = types.primitive.ValidatorIndex.Type; -const Block = state_transition.Block; -const SignedBlock = state_transition.SignedBlock; -const BeaconBlock = state_transition.BeaconBlock; -const SignedBeaconBlock = state_transition.SignedBeaconBlock; -const computeSigningRoot = state_transition.computeSigningRoot; -const G2_POINT_AT_INFINITY = @import("constants").G2_POINT_AT_INFINITY; diff --git a/test/int/process_withdrawals.zig b/test/int/process_withdrawals.zig deleted file mode 100644 index 681323a5b..000000000 --- a/test/int/process_withdrawals.zig +++ /dev/null @@ -1,38 +0,0 @@ -const Node = @import("persistent_merkle_tree").Node; - -test "process withdrawals - 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 withdrawals_result = WithdrawalsResult{ - .withdrawals = try Withdrawals.initCapacity( - allocator, - preset.MAX_WITHDRAWALS_PER_PAYLOAD, - ), - }; - defer withdrawals_result.withdrawals.deinit(allocator); - var withdrawal_balances = std.AutoHashMap(ValidatorIndex, usize).init(allocator); - defer withdrawal_balances.deinit(); - - var root: Root = undefined; - try types.capella.Withdrawals.hashTreeRoot(allocator, &withdrawals_result.withdrawals, &root); - - try getExpectedWithdrawals(allocator, &withdrawals_result, &withdrawal_balances, test_state.cached_state); - try processWithdrawals(allocator, test_state.cached_state, withdrawals_result, root); -} - -const std = @import("std"); -const state_transition = @import("state_transition"); -const preset = @import("preset").preset; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const processWithdrawals = state_transition.processWithdrawals; -const getExpectedWithdrawals = state_transition.getExpectedWithdrawals; -const WithdrawalsResult = state_transition.WithdrawalsResult; -const types = @import("consensus_types"); -const Root = types.primitive.Root.Type; -const Withdrawals = types.capella.Withdrawals.Type; -const ValidatorIndex = types.primitive.ValidatorIndex.Type; diff --git a/test/int/root.zig b/test/int/root.zig deleted file mode 100644 index 0d4a20b2c..000000000 --- a/test/int/root.zig +++ /dev/null @@ -1,48 +0,0 @@ -const std = @import("std"); -const testing = std.testing; -const state_transition = @import("./state_transition.zig"); -const process_justification_and_finalization = @import("./epoch/process_justification_and_finalization.zig"); -const process_inactivity_updates = @import("./epoch/process_inactivity_updates.zig"); -const process_registry_updates = @import("./epoch/process_registry_updates.zig"); -const process_slashings = @import("./epoch/process_slashings.zig"); -const process_rewards_and_penalties = @import("./epoch/process_rewards_and_penalties.zig"); -const process_eth1_data_reset = @import("./epoch/process_eth1_data_reset.zig"); -const process_pending_deposits = @import("./epoch/process_pending_deposits.zig"); -const process_pending_consolidations = @import("./epoch/process_pending_consolidations.zig"); -const process_effective_balance_updates = @import("./epoch/process_effective_balance_updates.zig"); -const process_slashings_reset = @import("./epoch/process_slashings_reset.zig"); -const process_randao_mixes_reset = @import("./epoch/process_randao_mixes_reset.zig"); -const process_historical_summaries_update = @import("./epoch/process_historical_summaries_update.zig"); -const process_participation_flag_updates = @import("./epoch/process_participation_flag_updates.zig"); -const process_sync_committee_updates = @import("./epoch/process_sync_committee_updates.zig"); -const process_proposer_lookahead = @import("./epoch/process_proposer_lookahead.zig"); -const process_epoch = @import("./epoch/process_epoch.zig"); - -test { - testing.refAllDecls(process_justification_and_finalization); - testing.refAllDecls(process_rewards_and_penalties); - testing.refAllDecls(process_inactivity_updates); - testing.refAllDecls(process_slashings); - testing.refAllDecls(process_registry_updates); - testing.refAllDecls(process_eth1_data_reset); - testing.refAllDecls(process_pending_deposits); - testing.refAllDecls(process_pending_consolidations); - testing.refAllDecls(process_effective_balance_updates); - testing.refAllDecls(process_slashings_reset); - testing.refAllDecls(process_randao_mixes_reset); - testing.refAllDecls(process_historical_summaries_update); - testing.refAllDecls(process_participation_flag_updates); - testing.refAllDecls(process_sync_committee_updates); - testing.refAllDecls(process_proposer_lookahead); - testing.refAllDecls(process_epoch); - testing.refAllDecls(state_transition); - - testing.refAllDecls(@import("./process_block_header.zig")); - testing.refAllDecls(@import("./process_withdrawals.zig")); - testing.refAllDecls(@import("./process_execution_payload.zig")); - testing.refAllDecls(@import("./process_randao.zig")); - testing.refAllDecls(@import("./process_eth1_data.zig")); - testing.refAllDecls(@import("./process_operations.zig")); - testing.refAllDecls(@import("./process_sync_aggregate.zig")); - testing.refAllDecls(@import("./process_blob_kzg_commitments.zig")); -} diff --git a/test/int/state_transition.zig b/test/int/state_transition.zig deleted file mode 100644 index af4b54045..000000000 --- a/test/int/state_transition.zig +++ /dev/null @@ -1,69 +0,0 @@ -const std = @import("std"); -const testing = std.testing; -const Allocator = std.mem.Allocator; -const TestCachedBeaconState = state_transition.test_utils.TestCachedBeaconState; -const generateElectraBlock = state_transition.test_utils.generateElectraBlock; -const types = @import("consensus_types"); -const Root = types.primitive.Root.Type; -const ZERO_HASH = @import("constants").ZERO_HASH; - -const state_transition = @import("state_transition"); -const Node = @import("persistent_merkle_tree").Node; -const stateTransition = state_transition.state_transition.stateTransition; -const TransitionOpt = state_transition.state_transition.TransitionOpt; -const SignedBeaconBlock = state_transition.state_transition.SignedBeaconBlock; -const CachedBeaconState = state_transition.CachedBeaconState; -const SignedBlock = state_transition.SignedBlock; - -const TestCase = struct { - transition_opt: TransitionOpt, - expect_error: bool, -}; - -test "state transition - electra block" { - const test_cases = [_]TestCase{ - .{ .transition_opt = .{ .verify_signatures = true }, .expect_error = true }, - .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = true }, .expect_error = true }, - .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = false, .verify_state_root = true }, .expect_error = true }, - // this runs through epoch transition + process block without verifications - .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = false, .verify_state_root = false }, .expect_error = false }, - }; - inline for (test_cases) |tc| { - 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 electra_block_ptr = try allocator.create(types.electra.SignedBeaconBlock.Type); - try generateElectraBlock(allocator, test_state.cached_state, electra_block_ptr); - defer { - types.electra.SignedBeaconBlock.deinit(allocator, electra_block_ptr); - allocator.destroy(electra_block_ptr); - } - - const signed_beacon_block = SignedBeaconBlock{ .electra = electra_block_ptr }; - const signed_block = SignedBlock{ .regular = signed_beacon_block }; - - // this returns the error so no need to handle returned post_state - // TODO: if blst can publish BlstError.BadEncoding, can just use testing.expectError - // testing.expectError(blst.c.BLST_BAD_ENCODING, stateTransition(allocator, test_state.cached_state, signed_block, .{ .verify_signatures = true })); - const res = stateTransition(allocator, test_state.cached_state, signed_block, tc.transition_opt); - if (tc.expect_error) { - if (res) |_| { - try testing.expect(false); - } else |_| {} - } else { - if (res) |post_state| { - defer { - post_state.deinit(); - allocator.destroy(post_state); - } - } else |_| { - try testing.expect(false); - } - } - } - - defer state_transition.deinitStateTransition(); -} diff --git a/test/int_slow/era/root.zig b/test/int_slow/era/root.zig deleted file mode 100644 index e4f061181..000000000 --- a/test/int_slow/era/root.zig +++ /dev/null @@ -1,117 +0,0 @@ -const std = @import("std"); -const era = @import("era"); -const download_era_options = @import("download_era_options"); -const c = @import("config"); - -const allocator = std.testing.allocator; - -test "validate an existing era file" { - const era_path = try std.fs.path.join( - allocator, - &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, - ); - defer allocator.free(era_path); - - // First check that the era file exists - if (std.fs.cwd().openFile(era_path, .{})) |f| { - f.close(); - } else |_| { - return error.SkipZigTest; - } - - var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); - defer reader.close(allocator); - - // Main validation - try reader.validate(allocator); -} - -test "write an era file from an existing era file" { - const era_path = try std.fs.path.join( - allocator, - &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, - ); - defer allocator.free(era_path); - - // First check that the era file exists - if (std.fs.cwd().openFile(era_path, .{})) |f| { - f.close(); - } else |_| { - return error.SkipZigTest; - } - - // Read known-good era file - var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); - defer reader.close(allocator); - - var tmp_dir = std.testing.tmpDir(.{}); - defer tmp_dir.cleanup(); - - const tmp_dir_path = try tmp_dir.dir.realpathAlloc(allocator, "."); - defer allocator.free(tmp_dir_path); - const out_path = try std.fs.path.join(allocator, &[_][]const u8{ tmp_dir_path, "out.era" }); - defer allocator.free(out_path); - - // Write known-good era to a new era file - var writer = try era.Writer.open(c.mainnet.config, out_path, reader.era_number); - - const blocks_index = reader.group_indices[0].blocks_index orelse return error.NoBlockIndex; - for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { - const block = try reader.readBlock(allocator, slot) orelse continue; - defer block.deinit(allocator); - - try writer.writeBlock(allocator, block); - } - var state = try reader.readState(allocator, null); - defer state.deinit(); - - try writer.writeState(allocator, state); - - const final_out_path = try writer.finish(allocator); - defer allocator.free(final_out_path); - - // Now check that the two era files are equivalent - - // Compare file names - if (!std.mem.eql(u8, std.fs.path.basename(final_out_path), std.fs.path.basename(era_path))) { - return error.IncorrectWrittenEraFileName; - } - var out_reader = try era.Reader.open(allocator, c.mainnet.config, final_out_path); - defer out_reader.close(allocator); - - // Compare struct fields - if (out_reader.era_number != reader.era_number) { - return error.IncorrectWrittenEraNumber; - } - if (!std.mem.eql(u8, &reader.short_historical_root, &out_reader.short_historical_root)) { - return error.IncorrectWrittenShortHistoricalRoot; - } - // We can't directly compare bytes or offsets (snappy compression isn't deterministic across implementations) - // if (!std.mem.eql(u8, std.mem.sliceAsBytes(reader.groups), std.mem.sliceAsBytes(out_reader.groups))) { - // return error.IncorrectWrittenEraIndices; - // } - - // Compare blocks - for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { - const block = try reader.readSerializedBlock(allocator, slot) orelse continue; - const out_block = try out_reader.readSerializedBlock(allocator, slot) orelse return error.MissingBlock; - defer allocator.free(block); - defer allocator.free(out_block); - - if (!std.mem.eql(u8, block, out_block)) { - return error.IncorrectWrittenBlock; - } - } - // Compare state - var out_state = try out_reader.readState(allocator, null); - defer out_state.deinit(); - - const serialized = try state.serialize(allocator); - defer allocator.free(serialized); - const out_serialized = try out_state.serialize(allocator); - defer allocator.free(out_serialized); - - if (!std.mem.eql(u8, serialized, out_serialized)) { - return error.IncorrectWrittenState; - } -} diff --git a/test/int_slow/root.zig b/test/int_slow/root.zig deleted file mode 100644 index 94ff6c9cb..000000000 --- a/test/int_slow/root.zig +++ /dev/null @@ -1,5 +0,0 @@ -const testing = @import("std").testing; - -test { - testing.refAllDecls(@import("./era/root.zig")); -} diff --git a/zbuild.zon b/zbuild.zon index 36d7e4af9..9986b09ed 100644 --- a/zbuild.zon +++ b/zbuild.zon @@ -203,22 +203,6 @@ .int = .{ .root_module = .{ .root_source_file = "test/int/root.zig", - .imports = .{ - .build_options, - .state_transition, - .config, - .consensus_types, - .preset, - .constants, - .blst, - .persistent_merkle_tree, - }, - }, - .filters = .{}, - }, - .int_slow = .{ - .root_module = .{ - .root_source_file = "test/int_slow/root.zig", .imports = .{ .config, .download_era_options, From b167eea1bc68d7b21e643f08535173b4118dafc7 Mon Sep 17 00:00:00 2001 From: bing Date: Tue, 20 Jan 2026 22:48:38 +0800 Subject: [PATCH 2/6] more fixes --- .../block/process_block_header.zig | 14 +++++++++----- .../block/process_execution_payload.zig | 16 ++++++++++------ .../block/process_operations.zig | 9 +++++++-- src/state_transition/block/process_randao.zig | 15 +++++++++------ .../block/process_sync_committee.zig | 14 +++++++++----- .../block/process_withdrawals.zig | 10 ++++++++-- .../epoch/process_sync_committee_updates.zig | 8 ++++++-- src/state_transition/state_transition.zig | 8 ++++++-- 8 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/state_transition/block/process_block_header.zig b/src/state_transition/block/process_block_header.zig index 4b29bd8e2..f05b1f59c 100644 --- a/src/state_transition/block/process_block_header.zig +++ b/src/state_transition/block/process_block_header.zig @@ -68,13 +68,17 @@ pub fn blockToHeader(allocator: Allocator, signed_block: SignedBlock, out: *Beac try block.hashTreeRoot(allocator, &out.body_root); } -const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; const preset = @import("preset").preset; +const Node = @import("persistent_merkle_tree").Node; test "process block header - sanity" { const allocator = std.testing.allocator; - var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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(); @@ -83,12 +87,12 @@ test "process block header - sanity" { var message: types.electra.BeaconBlock.Type = types.electra.BeaconBlock.default_value; const proposer_index = proposers[slot % preset.SLOTS_PER_EPOCH]; - var header_parent_root: [32]u8 = undefined; - try types.phase0.BeaconBlockHeader.hashTreeRoot(test_state.cached_state.state.latestBlockHeader(), &header_parent_root); + 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; + message.parent_root = header_parent_root.*; const beacon_block = BeaconBlock{ .electra = &message }; diff --git a/src/state_transition/block/process_execution_payload.zig b/src/state_transition/block/process_execution_payload.zig index 1d21b1cbb..b01f62282 100644 --- a/src/state_transition/block/process_execution_payload.zig +++ b/src/state_transition/block/process_execution_payload.zig @@ -31,7 +31,6 @@ pub fn processExecutionPayload( ) !void { const state = cached_state.state; const epoch_cache = cached_state.getEpochCache(); - const epoch_cache_config = epoch_cache.config; var partial_payload = PartialPayload{}; switch (body) { .regular => |b| { @@ -73,12 +72,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 != state.genesisTime() + state.slot() * config.chain.SECONDS_PER_SLOT) { + if (partial_payload.timestamp != try state.genesisTime() + try state.slot() * config.mainnet.chain_config.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 = config.mainnet.config.getMaxBlobsPerBlock(computeEpochAtSlot(try state.slot())); if (body.blobKzgCommitmentsLen() > max_blobs_per_block) { return error.BlobKzgCommitmentsExceedsLimit; } @@ -109,15 +108,20 @@ pub fn processExecutionPayload( const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; const Block = @import("../types/block.zig").Block; -const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +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 test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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; - execution_payload.timestamp = test_state.cached_state.state.genesisTime() + test_state.cached_state.state.slot() * config.mainnet.chain_config.SECONDS_PER_SLOT; + execution_payload.timestamp = try test_state.cached_state.state.genesisTime() + try test_state.cached_state.state.slot() * config.mainnet.chain_config.SECONDS_PER_SLOT; var body: types.electra.BeaconBlockBody.Type = types.electra.BeaconBlockBody.default_value; body.execution_payload = execution_payload; diff --git a/src/state_transition/block/process_operations.zig b/src/state_transition/block/process_operations.zig index 03182cdab..9ac64b855 100644 --- a/src/state_transition/block/process_operations.zig +++ b/src/state_transition/block/process_operations.zig @@ -79,13 +79,18 @@ pub fn processOperations( } } -const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; const Block = @import("../types/block.zig").Block; const BeaconBlock = @import("../types/beacon_block.zig").BeaconBlock; +const Node = @import("persistent_merkle_tree").Node; + test "process operations" { const allocator = std.testing.allocator; - var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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 electra_block = types.electra.BeaconBlock.default_value; diff --git a/src/state_transition/block/process_randao.zig b/src/state_transition/block/process_randao.zig index 67261108c..c1f59cfd6 100644 --- a/src/state_transition/block/process_randao.zig +++ b/src/state_transition/block/process_randao.zig @@ -45,13 +45,17 @@ fn xor(a: *const [32]u8, b: *const [32]u8, out: *[32]u8) void { } } -const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +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 test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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(); @@ -59,13 +63,12 @@ test "process randao - sanity" { var message: types.electra.BeaconBlock.Type = types.electra.BeaconBlock.default_value; const proposer_index = proposers[slot % preset.SLOTS_PER_EPOCH]; - - var header_parent_root: [32]u8 = undefined; - try types.phase0.BeaconBlockHeader.hashTreeRoot(test_state.cached_state.state.latestBlockHeader(), &header_parent_root); + 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; + message.parent_root = header_parent_root.*; const beacon_block = BeaconBlock{ .electra = &message }; const block = Block{ .regular = beacon_block }; diff --git a/src/state_transition/block/process_sync_committee.zig b/src/state_transition/block/process_sync_committee.zig index a16ccb5d4..14a6c98bb 100644 --- a/src/state_transition/block/process_sync_committee.zig +++ b/src/state_transition/block/process_sync_committee.zig @@ -164,22 +164,26 @@ pub fn getSyncCommitteeSignatureSet(allocator: Allocator, cached_state: *CachedB }; } -const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; const test_utils = @import("../test_utils/root.zig"); +const Node = @import("persistent_merkle_tree").Node; test "process sync aggregate - sanity" { const allocator = std.testing.allocator; - var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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 state = test_state.cached_state.state; const config = test_state.cached_state.config; - const previous_slot = state.slot() - 1; + const previous_slot = try state.slot() - 1; const root_signed = try getBlockRootAtSlot(state, previous_slot); - const domain = try config.getDomain(state.slot(), c.DOMAIN_SYNC_COMMITTEE, previous_slot); + const domain = try config.getDomain(try state.slot(), c.DOMAIN_SYNC_COMMITTEE, previous_slot); var signing_root: Root = undefined; - try computeSigningRoot(types.primitive.Root, &root_signed, domain, &signing_root); + try computeSigningRoot(types.primitive.Root, root_signed, domain, &signing_root); const committee_indices = @as(*const [preset.SYNC_COMMITTEE_SIZE]ValidatorIndex, @ptrCast(test_state.cached_state.getEpochCache().current_sync_committee_indexed.get().getValidatorIndices())); // validator 0 signs diff --git a/src/state_transition/block/process_withdrawals.zig b/src/state_transition/block/process_withdrawals.zig index b435f3470..5bc181726 100644 --- a/src/state_transition/block/process_withdrawals.zig +++ b/src/state_transition/block/process_withdrawals.zig @@ -218,12 +218,18 @@ pub fn getExpectedWithdrawals( withdrawals_result.sampled_validators = n; withdrawals_result.processed_partial_withdrawals_count = processed_partial_withdrawals_count; } -const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; +const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; +const Node = @import("persistent_merkle_tree").Node; + test "process withdrawals - sanity" { const allocator = std.testing.allocator; - var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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 withdrawals_result = WithdrawalsResult{ .withdrawals = try Withdrawals.initCapacity( allocator, diff --git a/src/state_transition/epoch/process_sync_committee_updates.zig b/src/state_transition/epoch/process_sync_committee_updates.zig index a5b9ad23e..d658b9295 100644 --- a/src/state_transition/epoch/process_sync_committee_updates.zig +++ b/src/state_transition/epoch/process_sync_committee_updates.zig @@ -29,13 +29,17 @@ pub fn processSyncCommitteeUpdates(allocator: Allocator, cached_state: *CachedBe } } +const Node = @import("persistent_merkle_tree").Node; test "processSyncCommitteeUpdates - sanity" { - const TestCachedBeaconStateAllForks = @import("../test_utils/root.zig").TestCachedBeaconStateAllForks; + const TestCachedBeaconState = @import("../test_utils/root.zig").TestCachedBeaconState; const allocator = std.testing.allocator; const validator_count_arr = &.{ 256, 10_000 }; inline for (validator_count_arr) |validator_count| { - var test_state = try TestCachedBeaconStateAllForks.init(allocator, validator_count); + var pool = try Node.Pool.init(allocator, 1024); + defer pool.deinit(); + + var test_state = try TestCachedBeaconState.init(allocator, &pool, validator_count); defer test_state.deinit(); try processSyncCommitteeUpdates(allocator, test_state.cached_state); } diff --git a/src/state_transition/state_transition.zig b/src/state_transition/state_transition.zig index c6030e8f6..e199ccc31 100644 --- a/src/state_transition/state_transition.zig +++ b/src/state_transition/state_transition.zig @@ -214,9 +214,10 @@ const TestCase = struct { expect_error: bool, }; -const TestCachedBeaconStateAllForks = @import("test_utils/root.zig").TestCachedBeaconStateAllForks; +const TestCachedBeaconState = @import("test_utils/root.zig").TestCachedBeaconState; const generateElectraBlock = @import("test_utils/generate_block.zig").generateElectraBlock; const testing = std.testing; +const Node = @import("persistent_merkle_tree").Node; test "state transition - electra block" { const test_cases = [_]TestCase{ @@ -226,10 +227,13 @@ test "state transition - electra block" { // this runs through epoch transition + process block without verifications .{ .transition_opt = .{ .verify_signatures = false, .verify_proposer = false, .verify_state_root = false }, .expect_error = false }, }; + inline for (test_cases) |tc| { const allocator = std.testing.allocator; - var test_state = try TestCachedBeaconStateAllForks.init(allocator, 256); + 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 electra_block_ptr = try allocator.create(types.electra.SignedBeaconBlock.Type); try generateElectraBlock(allocator, test_state.cached_state, electra_block_ptr); From 7ac3b3e33d864eb3c7c9aa52363089b5ae347e77 Mon Sep 17 00:00:00 2001 From: bing Date: Tue, 20 Jan 2026 22:50:07 +0800 Subject: [PATCH 3/6] fix CI --- .github/workflows/CI.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 894794eb9..93909e44d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -99,9 +99,6 @@ jobs: - name: Run state-transition tests run: | zig build test:state_transition - - name: Run Int Tests - run: | - zig build test:int build-test-slow: name: slow tests @@ -126,7 +123,7 @@ jobs: zig build run:download_era_files - name: Run slow int tests run: | - zig build test:int_slow + zig build test:int spec-test-ssz: name: spec tests - ssz From c17ec5e58ad8377cdbe47031ce44e3d869507393 Mon Sep 17 00:00:00 2001 From: bing Date: Tue, 20 Jan 2026 22:52:34 +0800 Subject: [PATCH 4/6] conflcits --- test/int/era/root.zig | 240 ++++++++++++++++++++---------------------- zbuild.zon | 2 +- 2 files changed, 118 insertions(+), 124 deletions(-) diff --git a/test/int/era/root.zig b/test/int/era/root.zig index 5aa0df9ca..e4f061181 100644 --- a/test/int/era/root.zig +++ b/test/int/era/root.zig @@ -1,123 +1,117 @@ -<<<<<<< Conflict 1 of 1 -%%%%%%% Changes from base to side #1 - const std = @import("std"); - const era = @import("era"); - const download_era_options = @import("download_era_options"); - const c = @import("config"); - - const allocator = std.testing.allocator; - - test "validate an existing era file" { - const era_path = try std.fs.path.join( - allocator, - &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, - ); - defer allocator.free(era_path); - - // First check that the era file exists - if (std.fs.cwd().openFile(era_path, .{})) |f| { - f.close(); - } else |_| { - return error.SkipZigTest; - } - - var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); - defer reader.close(allocator); - - // Main validation - try reader.validate(allocator); - } - - test "write an era file from an existing era file" { - const era_path = try std.fs.path.join( - allocator, - &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, - ); - defer allocator.free(era_path); - - // First check that the era file exists - if (std.fs.cwd().openFile(era_path, .{})) |f| { - f.close(); - } else |_| { - return error.SkipZigTest; - } - - // Read known-good era file - var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); - defer reader.close(allocator); - - var tmp_dir = std.testing.tmpDir(.{}); - defer tmp_dir.cleanup(); - - const tmp_dir_path = try tmp_dir.dir.realpathAlloc(allocator, "."); - defer allocator.free(tmp_dir_path); - const out_path = try std.fs.path.join(allocator, &[_][]const u8{ tmp_dir_path, "out.era" }); - defer allocator.free(out_path); - - // Write known-good era to a new era file - var writer = try era.Writer.open(c.mainnet.config, out_path, reader.era_number); - - const blocks_index = reader.group_indices[0].blocks_index orelse return error.NoBlockIndex; - for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { - const block = try reader.readBlock(allocator, slot) orelse continue; - defer block.deinit(allocator); - - try writer.writeBlock(allocator, block); - } - var state = try reader.readState(allocator, null); -- defer state.deinit(allocator); -+ defer state.deinit(); - - try writer.writeState(allocator, state); - - const final_out_path = try writer.finish(allocator); - defer allocator.free(final_out_path); - - // Now check that the two era files are equivalent - - // Compare file names - if (!std.mem.eql(u8, std.fs.path.basename(final_out_path), std.fs.path.basename(era_path))) { - return error.IncorrectWrittenEraFileName; - } - var out_reader = try era.Reader.open(allocator, c.mainnet.config, final_out_path); - defer out_reader.close(allocator); - - // Compare struct fields - if (out_reader.era_number != reader.era_number) { - return error.IncorrectWrittenEraNumber; - } - if (!std.mem.eql(u8, &reader.short_historical_root, &out_reader.short_historical_root)) { - return error.IncorrectWrittenShortHistoricalRoot; - } - // We can't directly compare bytes or offsets (snappy compression isn't deterministic across implementations) - // if (!std.mem.eql(u8, std.mem.sliceAsBytes(reader.groups), std.mem.sliceAsBytes(out_reader.groups))) { - // return error.IncorrectWrittenEraIndices; - // } - - // Compare blocks - for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { - const block = try reader.readSerializedBlock(allocator, slot) orelse continue; - const out_block = try out_reader.readSerializedBlock(allocator, slot) orelse return error.MissingBlock; - defer allocator.free(block); - defer allocator.free(out_block); - - if (!std.mem.eql(u8, block, out_block)) { - return error.IncorrectWrittenBlock; - } - } - // Compare state - var out_state = try out_reader.readState(allocator, null); -- defer out_state.deinit(allocator); -+ defer out_state.deinit(); - - const serialized = try state.serialize(allocator); - defer allocator.free(serialized); - const out_serialized = try out_state.serialize(allocator); - defer allocator.free(out_serialized); - - if (!std.mem.eql(u8, serialized, out_serialized)) { - return error.IncorrectWrittenState; - } - } -+++++++ Contents of side #2 ->>>>>>> Conflict 1 of 1 ends +const std = @import("std"); +const era = @import("era"); +const download_era_options = @import("download_era_options"); +const c = @import("config"); + +const allocator = std.testing.allocator; + +test "validate an existing era file" { + const era_path = try std.fs.path.join( + allocator, + &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, + ); + defer allocator.free(era_path); + + // First check that the era file exists + if (std.fs.cwd().openFile(era_path, .{})) |f| { + f.close(); + } else |_| { + return error.SkipZigTest; + } + + var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); + defer reader.close(allocator); + + // Main validation + try reader.validate(allocator); +} + +test "write an era file from an existing era file" { + const era_path = try std.fs.path.join( + allocator, + &[_][]const u8{ download_era_options.era_out_dir, download_era_options.era_files[0] }, + ); + defer allocator.free(era_path); + + // First check that the era file exists + if (std.fs.cwd().openFile(era_path, .{})) |f| { + f.close(); + } else |_| { + return error.SkipZigTest; + } + + // Read known-good era file + var reader = try era.Reader.open(allocator, c.mainnet.config, era_path); + defer reader.close(allocator); + + var tmp_dir = std.testing.tmpDir(.{}); + defer tmp_dir.cleanup(); + + const tmp_dir_path = try tmp_dir.dir.realpathAlloc(allocator, "."); + defer allocator.free(tmp_dir_path); + const out_path = try std.fs.path.join(allocator, &[_][]const u8{ tmp_dir_path, "out.era" }); + defer allocator.free(out_path); + + // Write known-good era to a new era file + var writer = try era.Writer.open(c.mainnet.config, out_path, reader.era_number); + + const blocks_index = reader.group_indices[0].blocks_index orelse return error.NoBlockIndex; + for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { + const block = try reader.readBlock(allocator, slot) orelse continue; + defer block.deinit(allocator); + + try writer.writeBlock(allocator, block); + } + var state = try reader.readState(allocator, null); + defer state.deinit(); + + try writer.writeState(allocator, state); + + const final_out_path = try writer.finish(allocator); + defer allocator.free(final_out_path); + + // Now check that the two era files are equivalent + + // Compare file names + if (!std.mem.eql(u8, std.fs.path.basename(final_out_path), std.fs.path.basename(era_path))) { + return error.IncorrectWrittenEraFileName; + } + var out_reader = try era.Reader.open(allocator, c.mainnet.config, final_out_path); + defer out_reader.close(allocator); + + // Compare struct fields + if (out_reader.era_number != reader.era_number) { + return error.IncorrectWrittenEraNumber; + } + if (!std.mem.eql(u8, &reader.short_historical_root, &out_reader.short_historical_root)) { + return error.IncorrectWrittenShortHistoricalRoot; + } + // We can't directly compare bytes or offsets (snappy compression isn't deterministic across implementations) + // if (!std.mem.eql(u8, std.mem.sliceAsBytes(reader.groups), std.mem.sliceAsBytes(out_reader.groups))) { + // return error.IncorrectWrittenEraIndices; + // } + + // Compare blocks + for (blocks_index.start_slot..blocks_index.start_slot + blocks_index.offsets.len) |slot| { + const block = try reader.readSerializedBlock(allocator, slot) orelse continue; + const out_block = try out_reader.readSerializedBlock(allocator, slot) orelse return error.MissingBlock; + defer allocator.free(block); + defer allocator.free(out_block); + + if (!std.mem.eql(u8, block, out_block)) { + return error.IncorrectWrittenBlock; + } + } + // Compare state + var out_state = try out_reader.readState(allocator, null); + defer out_state.deinit(); + + const serialized = try state.serialize(allocator); + defer allocator.free(serialized); + const out_serialized = try out_state.serialize(allocator); + defer allocator.free(out_serialized); + + if (!std.mem.eql(u8, serialized, out_serialized)) { + return error.IncorrectWrittenState; + } +} diff --git a/zbuild.zon b/zbuild.zon index 9986b09ed..03366558a 100644 --- a/zbuild.zon +++ b/zbuild.zon @@ -202,7 +202,7 @@ .tests = .{ .int = .{ .root_module = .{ - .root_source_file = "test/int/root.zig", + .root_source_file = "test/int/era/root.zig", .imports = .{ .config, .download_era_options, From 318ce49ab0bf431189a4fc76a6617c5dc4a10206 Mon Sep 17 00:00:00 2001 From: bing Date: Tue, 20 Jan 2026 22:53:27 +0800 Subject: [PATCH 5/6] update build.zig --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 740a4c075..bf5fefecd 100644 --- a/build.zig +++ b/build.zig @@ -752,7 +752,7 @@ pub fn build(b: *std.Build) void { tls_run_test.dependOn(&run_test_bench_process_epoch.step); const module_int = b.createModule(.{ - .root_source_file = b.path("test/int/root.zig"), + .root_source_file = b.path("test/int/era/root.zig"), .target = target, .optimize = optimize, }); From f180d8d931224222189125758aa12ee6ce513518 Mon Sep 17 00:00:00 2001 From: bing Date: Tue, 20 Jan 2026 22:53:27 +0800 Subject: [PATCH 6/6] Fix config --- src/state_transition/block/process_execution_payload.zig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/state_transition/block/process_execution_payload.zig b/src/state_transition/block/process_execution_payload.zig index b01f62282..43924c32e 100644 --- a/src/state_transition/block/process_execution_payload.zig +++ b/src/state_transition/block/process_execution_payload.zig @@ -30,6 +30,7 @@ pub fn processExecutionPayload( external_data: BlockExternalData, ) !void { const state = cached_state.state; + const beacon_config = cached_state.config; const epoch_cache = cached_state.getEpochCache(); var partial_payload = PartialPayload{}; switch (body) { @@ -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.mainnet.chain_config.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.mainnet.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; } @@ -121,7 +122,8 @@ test "process execution payload - sanity" { defer test_state.deinit(); var execution_payload: types.electra.ExecutionPayload.Type = types.electra.ExecutionPayload.default_value; - execution_payload.timestamp = try test_state.cached_state.state.genesisTime() + try test_state.cached_state.state.slot() * config.mainnet.chain_config.SECONDS_PER_SLOT; + 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;