diff --git a/src/consensus/helpers/domain.zig b/src/consensus/helpers/domain.zig index 65d9886..faa53b2 100644 --- a/src/consensus/helpers/domain.zig +++ b/src/consensus/helpers/domain.zig @@ -2,6 +2,9 @@ const std = @import("std"); const primitives = @import("../../primitives/types.zig"); const consensus = @import("../../consensus/types.zig"); const configs = @import("../../configs/config.zig"); +const altair = @import("../../consensus/altair/types.zig"); +const preset = @import("../../presets/preset.zig"); +const epoch_helper = @import("./epoch.zig"); const ssz = @import("../../ssz/ssz.zig"); /// computeForkDataRoot return the 32-byte fork data root for the ``current_version`` and ``genesis_validators_root``. @@ -26,7 +29,6 @@ pub fn computeForkDataRoot(current_version: primitives.Version, genesis_validato .genesis_validators_root = genesis_validators_root, }; - std.log.debug("ForkData: {}\n", .{fork_data}); var out: primitives.Root = undefined; try ssz.hashTreeRoot(fork_data, &out, allocator); return out; @@ -88,24 +90,87 @@ pub fn computeDomain(domain_type: primitives.DomainType, fork_version: ?primitiv return result; } +/// getDomain returns the domain for the ``domain_type`` and ``epoch``. +/// @param state - The state. +/// @param domain_type - The domain type. +/// @param epoch - The epoch. +/// @returns The domain. +/// Spec pseudocode definition: +/// def get_domain(state: BeaconState, domain_type: DomainType, epoch: Epoch=None) -> Domain: +/// """ +/// Return the signature domain (fork version concatenated with domain type) of a message. +/// """ +/// epoch = get_current_epoch(state) if epoch is None else epoch +/// fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version +/// return compute_domain(domain_type, fork_version, state.genesis_validators_root) +pub fn getDomain(state: *const consensus.BeaconState, domainType: primitives.DomainType, epoch: ?primitives.Epoch, allocator: std.mem.Allocator) !primitives.Domain { + const current_epoch = epoch orelse epoch_helper.getCurrentEpoch(state); + const fork_version = if (current_epoch < state.fork().epoch) state.fork().previous_version else state.fork().current_version; + return try computeDomain(domainType, fork_version, state.genesisValidatorsRoot(), allocator); +} + test "test computeForkDigest" { - const currentVersion = .{0} ** 4; - const genesisValidatorsRoot = .{0} ** 32; - const forkDigest =try computeForkDigest(currentVersion, genesisValidatorsRoot, std.testing.allocator); + const currentVersion = .{3} ** 4; + const genesisValidatorsRoot = .{2} ** 32; + const forkDigest = try computeForkDigest(currentVersion, genesisValidatorsRoot, std.testing.allocator); try std.testing.expectEqual(4, forkDigest.len); + try std.testing.expectEqual([4]u8{ 164, 100, 54, 186 }, forkDigest); } test "test computeForkDataRoot" { const currentVersion = .{0} ** 4; const genesisValidatorsRoot = .{0} ** 32; - const forkDataRoot =try computeForkDataRoot(currentVersion, genesisValidatorsRoot, std.testing.allocator); + const forkDataRoot = try computeForkDataRoot(currentVersion, genesisValidatorsRoot, std.testing.allocator); try std.testing.expectEqual(32, forkDataRoot.len); + try std.testing.expectEqual([32]u8{ 245, 165, 253, 66, 209, 106, 32, 48, 39, 152, 239, 110, 211, 9, 151, 155, 67, 0, 61, 35, 32, 217, 240, 232, 234, 152, 49, 169, 39, 89, 251, 75 }, forkDataRoot); } test "test computeDomain" { - const domainType = .{0} ** 4; - const forkVersion = .{0} ** 4; - const genesisValidatorsRoot = .{0} ** 32; + const domainType = .{2} ** 4; + const forkVersion = .{4} ** 4; + const genesisValidatorsRoot = .{5} ** 32; const domain = try computeDomain(domainType, forkVersion, genesisValidatorsRoot, std.testing.allocator); try std.testing.expectEqual(32, domain.len); + try std.testing.expectEqual([32]u8{ 2, 2, 2, 2, 32, 125, 236, 13, 25, 22, 206, 134, 1, 218, 218, 156, 241, 61, 204, 254, 64, 74, 66, 44, 6, 212, 31, 140, 234, 29, 169, 68 }, domain); +} + +test "test getDomain" { + configs.ActiveConfig.set(preset.Presets.minimal); + defer configs.ActiveConfig.reset(); + const state = consensus.BeaconState{ + .altair = altair.BeaconState{ + .genesis_time = 0, + .genesis_validators_root = .{8} ** 32, + .slot = 100, + .fork = consensus.Fork{ + .previous_version = .{0} ** 4, + .current_version = .{1} ** 4, + .epoch = 10, + }, + .block_roots = undefined, + .state_roots = undefined, + .historical_roots = undefined, + .eth1_data = undefined, + .eth1_data_votes = undefined, + .eth1_deposit_index = 0, + .validators = undefined, + .balances = undefined, + .randao_mixes = undefined, + .slashings = undefined, + .previous_epoch_attestations = undefined, + .current_epoch_attestations = undefined, + .justification_bits = undefined, + .previous_justified_checkpoint = undefined, + .current_justified_checkpoint = undefined, + .finalized_checkpoint = undefined, + .latest_block_header = undefined, + .inactivity_scores = undefined, + .current_sync_committee = undefined, + .next_sync_committee = undefined, + }, + }; + const domainType = .{3} ** 4; + const domain = try getDomain(&state, domainType, 5, std.testing.allocator); + try std.testing.expectEqual(32, domain.len); + try std.testing.expectEqual([32]u8{ 3, 3, 3, 3, 61, 113, 193, 5, 44, 77, 156, 103, 107, 126, 246, 245, 190, 212, 101, 12, 208, 96, 214, 77, 178, 157, 214, 159, 250, 25, 45, 56 }, domain); } diff --git a/src/consensus/phase0/types.zig b/src/consensus/phase0/types.zig index 9ea126e..bcc7944 100644 --- a/src/consensus/phase0/types.zig +++ b/src/consensus/phase0/types.zig @@ -25,7 +25,7 @@ pub const BeaconState = struct { genesis_time: u64, genesis_validators_root: primitives.Root, slot: primitives.Slot, - fork: *consensus.Fork, + fork: consensus.Fork, latest_block_header: ?*consensus.BeaconBlockHeader, block_roots: []primitives.Root, state_roots: []primitives.Root, diff --git a/src/consensus/types.zig b/src/consensus/types.zig index a43d2be..1f23b44 100644 --- a/src/consensus/types.zig +++ b/src/consensus/types.zig @@ -434,6 +434,18 @@ pub const BeaconState = union(primitives.ForkType) { deneb: capella.BeaconState, electra: electra.BeaconState, + pub fn genesisValidatorsRoot(self: *const BeaconState) primitives.Root { + return switch (self.*) { + inline else => |state| state.genesis_validators_root, + }; + } + + pub fn fork(self: *const BeaconState) Fork { + return switch (self.*) { + inline else => |state| state.fork, + }; + } + /// randaoMixes returns the randao mixes of the given state. /// @return The randao mixes of the state. pub fn randaoMixes(self: *const BeaconState) []const primitives.Root {