Compare commits

...

5 Commits

Author SHA1 Message Date
Bastin
06aaf4aa36 update lightclient code for gloas 2026-01-27 14:40:49 +01:00
terence
2cbb743606 gloas: add new payload attestation processing (#15650)
This PR implements
[process_payload_attestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_payload_attestation)
and spec tests
2026-01-27 03:34:12 +00:00
james-prysm
ce9c968dcc adding gloas block support to /eth/v2/beacon/blocks/{block_id} and /eth/v1/beacon/blocks/{block_id}/root (#16278)
**What type of PR is this?**
Feature

**What does this PR do? Why is it needed?**

adding gloas block return on `/eth/v2/beacon/blocks/{block_id}` endpoint

-
[/eth/v1/beacon/blocks/{block_id}/root](https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getBlockRoot)
should inherit this as well

reference
https://github.com/ethereum/beacon-APIs/pull/552/files#r2722805266

**Which issues(s) does this PR fix?**

Fixes #

**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).
2026-01-27 00:02:16 +00:00
Potuz
60e5c29b92 Fix arm64 hashtree builds (#16288)
This PR fixes release builds that fail because of hashtree's patch.
Should be in conjunction with #16281

---------

Co-authored-by: Preston Van Loon <preston@pvl.dev>
2026-01-26 20:20:57 +00:00
Bastin
e27445bae2 Add cmd/* to gen-logs.sh (#16285)
**What does this PR do? Why is it needed?**
This PR adds the `cmd` directory and all it's subcategories to the
`hack/gen-logs.sh`. meaning that they will now have a `log.go` file and
a `package` field. see the list of added packages below. some of them
had different names, which has been added to the `prefixReplacements`
map.

packages added:
"cmd"
"cmd/validator/web"
"cmd/validator/wallet"
"cmd/validator/slashing-protection"
"cmd/validator/db"
"cmd/validator/accounts"
"cmd/prysmctl"
"cmd/prysmctl/weaksubjectivity"
"cmd/prysmctl/validator"
"cmd/prysmctl/testnet"
"cmd/prysmctl/p2p"
"cmd/prysmctl/db"
"cmd/prysmctl/checkpointsync"
"cmd/client-stats"
"cmd/beacon-chain"
"cmd/beacon-chain/storage"
"cmd/beacon-chain/jwt"
"cmd/beacon-chain/genesis"
"cmd/beacon-chain/flags"
"cmd/beacon-chain/db"
2026-01-26 17:49:52 +00:00
84 changed files with 1809 additions and 52 deletions

View File

@@ -503,3 +503,77 @@ func (s *SignedBlindedBeaconBlockFulu) MessageRawJson() ([]byte, error) {
func (s *SignedBlindedBeaconBlockFulu) SigString() string {
return s.Signature
}
// ----------------------------------------------------------------------------
// Gloas
// ----------------------------------------------------------------------------
type ExecutionPayloadBid struct {
ParentBlockHash string `json:"parent_block_hash"`
ParentBlockRoot string `json:"parent_block_root"`
BlockHash string `json:"block_hash"`
PrevRandao string `json:"prev_randao"`
FeeRecipient string `json:"fee_recipient"`
GasLimit string `json:"gas_limit"`
BuilderIndex string `json:"builder_index"`
Slot string `json:"slot"`
Value string `json:"value"`
ExecutionPayment string `json:"execution_payment"`
BlobKzgCommitmentsRoot string `json:"blob_kzg_commitments_root"`
}
type SignedExecutionPayloadBid struct {
Message *ExecutionPayloadBid `json:"message"`
Signature string `json:"signature"`
}
type PayloadAttestationData struct {
BeaconBlockRoot string `json:"beacon_block_root"`
Slot string `json:"slot"`
PayloadPresent bool `json:"payload_present"`
BlobDataAvailable bool `json:"blob_data_available"`
}
type PayloadAttestation struct {
AggregationBits string `json:"aggregation_bits"`
Data *PayloadAttestationData `json:"data"`
Signature string `json:"signature"`
}
type BeaconBlockBodyGloas struct {
RandaoReveal string `json:"randao_reveal"`
Eth1Data *Eth1Data `json:"eth1_data"`
Graffiti string `json:"graffiti"`
ProposerSlashings []*ProposerSlashing `json:"proposer_slashings"`
AttesterSlashings []*AttesterSlashingElectra `json:"attester_slashings"`
Attestations []*AttestationElectra `json:"attestations"`
Deposits []*Deposit `json:"deposits"`
VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits"`
SyncAggregate *SyncAggregate `json:"sync_aggregate"`
BLSToExecutionChanges []*SignedBLSToExecutionChange `json:"bls_to_execution_changes"`
SignedExecutionPayloadBid *SignedExecutionPayloadBid `json:"signed_execution_payload_bid"`
PayloadAttestations []*PayloadAttestation `json:"payload_attestations"`
}
type BeaconBlockGloas struct {
Slot string `json:"slot"`
ProposerIndex string `json:"proposer_index"`
ParentRoot string `json:"parent_root"`
StateRoot string `json:"state_root"`
Body *BeaconBlockBodyGloas `json:"body"`
}
type SignedBeaconBlockGloas struct {
Message *BeaconBlockGloas `json:"message"`
Signature string `json:"signature"`
}
var _ SignedMessageJsoner = &SignedBeaconBlockGloas{}
func (s *SignedBeaconBlockGloas) MessageRawJson() ([]byte, error) {
return json.Marshal(s.Message)
}
func (s *SignedBeaconBlockGloas) SigString() string {
return s.Signature
}

View File

@@ -268,6 +268,8 @@ func SignedBeaconBlockMessageJsoner(block interfaces.ReadOnlySignedBeaconBlock)
return SignedBlindedBeaconBlockFuluFromConsensus(pbStruct)
case *eth.SignedBeaconBlockFulu:
return SignedBeaconBlockFuluFromConsensus(pbStruct)
case *eth.SignedBeaconBlockGloas:
return SignedBeaconBlockGloasFromConsensus(pbStruct)
default:
return nil, ErrUnsupportedConversion
}
@@ -2885,3 +2887,379 @@ func SignedBeaconBlockFuluFromConsensus(b *eth.SignedBeaconBlockFulu) (*SignedBe
Signature: hexutil.Encode(b.Signature),
}, nil
}
// ----------------------------------------------------------------------------
// Gloas
// ----------------------------------------------------------------------------
func SignedBeaconBlockGloasFromConsensus(b *eth.SignedBeaconBlockGloas) (*SignedBeaconBlockGloas, error) {
block, err := BeaconBlockGloasFromConsensus(b.Block)
if err != nil {
return nil, err
}
return &SignedBeaconBlockGloas{
Message: block,
Signature: hexutil.Encode(b.Signature),
}, nil
}
func BeaconBlockGloasFromConsensus(b *eth.BeaconBlockGloas) (*BeaconBlockGloas, error) {
payloadAttestations := make([]*PayloadAttestation, len(b.Body.PayloadAttestations))
for i, pa := range b.Body.PayloadAttestations {
payloadAttestations[i] = PayloadAttestationFromConsensus(pa)
}
return &BeaconBlockGloas{
Slot: fmt.Sprintf("%d", b.Slot),
ProposerIndex: fmt.Sprintf("%d", b.ProposerIndex),
ParentRoot: hexutil.Encode(b.ParentRoot),
StateRoot: hexutil.Encode(b.StateRoot),
Body: &BeaconBlockBodyGloas{
RandaoReveal: hexutil.Encode(b.Body.RandaoReveal),
Eth1Data: Eth1DataFromConsensus(b.Body.Eth1Data),
Graffiti: hexutil.Encode(b.Body.Graffiti),
ProposerSlashings: ProposerSlashingsFromConsensus(b.Body.ProposerSlashings),
AttesterSlashings: AttesterSlashingsElectraFromConsensus(b.Body.AttesterSlashings),
Attestations: AttsElectraFromConsensus(b.Body.Attestations),
Deposits: DepositsFromConsensus(b.Body.Deposits),
VoluntaryExits: SignedExitsFromConsensus(b.Body.VoluntaryExits),
SyncAggregate: SyncAggregateFromConsensus(b.Body.SyncAggregate),
BLSToExecutionChanges: SignedBLSChangesFromConsensus(b.Body.BlsToExecutionChanges),
SignedExecutionPayloadBid: SignedExecutionPayloadBidFromConsensus(b.Body.SignedExecutionPayloadBid),
PayloadAttestations: payloadAttestations,
},
}, nil
}
func SignedExecutionPayloadBidFromConsensus(b *eth.SignedExecutionPayloadBid) *SignedExecutionPayloadBid {
return &SignedExecutionPayloadBid{
Message: ExecutionPayloadBidFromConsensus(b.Message),
Signature: hexutil.Encode(b.Signature),
}
}
func ExecutionPayloadBidFromConsensus(b *eth.ExecutionPayloadBid) *ExecutionPayloadBid {
return &ExecutionPayloadBid{
ParentBlockHash: hexutil.Encode(b.ParentBlockHash),
ParentBlockRoot: hexutil.Encode(b.ParentBlockRoot),
BlockHash: hexutil.Encode(b.BlockHash),
PrevRandao: hexutil.Encode(b.PrevRandao),
FeeRecipient: hexutil.Encode(b.FeeRecipient),
GasLimit: fmt.Sprintf("%d", b.GasLimit),
BuilderIndex: fmt.Sprintf("%d", b.BuilderIndex),
Slot: fmt.Sprintf("%d", b.Slot),
Value: fmt.Sprintf("%d", b.Value),
ExecutionPayment: fmt.Sprintf("%d", b.ExecutionPayment),
BlobKzgCommitmentsRoot: hexutil.Encode(b.BlobKzgCommitmentsRoot),
}
}
func PayloadAttestationFromConsensus(pa *eth.PayloadAttestation) *PayloadAttestation {
return &PayloadAttestation{
AggregationBits: hexutil.Encode(pa.AggregationBits),
Data: PayloadAttestationDataFromConsensus(pa.Data),
Signature: hexutil.Encode(pa.Signature),
}
}
func PayloadAttestationDataFromConsensus(d *eth.PayloadAttestationData) *PayloadAttestationData {
return &PayloadAttestationData{
BeaconBlockRoot: hexutil.Encode(d.BeaconBlockRoot),
Slot: fmt.Sprintf("%d", d.Slot),
PayloadPresent: d.PayloadPresent,
BlobDataAvailable: d.BlobDataAvailable,
}
}
func (b *SignedBeaconBlockGloas) ToConsensus() (*eth.SignedBeaconBlockGloas, error) {
if b == nil {
return nil, errNilValue
}
sig, err := bytesutil.DecodeHexWithLength(b.Signature, fieldparams.BLSSignatureLength)
if err != nil {
return nil, server.NewDecodeError(err, "Signature")
}
block, err := b.Message.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, "Message")
}
return &eth.SignedBeaconBlockGloas{
Block: block,
Signature: sig,
}, nil
}
func (b *BeaconBlockGloas) ToConsensus() (*eth.BeaconBlockGloas, error) {
if b == nil {
return nil, errNilValue
}
if b.Body == nil {
return nil, server.NewDecodeError(errNilValue, "Body")
}
if b.Body.Eth1Data == nil {
return nil, server.NewDecodeError(errNilValue, "Body.Eth1Data")
}
if b.Body.SyncAggregate == nil {
return nil, server.NewDecodeError(errNilValue, "Body.SyncAggregate")
}
if b.Body.SignedExecutionPayloadBid == nil {
return nil, server.NewDecodeError(errNilValue, "Body.SignedExecutionPayloadBid")
}
slot, err := strconv.ParseUint(b.Slot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "Slot")
}
proposerIndex, err := strconv.ParseUint(b.ProposerIndex, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "ProposerIndex")
}
parentRoot, err := bytesutil.DecodeHexWithLength(b.ParentRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "ParentRoot")
}
stateRoot, err := bytesutil.DecodeHexWithLength(b.StateRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "StateRoot")
}
body, err := b.Body.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, "Body")
}
return &eth.BeaconBlockGloas{
Slot: primitives.Slot(slot),
ProposerIndex: primitives.ValidatorIndex(proposerIndex),
ParentRoot: parentRoot,
StateRoot: stateRoot,
Body: body,
}, nil
}
func (b *BeaconBlockBodyGloas) ToConsensus() (*eth.BeaconBlockBodyGloas, error) {
if b == nil {
return nil, errNilValue
}
randaoReveal, err := bytesutil.DecodeHexWithLength(b.RandaoReveal, fieldparams.BLSSignatureLength)
if err != nil {
return nil, server.NewDecodeError(err, "RandaoReveal")
}
depositRoot, err := bytesutil.DecodeHexWithLength(b.Eth1Data.DepositRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "Eth1Data.DepositRoot")
}
depositCount, err := strconv.ParseUint(b.Eth1Data.DepositCount, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "Eth1Data.DepositCount")
}
blockHash, err := bytesutil.DecodeHexWithLength(b.Eth1Data.BlockHash, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "Eth1Data.BlockHash")
}
graffiti, err := bytesutil.DecodeHexWithLength(b.Graffiti, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "Graffiti")
}
proposerSlashings, err := ProposerSlashingsToConsensus(b.ProposerSlashings)
if err != nil {
return nil, server.NewDecodeError(err, "ProposerSlashings")
}
attesterSlashings, err := AttesterSlashingsElectraToConsensus(b.AttesterSlashings)
if err != nil {
return nil, server.NewDecodeError(err, "AttesterSlashings")
}
atts, err := AttsElectraToConsensus(b.Attestations)
if err != nil {
return nil, server.NewDecodeError(err, "Attestations")
}
deposits, err := DepositsToConsensus(b.Deposits)
if err != nil {
return nil, server.NewDecodeError(err, "Deposits")
}
exits, err := SignedExitsToConsensus(b.VoluntaryExits)
if err != nil {
return nil, server.NewDecodeError(err, "VoluntaryExits")
}
syncCommitteeBits, err := bytesutil.DecodeHexWithLength(b.SyncAggregate.SyncCommitteeBits, fieldparams.SyncAggregateSyncCommitteeBytesLength)
if err != nil {
return nil, server.NewDecodeError(err, "SyncAggregate.SyncCommitteeBits")
}
syncCommitteeSig, err := bytesutil.DecodeHexWithLength(b.SyncAggregate.SyncCommitteeSignature, fieldparams.BLSSignatureLength)
if err != nil {
return nil, server.NewDecodeError(err, "SyncAggregate.SyncCommitteeSignature")
}
blsChanges, err := SignedBLSChangesToConsensus(b.BLSToExecutionChanges)
if err != nil {
return nil, server.NewDecodeError(err, "BLSToExecutionChanges")
}
signedBid, err := b.SignedExecutionPayloadBid.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, "SignedExecutionPayloadBid")
}
payloadAttestations, err := PayloadAttestationsToConsensus(b.PayloadAttestations)
if err != nil {
return nil, server.NewDecodeError(err, "PayloadAttestations")
}
return &eth.BeaconBlockBodyGloas{
RandaoReveal: randaoReveal,
Eth1Data: &eth.Eth1Data{
DepositRoot: depositRoot,
DepositCount: depositCount,
BlockHash: blockHash,
},
Graffiti: graffiti,
ProposerSlashings: proposerSlashings,
AttesterSlashings: attesterSlashings,
Attestations: atts,
Deposits: deposits,
VoluntaryExits: exits,
SyncAggregate: &eth.SyncAggregate{
SyncCommitteeBits: syncCommitteeBits,
SyncCommitteeSignature: syncCommitteeSig,
},
BlsToExecutionChanges: blsChanges,
SignedExecutionPayloadBid: signedBid,
PayloadAttestations: payloadAttestations,
}, nil
}
func (b *SignedExecutionPayloadBid) ToConsensus() (*eth.SignedExecutionPayloadBid, error) {
if b == nil {
return nil, errNilValue
}
sig, err := bytesutil.DecodeHexWithLength(b.Signature, fieldparams.BLSSignatureLength)
if err != nil {
return nil, server.NewDecodeError(err, "Signature")
}
message, err := b.Message.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, "Message")
}
return &eth.SignedExecutionPayloadBid{
Message: message,
Signature: sig,
}, nil
}
func (b *ExecutionPayloadBid) ToConsensus() (*eth.ExecutionPayloadBid, error) {
if b == nil {
return nil, errNilValue
}
parentBlockHash, err := bytesutil.DecodeHexWithLength(b.ParentBlockHash, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "ParentBlockHash")
}
parentBlockRoot, err := bytesutil.DecodeHexWithLength(b.ParentBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "ParentBlockRoot")
}
blockHash, err := bytesutil.DecodeHexWithLength(b.BlockHash, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "BlockHash")
}
prevRandao, err := bytesutil.DecodeHexWithLength(b.PrevRandao, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "PrevRandao")
}
feeRecipient, err := bytesutil.DecodeHexWithLength(b.FeeRecipient, fieldparams.FeeRecipientLength)
if err != nil {
return nil, server.NewDecodeError(err, "FeeRecipient")
}
gasLimit, err := strconv.ParseUint(b.GasLimit, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "GasLimit")
}
builderIndex, err := strconv.ParseUint(b.BuilderIndex, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "BuilderIndex")
}
slot, err := strconv.ParseUint(b.Slot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "Slot")
}
value, err := strconv.ParseUint(b.Value, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "Value")
}
executionPayment, err := strconv.ParseUint(b.ExecutionPayment, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "ExecutionPayment")
}
blobKzgCommitmentsRoot, err := bytesutil.DecodeHexWithLength(b.BlobKzgCommitmentsRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "BlobKzgCommitmentsRoot")
}
return &eth.ExecutionPayloadBid{
ParentBlockHash: parentBlockHash,
ParentBlockRoot: parentBlockRoot,
BlockHash: blockHash,
PrevRandao: prevRandao,
FeeRecipient: feeRecipient,
GasLimit: gasLimit,
BuilderIndex: primitives.BuilderIndex(builderIndex),
Slot: primitives.Slot(slot),
Value: primitives.Gwei(value),
ExecutionPayment: primitives.Gwei(executionPayment),
BlobKzgCommitmentsRoot: blobKzgCommitmentsRoot,
}, nil
}
func PayloadAttestationsToConsensus(pa []*PayloadAttestation) ([]*eth.PayloadAttestation, error) {
if pa == nil {
return nil, errNilValue
}
result := make([]*eth.PayloadAttestation, len(pa))
for i, p := range pa {
converted, err := p.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, fmt.Sprintf("[%d]", i))
}
result[i] = converted
}
return result, nil
}
func (p *PayloadAttestation) ToConsensus() (*eth.PayloadAttestation, error) {
if p == nil {
return nil, errNilValue
}
aggregationBits, err := hexutil.Decode(p.AggregationBits)
if err != nil {
return nil, server.NewDecodeError(err, "AggregationBits")
}
data, err := p.Data.ToConsensus()
if err != nil {
return nil, server.NewDecodeError(err, "Data")
}
sig, err := bytesutil.DecodeHexWithLength(p.Signature, fieldparams.BLSSignatureLength)
if err != nil {
return nil, server.NewDecodeError(err, "Signature")
}
return &eth.PayloadAttestation{
AggregationBits: aggregationBits,
Data: data,
Signature: sig,
}, nil
}
func (d *PayloadAttestationData) ToConsensus() (*eth.PayloadAttestationData, error) {
if d == nil {
return nil, errNilValue
}
beaconBlockRoot, err := bytesutil.DecodeHexWithLength(d.BeaconBlockRoot, fieldparams.RootLength)
if err != nil {
return nil, server.NewDecodeError(err, "BeaconBlockRoot")
}
slot, err := strconv.ParseUint(d.Slot, 10, 64)
if err != nil {
return nil, server.NewDecodeError(err, "Slot")
}
return &eth.PayloadAttestationData{
BeaconBlockRoot: beaconBlockRoot,
Slot: primitives.Slot(slot),
PayloadPresent: d.PayloadPresent,
BlobDataAvailable: d.BlobDataAvailable,
}, nil
}

View File

@@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"bid.go",
"payload_attestation.go",
"pending_payment.go",
"proposer_slashing.go",
],
@@ -14,12 +15,16 @@ go_library(
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/state:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/bls/common:go_default_library",
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//time/slots:go_default_library",
"@com_github_pkg_errors//:go_default_library",
@@ -30,6 +35,7 @@ go_test(
name = "go_default_test",
srcs = [
"bid_test.go",
"payload_attestation_test.go",
"pending_payment_test.go",
"proposer_slashing_test.go",
],
@@ -40,6 +46,7 @@ go_test(
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/primitives:go_default_library",
"//crypto/bls:go_default_library",
@@ -50,8 +57,10 @@ go_test(
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//runtime/version:go_default_library",
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"//time/slots:go_default_library",
"@com_github_prysmaticlabs_fastssz//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
],
)

View File

@@ -0,0 +1,253 @@
package gloas
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"slices"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/signing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/config/params"
consensus_types "github.com/OffchainLabs/prysm/v7/consensus-types"
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/crypto/bls"
"github.com/OffchainLabs/prysm/v7/crypto/hash"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/time/slots"
"github.com/pkg/errors"
)
// ProcessPayloadAttestations validates payload attestations in a block body.
// Spec v1.7.0-alpha.0 (pseudocode):
// process_payload_attestation(state: BeaconState, payload_attestation: PayloadAttestation):
//
// data = payload_attestation.data
// assert data.beacon_block_root == state.latest_block_header.parent_root
// assert data.slot + 1 == state.slot
// indexed = get_indexed_payload_attestation(state, data.slot, payload_attestation)
// assert is_valid_indexed_payload_attestation(state, indexed)
func ProcessPayloadAttestations(ctx context.Context, st state.BeaconState, body interfaces.ReadOnlyBeaconBlockBody) error {
atts, err := body.PayloadAttestations()
if err != nil {
return errors.Wrap(err, "failed to get payload attestations from block body")
}
if len(atts) == 0 {
return nil
}
header := st.LatestBlockHeader()
for i, att := range atts {
data := att.Data
if !bytes.Equal(data.BeaconBlockRoot, header.ParentRoot) {
return fmt.Errorf("payload attestation %d has wrong parent: got %x want %x", i, data.BeaconBlockRoot, header.ParentRoot)
}
dataSlot, err := data.Slot.SafeAdd(1)
if err != nil {
return errors.Wrapf(err, "payload attestation %d has invalid slot addition", i)
}
if dataSlot != st.Slot() {
return fmt.Errorf("payload attestation %d has wrong slot: got %d want %d", i, data.Slot+1, st.Slot())
}
indexed, err := indexedPayloadAttestation(ctx, st, att)
if err != nil {
return errors.Wrapf(err, "payload attestation %d failed to convert to indexed form", i)
}
if err := validIndexedPayloadAttestation(st, indexed); err != nil {
return errors.Wrapf(err, "payload attestation %d failed to verify indexed form", i)
}
}
return nil
}
// indexedPayloadAttestation converts a payload attestation into its indexed form.
func indexedPayloadAttestation(ctx context.Context, st state.ReadOnlyBeaconState, att *eth.PayloadAttestation) (*consensus_types.IndexedPayloadAttestation, error) {
committee, err := payloadCommittee(ctx, st, att.Data.Slot)
if err != nil {
return nil, err
}
indices := make([]primitives.ValidatorIndex, 0, len(committee))
for i, idx := range committee {
if att.AggregationBits.BitAt(uint64(i)) {
indices = append(indices, idx)
}
}
slices.Sort(indices)
return &consensus_types.IndexedPayloadAttestation{
AttestingIndices: indices,
Data: att.Data,
Signature: att.Signature,
}, nil
}
// payloadCommittee returns the payload timeliness committee for a given slot for the state.
// Spec v1.7.0-alpha.0 (pseudocode):
// get_ptc(state: BeaconState, slot: Slot) -> Vector[ValidatorIndex, PTC_SIZE]:
//
// epoch = compute_epoch_at_slot(slot)
// seed = hash(get_seed(state, epoch, DOMAIN_PTC_ATTESTER) + uint_to_bytes(slot))
// indices = []
// committees_per_slot = get_committee_count_per_slot(state, epoch)
// for i in range(committees_per_slot):
// committee = get_beacon_committee(state, slot, CommitteeIndex(i))
// indices.extend(committee)
// return compute_balance_weighted_selection(state, indices, seed, size=PTC_SIZE, shuffle_indices=False)
func payloadCommittee(ctx context.Context, st state.ReadOnlyBeaconState, slot primitives.Slot) ([]primitives.ValidatorIndex, error) {
epoch := slots.ToEpoch(slot)
seed, err := ptcSeed(st, epoch, slot)
if err != nil {
return nil, err
}
activeCount, err := helpers.ActiveValidatorCount(ctx, st, epoch)
if err != nil {
return nil, err
}
committeesPerSlot := helpers.SlotCommitteeCount(activeCount)
out := make([]primitives.ValidatorIndex, 0, activeCount/uint64(params.BeaconConfig().SlotsPerEpoch))
for i := primitives.CommitteeIndex(0); i < primitives.CommitteeIndex(committeesPerSlot); i++ {
committee, err := helpers.BeaconCommitteeFromState(ctx, st, slot, i)
if err != nil {
return nil, errors.Wrapf(err, "failed to get beacon committee %d", i)
}
out = append(out, committee...)
}
return selectByBalance(ctx, st, out, seed, fieldparams.PTCSize)
}
// ptcSeed computes the seed for the payload timeliness committee.
func ptcSeed(st state.ReadOnlyBeaconState, epoch primitives.Epoch, slot primitives.Slot) ([32]byte, error) {
seed, err := helpers.Seed(st, epoch, params.BeaconConfig().DomainPTCAttester)
if err != nil {
return [32]byte{}, err
}
return hash.Hash(append(seed[:], bytesutil.Bytes8(uint64(slot))...)), nil
}
// selectByBalance selects a balance-weighted subset of input candidates.
// Spec v1.7.0-alpha.0 (pseudocode):
// compute_balance_weighted_selection(state, indices, seed, size, shuffle_indices):
// Note: shuffle_indices is false for PTC.
//
// total = len(indices); selected = []; i = 0
// while len(selected) < size:
// next = i % total
// if shuffle_indices: next = compute_shuffled_index(next, total, seed)
// if compute_balance_weighted_acceptance(state, indices[next], seed, i):
// selected.append(indices[next])
// i += 1
func selectByBalance(ctx context.Context, st state.ReadOnlyBeaconState, candidates []primitives.ValidatorIndex, seed [32]byte, count uint64) ([]primitives.ValidatorIndex, error) {
if len(candidates) == 0 {
return nil, errors.New("no candidates for balance weighted selection")
}
hashFunc := hash.CustomSHA256Hasher()
// Pre-allocate buffer for hash input: seed (32 bytes) + round counter (8 bytes).
var buf [40]byte
copy(buf[:], seed[:])
maxBalance := params.BeaconConfig().MaxEffectiveBalanceElectra
selected := make([]primitives.ValidatorIndex, 0, count)
total := uint64(len(candidates))
for i := uint64(0); uint64(len(selected)) < count; i++ {
if ctx.Err() != nil {
return nil, ctx.Err()
}
idx := candidates[i%total]
ok, err := acceptByBalance(st, idx, buf[:], hashFunc, maxBalance, i)
if err != nil {
return nil, err
}
if ok {
selected = append(selected, idx)
}
}
return selected, nil
}
// acceptByBalance determines if a validator is accepted based on its effective balance.
// Spec v1.7.0-alpha.0 (pseudocode):
// compute_balance_weighted_acceptance(state, index, seed, i):
//
// MAX_RANDOM_VALUE = 2**16 - 1
// random_bytes = hash(seed + uint_to_bytes(i // 16))
// offset = i % 16 * 2
// random_value = bytes_to_uint64(random_bytes[offset:offset+2])
// effective_balance = state.validators[index].effective_balance
// return effective_balance * MAX_RANDOM_VALUE >= MAX_EFFECTIVE_BALANCE_ELECTRA * random_value
func acceptByBalance(st state.ReadOnlyBeaconState, idx primitives.ValidatorIndex, seedBuf []byte, hashFunc func([]byte) [32]byte, maxBalance uint64, round uint64) (bool, error) {
// Reuse the seed buffer by overwriting the last 8 bytes with the round counter.
binary.LittleEndian.PutUint64(seedBuf[len(seedBuf)-8:], round/16)
random := hashFunc(seedBuf)
offset := (round % 16) * 2
randomValue := uint64(binary.LittleEndian.Uint16(random[offset : offset+2])) // 16-bit draw per spec
val, err := st.ValidatorAtIndex(idx)
if err != nil {
return false, errors.Wrapf(err, "validator %d", idx)
}
return val.EffectiveBalance*fieldparams.MaxRandomValueElectra >= maxBalance*randomValue, nil
}
// validIndexedPayloadAttestation verifies the signature of an indexed payload attestation.
// Spec v1.7.0-alpha.0 (pseudocode):
// is_valid_indexed_payload_attestation(state: BeaconState, indexed_payload_attestation: IndexedPayloadAttestation) -> bool:
//
// indices = indexed_payload_attestation.attesting_indices
// return len(indices) > 0 and indices == sorted(indices) and
// bls.FastAggregateVerify(
// [state.validators[i].pubkey for i in indices],
// compute_signing_root(indexed_payload_attestation.data, get_domain(state, DOMAIN_PTC_ATTESTER, compute_epoch_at_slot(attestation.data.slot)),
// indexed_payload_attestation.signature,
// )
func validIndexedPayloadAttestation(st state.ReadOnlyBeaconState, att *consensus_types.IndexedPayloadAttestation) error {
indices := att.AttestingIndices
if len(indices) == 0 || !slices.IsSorted(indices) {
return errors.New("attesting indices empty or unsorted")
}
pubkeys := make([]bls.PublicKey, len(indices))
for i, idx := range indices {
val, err := st.ValidatorAtIndexReadOnly(idx)
if err != nil {
return errors.Wrapf(err, "validator %d", idx)
}
keyBytes := val.PublicKey()
key, err := bls.PublicKeyFromBytes(keyBytes[:])
if err != nil {
return errors.Wrapf(err, "pubkey %d", idx)
}
pubkeys[i] = key
}
domain, err := signing.Domain(st.Fork(), slots.ToEpoch(att.Data.Slot), params.BeaconConfig().DomainPTCAttester, st.GenesisValidatorsRoot())
if err != nil {
return err
}
root, err := signing.ComputeSigningRoot(att.Data, domain)
if err != nil {
return err
}
sig, err := bls.SignatureFromBytes(att.Signature)
if err != nil {
return err
}
if !sig.FastAggregateVerify(pubkeys, root) {
return errors.New("invalid signature")
}
return nil
}

View File

@@ -0,0 +1,305 @@
package gloas_test
import (
"bytes"
"testing"
"github.com/OffchainLabs/go-bitfield"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/signing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/crypto/bls"
"github.com/OffchainLabs/prysm/v7/crypto/bls/common"
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/testing/require"
testutil "github.com/OffchainLabs/prysm/v7/testing/util"
"github.com/OffchainLabs/prysm/v7/time/slots"
)
func TestProcessPayloadAttestations_WrongParent(t *testing.T) {
setupTestConfig(t)
_, pk := newKey(t)
st := newTestState(t, []*eth.Validator{activeValidator(pk)}, 1)
require.NoError(t, st.SetSlot(2))
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
att := &eth.PayloadAttestation{
Data: &eth.PayloadAttestationData{
BeaconBlockRoot: bytes.Repeat([]byte{0xbb}, 32),
Slot: 1,
},
AggregationBits: bitfield.NewBitvector512(),
Signature: make([]byte, 96),
}
body := buildBody(t, att)
err := gloas.ProcessPayloadAttestations(t.Context(), st, body)
require.ErrorContains(t, "wrong parent", err)
}
func TestProcessPayloadAttestations_WrongSlot(t *testing.T) {
setupTestConfig(t)
_, pk := newKey(t)
st := newTestState(t, []*eth.Validator{activeValidator(pk)}, 1)
require.NoError(t, st.SetSlot(3))
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
att := &eth.PayloadAttestation{
Data: &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 1,
},
AggregationBits: bitfield.NewBitvector512(),
Signature: make([]byte, 96),
}
body := buildBody(t, att)
err := gloas.ProcessPayloadAttestations(t.Context(), st, body)
require.ErrorContains(t, "wrong slot", err)
}
func TestProcessPayloadAttestations_InvalidSignature(t *testing.T) {
setupTestConfig(t)
_, pk1 := newKey(t)
sk2, pk2 := newKey(t)
vals := []*eth.Validator{activeValidator(pk1), activeValidator(pk2)}
st := newTestState(t, vals, 2)
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
attData := &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 1,
}
att := &eth.PayloadAttestation{
Data: attData,
AggregationBits: setBits(bitfield.NewBitvector512(), 0),
Signature: signAttestation(t, st, attData, []common.SecretKey{sk2}),
}
body := buildBody(t, att)
err := gloas.ProcessPayloadAttestations(t.Context(), st, body)
require.ErrorContains(t, "failed to verify indexed form", err)
require.ErrorContains(t, "invalid signature", err)
}
func TestProcessPayloadAttestations_EmptyAggregationBits(t *testing.T) {
setupTestConfig(t)
_, pk := newKey(t)
st := newTestState(t, []*eth.Validator{activeValidator(pk)}, 1)
require.NoError(t, st.SetSlot(2))
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
attData := &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 1,
}
att := &eth.PayloadAttestation{
Data: attData,
AggregationBits: bitfield.NewBitvector512(),
Signature: make([]byte, 96),
}
body := buildBody(t, att)
err := gloas.ProcessPayloadAttestations(t.Context(), st, body)
require.ErrorContains(t, "failed to verify indexed form", err)
require.ErrorContains(t, "attesting indices empty or unsorted", err)
}
func TestProcessPayloadAttestations_HappyPath(t *testing.T) {
helpers.ClearCache()
setupTestConfig(t)
sk1, pk1 := newKey(t)
sk2, pk2 := newKey(t)
vals := []*eth.Validator{activeValidator(pk1), activeValidator(pk2)}
st := newTestState(t, vals, 2)
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
attData := &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 1,
}
aggBits := bitfield.NewBitvector512()
aggBits.SetBitAt(0, true)
aggBits.SetBitAt(1, true)
att := &eth.PayloadAttestation{
Data: attData,
AggregationBits: aggBits,
Signature: signAttestation(t, st, attData, []common.SecretKey{sk1, sk2}),
}
body := buildBody(t, att)
err := gloas.ProcessPayloadAttestations(t.Context(), st, body)
require.NoError(t, err)
}
func TestProcessPayloadAttestations_MultipleAttestations(t *testing.T) {
helpers.ClearCache()
setupTestConfig(t)
sk1, pk1 := newKey(t)
sk2, pk2 := newKey(t)
vals := []*eth.Validator{activeValidator(pk1), activeValidator(pk2)}
st := newTestState(t, vals, 2)
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
attData1 := &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 1,
}
attData2 := &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 1,
}
att1 := &eth.PayloadAttestation{
Data: attData1,
AggregationBits: setBits(bitfield.NewBitvector512(), 0),
Signature: signAttestation(t, st, attData1, []common.SecretKey{sk1}),
}
att2 := &eth.PayloadAttestation{
Data: attData2,
AggregationBits: setBits(bitfield.NewBitvector512(), 1),
Signature: signAttestation(t, st, attData2, []common.SecretKey{sk2}),
}
body := buildBody(t, att1, att2)
err := gloas.ProcessPayloadAttestations(t.Context(), st, body)
require.NoError(t, err)
}
func TestProcessPayloadAttestations_IndexedVerificationError(t *testing.T) {
setupTestConfig(t)
_, pk := newKey(t)
st := newTestState(t, []*eth.Validator{activeValidator(pk)}, 1)
parentRoot := bytes.Repeat([]byte{0xaa}, 32)
require.NoError(t, st.SetLatestBlockHeader(&eth.BeaconBlockHeader{ParentRoot: parentRoot}))
attData := &eth.PayloadAttestationData{
BeaconBlockRoot: parentRoot,
Slot: 0,
}
att := &eth.PayloadAttestation{
Data: attData,
AggregationBits: setBits(bitfield.NewBitvector512(), 0),
Signature: make([]byte, 96),
}
body := buildBody(t, att)
errState := &validatorLookupErrState{
BeaconState: st,
errIndex: 0,
}
err := gloas.ProcessPayloadAttestations(t.Context(), errState, body)
require.ErrorContains(t, "failed to verify indexed form", err)
require.ErrorContains(t, "validator 0", err)
}
func newTestState(t *testing.T, vals []*eth.Validator, slot primitives.Slot) state.BeaconState {
st, err := testutil.NewBeaconState()
require.NoError(t, err)
for _, v := range vals {
require.NoError(t, st.AppendValidator(v))
require.NoError(t, st.AppendBalance(v.EffectiveBalance))
}
require.NoError(t, st.SetSlot(slot))
require.NoError(t, helpers.UpdateCommitteeCache(t.Context(), st, slots.ToEpoch(slot)))
return st
}
func setupTestConfig(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig().Copy()
cfg.SlotsPerEpoch = 1
cfg.MaxEffectiveBalanceElectra = cfg.MaxEffectiveBalance
params.OverrideBeaconConfig(cfg)
}
func buildBody(t *testing.T, atts ...*eth.PayloadAttestation) interfaces.ReadOnlyBeaconBlockBody {
body := &eth.BeaconBlockBodyGloas{
PayloadAttestations: atts,
RandaoReveal: make([]byte, 96),
Eth1Data: &eth.Eth1Data{},
Graffiti: make([]byte, 32),
ProposerSlashings: []*eth.ProposerSlashing{},
AttesterSlashings: []*eth.AttesterSlashingElectra{},
Attestations: []*eth.AttestationElectra{},
Deposits: []*eth.Deposit{},
VoluntaryExits: []*eth.SignedVoluntaryExit{},
SyncAggregate: &eth.SyncAggregate{},
BlsToExecutionChanges: []*eth.SignedBLSToExecutionChange{},
}
wrapped, err := blocks.NewBeaconBlockBody(body)
require.NoError(t, err)
return wrapped
}
func setBits(bits bitfield.Bitvector512, idx uint64) bitfield.Bitvector512 {
bits.SetBitAt(idx, true)
return bits
}
func activeValidator(pub []byte) *eth.Validator {
return &eth.Validator{
PublicKey: pub,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
WithdrawalCredentials: make([]byte, 32),
ActivationEligibilityEpoch: 0,
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
WithdrawableEpoch: params.BeaconConfig().FarFutureEpoch,
}
}
func newKey(t *testing.T) (common.SecretKey, []byte) {
sk, err := bls.RandKey()
require.NoError(t, err)
return sk, sk.PublicKey().Marshal()
}
func signAttestation(t *testing.T, st state.ReadOnlyBeaconState, data *eth.PayloadAttestationData, sks []common.SecretKey) []byte {
domain, err := signing.Domain(st.Fork(), slots.ToEpoch(data.Slot), params.BeaconConfig().DomainPTCAttester, st.GenesisValidatorsRoot())
require.NoError(t, err)
root, err := signing.ComputeSigningRoot(data, domain)
require.NoError(t, err)
sigs := make([]common.Signature, len(sks))
for i, sk := range sks {
sigs[i] = sk.Sign(root[:])
}
agg := bls.AggregateSignatures(sigs)
return agg.Marshal()
}
type validatorLookupErrState struct {
state.BeaconState
errIndex primitives.ValidatorIndex
}
// ValidatorAtIndexReadOnly is overridden to simulate a missing validator lookup.
func (s *validatorLookupErrState) ValidatorAtIndexReadOnly(idx primitives.ValidatorIndex) (state.ReadOnlyValidator, error) {
if idx == s.errIndex {
return nil, state.ErrNilValidatorsInState
}
return s.BeaconState.ValidatorAtIndexReadOnly(idx)
}

View File

@@ -413,7 +413,7 @@ func CreateDefaultLightClientUpdate(attestedBlock interfaces.ReadOnlySignedBeaco
SyncCommitteeSignature: make([]byte, 96),
},
}
case version.Electra, version.Fulu:
case version.Electra, version.Fulu, version.Gloas:
m = &pb.LightClientUpdateElectra{
AttestedHeader: &pb.LightClientHeaderDeneb{
Beacon: &pb.BeaconBlockHeader{
@@ -515,7 +515,7 @@ func ComputeWithdrawalsRoot(payload interfaces.ExecutionData) ([]byte, error) {
func BlockToLightClientHeader(
ctx context.Context,
attestedBlockVersion int, // this is the version that the light client header should be in, based on the attested block.
attestedBlockVersion int, // this is the version that the light client header should be in, based on the attested block.
block interfaces.ReadOnlySignedBeaconBlock, // this block is either the attested block, or the finalized block. in case of the latter, we might need to upgrade it to the attested block's version.
) (interfaces.LightClientHeader, error) {
if block.Version() > attestedBlockVersion {
@@ -543,7 +543,7 @@ func BlockToLightClientHeader(
Execution: payloadHeader,
ExecutionBranch: payloadProof,
}
case version.Deneb, version.Electra, version.Fulu:
case version.Deneb, version.Electra, version.Fulu, version.Gloas:
payloadHeader, payloadProof, err := makeExecutionAndProofDeneb(ctx, block)
if err != nil {
return nil, errors.Wrap(err, "could not make execution payload header and proof")

View File

@@ -50,6 +50,14 @@ import (
"go.uber.org/mock/gomock"
)
// fillGloasBlockTestData populates a Gloas block with non-zero test values for the
// Gloas-specific fields: SignedExecutionPayloadBid and PayloadAttestations.
func fillGloasBlockTestData(b *eth.SignedBeaconBlockGloas, numPayloadAttestations int) {
slot := b.Block.Slot
b.Block.Body.SignedExecutionPayloadBid = util.GenerateTestSignedExecutionPayloadBid(slot)
b.Block.Body.PayloadAttestations = util.GenerateTestPayloadAttestations(numPayloadAttestations, slot)
}
func fillDBTestBlocks(ctx context.Context, t *testing.T, beaconDB db.Database) (*eth.SignedBeaconBlock, []*eth.BeaconBlockContainer) {
parentRoot := [32]byte{1, 2, 3}
genBlk := util.NewBeaconBlock()
@@ -335,6 +343,50 @@ func TestGetBlockV2(t *testing.T) {
require.NoError(t, err)
assert.DeepEqual(t, blk, b)
})
t.Run("gloas", func(t *testing.T) {
b := util.NewBeaconBlockGloas()
b.Block.Slot = 123
fillGloasBlockTestData(b, 2)
sb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
mockBlockFetcher := &testutil.MockBlocker{BlockToReturn: sb}
mockChainService := &chainMock.ChainService{
FinalizedRoots: map[[32]byte]bool{},
}
s := &Server{
OptimisticModeFetcher: mockChainService,
FinalizationFetcher: mockChainService,
Blocker: mockBlockFetcher,
}
request := httptest.NewRequest(http.MethodGet, "http://foo.example/eth/v2/beacon/blocks/{block_id}", nil)
request.SetPathValue("block_id", "head")
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
resp := &structs.GetBlockV2Response{}
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
assert.Equal(t, version.String(version.Gloas), resp.Version)
sbb := &structs.SignedBeaconBlockGloas{Message: &structs.BeaconBlockGloas{}}
require.NoError(t, json.Unmarshal(resp.Data.Message, sbb.Message))
sbb.Signature = resp.Data.Signature
blk, err := sbb.ToConsensus()
require.NoError(t, err)
assert.DeepEqual(t, blk, b)
// Verify Gloas-specific fields are correctly serialized/deserialized
require.NotNil(t, blk.Block.Body.SignedExecutionPayloadBid)
assert.Equal(t, primitives.Slot(123), blk.Block.Body.SignedExecutionPayloadBid.Message.Slot)
assert.Equal(t, primitives.BuilderIndex(1), blk.Block.Body.SignedExecutionPayloadBid.Message.BuilderIndex)
require.Equal(t, 2, len(blk.Block.Body.PayloadAttestations))
for _, att := range blk.Block.Body.PayloadAttestations {
assert.Equal(t, primitives.Slot(123), att.Data.Slot)
assert.Equal(t, true, att.Data.PayloadPresent)
assert.Equal(t, true, att.Data.BlobDataAvailable)
}
})
t.Run("execution optimistic", func(t *testing.T) {
b := util.NewBeaconBlockBellatrix()
sb, err := blocks.NewSignedBeaconBlock(b)
@@ -574,6 +626,37 @@ func TestGetBlockSSZV2(t *testing.T) {
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())
})
t.Run("gloas", func(t *testing.T) {
b := util.NewBeaconBlockGloas()
b.Block.Slot = 123
fillGloasBlockTestData(b, 2)
sb, err := blocks.NewSignedBeaconBlock(b)
require.NoError(t, err)
s := &Server{
Blocker: &testutil.MockBlocker{BlockToReturn: sb},
}
request := httptest.NewRequest(http.MethodGet, "http://foo.example/eth/v2/beacon/blocks/{block_id}", nil)
request.SetPathValue("block_id", "head")
request.Header.Set("Accept", api.OctetStreamMediaType)
writer := httptest.NewRecorder()
writer.Body = &bytes.Buffer{}
s.GetBlockV2(writer, request)
require.Equal(t, http.StatusOK, writer.Code)
assert.Equal(t, version.String(version.Gloas), writer.Header().Get(api.VersionHeader))
sszExpected, err := b.MarshalSSZ()
require.NoError(t, err)
assert.DeepEqual(t, sszExpected, writer.Body.Bytes())
// Verify SSZ round-trip preserves Gloas-specific fields
decoded := &eth.SignedBeaconBlockGloas{}
require.NoError(t, decoded.UnmarshalSSZ(writer.Body.Bytes()))
require.NotNil(t, decoded.Block.Body.SignedExecutionPayloadBid)
assert.Equal(t, primitives.Slot(123), decoded.Block.Body.SignedExecutionPayloadBid.Message.Slot)
require.Equal(t, 2, len(decoded.Block.Body.PayloadAttestations))
})
}
func TestGetBlockAttestationsV2(t *testing.T) {

View File

@@ -197,6 +197,9 @@ func TestGetSpec(t *testing.T) {
var dbb [4]byte
copy(dbb[:], []byte{'0', '0', '0', '8'})
config.DomainBeaconBuilder = dbb
var dptc [4]byte
copy(dptc[:], []byte{'0', '0', '0', '8'})
config.DomainPTCAttester = dptc
var dam [4]byte
copy(dam[:], []byte{'1', '0', '0', '0'})
config.DomainApplicationMask = dam
@@ -212,7 +215,7 @@ func TestGetSpec(t *testing.T) {
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), &resp))
data, ok := resp.Data.(map[string]any)
require.Equal(t, true, ok)
assert.Equal(t, 186, len(data))
assert.Equal(t, 187, len(data))
for k, v := range data {
t.Run(k, func(t *testing.T) {
switch k {
@@ -414,6 +417,8 @@ func TestGetSpec(t *testing.T) {
assert.Equal(t, "0x30303036", v)
case "DOMAIN_AGGREGATE_AND_PROOF":
assert.Equal(t, "0x30303037", v)
case "DOMAIN_PTC_ATTESTER":
assert.Equal(t, "0x30303038", v)
case "DOMAIN_APPLICATION_MASK":
assert.Equal(t, "0x31303030", v)
case "DOMAIN_SYNC_COMMITTEE":

View File

@@ -0,0 +1,3 @@
### Ignored
- add `cmd` and all it's subcategories to the log.go generation process.

View File

@@ -0,0 +1,3 @@
### Added
- gloas block return support for /eth/v2/beacon/blocks/{block_id} and /eth/v1/beacon/blocks/{block_id}/root endpoints.

View File

@@ -0,0 +1,2 @@
### Fixed
- Fix hashtree release builds.

View File

@@ -0,0 +1,3 @@
### Added
- Add Gloas process payload attestation

View File

@@ -9,6 +9,7 @@ go_library(
"defaults.go",
"flags.go",
"helpers.go",
"log.go",
"password_reader.go",
"wrap_flags.go",
],

View File

@@ -2,7 +2,10 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["db.go"],
srcs = [
"db.go",
"log.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/beacon-chain/db",
visibility = ["//visibility:public"],
deps = [

View File

@@ -4,12 +4,9 @@ import (
beacondb "github.com/OffchainLabs/prysm/v7/beacon-chain/db"
"github.com/OffchainLabs/prysm/v7/cmd"
"github.com/OffchainLabs/prysm/v7/runtime/tos"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "db")
// Commands for interacting with a beacon chain database.
var Commands = &cli.Command{
Name: "db",

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package db
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/beacon-chain/db")

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package flags
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "flags")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/beacon-chain/flags")

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package genesis
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "genesis")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/beacon-chain/genesis")

View File

@@ -2,7 +2,10 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["jwt.go"],
srcs = [
"jwt.go",
"log.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/beacon-chain/jwt",
visibility = ["//visibility:public"],
deps = [

View File

@@ -6,7 +6,6 @@ import (
"github.com/OffchainLabs/prysm/v7/api"
"github.com/OffchainLabs/prysm/v7/cmd"
"github.com/OffchainLabs/prysm/v7/io/file"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
@@ -23,7 +22,7 @@ var Commands = &cli.Command{
}),
Action: func(cliCtx *cli.Context) error {
if err := generateAuthSecretInFile(cliCtx); err != nil {
logrus.WithError(err).Fatal("Could not generate jwt")
log.WithError(err).Fatal("Could not generate jwt")
}
return nil
},
@@ -57,6 +56,6 @@ func generateAuthSecretInFile(c *cli.Context) error {
if err := file.WriteFile(fileName, []byte(secret)); err != nil {
return err
}
logrus.Infof("Successfully wrote JSON-RPC authentication secret to file %s", fileName)
log.Infof("Successfully wrote JSON-RPC authentication secret to file %s", fileName)
return nil
}

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package jwt
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/beacon-chain/jwt")

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package main
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "main")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/beacon-chain")

View File

@@ -2,7 +2,10 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["options.go"],
srcs = [
"log.go",
"options.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/beacon-chain/storage",
visibility = ["//visibility:public"],
deps = [

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package storage
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/beacon-chain/storage")

View File

@@ -15,7 +15,6 @@ import (
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package main
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "main")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/client-stats")

View File

@@ -14,8 +14,6 @@ import (
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "node")
// ConfirmAction uses the passed in actionText as the confirmation text displayed in the terminal.
// The user must enter Y or N to indicate whether they confirm the action detailed in the warning text.
// Returns a boolean representing the user's answer.

9
cmd/log.go Normal file
View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package cmd
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd")

View File

@@ -4,7 +4,10 @@ load("//tools:prysm_image.bzl", "prysm_image_upload")
go_library(
name = "go_default_library",
srcs = ["main.go"],
srcs = [
"log.go",
"main.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/prysmctl",
visibility = ["//visibility:private"],
deps = [

View File

@@ -5,6 +5,7 @@ go_library(
srcs = [
"cmd.go",
"download.go",
"log.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/prysmctl/checkpointsync",
visibility = ["//visibility:public"],

View File

@@ -8,7 +8,6 @@ import (
"github.com/OffchainLabs/prysm/v7/api/client"
"github.com/OffchainLabs/prysm/v7/api/client/beacon"
"github.com/OffchainLabs/prysm/v7/beacon-chain/sync/checkpoint"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package checkpointsync
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl/checkpointsync")

View File

@@ -5,6 +5,7 @@ go_library(
srcs = [
"buckets.go",
"cmd.go",
"log.go",
"query.go",
"span.go",
],

9
cmd/prysmctl/db/log.go Normal file
View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package db
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl/db")

View File

@@ -8,7 +8,6 @@ import (
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
bolt "go.etcd.io/bbolt"
)

9
cmd/prysmctl/log.go Normal file
View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package main
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl")

View File

@@ -9,7 +9,6 @@ import (
"github.com/OffchainLabs/prysm/v7/cmd/prysmctl/testnet"
"github.com/OffchainLabs/prysm/v7/cmd/prysmctl/validator"
"github.com/OffchainLabs/prysm/v7/cmd/prysmctl/weaksubjectivity"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package p2p
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "prysmctl-p2p")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl/p2p")

View File

@@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"generate_genesis.go",
"log.go",
"testnet.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/prysmctl/testnet",

View File

@@ -43,7 +43,6 @@ var (
GethGenesisJsonIn string
GethGenesisJsonOut string
}{}
log = logrus.WithField("prefix", "genesis")
outputSSZFlag = &cli.StringFlag{
Name: "output-ssz",
Destination: &generateGenesisStateFlags.OutputSSZ,

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package testnet
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl/testnet")

View File

@@ -5,6 +5,7 @@ go_library(
srcs = [
"cmd.go",
"error.go",
"log.go",
"proposer_settings.go",
"withdraw.go",
],

View File

@@ -10,7 +10,6 @@ import (
"github.com/OffchainLabs/prysm/v7/config/features"
"github.com/OffchainLabs/prysm/v7/runtime/tos"
"github.com/logrusorgru/aurora"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package validator
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl/validator")

View File

@@ -16,7 +16,6 @@ import (
"github.com/OffchainLabs/prysm/v7/monitoring/tracing/trace"
validatorpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1/validator-client"
"github.com/ethereum/go-ethereum/common"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

View File

@@ -18,7 +18,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/logrusorgru/aurora"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
@@ -143,7 +143,7 @@ func checkIfWithdrawsAreInPool(ctx context.Context, client *beacon.Client, reque
}
if len(requestMap) != 0 {
for key, address := range requestMap {
log.WithFields(log.Fields{
log.WithFields(logrus.Fields{
"validatorIndex": key,
"executionAddress:": address,
}).Warn("Set withdrawal address message not found in the node's operations pool.")

View File

@@ -5,6 +5,7 @@ go_library(
srcs = [
"checkpoint.go",
"cmd.go",
"log.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/prysmctl/weaksubjectivity",
visibility = ["//visibility:public"],

View File

@@ -8,7 +8,6 @@ import (
"github.com/OffchainLabs/prysm/v7/api/client"
"github.com/OffchainLabs/prysm/v7/api/client/beacon"
"github.com/OffchainLabs/prysm/v7/beacon-chain/sync/checkpoint"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package weaksubjectivity
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/prysmctl/weaksubjectivity")

View File

@@ -5,6 +5,7 @@ load("//tools:prysm_image.bzl", "prysm_image_upload")
go_library(
name = "go_default_library",
srcs = [
"log.go",
"main.go",
"usage.go",
],

View File

@@ -9,6 +9,7 @@ go_library(
"exit.go",
"import.go",
"list.go",
"log.go",
"wallet_utils.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/validator/accounts",

View File

@@ -7,12 +7,9 @@ import (
"github.com/OffchainLabs/prysm/v7/cmd/validator/flags"
"github.com/OffchainLabs/prysm/v7/config/features"
"github.com/OffchainLabs/prysm/v7/runtime/tos"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "accounts")
// Commands for managing Prysm validator accounts.
var Commands = &cli.Command{
Name: "accounts",

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package accounts
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/validator/accounts")

View File

@@ -2,7 +2,10 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["db.go"],
srcs = [
"db.go",
"log.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/cmd/validator/db",
visibility = ["//visibility:public"],
deps = [

View File

@@ -4,12 +4,9 @@ import (
"github.com/OffchainLabs/prysm/v7/cmd"
"github.com/OffchainLabs/prysm/v7/runtime/tos"
validatordb "github.com/OffchainLabs/prysm/v7/validator/db"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "db")
var (
// SourceDataDirFlag defines a path on disk where source Prysm databases are stored. Used for conversion.
SourceDataDirFlag = &cli.StringFlag{

9
cmd/validator/db/log.go Normal file
View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package db
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/validator/db")

9
cmd/validator/log.go Normal file
View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package main
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/validator")

View File

@@ -34,8 +34,6 @@ import (
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "main")
func startNode(ctx *cli.Context) error {
// Verify if ToS is accepted.
if err := tos.VerifyTosAcceptedOrPrompt(ctx); err != nil {

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package historycmd
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "historycmd")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/validator/slashing-protection")

View File

@@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"create.go",
"log.go",
"recover.go",
"wallet.go",
],

View File

@@ -0,0 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package wallet
import "github.com/sirupsen/logrus"
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/validator/wallet")

View File

@@ -5,12 +5,9 @@ import (
"github.com/OffchainLabs/prysm/v7/cmd/validator/flags"
"github.com/OffchainLabs/prysm/v7/config/features"
"github.com/OffchainLabs/prysm/v7/runtime/tos"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "wallet")
// Commands for wallets for Prysm validators.
var Commands = &cli.Command{
Name: "wallet",

View File

@@ -1,5 +1,9 @@
// Code generated by hack/gen-logs.sh; DO NOT EDIT.
// This file is created and regenerated automatically. Anything added here might get removed.
package web
import "github.com/sirupsen/logrus"
var log = logrus.WithField("prefix", "web")
// The prefix for logs from this package will be the text after the last slash in the package path.
// If you wish to change this, you should add your desired name in the runtime/logging/logrus-prefixed-formatter/prefix-replacement.go file.
var log = logrus.WithField("package", "cmd/validator/web")

View File

@@ -50,4 +50,7 @@ const (
// Introduced in Fulu network upgrade.
NumberOfColumns = 128 // NumberOfColumns refers to the specified number of data columns that can exist in a network.
CellsPerBlob = 64 // CellsPerBlob refers to the number of cells in a (non-extended) blob.
// Introduced in Gloas network upgrade.
PTCSize = 512 // PTCSize is the size of the payload timeliness committee.
)

View File

@@ -50,4 +50,7 @@ const (
// Introduced in Fulu network upgrade.
NumberOfColumns = 128 // NumberOfColumns refers to the specified number of data columns that can exist in a network.
CellsPerBlob = 64 // CellsPerBlob refers to the number of cells in a (non-extended) blob.
// Introduced in Gloas network upgrade.
PTCSize = 2 // PTCSize is the size of the payload timeliness committee.
)

View File

@@ -142,6 +142,7 @@ type BeaconChainConfig struct {
DomainApplicationBuilder [4]byte `yaml:"DOMAIN_APPLICATION_BUILDER" spec:"true"` // DomainApplicationBuilder defines the BLS signature domain for application builder.
DomainBLSToExecutionChange [4]byte `yaml:"DOMAIN_BLS_TO_EXECUTION_CHANGE" spec:"true"` // DomainBLSToExecutionChange defines the BLS signature domain to change withdrawal addresses to ETH1 prefix
DomainBeaconBuilder [4]byte `yaml:"DOMAIN_BEACON_BUILDER" spec:"true"` // DomainBeaconBuilder defines the BLS signature domain for beacon block builder.
DomainPTCAttester [4]byte `yaml:"DOMAIN_PTC_ATTESTER" spec:"true"` // DomainPTCAttester defines the BLS signature domain for payload transaction committee attester.
// Prysm constants.
GenesisValidatorsRoot [32]byte // GenesisValidatorsRoot is the root hash of the genesis validators.

View File

@@ -185,6 +185,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{
DomainApplicationBuilder: bytesutil.Uint32ToBytes4(0x00000001),
DomainBLSToExecutionChange: bytesutil.Uint32ToBytes4(0x0A000000),
DomainBeaconBuilder: bytesutil.Uint32ToBytes4(0x0B000000),
DomainPTCAttester: bytesutil.Uint32ToBytes4(0x0C000000),
// Prysm constants.
GenesisValidatorsRoot: [32]byte{75, 54, 61, 185, 78, 40, 97, 32, 215, 110, 185, 5, 52, 15, 221, 78, 84, 191, 233, 240, 107, 243, 63, 246, 207, 90, 210, 127, 81, 27, 254, 149},

View File

@@ -2,10 +2,15 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["types.go"],
srcs = [
"indexed_payload_attestation.go",
"types.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/consensus-types",
visibility = ["//visibility:public"],
deps = [
"//consensus-types/primitives:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
"@com_github_pkg_errors//:go_default_library",
],

View File

@@ -0,0 +1,36 @@
package consensus_types
import (
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
)
type IndexedPayloadAttestation struct {
AttestingIndices []primitives.ValidatorIndex
Data *eth.PayloadAttestationData
Signature []byte
}
// GetAttestingIndices returns the attesting indices or nil when the receiver is nil.
func (x *IndexedPayloadAttestation) GetAttestingIndices() []primitives.ValidatorIndex {
if x == nil {
return nil
}
return x.AttestingIndices
}
// GetData returns the attestation data or nil when the receiver is nil.
func (x *IndexedPayloadAttestation) GetData() *eth.PayloadAttestationData {
if x == nil {
return nil
}
return x.Data
}
// GetSignature returns the signature bytes or nil when the receiver is nil.
func (x *IndexedPayloadAttestation) GetSignature() []byte {
if x == nil {
return nil
}
return x.Signature
}

View File

@@ -14,7 +14,6 @@ EXCLUDED_PATH_PREFIXES=(
"runtime"
"monitoring"
"io"
"cmd"
".well-known"
"changelog"
"hack"

View File

@@ -1,6 +1,13 @@
package prefixed
var prefixReplacements = map[string]string{
"cmd/beacon-chain": "main",
"cmd/client-stats": "main",
"cmd/prysmctl/p2p": "prysmctl-p2p",
"cmd/prysmctl/testnet": "genesis",
"cmd/validator/slashing-protection": "historycmd",
"cmd/validator": "main",
"cmd": "node",
"beacon-chain/cache/depositsnapshot": "cache",
"beacon-chain/core/transition": "state",
"beacon-chain/db/kv": "db",

View File

@@ -202,6 +202,7 @@ go_test(
"fulu__ssz_static__ssz_static_test.go",
"gloas__epoch_processing__process_builder_pending_payments_test.go",
"gloas__operations__execution_payload_header_test.go",
"gloas__operations__payload_attestation_test.go",
"gloas__operations__proposer_slashing_test.go",
"gloas__sanity__slots_test.go",
"gloas__ssz_static__ssz_static_test.go",

View File

@@ -0,0 +1,11 @@
package mainnet
import (
"testing"
"github.com/OffchainLabs/prysm/v7/testing/spectest/shared/gloas/operations"
)
func TestMainnet_Gloas_Operations_PayloadAttestation(t *testing.T) {
operations.RunPayloadAttestationTest(t, "mainnet")
}

View File

@@ -208,6 +208,7 @@ go_test(
"fulu__ssz_static__ssz_static_test.go",
"gloas__epoch_processing__process_builder_pending_payments_test.go",
"gloas__operations__execution_payload_bid_test.go",
"gloas__operations__payload_attestation_test.go",
"gloas__operations__proposer_slashing_test.go",
"gloas__sanity__slots_test.go",
"gloas__ssz_static__ssz_static_test.go",

View File

@@ -0,0 +1,11 @@
package minimal
import (
"testing"
"github.com/OffchainLabs/prysm/v7/testing/spectest/shared/gloas/operations"
)
func TestMinimal_Gloas_Operations_PayloadAttestation(t *testing.T) {
operations.RunPayloadAttestationTest(t, "minimal")
}

View File

@@ -13,6 +13,7 @@ go_library(
"deposit_request.go",
"execution_payload.go",
"execution_payload_bid.go",
"payload_attestation.go",
"proposer_slashing.go",
"slashing.go",
"sync_aggregate.go",

View File

@@ -0,0 +1,122 @@
package operations
import (
"context"
"path"
"testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/testing/require"
"github.com/OffchainLabs/prysm/v7/testing/spectest/utils"
"github.com/OffchainLabs/prysm/v7/testing/util"
"github.com/golang/snappy"
)
type PayloadAttestationOperation func(ctx context.Context, s state.BeaconState, att *eth.PayloadAttestation) (state.BeaconState, error)
func RunPayloadAttestationTest(t *testing.T, config string, fork string, sszToState SSZToState) {
runPayloadAttestationTest(t, config, fork, "payload_attestation", sszToState, func(ctx context.Context, s state.BeaconState, att *eth.PayloadAttestation) (state.BeaconState, error) {
// Create a mock block body with the payload attestation
body, err := createMockBlockBodyWithPayloadAttestation(att)
if err != nil {
return s, err
}
// Wrap the protobuf body in the interface
wrappedBody, err := blocks.NewBeaconBlockBody(body)
if err != nil {
return s, err
}
err = gloas.ProcessPayloadAttestations(ctx, s, wrappedBody)
return s, err
})
}
func runPayloadAttestationTest(t *testing.T, config string, fork string, objName string, sszToState SSZToState, operationFn PayloadAttestationOperation) {
require.NoError(t, utils.SetConfig(t, config))
testFolders, testsFolderPath := utils.TestFolders(t, config, fork, "operations/"+objName+"/pyspec_tests")
if len(testFolders) == 0 {
t.Fatalf("No test folders found for %s/%s/%s", config, fork, "operations/"+objName+"/pyspec_tests")
}
for _, folder := range testFolders {
t.Run(folder.Name(), func(t *testing.T) {
helpers.ClearCache()
folderPath := path.Join(testsFolderPath, folder.Name())
// Load payload attestation from payload_attestation.ssz_snappy
attestationFile, err := util.BazelFileBytes(folderPath, "payload_attestation.ssz_snappy")
require.NoError(t, err)
attestationSSZ, err := snappy.Decode(nil /* dst */, attestationFile)
require.NoError(t, err, "Failed to decompress payload attestation")
// Unmarshal payload attestation
att := &eth.PayloadAttestation{}
err = att.UnmarshalSSZ(attestationSSZ)
require.NoError(t, err, "Failed to unmarshal payload attestation")
runPayloadAttestationOperationTest(t, folderPath, att, sszToState, operationFn)
})
}
}
// runPayloadAttestationOperationTest runs a single payload attestation operation test
func runPayloadAttestationOperationTest(t *testing.T, folderPath string, att *eth.PayloadAttestation, sszToState SSZToState, operationFn PayloadAttestationOperation) {
preBeaconStateFile, err := util.BazelFileBytes(folderPath, "pre.ssz_snappy")
require.NoError(t, err)
preBeaconStateSSZ, err := snappy.Decode(nil /* dst */, preBeaconStateFile)
require.NoError(t, err, "Failed to decompress")
beaconState, err := sszToState(preBeaconStateSSZ)
require.NoError(t, err)
// Check if post state exists
postStateExists := true
postBeaconStateFile, err := util.BazelFileBytes(folderPath, "post.ssz_snappy")
if err != nil {
postStateExists = false
}
ctx := t.Context()
resultState, err := operationFn(ctx, beaconState, att)
if postStateExists {
// Test should succeed
require.NoError(t, err, "Operation should succeed")
// Compare with expected post state
postBeaconStateSSZ, err := snappy.Decode(nil /* dst */, postBeaconStateFile)
require.NoError(t, err, "Failed to decompress post state")
expectedState, err := sszToState(postBeaconStateSSZ)
require.NoError(t, err)
expectedRoot, err := expectedState.HashTreeRoot(ctx)
require.NoError(t, err)
resultRoot, err := resultState.HashTreeRoot(ctx)
require.NoError(t, err)
require.DeepEqual(t, expectedRoot, resultRoot, "Post state does not match expected")
} else {
// Test should fail (no post.ssz_snappy means the operation should error)
require.NotNil(t, err, "Operation should fail but succeeded")
}
}
// createMockBlockBodyWithPayloadAttestation creates a mock block body containing the payload attestation
func createMockBlockBodyWithPayloadAttestation(att *eth.PayloadAttestation) (*eth.BeaconBlockBodyGloas, error) {
body := &eth.BeaconBlockBodyGloas{
PayloadAttestations: []*eth.PayloadAttestation{att},
// Default values
RandaoReveal: make([]byte, 96),
Eth1Data: &eth.Eth1Data{},
Graffiti: make([]byte, 32),
ProposerSlashings: []*eth.ProposerSlashing{},
AttesterSlashings: []*eth.AttesterSlashingElectra{},
Attestations: []*eth.AttestationElectra{},
Deposits: []*eth.Deposit{},
VoluntaryExits: []*eth.SignedVoluntaryExit{},
SyncAggregate: &eth.SyncAggregate{},
BlsToExecutionChanges: []*eth.SignedBLSToExecutionChange{},
}
return body, nil
}

