diff --git a/bindings/napi/BeaconStateView.zig b/bindings/napi/BeaconStateView.zig index a92dd04cd..c8dd912c5 100644 --- a/bindings/napi/BeaconStateView.zig +++ b/bindings/napi/BeaconStateView.zig @@ -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 { @@ -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), diff --git a/bindings/src/index.d.ts b/bindings/src/index.d.ts index fed4ee54c..5371469ec 100644 --- a/bindings/src/index.d.ts +++ b/bindings/src/index.d.ts @@ -139,6 +139,8 @@ declare class BeaconStateView { previousEpochParticipation: number[]; currentEpochParticipation: number[]; latestExecutionPayloadHeader: ExecutionPayloadHeader; + latestBlockHash: Uint8Array; + payloadBlockNumber: number; historicalSummaries: HistoricalSummary[]; pendingDeposits: Uint8Array; pendingDepositsCount: number; diff --git a/src/fork_types/any_beacon_state.zig b/src/fork_types/any_beacon_state.zig index fc5577a40..b8ff8cfce 100644 --- a/src/fork_types/any_beacon_state.zig +++ b/src/fork_types/any_beacon_state.zig @@ -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"); + }, + }; + } + pub fn setLatestExecutionPayloadHeader(self: *AnyBeaconState, header: *const AnyExecutionPayloadHeader) !void { switch (self.*) { .bellatrix => |state| try state.setValue("latest_execution_payload_header", &header.bellatrix),