mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-26 21:59:13 -05:00
Compare commits
1 Commits
deflake-ev
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce9c968dcc |
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 ð.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 ð.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 ð.BeaconBlockBodyGloas{
|
||||
RandaoReveal: randaoReveal,
|
||||
Eth1Data: ð.Eth1Data{
|
||||
DepositRoot: depositRoot,
|
||||
DepositCount: depositCount,
|
||||
BlockHash: blockHash,
|
||||
},
|
||||
Graffiti: graffiti,
|
||||
ProposerSlashings: proposerSlashings,
|
||||
AttesterSlashings: attesterSlashings,
|
||||
Attestations: atts,
|
||||
Deposits: deposits,
|
||||
VoluntaryExits: exits,
|
||||
SyncAggregate: ð.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 ð.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 ð.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 ð.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 ð.PayloadAttestationData{
|
||||
BeaconBlockRoot: beaconBlockRoot,
|
||||
Slot: primitives.Slot(slot),
|
||||
PayloadPresent: d.PayloadPresent,
|
||||
BlobDataAvailable: d.BlobDataAvailable,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -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 := ð.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) {
|
||||
|
||||
3
changelog/james-prysm_gloas-getblockv2-rest.md
Normal file
3
changelog/james-prysm_gloas-getblockv2-rest.md
Normal 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.
|
||||
@@ -163,103 +163,80 @@ func allNodesHaveSameHead(_ *e2etypes.EvaluationContext, conns ...*grpc.ClientCo
|
||||
return errors.Wrap(err, "failed waiting for mid-epoch")
|
||||
}
|
||||
|
||||
// Retry up to 3 times with 2 second delays to handle data availability delays.
|
||||
// With PeerDAS, non-proposer nodes may take longer to sync blocks while
|
||||
// fetching data columns from the network.
|
||||
const maxRetries = 3
|
||||
const retryDelay = 2 * time.Second
|
||||
var lastErr error
|
||||
headEpochs := make([]primitives.Epoch, len(conns))
|
||||
headBlockRoots := make([][]byte, len(conns))
|
||||
justifiedRoots := make([][]byte, len(conns))
|
||||
prevJustifiedRoots := make([][]byte, len(conns))
|
||||
finalizedRoots := make([][]byte, len(conns))
|
||||
chainHeads := make([]*eth.ChainHead, len(conns))
|
||||
g, _ := errgroup.WithContext(context.Background())
|
||||
|
||||
for attempt := range maxRetries {
|
||||
if attempt > 0 {
|
||||
time.Sleep(retryDelay)
|
||||
}
|
||||
|
||||
headEpochs := make([]primitives.Epoch, len(conns))
|
||||
headBlockRoots := make([][]byte, len(conns))
|
||||
justifiedRoots := make([][]byte, len(conns))
|
||||
prevJustifiedRoots := make([][]byte, len(conns))
|
||||
finalizedRoots := make([][]byte, len(conns))
|
||||
chainHeads := make([]*eth.ChainHead, len(conns))
|
||||
g, _ := errgroup.WithContext(context.Background())
|
||||
|
||||
for i, conn := range conns {
|
||||
conIdx := i
|
||||
currConn := conn
|
||||
g.Go(func() error {
|
||||
beaconClient := eth.NewBeaconChainClient(currConn)
|
||||
chainHead, err := beaconClient.GetChainHead(context.Background(), &emptypb.Empty{})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "connection number=%d", conIdx)
|
||||
}
|
||||
headEpochs[conIdx] = chainHead.HeadEpoch
|
||||
headBlockRoots[conIdx] = chainHead.HeadBlockRoot
|
||||
justifiedRoots[conIdx] = chainHead.JustifiedBlockRoot
|
||||
prevJustifiedRoots[conIdx] = chainHead.PreviousJustifiedBlockRoot
|
||||
finalizedRoots[conIdx] = chainHead.FinalizedBlockRoot
|
||||
chainHeads[conIdx] = chainHead
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if err := g.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lastErr = nil
|
||||
for i := range conns {
|
||||
if headEpochs[0] != headEpochs[i] {
|
||||
lastErr = fmt.Errorf(
|
||||
"received conflicting head epochs on node %d, expected %d, received %d",
|
||||
i,
|
||||
headEpochs[0],
|
||||
headEpochs[i],
|
||||
)
|
||||
break
|
||||
for i, conn := range conns {
|
||||
conIdx := i
|
||||
currConn := conn
|
||||
g.Go(func() error {
|
||||
beaconClient := eth.NewBeaconChainClient(currConn)
|
||||
chainHead, err := beaconClient.GetChainHead(context.Background(), &emptypb.Empty{})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "connection number=%d", conIdx)
|
||||
}
|
||||
if !bytes.Equal(headBlockRoots[0], headBlockRoots[i]) {
|
||||
lastErr = fmt.Errorf(
|
||||
"received conflicting head block roots on node %d, expected %#x, received %#x",
|
||||
i,
|
||||
headBlockRoots[0],
|
||||
headBlockRoots[i],
|
||||
)
|
||||
break
|
||||
}
|
||||
if !bytes.Equal(justifiedRoots[0], justifiedRoots[i]) {
|
||||
lastErr = fmt.Errorf(
|
||||
"received conflicting justified block roots on node %d, expected %#x, received %#x: %s and %s",
|
||||
i,
|
||||
justifiedRoots[0],
|
||||
justifiedRoots[i],
|
||||
chainHeads[0].String(),
|
||||
chainHeads[i].String(),
|
||||
)
|
||||
break
|
||||
}
|
||||
if !bytes.Equal(prevJustifiedRoots[0], prevJustifiedRoots[i]) {
|
||||
lastErr = fmt.Errorf(
|
||||
"received conflicting previous justified block roots on node %d, expected %#x, received %#x",
|
||||
i,
|
||||
prevJustifiedRoots[0],
|
||||
prevJustifiedRoots[i],
|
||||
)
|
||||
break
|
||||
}
|
||||
if !bytes.Equal(finalizedRoots[0], finalizedRoots[i]) {
|
||||
lastErr = fmt.Errorf(
|
||||
"received conflicting finalized epoch roots on node %d, expected %#x, received %#x",
|
||||
i,
|
||||
finalizedRoots[0],
|
||||
finalizedRoots[i],
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if lastErr == nil {
|
||||
headEpochs[conIdx] = chainHead.HeadEpoch
|
||||
headBlockRoots[conIdx] = chainHead.HeadBlockRoot
|
||||
justifiedRoots[conIdx] = chainHead.JustifiedBlockRoot
|
||||
prevJustifiedRoots[conIdx] = chainHead.PreviousJustifiedBlockRoot
|
||||
finalizedRoots[conIdx] = chainHead.FinalizedBlockRoot
|
||||
chainHeads[conIdx] = chainHead
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if err := g.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range conns {
|
||||
if headEpochs[0] != headEpochs[i] {
|
||||
return fmt.Errorf(
|
||||
"received conflicting head epochs on node %d, expected %d, received %d",
|
||||
i,
|
||||
headEpochs[0],
|
||||
headEpochs[i],
|
||||
)
|
||||
}
|
||||
if !bytes.Equal(headBlockRoots[0], headBlockRoots[i]) {
|
||||
return fmt.Errorf(
|
||||
"received conflicting head block roots on node %d, expected %#x, received %#x",
|
||||
i,
|
||||
headBlockRoots[0],
|
||||
headBlockRoots[i],
|
||||
)
|
||||
}
|
||||
if !bytes.Equal(justifiedRoots[0], justifiedRoots[i]) {
|
||||
return fmt.Errorf(
|
||||
"received conflicting justified block roots on node %d, expected %#x, received %#x: %s and %s",
|
||||
i,
|
||||
justifiedRoots[0],
|
||||
justifiedRoots[i],
|
||||
chainHeads[0].String(),
|
||||
chainHeads[i].String(),
|
||||
)
|
||||
}
|
||||
if !bytes.Equal(prevJustifiedRoots[0], prevJustifiedRoots[i]) {
|
||||
return fmt.Errorf(
|
||||
"received conflicting previous justified block roots on node %d, expected %#x, received %#x",
|
||||
i,
|
||||
prevJustifiedRoots[0],
|
||||
prevJustifiedRoots[i],
|
||||
)
|
||||
}
|
||||
if !bytes.Equal(finalizedRoots[0], finalizedRoots[i]) {
|
||||
return fmt.Errorf(
|
||||
"received conflicting finalized epoch roots on node %d, expected %#x, received %#x",
|
||||
i,
|
||||
finalizedRoots[0],
|
||||
finalizedRoots[i],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return lastErr
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/OffchainLabs/prysm/v7/api/server/structs"
|
||||
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/altair"
|
||||
@@ -124,25 +123,6 @@ func validatorsAreActive(ec *types.EvaluationContext, conns ...*grpc.ClientConn)
|
||||
|
||||
// validatorsParticipating ensures the validators have an acceptable participation rate.
|
||||
func validatorsParticipating(_ *types.EvaluationContext, conns ...*grpc.ClientConn) error {
|
||||
// Retry up to 3 times with 2 second delays to handle timing flakes where
|
||||
// attestations haven't been fully processed yet due to block propagation delays.
|
||||
const maxRetries = 3
|
||||
const retryDelay = 2 * time.Second
|
||||
var lastErr error
|
||||
|
||||
for attempt := range maxRetries {
|
||||
if attempt > 0 {
|
||||
time.Sleep(retryDelay)
|
||||
}
|
||||
lastErr = checkValidatorsParticipating(conns)
|
||||
if lastErr == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func checkValidatorsParticipating(conns []*grpc.ClientConn) error {
|
||||
conn := conns[0]
|
||||
client := ethpb.NewBeaconChainClient(conn)
|
||||
validatorRequest := ðpb.GetValidatorParticipationRequest{}
|
||||
@@ -254,25 +234,6 @@ func checkValidatorsParticipating(conns []*grpc.ClientConn) error {
|
||||
// validatorsSyncParticipation ensures the validators have an acceptable participation rate for
|
||||
// sync committee assignments.
|
||||
func validatorsSyncParticipation(_ *types.EvaluationContext, conns ...*grpc.ClientConn) error {
|
||||
// Retry up to 3 times with 2 second delays to handle timing flakes where
|
||||
// sync committee messages haven't fully propagated yet.
|
||||
const maxRetries = 3
|
||||
const retryDelay = 2 * time.Second
|
||||
var lastErr error
|
||||
|
||||
for attempt := range maxRetries {
|
||||
if attempt > 0 {
|
||||
time.Sleep(retryDelay)
|
||||
}
|
||||
lastErr = checkSyncParticipation(conns)
|
||||
if lastErr == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func checkSyncParticipation(conns []*grpc.ClientConn) error {
|
||||
conn := conns[0]
|
||||
client := ethpb.NewNodeClient(conn)
|
||||
altairClient := ethpb.NewBeaconChainClient(conn)
|
||||
|
||||
@@ -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 = ðpb.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 = ðpb.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 = ðpb.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 = ðpb.Eth1Data{
|
||||
DepositRoot: make([]byte, fieldparams.RootLength),
|
||||
BlockHash: make([]byte, fieldparams.RootLength),
|
||||
}
|
||||
}
|
||||
if b.SyncAggregate == nil {
|
||||
b.SyncAggregate = ðpb.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 = ðpb.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 = ðpb.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 = ðpb.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 = ðpb.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] = ðpb.PayloadAttestation{
|
||||
AggregationBits: aggregationBits,
|
||||
Signature: signature,
|
||||
Data: ðpb.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 ðpb.SignedExecutionPayloadBid{
|
||||
Message: ðpb.ExecutionPayloadBid{
|
||||
Slot: slot,
|
||||
BuilderIndex: 1,
|
||||
ParentBlockHash: parentBlockHash,
|
||||
ParentBlockRoot: parentBlockRoot,
|
||||
BlockHash: blockHash,
|
||||
GasLimit: 30000000,
|
||||
PrevRandao: prevRandao,
|
||||
FeeRecipient: feeRecipient,
|
||||
Value: 1000000,
|
||||
BlobKzgCommitmentsRoot: blobKzgRoot,
|
||||
},
|
||||
Signature: signature,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 := ðpbalpha.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 := ðpbalpha.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)
|
||||
}
|
||||
|
||||
@@ -88,3 +88,12 @@ func NewBeaconBlockContentsFulu() *ethpb.SignedBeaconBlockContentsFulu {
|
||||
func NewBlindedBeaconBlockFulu() *ethpb.SignedBlindedBeaconBlockFulu {
|
||||
return HydrateSignedBlindedBeaconBlockFulu(ðpb.SignedBlindedBeaconBlockFulu{})
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Gloas
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// NewBeaconBlockGloas creates a beacon block with minimum marshalable fields.
|
||||
func NewBeaconBlockGloas() *ethpb.SignedBeaconBlockGloas {
|
||||
return HydrateSignedBeaconBlockGloas(ðpb.SignedBeaconBlockGloas{})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user