View File

@@ -6,6 +6,7 @@ go_library(
srcs = [
"execution_payload_bid.go",
"helpers.go",
"payload_attestation.go",
"proposer_slashing.go",
],
importpath = "github.com/OffchainLabs/prysm/v7/testing/spectest/shared/gloas/operations",

View File

@@ -15,7 +15,6 @@ func sszToState(b []byte) (state.BeaconState, error) {
}
return state_native.InitializeFromProtoGloas(base)
}
func sszToBlock(b []byte) (interfaces.SignedBeaconBlock, error) {
base := &ethpb.BeaconBlockGloas{}
if err := base.UnmarshalSSZ(b); err != nil {

View File

@@ -0,0 +1,12 @@
package operations
import (
"testing"
"github.com/OffchainLabs/prysm/v7/runtime/version"
common "github.com/OffchainLabs/prysm/v7/testing/spectest/shared/common/operations"
)
func RunPayloadAttestationTest(t *testing.T, config string) {
common.RunPayloadAttestationTest(t, config, version.String(version.Gloas), sszToState)
}

View File

@@ -1473,3 +1473,185 @@ func HydrateBlindedBeaconBlockBodyFulu(b *ethpb.BlindedBeaconBlockBodyElectra) *
b.ExecutionRequests = HydrateExecutionRequests(b.ExecutionRequests)
return b
}
// HydrateSignedBeaconBlockGloas hydrates a signed beacon block with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateSignedBeaconBlockGloas(b *ethpb.SignedBeaconBlockGloas) *ethpb.SignedBeaconBlockGloas {
if b == nil {
b = &ethpb.SignedBeaconBlockGloas{}
}
if b.Signature == nil {
b.Signature = make([]byte, fieldparams.BLSSignatureLength)
}
b.Block = HydrateBeaconBlockGloas(b.Block)
return b
}
// HydrateBeaconBlockGloas hydrates a beacon block with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateBeaconBlockGloas(b *ethpb.BeaconBlockGloas) *ethpb.BeaconBlockGloas {
if b == nil {
b = &ethpb.BeaconBlockGloas{}
}
if b.ParentRoot == nil {
b.ParentRoot = make([]byte, fieldparams.RootLength)
}
if b.StateRoot == nil {
b.StateRoot = make([]byte, fieldparams.RootLength)
}
b.Body = HydrateBeaconBlockBodyGloas(b.Body)
return b
}
// HydrateBeaconBlockBodyGloas hydrates a beacon block body with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateBeaconBlockBodyGloas(b *ethpb.BeaconBlockBodyGloas) *ethpb.BeaconBlockBodyGloas {
if b == nil {
b = &ethpb.BeaconBlockBodyGloas{}
}
if b.RandaoReveal == nil {
b.RandaoReveal = make([]byte, fieldparams.BLSSignatureLength)
}
if b.Graffiti == nil {
b.Graffiti = make([]byte, fieldparams.RootLength)
}
if b.Eth1Data == nil {
b.Eth1Data = &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
}
}
if b.SyncAggregate == nil {
b.SyncAggregate = &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncAggregateSyncCommitteeBytesLength),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
}
}
b.SignedExecutionPayloadBid = HydrateSignedExecutionPayloadBid(b.SignedExecutionPayloadBid)
if b.PayloadAttestations == nil {
b.PayloadAttestations = make([]*ethpb.PayloadAttestation, 0)
}
return b
}
// HydrateSignedExecutionPayloadBid hydrates a signed execution payload bid with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateSignedExecutionPayloadBid(b *ethpb.SignedExecutionPayloadBid) *ethpb.SignedExecutionPayloadBid {
if b == nil {
b = &ethpb.SignedExecutionPayloadBid{}
}
if b.Signature == nil {
b.Signature = make([]byte, fieldparams.BLSSignatureLength)
}
b.Message = HydrateExecutionPayloadBid(b.Message)
return b
}
// HydrateExecutionPayloadBid hydrates an execution payload bid with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydrateExecutionPayloadBid(b *ethpb.ExecutionPayloadBid) *ethpb.ExecutionPayloadBid {
if b == nil {
b = &ethpb.ExecutionPayloadBid{}
}
if b.ParentBlockHash == nil {
b.ParentBlockHash = make([]byte, fieldparams.RootLength)
}
if b.ParentBlockRoot == nil {
b.ParentBlockRoot = make([]byte, fieldparams.RootLength)
}
if b.BlockHash == nil {
b.BlockHash = make([]byte, fieldparams.RootLength)
}
if b.PrevRandao == nil {
b.PrevRandao = make([]byte, fieldparams.RootLength)
}
if b.FeeRecipient == nil {
b.FeeRecipient = make([]byte, fieldparams.FeeRecipientLength)
}
if b.BlobKzgCommitmentsRoot == nil {
b.BlobKzgCommitmentsRoot = make([]byte, fieldparams.RootLength)
}
return b
}
// HydratePayloadAttestation hydrates a payload attestation with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydratePayloadAttestation(p *ethpb.PayloadAttestation) *ethpb.PayloadAttestation {
if p == nil {
p = &ethpb.PayloadAttestation{}
}
if p.AggregationBits == nil {
p.AggregationBits = make([]byte, 64)
}
if p.Signature == nil {
p.Signature = make([]byte, fieldparams.BLSSignatureLength)
}
p.Data = HydratePayloadAttestationData(p.Data)
return p
}
// HydratePayloadAttestationData hydrates a payload attestation data with correct field length sizes
// to comply with fssz marshalling and unmarshalling rules.
func HydratePayloadAttestationData(d *ethpb.PayloadAttestationData) *ethpb.PayloadAttestationData {
if d == nil {
d = &ethpb.PayloadAttestationData{}
}
if d.BeaconBlockRoot == nil {
d.BeaconBlockRoot = make([]byte, fieldparams.RootLength)
}
return d
}
// GenerateTestPayloadAttestations generates a slice of payload attestations with non-zero test values.
// This is useful for testing Gloas-specific fields.
func GenerateTestPayloadAttestations(count int, slot primitives.Slot) []*ethpb.PayloadAttestation {
attestations := make([]*ethpb.PayloadAttestation, count)
for i := range count {
aggregationBits := make([]byte, 64)
aggregationBits[0] = 0x01 // Set at least one bit
signature := make([]byte, fieldparams.BLSSignatureLength)
signature[0] = byte(i + 1) // Make each signature unique
beaconBlockRoot := make([]byte, fieldparams.RootLength)
beaconBlockRoot[0] = byte(i + 1) // Make each root unique
attestations[i] = &ethpb.PayloadAttestation{
AggregationBits: aggregationBits,
Signature: signature,
Data: &ethpb.PayloadAttestationData{
BeaconBlockRoot: beaconBlockRoot,
Slot: slot,
PayloadPresent: true,
BlobDataAvailable: true,
},
}
}
return attestations
}
// GenerateTestSignedExecutionPayloadBid generates a signed execution payload bid with non-zero test values.
// This is useful for testing Gloas-specific fields.
func GenerateTestSignedExecutionPayloadBid(slot primitives.Slot) *ethpb.SignedExecutionPayloadBid {
parentBlockHash := bytesutil.PadTo([]byte{0x01}, fieldparams.RootLength)
parentBlockRoot := bytesutil.PadTo([]byte{0x02}, fieldparams.RootLength)
blockHash := bytesutil.PadTo([]byte{0x03}, fieldparams.RootLength)
prevRandao := bytesutil.PadTo([]byte{0x04}, fieldparams.RootLength)
feeRecipient := bytesutil.PadTo([]byte{0x05}, fieldparams.FeeRecipientLength)
blobKzgRoot := bytesutil.PadTo([]byte{0x06}, fieldparams.RootLength)
signature := bytesutil.PadTo([]byte{0x07}, fieldparams.BLSSignatureLength)
return &ethpb.SignedExecutionPayloadBid{
Message: &ethpb.ExecutionPayloadBid{
Slot: slot,
BuilderIndex: 1,
ParentBlockHash: parentBlockHash,
ParentBlockRoot: parentBlockRoot,
BlockHash: blockHash,
GasLimit: 30000000,
PrevRandao: prevRandao,
FeeRecipient: feeRecipient,
Value: 1000000,
BlobKzgCommitmentsRoot: blobKzgRoot,
},
Signature: signature,
}
}

