Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions bindings/napi/BeaconStateView.zig
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,38 @@ pub fn BeaconStateView_latestExecutionPayloadHeader(env: napi.Env, cb: napi.Call
};
}

/// Get the block hash from the latest execution payload header (bellatrix+).
/// Returns: Bytes32 (Uint8Array)
pub fn BeaconStateView_latestBlockHash(env: napi.Env, cb: napi.CallbackInfo(0)) !napi.Value {
const cached_state = try env.unwrap(CachedBeaconState, cb.this());
const block_hash = cached_state.state.latestExecutionPayloadHeaderBlockHash() catch |err| {
switch (err) {
error.InvalidAtFork => {
try env.throwError("INVALID_FORK", "latestBlockHash not available before bellatrix");
return env.getNull();
},
else => return err,
}
};
return sszValueToNapiValue(env, ct.primitive.Bytes32, block_hash);
}

/// Get the block number from the latest execution payload header (bellatrix+).
/// Returns: number
pub fn BeaconStateView_payloadBlockNumber(env: napi.Env, cb: napi.CallbackInfo(0)) !napi.Value {
const cached_state = try env.unwrap(CachedBeaconState, cb.this());
const block_number = cached_state.state.latestExecutionPayloadHeaderBlockNumber() catch |err| {
switch (err) {
error.InvalidAtFork => {
try env.throwError("INVALID_FORK", "payloadBlockNumber not available before bellatrix");
return env.getNull();
},
else => return err,
}
};
return env.createInt64(@intCast(block_number));
}

/// Get the historical summaries from the state (Capella+).
/// Returns: array of {blockSummaryRoot: Uint8Array, stateSummaryRoot: Uint8Array}
pub fn BeaconStateView_historicalSummaries(env: napi.Env, cb: napi.CallbackInfo(0)) !napi.Value {
Expand Down Expand Up @@ -1012,6 +1044,8 @@ pub fn register(env: napi.Env, exports: napi.Value) !void {
getter(BeaconStateView_previousEpochParticipation),
getter(BeaconStateView_currentEpochParticipation),
getter(BeaconStateView_latestExecutionPayloadHeader),
getter(BeaconStateView_latestBlockHash),
getter(BeaconStateView_payloadBlockNumber),
getter(BeaconStateView_historicalSummaries),
getter(BeaconStateView_pendingDeposits),
getter(BeaconStateView_pendingDepositsCount),
Expand Down
2 changes: 2 additions & 0 deletions bindings/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ declare class BeaconStateView {
previousEpochParticipation: number[];
currentEpochParticipation: number[];
latestExecutionPayloadHeader: ExecutionPayloadHeader;
latestBlockHash: Uint8Array;
payloadBlockNumber: number;
historicalSummaries: HistoricalSummary[];
pendingDeposits: Uint8Array;
pendingDepositsCount: number;
Expand Down
10 changes: 10 additions & 0 deletions src/fork_types/any_beacon_state.zig
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,16 @@ pub const AnyBeaconState = union(ForkSeq) {
};
}

pub fn latestExecutionPayloadHeaderBlockNumber(self: *AnyBeaconState) !u64 {
return switch (self.*) {
.phase0, .altair => error.InvalidAtFork,
inline else => |state| {
var header = try state.get("latest_execution_payload_header");
return try header.get("block_number");
},
};
}
Comment on lines +643 to +651
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function is missing assertions, which is a violation of the repository's style guide. The style guide requires an average of two assertions per function to ensure code safety and document invariants (lines 51-55).

Consider adding assertions for preconditions, such as checking that self is not null, and for critical invariants. For example, you could assert that the fork is indeed Bellatrix or newer before accessing fork-specific fields. The style guide encourages such "blatantly true assertions" as a form of documentation (line 62).

    pub fn latestExecutionPayloadHeaderBlockNumber(self: *AnyBeaconState) !u64 {
        std.debug.assert(self != null);
        return switch (self.*) {
            .phase0, .altair => error.InvalidAtFork,
            inline else => |state| {
                std.debug.assert(self.forkSeq().gte(.bellatrix));
                var header = try state.get("latest_execution_payload_header");
                return try header.get("block_number");
            },
        };
    }
References
  1. Functions should contain assertions to check for pre/postconditions and invariants. The style guide mandates an average of at least two assertions per function to improve code safety and act as documentation. (link)


pub fn setLatestExecutionPayloadHeader(self: *AnyBeaconState, header: *const AnyExecutionPayloadHeader) !void {
switch (self.*) {
.bellatrix => |state| try state.setValue("latest_execution_payload_header", &header.bellatrix),
Expand Down
Loading