Skip to content

Commit

Permalink
Merge branch 'main' into toml-is-my-loml
Browse files Browse the repository at this point in the history
  • Loading branch information
ocnc2 authored Jul 29, 2024
2 parents 368550a + 7320ce8 commit 62deb9a
Show file tree
Hide file tree
Showing 20 changed files with 410 additions and 88 deletions.
65 changes: 62 additions & 3 deletions contracts/src/eip4788/BeaconVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ contract BeaconVerifier is Verifier, Ownable, IBeaconVerifier {

/// @inheritdoc IBeaconVerifier
uint256 public zeroValidatorPubkeyGIndex;
/// @inheritdoc IBeaconVerifier
uint256 public executionNumberGIndex;

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* ADMIN FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

constructor(uint256 _zeroValidatorPubkeyGIndex) {
constructor(
uint256 _zeroValidatorPubkeyGIndex,
uint256 _executionNumberGIndex
) {
zeroValidatorPubkeyGIndex = _zeroValidatorPubkeyGIndex;
executionNumberGIndex = _executionNumberGIndex;

_initializeOwner(msg.sender);
}
Expand All @@ -47,6 +53,14 @@ contract BeaconVerifier is Verifier, Ownable, IBeaconVerifier {
emit ZeroValidatorPubkeyGIndexChanged(_zeroValidatorPubkeyGIndex);
}

function setExecutionNumberGIndex(uint256 _executionNumberGIndex)
external
onlyOwner
{
executionNumberGIndex = _executionNumberGIndex;
emit ExecutionNumberGIndexChanged(_executionNumberGIndex);
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* BEACON ROOT VIEWS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
Expand All @@ -66,12 +80,12 @@ contract BeaconVerifier is Verifier, Ownable, IBeaconVerifier {
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PROOFS */
/* VERIFIERS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IBeaconVerifier
/// @dev gas used ~75381
function proveBeaconBlockProposer(
function verifyBeaconBlockProposer(
uint64 timestamp,
bytes32[] calldata validatorPubkeyProof,
bytes calldata validatorPubkey,
Expand All @@ -88,6 +102,27 @@ contract BeaconVerifier is Verifier, Ownable, IBeaconVerifier {
);
}

/// @inheritdoc IBeaconVerifier
/// @dev gas used ~41647
function verifyExecutionNumber(
uint64 timestamp,
bytes32[] calldata executionNumberProof,
uint64 blockNumber
)
external
view
{
proveExecutionNumberInBeaconBlock(
getParentBlockRoot(uint64(timestamp)),
executionNumberProof,
blockNumber
);
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* PROOFS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @notice Verifies the validator pubkey is in the registry of beacon state.
/// @param beaconBlockRoot `bytes32` root of the beacon block.
/// @param validatorPubkeyProof `bytes32[]` proof of the validator.
Expand Down Expand Up @@ -120,4 +155,28 @@ contract BeaconVerifier is Verifier, Ownable, IBeaconVerifier {
)
) revert InvalidProof();
}

/// @notice Verifies the execution number in the beacon block.
/// @param beaconBlockRoot `bytes32` root of the beacon block.
/// @param executionNumberProof `bytes32[]` proof of the execution number.
/// @param blockNumber `uint64` execution number of the block.
function proveExecutionNumberInBeaconBlock(
bytes32 beaconBlockRoot,
bytes32[] calldata executionNumberProof,
uint64 blockNumber
)
internal
view
{
bytes32 executionNumberRoot = SSZ.toLittleEndian(uint256(blockNumber));

if (
!SSZ.verifyProof(
executionNumberProof,
beaconBlockRoot,
executionNumberRoot,
executionNumberGIndex
)
) revert InvalidProof();
}
}
25 changes: 21 additions & 4 deletions contracts/src/eip4788/interfaces/IBeaconVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ pragma solidity ^0.8.21;
import { SSZ } from "../SSZ.sol";

interface IBeaconVerifier {
/// @dev Emitted when the validator pubkey length is not 48.
error InvalidValidatorPubkeyLength();

/// @notice Emitted when the zero validator pubkey Generalized Index is
/// changed.
event ZeroValidatorPubkeyGIndexChanged(
uint256 newZeroValidatorPubkeyGIndex
);
/// @notice Emitted when the execution number Generalized Index is changed.
event ExecutionNumberGIndexChanged(uint256 newExecutionNumberGIndex);

/// @dev Generalized Index of the pubkey of the first validator (validator
/// index of 0) in the registry of the beacon state in the beacon block.
/// @dev In the Deneb beacon chain fork, this should be 3254554418216960.
function zeroValidatorPubkeyGIndex() external view returns (uint256);

/// @dev Generalized Index of the execution number in the beacon state in
/// the beacon block.
/// @dev In the Deneb beacon chain fork, this should be 5894.
function executionNumberGIndex() external view returns (uint256);

/// @notice Get the parent beacon block root from a block's timestamp.
/// @param timestamp `uint64` timestamp of the block.
function getParentBeaconBlockRootAt(uint64 timestamp)
Expand All @@ -34,12 +38,25 @@ interface IBeaconVerifier {
/// @param validatorPubkeyProof `bytes32[]` proof of the validator pubkey.
/// @param validatorPubkey `ValidatorPubkey` to verify.
/// @param proposerIndex `uint64` validator index of the proposer.
function proveBeaconBlockProposer(
function verifyBeaconBlockProposer(
uint64 timestamp,
bytes32[] calldata validatorPubkeyProof,
bytes calldata validatorPubkey,
uint64 proposerIndex
)
external
view;

/// @notice Verifies the execution number in the beacon block at the given
/// timestamp. Reverts if proof invalid.
/// @param timestamp `uint64` timestamp of the block.
/// @param executionNumberProof `bytes32[]` proof of the execution number.
/// @param blockNumber `uint64` execution number of the block.
function verifyExecutionNumber(
uint64 timestamp,
bytes32[] calldata executionNumberProof,
uint64 blockNumber
)
external
view;
}
10 changes: 10 additions & 0 deletions contracts/test/eip4788/SSZ.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ contract SSZTest is Test {
bytes32(bytes.concat(hex"EFCDAB9078563412", bytes24(0)));
bytes32 actual = SSZ.toLittleEndian(v);
assertEq(actual, expected);

uint64 w = type(uint64).max;
expected = bytes32(bytes.concat(hex"FFFFFFFFFFFFFFFF", bytes24(0)));
actual = SSZ.toLittleEndian(w);
assertEq(actual, expected);

uint64 z = 123_456_789;
expected = bytes32(bytes.concat(hex"15CD5B0700000000", bytes24(0)));
actual = SSZ.toLittleEndian(z);
assertEq(actual, expected);
}

function test_log2floor() public pure {
Expand Down
7 changes: 0 additions & 7 deletions mod/node-api/handlers/beacon/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
package beacon

import (
"errors"

"github.com/berachain/beacon-kit/mod/node-api/handlers"
"github.com/berachain/beacon-kit/mod/node-api/handlers/beacon/types"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
Expand Down Expand Up @@ -56,8 +54,3 @@ func NewHandler[
}
return h
}

// NotImplemented is a placeholder for the beacon API.
func (h *Handler[_, ContextT, _, _]) NotImplemented(_ ContextT) (any, error) {
return nil, errors.New("not implemented")
}
7 changes: 1 addition & 6 deletions mod/node-api/handlers/builder/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package builder

import (
"github.com/berachain/beacon-kit/mod/node-api/handlers"
"github.com/berachain/beacon-kit/mod/node-api/handlers/types"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
)

Expand All @@ -32,13 +31,9 @@ type Handler[ContextT context.Context] struct {

func NewHandler[ContextT context.Context]() *Handler[ContextT] {
h := &Handler[ContextT]{
BaseHandler: handlers.NewBaseHandler[ContextT](
BaseHandler: handlers.NewBaseHandler(
handlers.NewRouteSet[ContextT](""),
),
}
return h
}

func (h *Handler[ContextT]) NotImplemented(_ ContextT) (any, error) {
return nil, types.ErrNotImplemented
}
7 changes: 1 addition & 6 deletions mod/node-api/handlers/config/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package config

import (
"github.com/berachain/beacon-kit/mod/node-api/handlers"
"github.com/berachain/beacon-kit/mod/node-api/handlers/types"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
)

Expand All @@ -32,13 +31,9 @@ type Handler[ContextT context.Context] struct {

func NewHandler[ContextT context.Context]() *Handler[ContextT] {
h := &Handler[ContextT]{
BaseHandler: handlers.NewBaseHandler[ContextT](
BaseHandler: handlers.NewBaseHandler(
handlers.NewRouteSet[ContextT](""),
),
}
return h
}

func (h *Handler[ContextT]) NotImplemented(_ ContextT) (any, error) {
return nil, types.ErrNotImplemented
}
7 changes: 1 addition & 6 deletions mod/node-api/handlers/debug/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package debug

import (
"github.com/berachain/beacon-kit/mod/node-api/handlers"
"github.com/berachain/beacon-kit/mod/node-api/handlers/types"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
)

Expand All @@ -32,13 +31,9 @@ type Handler[ContextT context.Context] struct {

func NewHandler[ContextT context.Context]() *Handler[ContextT] {
h := &Handler[ContextT]{
BaseHandler: handlers.NewBaseHandler[ContextT](
BaseHandler: handlers.NewBaseHandler(
handlers.NewRouteSet[ContextT](""),
),
}
return h
}

func (h *Handler[ContextT]) NotImplemented(_ ContextT) (any, error) {
return nil, types.ErrNotImplemented
}
7 changes: 1 addition & 6 deletions mod/node-api/handlers/events/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package events

import (
"github.com/berachain/beacon-kit/mod/node-api/handlers"
"github.com/berachain/beacon-kit/mod/node-api/handlers/types"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
)

Expand All @@ -32,13 +31,9 @@ type Handler[ContextT context.Context] struct {

func NewHandler[ContextT context.Context]() *Handler[ContextT] {
h := &Handler[ContextT]{
BaseHandler: handlers.NewBaseHandler[ContextT](
BaseHandler: handlers.NewBaseHandler(
handlers.NewRouteSet[ContextT](""),
),
}
return h
}

func (h *Handler[ContextT]) NotImplemented(_ ContextT) (any, error) {
return nil, types.ErrNotImplemented
}
6 changes: 6 additions & 0 deletions mod/node-api/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package handlers

import (
"github.com/berachain/beacon-kit/mod/errors"
"github.com/berachain/beacon-kit/mod/log"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
)
Expand Down Expand Up @@ -52,6 +53,11 @@ func NewBaseHandler[ContextT context.Context](
}
}

// NotImplemented is a placeholder for the beacon API.
func (b *BaseHandler[ContextT]) NotImplemented(ContextT) (any, error) {
return nil, errors.New("not implemented")
}

// RouteSet returns the route set for the base handler.
func (b *BaseHandler[ContextT]) RouteSet() *RouteSet[ContextT] {
return b.routes
Expand Down
5 changes: 0 additions & 5 deletions mod/node-api/handlers/node/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package node

import (
"github.com/berachain/beacon-kit/mod/node-api/handlers"
"github.com/berachain/beacon-kit/mod/node-api/handlers/types"
"github.com/berachain/beacon-kit/mod/node-api/server/context"
)

Expand All @@ -38,7 +37,3 @@ func NewHandler[ContextT context.Context]() *Handler[ContextT] {
}
return h
}

func (h *Handler[ContextT]) NotImplemented(_ ContextT) (any, error) {
return nil, types.ErrNotImplemented
}
67 changes: 67 additions & 0 deletions mod/node-api/handlers/proof/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: BUSL-1.1
//
// Copyright (C) 2024, Berachain Foundation. All rights reserved.
// Use of this software is governed by the Business Source License included
// in the LICENSE file of this repository and at www.mariadb.com/bsl11.
//
// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY
// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER
// VERSIONS OF THE LICENSED WORK.
//
// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF
// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF
// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).
//
// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
// TITLE.

package proof

import "github.com/berachain/beacon-kit/mod/node-api/handlers/utils"

// Get the slot from the given input of block id, beacon state, and beacon
// block header for the resolved slot.
func (h *Handler[
ContextT, BeaconBlockHeaderT, BeaconStateT, _, _, _,
]) resolveBlockID(blockID string) (
uint64, BeaconStateT, BeaconBlockHeaderT, error,
) {
var (
beaconState BeaconStateT
blockHeader BeaconBlockHeaderT
)

slot, err := utils.SlotFromBlockID(blockID, h.backend)
if err != nil {
return slot, beaconState, blockHeader, err
}

beaconState, err = h.backend.StateFromSlot(slot)
if err != nil {
return slot, beaconState, blockHeader, err
}

blockHeader, err = h.getBlockHeaderFromState(beaconState)
return slot, beaconState, blockHeader, err
}

// getBlockHeaderFromState returns the block header from the given state.
//
// TODO: remove once issue #1777 is fixed.
func (h *Handler[
_, BeaconBlockHeaderT, BeaconStateT, _, _, _,
]) getBlockHeaderFromState(bs BeaconStateT) (BeaconBlockHeaderT, error) {
blockHeader, err := bs.GetLatestBlockHeader()
if err != nil {
return blockHeader, err
}

// The state root must be patched onto the latest block header since it is
// committed to state with a 0 state root.
stateRoot, err := bs.HashTreeRoot()
blockHeader.SetStateRoot(stateRoot)
return blockHeader, err
}
Loading

0 comments on commit 62deb9a

Please sign in to comment.