View File

@@ -348,3 +348,81 @@ func Test_PostDenebPbGenericBlock_ErrorsForPlainBlock(t *testing.T) {
require.ErrorContains(t, "PbGenericBlock() only supports block content type but got", err)
})
}
func TestHydrateSignedBeaconBlockGloas_NoError(t *testing.T) {
b := &ethpbalpha.SignedBeaconBlockGloas{}
b = HydrateSignedBeaconBlockGloas(b)
_, err := b.HashTreeRoot()
require.NoError(t, err)
_, err = b.Block.HashTreeRoot()
require.NoError(t, err)
_, err = b.Block.Body.HashTreeRoot()
require.NoError(t, err)
}
func TestHydratePayloadAttestation_NoError(t *testing.T) {
p := &ethpbalpha.PayloadAttestation{}
p = HydratePayloadAttestation(p)
_, err := p.HashTreeRoot()
require.NoError(t, err)
_, err = p.Data.HashTreeRoot()
require.NoError(t, err)
}
func TestGenerateTestPayloadAttestations(t *testing.T) {
slot := primitives.Slot(123)
attestations := GenerateTestPayloadAttestations(3, slot)
require.Equal(t, 3, len(attestations))
for i, att := range attestations {
// Verify non-nil fields
require.NotNil(t, att.AggregationBits)
require.NotNil(t, att.Signature)
require.NotNil(t, att.Data)
require.NotNil(t, att.Data.BeaconBlockRoot)
// Verify slot is set correctly
require.Equal(t, slot, att.Data.Slot)
// Verify PayloadPresent and BlobDataAvailable are set
require.Equal(t, true, att.Data.PayloadPresent)
require.Equal(t, true, att.Data.BlobDataAvailable)
// Verify unique values
require.Equal(t, byte(i+1), att.Signature[0])
require.Equal(t, byte(i+1), att.Data.BeaconBlockRoot[0])
// Verify HashTreeRoot works
_, err := att.HashTreeRoot()
require.NoError(t, err)
}
}
func TestGenerateTestSignedExecutionPayloadBid(t *testing.T) {
slot := primitives.Slot(456)
bid := GenerateTestSignedExecutionPayloadBid(slot)
require.NotNil(t, bid)
require.NotNil(t, bid.Message)
require.NotNil(t, bid.Signature)
// Verify slot is set correctly
require.Equal(t, slot, bid.Message.Slot)
// Verify non-zero test values
require.Equal(t, primitives.BuilderIndex(1), bid.Message.BuilderIndex)
require.Equal(t, uint64(30000000), bid.Message.GasLimit)
require.Equal(t, primitives.Gwei(1000000), bid.Message.Value)
// Verify fields are populated
require.NotNil(t, bid.Message.ParentBlockHash)
require.NotNil(t, bid.Message.ParentBlockRoot)
require.NotNil(t, bid.Message.BlockHash)
require.NotNil(t, bid.Message.PrevRandao)
require.NotNil(t, bid.Message.FeeRecipient)
require.NotNil(t, bid.Message.BlobKzgCommitmentsRoot)
// Verify HashTreeRoot works
_, err := bid.HashTreeRoot()
require.NoError(t, err)
}

View File

@@ -88,3 +88,12 @@ func NewBeaconBlockContentsFulu() *ethpb.SignedBeaconBlockContentsFulu {
func NewBlindedBeaconBlockFulu() *ethpb.SignedBlindedBeaconBlockFulu {
return HydrateSignedBlindedBeaconBlockFulu(&ethpb.SignedBlindedBeaconBlockFulu{})
}
// ----------------------------------------------------------------------------
// Gloas
// ----------------------------------------------------------------------------
// NewBeaconBlockGloas creates a beacon block with minimum marshalable fields.
func NewBeaconBlockGloas() *ethpb.SignedBeaconBlockGloas {
return HydrateSignedBeaconBlockGloas(&ethpb.SignedBeaconBlockGloas{})
}

View File

@@ -1,7 +1,7 @@
diff -urN a/BUILD.bazel b/BUILD.bazel
--- a/BUILD.bazel 1969-12-31 18:00:00.000000000 -0600
+++ b/BUILD.bazel 2025-01-05 12:00:00.000000000 -0600
@@ -0,0 +1,86 @@
@@ -0,0 +1,89 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
@@ -44,14 +44,14 @@ diff -urN a/BUILD.bazel b/BUILD.bazel
+ name = "hashtree_arm64_syso",
+ srcs = [":hashtree_arm64"],
+ outs = ["hashtree_arm64.syso"],
+ cmd = "cp $(location :hashtree_arm64) $@",
+ cmd = "cp $$(echo $(locations :hashtree_arm64) | tr ' ' '\\n' | grep -v '\\.pic\\.' | head -1) $@",
+)
+
+genrule(
+ name = "hashtree_amd64_syso",
+ srcs = [":hashtree_amd64"],
+ outs = ["hashtree_amd64.syso"],
+ cmd = "cp $(location :hashtree_amd64) $@",
+ cmd = "cp $$(echo $(locations :hashtree_amd64) | tr ' ' '\\n' | grep -v '\\.pic\\.' | head -1) $@",
+)
+
+cc_library(
@@ -83,7 +83,10 @@ diff -urN a/BUILD.bazel b/BUILD.bazel
+ "src/sha256_sse_x1.S",
+ ],
+ hdrs = ["src/hashtree.h"],
+ copts = ["-O3", "-Wall", "-fno-integrated-as"],
+ copts = ["-O3", "-Wall"] + select({
+ "@platforms//os:windows": [],
+ "//conditions:default": ["-fno-integrated-as"],
+ }),
+ linkstatic = True,
+ strip_include_prefix = "src",
+ visibility = ["//visibility:public"],