Compare commits

...

15 Commits

Author SHA1 Message Date
terence
204302a821 Update hoodie boot nodes (#15240) 2025-05-01 21:49:46 +00:00
Potuz
8a22df902f Check for nil duties on checkDependentRoots (#15241) 2025-05-01 19:16:55 +00:00
Potuz
5e3a5b877a Remove slot from UpdateDuties (#15223)
* Remove slot from `UpdateDuties`

* Fix slot to epoch conversion

* Add gossip clock disparity

* do not use disparity

* check for nil duties

---------

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-04-29 18:25:09 +00:00
Bastin
b69c71d65a Add LC p2p validators and subscribers (#15214)
* add and pass lcstore to sync service

* validator for optimistic updates

* validator for finality updates

* subscribers

* gossip scorings

* tmp - add validation test

* optimistic update validation tests

* finality update validation tests

* tests for subscribers

* deps

* changelog entry

* play around with config cleanup

* better logs

* better logs 2

* better logs 3

* address comments

* add comments
2025-04-29 14:07:17 +00:00
Manu NALEPA
1298dc3a46 PeerDAS: Add needed proto files and corresponding generated code. (#15187)
* PeerDAS: Add needed proto files and corresponding generated code.

* Fix Nishant's comment.

* `max_cell_proofs_length.size`: Set to `CELLS_PER_EXT_BLOB * MAX_BLOB_COMMITMENTS_PER_BLOCK`.

* `BlobsBundleV2`: Add comment.
2025-04-28 16:08:28 +00:00
Potuz
3c463d8171 Pass dependent roots in block events (#15227)
* Pass dependent roots in block events

* Check for empty roots
2025-04-28 00:00:48 +00:00
kasey
0a48fafc71 extend payload attribute deadline to proposal slot (#15230)
* extend payload attribute deadline to proposal slot

* Update beacon-chain/blockchain/execution_engine.go

Co-authored-by: Potuz <potuz@prysmaticlabs.com>

* Terence's feedback

* skip past proposal slots

* lint and skip events during init sync

* finagle test to not trigger old event error

* fix blockchain tests that panic without SyncChecker

---------

Co-authored-by: Kasey <kasey@users.noreply.github.com>
Co-authored-by: Potuz <potuz@prysmaticlabs.com>
2025-04-27 23:59:37 +00:00
terence
28cd59c9b7 Fix payload attribute proposer calculation (#15228)
Process slots if epoch is greater than head state epoch
2025-04-27 17:52:09 +00:00
james-prysm
efaf6649e7 Update grpc deprecation message (#15222)
* comment updates and changelog

* some missed comments
2025-04-25 19:50:34 +00:00
Potuz
a1c1edf285 Fix deadlines (#15221)
* Fix deadlines

* use current slot in update duties

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
2025-04-25 19:10:20 +00:00
Radosław Kapka
bde7a57ec9 Implement pending consolidations Beacon API endpoint (#15219)
* get block

* Implement pending consolidations API endpoint

* changelog

* fixing test

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
Co-authored-by: james-prysm <james@prysmaticlabs.com>
2025-04-25 18:27:58 +00:00
kasey
c223957751 include block in attr event and use stategen (#15213)
* include block in attr event and use stategen

* use no-copy state cache for proposal in same epoch

* only advance to the start of epoch

---------

Co-authored-by: Kasey <kasey@users.noreply.github.com>
2025-04-25 15:11:38 +00:00
Preston Van Loon
f7eddedd1d update geth v1.15.9 (#15216)
* Update go-ethereum to v1.15.9

* Fix go-ethereum secp256k1 build after https://github.com/ethereum/go-ethereum/pull/31242

* Fix Ping API change

* Changelog fragment
2025-04-25 12:40:19 +00:00
kira
7887ebbc4a Broadcast Proposer Slashing on equivocation (#14693)
* Add equivocation detection logic; broadcast slashing immediately on equivocation

* nit: comments

* move equivocation detection to validateBeaconBlockPubSub

* include broadcasting logic within the helper function

* fix lint

* Add unit tests for equivocation detection

* remove comment that are not required

* Add changelog file

* Add descriptive comment for detectAndBroadcastEquivocation

* use head block instead of block cache for equivocation detection

* add more equivocation unit tests; update a mock to include HeadState error

* update the order of the checks

* move slashing before state fetch; update Tests

* update changelog

* use verifyProposerSlashing to verify and reject block; remove verifySlashableBlock; update tests

* Update changelog

* nit: cleaner error check

* nit: clean up

* revert code logic; update string check; add a unit test

* improve errors; merge tests

* Update a unit test

* fix lint

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-04-24 20:27:34 +00:00
Nishant Das
1b13520270 Fix Unmarshalling of BlobSidecarsByRoot Requests (#15209)
* Handle Electra Lists

* Changelog
2025-04-23 14:04:46 +00:00
116 changed files with 3187 additions and 699 deletions

View File

@@ -263,6 +263,13 @@ type ChainHead struct {
OptimisticStatus bool `json:"optimistic_status"`
}
type GetPendingConsolidationsResponse struct {
Version string `json:"version"`
ExecutionOptimistic bool `json:"execution_optimistic"`
Finalized bool `json:"finalized"`
Data []*PendingConsolidation `json:"data"`
}
type GetPendingDepositsResponse struct {
Version string `json:"version"`
ExecutionOptimistic bool `json:"execution_optimistic"`

View File

@@ -184,13 +184,17 @@ func (s *Service) notifyForkchoiceUpdate(ctx context.Context, arg *fcuConfig) (*
return payloadID, nil
}
func firePayloadAttributesEvent(_ context.Context, f event.SubscriberSender, nextSlot primitives.Slot) {
func (s *Service) firePayloadAttributesEvent(f event.SubscriberSender, block interfaces.ReadOnlySignedBeaconBlock, root [32]byte, nextSlot primitives.Slot) {
// If we're syncing a block in the past and init-sync is still running, we shouldn't fire this event.
if !s.cfg.SyncChecker.Synced() {
return
}
// the fcu args have differing amounts of completeness based on the code path,
// and there is work we only want to do if a client is actually listening to the events beacon api endpoint.
// temporary solution: just fire a blank event and fill in the details in the api handler.
f.Send(&feed.Event{
Type: statefeed.PayloadAttributes,
Data: payloadattribute.EventData{ProposalSlot: nextSlot},
Data: payloadattribute.EventData{HeadBlock: block, HeadRoot: root, ProposalSlot: nextSlot},
})
}

View File

@@ -102,7 +102,7 @@ func (s *Service) forkchoiceUpdateWithExecution(ctx context.Context, args *fcuCo
log.WithError(err).Error("could not save head")
}
go firePayloadAttributesEvent(ctx, s.cfg.StateNotifier.StateFeed(), s.CurrentSlot()+1)
go s.firePayloadAttributesEvent(s.cfg.StateNotifier.StateFeed(), args.headBlock, args.headRoot, s.CurrentSlot()+1)
// Only need to prune attestations from pool if the head has changed.
s.pruneAttsFromPool(s.ctx, args.headState, args.headBlock)

View File

@@ -20,6 +20,7 @@ func testServiceOptsWithDB(t *testing.T) []Option {
WithForkChoiceStore(fcs),
WithClockSynchronizer(cs),
WithStateNotifier(&mock.MockStateNotifier{RecordEvents: true}),
WithSyncChecker(&mock.MockSyncChecker{}),
}
}

View File

@@ -729,9 +729,13 @@ func (s *Service) lateBlockTasks(ctx context.Context) {
attribute := s.getPayloadAttribute(ctx, headState, s.CurrentSlot()+1, headRoot[:])
// return early if we are not proposing next slot
if attribute.IsEmpty() {
headBlock, err := s.headBlock()
if err != nil {
log.WithError(err).WithField("head_root", headRoot).Error("unable to retrieve head block to fire payload attributes event")
}
// notifyForkchoiceUpdate fires the payload attribute event. But in this case, we won't
// call notifyForkchoiceUpdate, so the event is fired here.
go firePayloadAttributesEvent(ctx, s.cfg.StateNotifier.StateFeed(), s.CurrentSlot()+1)
go s.firePayloadAttributesEvent(s.cfg.StateNotifier.StateFeed(), headBlock, headRoot, s.CurrentSlot()+1)
return
}

View File

@@ -103,15 +103,29 @@ func (s *Service) sendStateFeedOnBlock(cfg *postBlockProcessConfig) {
log.WithError(err).Debug("Could not check if block is optimistic")
optimistic = true
}
currEpoch := slots.ToEpoch(s.CurrentSlot())
currDependenRoot, err := s.cfg.ForkChoiceStore.DependentRoot(currEpoch)
if err != nil {
log.WithError(err).Debug("Could not get dependent root")
}
prevDependentRoot := [32]byte{}
if currEpoch > 0 {
prevDependentRoot, err = s.cfg.ForkChoiceStore.DependentRoot(currEpoch - 1)
if err != nil {
log.WithError(err).Debug("Could not get previous dependent root")
}
}
// Send notification of the processed block to the state feed.
s.cfg.StateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.BlockProcessed,
Data: &statefeed.BlockProcessedData{
Slot: cfg.roblock.Block().Slot(),
BlockRoot: cfg.roblock.Root(),
SignedBlock: cfg.roblock,
Verified: true,
Optimistic: optimistic,
Slot: cfg.roblock.Block().Slot(),
BlockRoot: cfg.roblock.Root(),
SignedBlock: cfg.roblock,
CurrDependentRoot: currDependenRoot,
PrevDependentRoot: prevDependentRoot,
Verified: true,
Optimistic: optimistic,
},
})
}

View File

@@ -53,6 +53,7 @@ type ChainService struct {
InitSyncBlockRoots map[[32]byte]bool
DB db.Database
State state.BeaconState
HeadStateErr error
Block interfaces.ReadOnlySignedBeaconBlock
VerifyBlkDescendantErr error
stateNotifier statefeed.Notifier
@@ -364,6 +365,9 @@ func (s *ChainService) HeadState(context.Context) (state.BeaconState, error) {
// HeadStateReadOnly mocks HeadStateReadOnly method in chain service.
func (s *ChainService) HeadStateReadOnly(context.Context) (state.ReadOnlyBeaconState, error) {
if s.HeadStateErr != nil {
return nil, s.HeadStateErr
}
return s.State, nil
}
@@ -715,3 +719,14 @@ func (c *ChainService) ReceiveBlob(_ context.Context, b blocks.VerifiedROBlob) e
func (c *ChainService) TargetRootForEpoch(_ [32]byte, _ primitives.Epoch) ([32]byte, error) {
return c.TargetRoot, nil
}
// MockSyncChecker is a mock implementation of blockchain.Checker.
// We can't make an assertion here that this is true because that would create a circular dependency.
type MockSyncChecker struct {
synced bool
}
// Synced satisfies the blockchain.Checker interface.
func (m *MockSyncChecker) Synced() bool {
return m.synced
}

View File

@@ -16,6 +16,9 @@ import (
"google.golang.org/protobuf/proto"
)
// ErrCouldNotVerifyBlockHeader is returned when a block header's signature cannot be verified.
var ErrCouldNotVerifyBlockHeader = errors.New("could not verify beacon block header")
type slashValidatorFunc func(
ctx context.Context,
st state.BeaconState,
@@ -114,7 +117,7 @@ func VerifyProposerSlashing(
for _, header := range headers {
if err := signing.ComputeDomainVerifySigningRoot(beaconState, pIdx, slots.ToEpoch(hSlot),
header.Header, params.BeaconConfig().DomainBeaconProposer, header.Signature); err != nil {
return errors.Wrap(err, "could not verify beacon block header")
return errors.Wrap(ErrCouldNotVerifyBlockHeader, err.Error())
}
}
return nil

View File

@@ -11,6 +11,8 @@ const (
// ReceivedBlockData is the data sent with ReceivedBlock events.
type ReceivedBlockData struct {
SignedBlock interfaces.ReadOnlySignedBeaconBlock
IsOptimistic bool
SignedBlock interfaces.ReadOnlySignedBeaconBlock
CurrDependentRoot [32]byte
PrevDependentRoot [32]byte
IsOptimistic bool
}

View File

@@ -43,6 +43,10 @@ type BlockProcessedData struct {
BlockRoot [32]byte
// SignedBlock is the physical processed block.
SignedBlock interfaces.ReadOnlySignedBeaconBlock
// CurrDependentRoot is the current dependent root
CurrDependentRoot [32]byte
// PrevDependentRoot is the previous dependent root
PrevDependentRoot [32]byte
// Verified is true if the block's BLS contents have been verified.
Verified bool
// Optimistic is true if the block is optimistic.

View File

@@ -865,6 +865,7 @@ func (b *BeaconNode) registerSyncService(initialSyncComplete chan struct{}, bFil
regularsync.WithVerifierWaiter(b.verifyInitWaiter),
regularsync.WithAvailableBlocker(bFillStore),
regularsync.WithSlasherEnabled(b.slasherEnabled),
regularsync.WithLightClientStore(b.lcStore),
)
return b.services.RegisterService(rs)
}

View File

@@ -105,7 +105,8 @@ func (l *listenerWrapper) RandomNodes() enode.Iterator {
func (l *listenerWrapper) Ping(node *enode.Node) error {
l.mu.RLock()
defer l.mu.RUnlock()
return l.listener.Ping(node)
_, err := l.listener.Ping(node)
return err
}
func (l *listenerWrapper) RequestENR(node *enode.Node) (*enode.Node, error) {

View File

@@ -44,6 +44,12 @@ const (
// blsToExecutionChangeWeight specifies the scoring weight that we apply to
// our bls to execution topic.
blsToExecutionChangeWeight = 0.05
// lightClientOptimisticUpdateWeight specifies the scoring weight that we apply to
// our light client optimistic update topic.
lightClientOptimisticUpdateWeight = 0.05
// lightClientFinalityUpdateWeight specifies the scoring weight that we apply to
// our light client finality update topic.
lightClientFinalityUpdateWeight = 0.05
// maxInMeshScore describes the max score a peer can attain from being in the mesh.
maxInMeshScore = 10
@@ -124,6 +130,10 @@ func (s *Service) topicScoreParams(topic string) (*pubsub.TopicScoreParams, erro
case strings.Contains(topic, GossipBlobSidecarMessage):
// TODO(Deneb): Using the default block scoring. But this should be updated.
return defaultBlockTopicParams(), nil
case strings.Contains(topic, GossipLightClientOptimisticUpdateMessage):
return defaultLightClientOptimisticUpdateTopicParams(), nil
case strings.Contains(topic, GossipLightClientFinalityUpdateMessage):
return defaultLightClientFinalityUpdateTopicParams(), nil
default:
return nil, errors.Errorf("unrecognized topic provided for parameter registration: %s", topic)
}
@@ -503,6 +513,50 @@ func defaultBlsToExecutionChangeTopicParams() *pubsub.TopicScoreParams {
}
}
func defaultLightClientOptimisticUpdateTopicParams() *pubsub.TopicScoreParams {
return &pubsub.TopicScoreParams{
TopicWeight: lightClientOptimisticUpdateWeight,
TimeInMeshWeight: maxInMeshScore / inMeshCap(),
TimeInMeshQuantum: inMeshTime(),
TimeInMeshCap: inMeshCap(),
FirstMessageDeliveriesWeight: 2,
FirstMessageDeliveriesDecay: scoreDecay(oneHundredEpochs),
FirstMessageDeliveriesCap: 5,
MeshMessageDeliveriesWeight: 0,
MeshMessageDeliveriesDecay: 0,
MeshMessageDeliveriesCap: 0,
MeshMessageDeliveriesThreshold: 0,
MeshMessageDeliveriesWindow: 0,
MeshMessageDeliveriesActivation: 0,
MeshFailurePenaltyWeight: 0,
MeshFailurePenaltyDecay: 0,
InvalidMessageDeliveriesWeight: -2000,
InvalidMessageDeliveriesDecay: scoreDecay(invalidDecayPeriod),
}
}
func defaultLightClientFinalityUpdateTopicParams() *pubsub.TopicScoreParams {
return &pubsub.TopicScoreParams{
TopicWeight: lightClientFinalityUpdateWeight,
TimeInMeshWeight: maxInMeshScore / inMeshCap(),
TimeInMeshQuantum: inMeshTime(),
TimeInMeshCap: inMeshCap(),
FirstMessageDeliveriesWeight: 2,
FirstMessageDeliveriesDecay: scoreDecay(oneHundredEpochs),
FirstMessageDeliveriesCap: 5,
MeshMessageDeliveriesWeight: 0,
MeshMessageDeliveriesDecay: 0,
MeshMessageDeliveriesCap: 0,
MeshMessageDeliveriesThreshold: 0,
MeshMessageDeliveriesWindow: 0,
MeshMessageDeliveriesActivation: 0,
MeshFailurePenaltyWeight: 0,
MeshFailurePenaltyDecay: 0,
InvalidMessageDeliveriesWeight: -2000,
InvalidMessageDeliveriesDecay: scoreDecay(invalidDecayPeriod),
}
}
func oneSlotDuration() time.Duration {
return time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second
}

View File

@@ -75,4 +75,6 @@ func TestLoggingParameters(_ *testing.T) {
logGossipParameters("testing", defaultAttesterSlashingTopicParams())
logGossipParameters("testing", defaultProposerSlashingTopicParams())
logGossipParameters("testing", defaultVoluntaryExitTopicParams())
logGossipParameters("testing", defaultLightClientOptimisticUpdateTopicParams())
logGossipParameters("testing", defaultLightClientFinalityUpdateTopicParams())
}

View File

@@ -73,6 +73,12 @@ func TestGossipTopicMappings_CorrectType(t *testing.T) {
pMessage = GossipTopicMappings(AggregateAndProofSubnetTopicFormat, altairForkEpoch)
_, ok = pMessage.(*ethpb.SignedAggregateAttestationAndProof)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientOptimisticUpdateTopicFormat, altairForkEpoch)
_, ok = pMessage.(*ethpb.LightClientOptimisticUpdateAltair)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientFinalityUpdateTopicFormat, altairForkEpoch)
_, ok = pMessage.(*ethpb.LightClientFinalityUpdateAltair)
assert.Equal(t, true, ok)
// Bellatrix Fork
pMessage = GossipTopicMappings(BlockSubnetTopicFormat, bellatrixForkEpoch)
@@ -87,6 +93,12 @@ func TestGossipTopicMappings_CorrectType(t *testing.T) {
pMessage = GossipTopicMappings(AggregateAndProofSubnetTopicFormat, bellatrixForkEpoch)
_, ok = pMessage.(*ethpb.SignedAggregateAttestationAndProof)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientOptimisticUpdateTopicFormat, bellatrixForkEpoch)
_, ok = pMessage.(*ethpb.LightClientOptimisticUpdateAltair)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientFinalityUpdateTopicFormat, bellatrixForkEpoch)
_, ok = pMessage.(*ethpb.LightClientFinalityUpdateAltair)
assert.Equal(t, true, ok)
// Capella Fork
pMessage = GossipTopicMappings(BlockSubnetTopicFormat, capellaForkEpoch)
@@ -101,6 +113,12 @@ func TestGossipTopicMappings_CorrectType(t *testing.T) {
pMessage = GossipTopicMappings(AggregateAndProofSubnetTopicFormat, capellaForkEpoch)
_, ok = pMessage.(*ethpb.SignedAggregateAttestationAndProof)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientOptimisticUpdateTopicFormat, capellaForkEpoch)
_, ok = pMessage.(*ethpb.LightClientOptimisticUpdateCapella)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientFinalityUpdateTopicFormat, capellaForkEpoch)
_, ok = pMessage.(*ethpb.LightClientFinalityUpdateCapella)
assert.Equal(t, true, ok)
// Deneb Fork
pMessage = GossipTopicMappings(BlockSubnetTopicFormat, denebForkEpoch)
@@ -115,6 +133,12 @@ func TestGossipTopicMappings_CorrectType(t *testing.T) {
pMessage = GossipTopicMappings(AggregateAndProofSubnetTopicFormat, denebForkEpoch)
_, ok = pMessage.(*ethpb.SignedAggregateAttestationAndProof)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientOptimisticUpdateTopicFormat, denebForkEpoch)
_, ok = pMessage.(*ethpb.LightClientOptimisticUpdateDeneb)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientFinalityUpdateTopicFormat, denebForkEpoch)
_, ok = pMessage.(*ethpb.LightClientFinalityUpdateDeneb)
assert.Equal(t, true, ok)
// Electra Fork
pMessage = GossipTopicMappings(BlockSubnetTopicFormat, electraForkEpoch)
@@ -129,4 +153,10 @@ func TestGossipTopicMappings_CorrectType(t *testing.T) {
pMessage = GossipTopicMappings(AggregateAndProofSubnetTopicFormat, electraForkEpoch)
_, ok = pMessage.(*ethpb.SignedAggregateAttestationAndProofElectra)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientOptimisticUpdateTopicFormat, electraForkEpoch)
_, ok = pMessage.(*ethpb.LightClientOptimisticUpdateDeneb)
assert.Equal(t, true, ok)
pMessage = GossipTopicMappings(LightClientFinalityUpdateTopicFormat, electraForkEpoch)
_, ok = pMessage.(*ethpb.LightClientFinalityUpdateElectra)
assert.Equal(t, true, ok)
}

View File

@@ -21,6 +21,7 @@ go_library(
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/light-client:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/wrapper:go_default_library",
"//encoding/bytesutil:go_default_library",

View File

@@ -4,6 +4,7 @@ import (
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v6/consensus-types/interfaces"
lightclientConsensusTypes "github.com/OffchainLabs/prysm/v6/consensus-types/light-client"
"github.com/OffchainLabs/prysm/v6/consensus-types/wrapper"
"github.com/OffchainLabs/prysm/v6/encoding/bytesutil"
enginev1 "github.com/OffchainLabs/prysm/v6/proto/engine/v1"
@@ -36,6 +37,12 @@ var (
// AttesterSlashingMap maps the fork-version to the underlying data type for that particular
// fork period.
AttesterSlashingMap map[[4]byte]func() (ethpb.AttSlashing, error)
// LightClientOptimisticUpdateMap maps the fork-version to the underlying data type for that
// particular fork period.
LightClientOptimisticUpdateMap map[[4]byte]func() (interfaces.LightClientOptimisticUpdate, error)
// LightClientFinalityUpdateMap maps the fork-version to the underlying data type for that
// particular fork period.
LightClientFinalityUpdateMap map[[4]byte]func() (interfaces.LightClientFinalityUpdate, error)
)
// InitializeDataMaps initializes all the relevant object maps. This function is called to
@@ -179,4 +186,42 @@ func InitializeDataMaps() {
return &ethpb.AttesterSlashingElectra{}, nil
},
}
// Reset our light client optimistic update map.
LightClientOptimisticUpdateMap = map[[4]byte]func() (interfaces.LightClientOptimisticUpdate, error){
bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion): func() (interfaces.LightClientOptimisticUpdate, error) {
return lightclientConsensusTypes.NewEmptyOptimisticUpdateAltair(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().BellatrixForkVersion): func() (interfaces.LightClientOptimisticUpdate, error) {
return lightclientConsensusTypes.NewEmptyOptimisticUpdateAltair(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().CapellaForkVersion): func() (interfaces.LightClientOptimisticUpdate, error) {
return lightclientConsensusTypes.NewEmptyOptimisticUpdateCapella(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().DenebForkVersion): func() (interfaces.LightClientOptimisticUpdate, error) {
return lightclientConsensusTypes.NewEmptyOptimisticUpdateDeneb(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().ElectraForkVersion): func() (interfaces.LightClientOptimisticUpdate, error) {
return lightclientConsensusTypes.NewEmptyOptimisticUpdateDeneb(), nil
},
}
// Reset our light client finality update map.
LightClientFinalityUpdateMap = map[[4]byte]func() (interfaces.LightClientFinalityUpdate, error){
bytesutil.ToBytes4(params.BeaconConfig().AltairForkVersion): func() (interfaces.LightClientFinalityUpdate, error) {
return lightclientConsensusTypes.NewEmptyFinalityUpdateAltair(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().BellatrixForkVersion): func() (interfaces.LightClientFinalityUpdate, error) {
return lightclientConsensusTypes.NewEmptyFinalityUpdateAltair(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().CapellaForkVersion): func() (interfaces.LightClientFinalityUpdate, error) {
return lightclientConsensusTypes.NewEmptyFinalityUpdateCapella(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().DenebForkVersion): func() (interfaces.LightClientFinalityUpdate, error) {
return lightclientConsensusTypes.NewEmptyFinalityUpdateDeneb(), nil
},
bytesutil.ToBytes4(params.BeaconConfig().ElectraForkVersion): func() (interfaces.LightClientFinalityUpdate, error) {
return lightclientConsensusTypes.NewEmptyFinalityUpdateElectra(), nil
},
}
}

View File

@@ -162,9 +162,9 @@ func (b *BlobSidecarsByRootReq) MarshalSSZ() ([]byte, error) {
// BlobSidecarsByRootReq value.
func (b *BlobSidecarsByRootReq) UnmarshalSSZ(buf []byte) error {
bufLen := len(buf)
maxLength := int(params.BeaconConfig().MaxRequestBlobSidecars) * blobIdSize
maxLength := int(params.BeaconConfig().MaxRequestBlobSidecarsElectra) * blobIdSize
if bufLen > maxLength {
return errors.Errorf("expected buffer with length of up to %d but received length %d", maxLength, bufLen)
return errors.Wrapf(ssz.ErrIncorrectListSize, "expected buffer with length of up to %d but received length %d", maxLength, bufLen)
}
if bufLen%blobIdSize != 0 {
return errors.Wrapf(ssz.ErrIncorrectByteSize, "size=%d", bufLen)

View File

@@ -43,6 +43,15 @@ func TestBlobSidecarsByRootReq_MarshalSSZ(t *testing.T) {
name: "10 item list",
ids: generateBlobIdentifiers(10),
},
{
name: "max list",
ids: generateBlobIdentifiers(int(params.BeaconConfig().MaxRequestBlobSidecarsElectra)),
},
{
name: "beyond max list",
ids: generateBlobIdentifiers(int(params.BeaconConfig().MaxRequestBlobSidecarsElectra) + 1),
unmarshalErr: ssz.ErrIncorrectListSize,
},
{
name: "wonky unmarshal size",
ids: generateBlobIdentifiers(10),

View File

@@ -894,6 +894,15 @@ func (s *Service) beaconEndpoints(
handler: server.GetPendingDeposits,
methods: []string{http.MethodGet},
},
{
template: "/eth/v1/beacon/states/{state_id}/pending_consolidations",
name: namespace + ".GetPendingConsolidations",
middleware: []middleware.Middleware{
middleware.AcceptHeaderHandler([]string{api.JsonMediaType}),
},
handler: server.GetPendingDeposits,
methods: []string{http.MethodGet},
},
{
template: "/eth/v1/beacon/states/{state_id}/pending_partial_withdrawals",
name: namespace + ".GetPendingPartialWithdrawals",
@@ -1041,6 +1050,7 @@ func (s *Service) eventsEndpoints() []endpoint {
HeadFetcher: s.cfg.HeadFetcher,
ChainInfoFetcher: s.cfg.ChainInfoFetcher,
TrackedValidatorsCache: s.cfg.TrackedValidatorsCache,
StateGen: s.cfg.StateGen,
}
const namespace = "events"

View File

@@ -30,6 +30,7 @@ func Test_endpoints(t *testing.T) {
"/eth/v1/beacon/states/{state_id}/randao": {http.MethodGet},
"/eth/v1/beacon/states/{state_id}/pending_deposits": {http.MethodGet},
"/eth/v1/beacon/states/{state_id}/pending_partial_withdrawals": {http.MethodGet},
"/eth/v1/beacon/states/{state_id}/pending_consolidations": {http.MethodGet},
"/eth/v1/beacon/headers": {http.MethodGet},
"/eth/v1/beacon/headers/{block_id}": {http.MethodGet},
"/eth/v1/beacon/blinded_blocks": {http.MethodPost},

View File

@@ -1613,6 +1613,62 @@ func (s *Server) broadcastSeenBlockSidecars(
return nil
}
// GetPendingConsolidations returns pending deposits for state with given 'stateId'.
// Should return 400 if the state retrieved is prior to Electra.
// Supports both JSON and SSZ responses based on Accept header.
func (s *Server) GetPendingConsolidations(w http.ResponseWriter, r *http.Request) {
ctx, span := trace.StartSpan(r.Context(), "beacon.GetPendingDeposits")
defer span.End()
stateId := r.PathValue("state_id")
if stateId == "" {
httputil.HandleError(w, "state_id is required in URL params", http.StatusBadRequest)
return
}
st, err := s.Stater.State(ctx, []byte(stateId))
if err != nil {
shared.WriteStateFetchError(w, err)
return
}
if st.Version() < version.Electra {
httputil.HandleError(w, "state_id is prior to electra", http.StatusBadRequest)
return
}
pd, err := st.PendingConsolidations()
if err != nil {
httputil.HandleError(w, "Could not get pending consolidations: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set(api.VersionHeader, version.String(st.Version()))
if httputil.RespondWithSsz(r) {
sszData, err := serializeItems(pd)
if err != nil {
httputil.HandleError(w, "Failed to serialize pending consolidations: "+err.Error(), http.StatusInternalServerError)
return
}
httputil.WriteSsz(w, sszData)
} else {
isOptimistic, err := helpers.IsOptimistic(ctx, []byte(stateId), s.OptimisticModeFetcher, s.Stater, s.ChainInfoFetcher, s.BeaconDB)
if err != nil {
httputil.HandleError(w, "Could not check optimistic status: "+err.Error(), http.StatusInternalServerError)
return
}
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
if err != nil {
httputil.HandleError(w, "Could not calculate root of latest block header: "+err.Error(), http.StatusInternalServerError)
return
}
isFinalized := s.FinalizationFetcher.IsFinalized(ctx, blockRoot)
resp := structs.GetPendingConsolidationsResponse{
Version: version.String(st.Version()),
ExecutionOptimistic: isOptimistic,
Finalized: isFinalized,
Data: structs.PendingConsolidationsFromConsensus(pd),
}
httputil.WriteJson(w, resp)
}
}
// GetPendingDeposits returns pending deposits for state with given 'stateId'.
// Should return 400 if the state retrieved is prior to Electra.
// Supports both JSON and SSZ responses based on Accept header.

View File

@@ -4755,6 +4755,191 @@ func Test_validateBlobSidecars(t *testing.T) {
require.ErrorContains(t, "could not verify blob proof: can't verify opening proof", s.validateBlobSidecars(b, [][]byte{blob[:]}, [][]byte{proof[:]}))
}
func TestGetPendingConsolidations(t *testing.T) {
st, _ := util.DeterministicGenesisStateElectra(t, 10)
cs := make([]*eth.PendingConsolidation, 10)
for i := 0; i < len(cs); i += 1 {
cs[i] = &eth.PendingConsolidation{
SourceIndex: primitives.ValidatorIndex(i),
TargetIndex: primitives.ValidatorIndex(i + 1),
}
}
require.NoError(t, st.SetPendingConsolidations(cs))
chainService := &chainMock.ChainService{
Optimistic: false,
FinalizedRoots: map[[32]byte]bool{},
}
server := &Server{
Stater: &testutil.MockStater{
BeaconState: st,
},
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
t.Run("json response", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
req.SetPathValue("state_id", "head")
rec := httptest.NewRecorder()
rec.Body = new(bytes.Buffer)
server.GetPendingConsolidations(rec, req)
require.Equal(t, http.StatusOK, rec.Code)
require.Equal(t, "electra", rec.Header().Get(api.VersionHeader))
var resp structs.GetPendingConsolidationsResponse
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
expectedVersion := version.String(st.Version())
require.Equal(t, expectedVersion, resp.Version)
require.Equal(t, false, resp.ExecutionOptimistic)
require.Equal(t, false, resp.Finalized)
expectedConsolidations := structs.PendingConsolidationsFromConsensus(cs)
require.DeepEqual(t, expectedConsolidations, resp.Data)
})
t.Run("ssz response", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
req.Header.Set("Accept", "application/octet-stream")
req.SetPathValue("state_id", "head")
rec := httptest.NewRecorder()
rec.Body = new(bytes.Buffer)
server.GetPendingConsolidations(rec, req)
require.Equal(t, http.StatusOK, rec.Code)
require.Equal(t, "electra", rec.Header().Get(api.VersionHeader))
responseBytes := rec.Body.Bytes()
var recoveredConsolidations []*eth.PendingConsolidation
// Verify total size matches expected number of deposits
consolidationSize := (&eth.PendingConsolidation{}).SizeSSZ()
require.Equal(t, len(responseBytes), consolidationSize*len(cs))
for i := 0; i < len(cs); i++ {
start := i * consolidationSize
end := start + consolidationSize
var c eth.PendingConsolidation
require.NoError(t, c.UnmarshalSSZ(responseBytes[start:end]))
recoveredConsolidations = append(recoveredConsolidations, &c)
}
require.DeepEqual(t, cs, recoveredConsolidations)
})
t.Run("pre electra state", func(t *testing.T) {
preElectraSt, _ := util.DeterministicGenesisStateDeneb(t, 1)
preElectraServer := &Server{
Stater: &testutil.MockStater{
BeaconState: preElectraSt,
},
OptimisticModeFetcher: chainService,
FinalizationFetcher: chainService,
}
// Test JSON request
req := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
req.SetPathValue("state_id", "head")
rec := httptest.NewRecorder()
rec.Body = new(bytes.Buffer)
preElectraServer.GetPendingConsolidations(rec, req)
require.Equal(t, http.StatusBadRequest, rec.Code)
var errResp struct {
Code int `json:"code"`
Message string `json:"message"`
}
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &errResp))
require.Equal(t, "state_id is prior to electra", errResp.Message)
// Test SSZ request
sszReq := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
sszReq.Header.Set("Accept", "application/octet-stream")
sszReq.SetPathValue("state_id", "head")
sszRec := httptest.NewRecorder()
sszRec.Body = new(bytes.Buffer)
preElectraServer.GetPendingConsolidations(sszRec, sszReq)
require.Equal(t, http.StatusBadRequest, sszRec.Code)
var sszErrResp struct {
Code int `json:"code"`
Message string `json:"message"`
}
require.NoError(t, json.Unmarshal(sszRec.Body.Bytes(), &sszErrResp))
require.Equal(t, "state_id is prior to electra", sszErrResp.Message)
})
t.Run("missing state_id parameter", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
// Intentionally not setting state_id
rec := httptest.NewRecorder()
rec.Body = new(bytes.Buffer)
server.GetPendingConsolidations(rec, req)
require.Equal(t, http.StatusBadRequest, rec.Code)
var errResp struct {
Code int `json:"code"`
Message string `json:"message"`
}
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &errResp))
require.Equal(t, "state_id is required in URL params", errResp.Message)
})
t.Run("optimistic node", func(t *testing.T) {
optimisticChainService := &chainMock.ChainService{
Optimistic: true,
FinalizedRoots: map[[32]byte]bool{},
}
optimisticServer := &Server{
Stater: server.Stater,
OptimisticModeFetcher: optimisticChainService,
FinalizationFetcher: optimisticChainService,
}
req := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
req.SetPathValue("state_id", "head")
rec := httptest.NewRecorder()
rec.Body = new(bytes.Buffer)
optimisticServer.GetPendingConsolidations(rec, req)
require.Equal(t, http.StatusOK, rec.Code)
var resp structs.GetPendingConsolidationsResponse
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
require.Equal(t, true, resp.ExecutionOptimistic)
})
t.Run("finalized node", func(t *testing.T) {
blockRoot, err := st.LatestBlockHeader().HashTreeRoot()
require.NoError(t, err)
finalizedChainService := &chainMock.ChainService{
Optimistic: false,
FinalizedRoots: map[[32]byte]bool{blockRoot: true},
}
finalizedServer := &Server{
Stater: server.Stater,
OptimisticModeFetcher: finalizedChainService,
FinalizationFetcher: finalizedChainService,
}
req := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v1/beacon/states/{state_id}/pending_consolidations", nil)
req.SetPathValue("state_id", "head")
rec := httptest.NewRecorder()
rec.Body = new(bytes.Buffer)
finalizedServer.GetPendingConsolidations(rec, req)
require.Equal(t, http.StatusOK, rec.Code)
var resp structs.GetPendingConsolidationsResponse
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
require.Equal(t, true, resp.Finalized)
})
}
func TestGetPendingDeposits(t *testing.T) {
st, _ := util.DeterministicGenesisStateElectra(t, 10)

View File

@@ -20,6 +20,7 @@ go_library(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//config/params:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/payload-attribute:go_default_library",
@@ -53,6 +54,7 @@ go_test(
"//beacon-chain/core/feed/operation:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/stategen/mock:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",

View File

@@ -37,7 +37,6 @@ import (
)
const DefaultEventFeedDepth = 1000
const payloadAttributeTimeout = 2 * time.Second
const (
InvalidTopic = "__invalid__"
@@ -627,6 +626,7 @@ func (s *Server) lazyReaderForEvent(ctx context.Context, event *feed.Event, topi
}
var errUnsupportedPayloadAttribute = errors.New("cannot compute payload attributes pre-Bellatrix")
var errPayloadAttributeExpired = errors.New("skipping payload attribute event for past slot")
func (s *Server) computePayloadAttributes(ctx context.Context, st state.ReadOnlyBeaconState, root [32]byte, proposer primitives.ValidatorIndex, timestamp uint64, randao []byte) (payloadattribute.Attributer, error) {
v := st.Version()
@@ -681,48 +681,48 @@ var zeroRoot [32]byte
// needsFill allows tests to provide filled EventData values. An ordinary event data value fired by the blockchain package will have
// all of the checked fields empty, so the logical short circuit should hit immediately.
func needsFill(ev payloadattribute.EventData) bool {
return ev.HeadState == nil || ev.HeadState.IsNil() || ev.HeadState.LatestBlockHeader() == nil ||
ev.HeadBlock == nil || ev.HeadBlock.IsNil() ||
ev.HeadRoot == zeroRoot || len(ev.ParentBlockRoot) == 0 || len(ev.ParentBlockHash) == 0 ||
return len(ev.ParentBlockHash) == 0 ||
ev.Attributer == nil || ev.Attributer.IsEmpty()
}
func (s *Server) fillEventData(ctx context.Context, ev payloadattribute.EventData) (payloadattribute.EventData, error) {
var err error
if !needsFill(ev) {
return ev, nil
}
ev.HeadState, err = s.HeadFetcher.HeadState(ctx)
if err != nil {
return ev, errors.Wrap(err, "could not get head state")
if ev.HeadBlock == nil || ev.HeadBlock.IsNil() {
return ev, errors.New("head block is nil")
}
if ev.HeadRoot == zeroRoot {
return ev, errors.New("head root is empty")
}
ev.HeadBlock, err = s.HeadFetcher.HeadBlock(ctx)
if err != nil {
return ev, errors.Wrap(err, "could not look up head block")
}
ev.HeadRoot, err = ev.HeadBlock.Block().HashTreeRoot()
if err != nil {
return ev, errors.Wrap(err, "could not compute head block root")
}
pr := ev.HeadBlock.Block().ParentRoot()
ev.ParentBlockRoot = pr[:]
hsr, err := ev.HeadState.LatestBlockHeader().HashTreeRoot()
if err != nil {
return ev, errors.Wrap(err, "could not compute latest block header root")
}
var err error
var st state.BeaconState
// If head is in the same block as the proposal slot, we can use the "read only" state cache.
pse := slots.ToEpoch(ev.ProposalSlot)
st := ev.HeadState
if slots.ToEpoch(st.Slot()) != pse {
st, err = transition.ProcessSlotsUsingNextSlotCache(ctx, st, hsr[:], ev.ProposalSlot)
if slots.ToEpoch(ev.HeadBlock.Block().Slot()) == pse {
st = s.StateGen.StateByRootIfCachedNoCopy(ev.HeadRoot)
}
// If st is nil, we couldn't get the state from the cache, or it isn't in the same epoch.
if st == nil || st.IsNil() {
st, err = s.StateGen.StateByRoot(ctx, ev.HeadRoot)
if err != nil {
return ev, errors.Wrap(err, "could not run process blocks on head state into the proposal slot epoch")
return ev, errors.Wrap(err, "could not get head state")
}
// double check that we need to process_slots, just in case we got here via a hot state cache miss.
if slots.ToEpoch(st.Slot()) < pse {
start, err := slots.EpochStart(pse)
if err != nil {
return ev, errors.Wrap(err, "invalid state slot; could not compute epoch start")
}
st, err = transition.ProcessSlotsUsingNextSlotCache(ctx, st, ev.HeadRoot[:], start)
if err != nil {
return ev, errors.Wrap(err, "could not run process blocks on head state into the proposal slot epoch")
}
}
}
ev.ProposerIndex, err = helpers.BeaconProposerIndexAtSlot(ctx, st, ev.ProposalSlot)
if err != nil {
return ev, errors.Wrap(err, "failed to compute proposer index")
@@ -743,14 +743,18 @@ func (s *Server) fillEventData(ctx context.Context, ev payloadattribute.EventDat
if err != nil {
return ev, errors.Wrap(err, "could not get head state slot time")
}
ev.Attributer, err = s.computePayloadAttributes(ctx, st, hsr, ev.ProposerIndex, uint64(t.Unix()), randao)
ev.Attributer, err = s.computePayloadAttributes(ctx, st, ev.HeadRoot, ev.ProposerIndex, uint64(t.Unix()), randao)
return ev, err
}
// This event stream is intended to be used by builders and relays.
// Parent fields are based on state at N_{current_slot}, while the rest of fields are based on state of N_{current_slot + 1}
func (s *Server) payloadAttributesReader(ctx context.Context, ev payloadattribute.EventData) (lazyReader, error) {
ctx, cancel := context.WithTimeout(ctx, payloadAttributeTimeout)
deadline := slots.BeginsAt(ev.ProposalSlot, s.ChainInfoFetcher.GenesisTime())
if deadline.Before(time.Now()) {
return nil, errors.Wrapf(errPayloadAttributeExpired, "proposal slot time %d", deadline.Unix())
}
ctx, cancel := context.WithDeadline(ctx, deadline)
edc := make(chan asyncPayloadAttrData)
go func() {
d := asyncPayloadAttrData{}
@@ -772,7 +776,7 @@ func (s *Server) payloadAttributesReader(ctx context.Context, ev payloadattribut
ProposerIndex: strconv.FormatUint(uint64(ev.ProposerIndex), 10),
ProposalSlot: strconv.FormatUint(uint64(ev.ProposalSlot), 10),
ParentBlockNumber: strconv.FormatUint(ev.ParentBlockNumber, 10),
ParentBlockRoot: hexutil.Encode(ev.ParentBlockRoot),
ParentBlockRoot: hexutil.Encode(ev.HeadRoot[:]),
ParentBlockHash: hexutil.Encode(ev.ParentBlockHash),
PayloadAttributes: attributesBytes,
})

View File

@@ -18,6 +18,7 @@ import (
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/operation"
statefeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/state"
"github.com/OffchainLabs/prysm/v6/beacon-chain/state"
"github.com/OffchainLabs/prysm/v6/beacon-chain/state/stategen/mock"
fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
@@ -522,15 +523,22 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
// to avoid slot processing
require.NoError(t, st.SetSlot(currentSlot+1))
b := tc.getBlock()
genesis := time.Now()
require.NoError(t, st.SetGenesisTime(uint64(genesis.Unix())))
mockChainService := &mockChain.ChainService{
Root: make([]byte, 32),
State: st,
Block: b,
Slot: &currentSlot,
Root: make([]byte, 32),
State: st,
Block: b,
Slot: &currentSlot,
Genesis: genesis,
}
headRoot, err := b.Block().HashTreeRoot()
require.NoError(t, err)
stn := mockChain.NewEventFeedWrapper()
opn := mockChain.NewEventFeedWrapper()
stategen := mock.NewService()
stategen.AddStateForRoot(st, headRoot)
s := &Server{
StateNotifier: &mockChain.SimpleNotifier{Feed: stn},
OperationNotifier: &mockChain.SimpleNotifier{Feed: opn},
@@ -538,6 +546,7 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
ChainInfoFetcher: mockChainService,
TrackedValidatorsCache: cache.NewTrackedValidatorsCache(),
EventWriteTimeout: testEventWriteTimeout,
StateGen: stategen,
}
if tc.SetTrackedValidatorsCache != nil {
tc.SetTrackedValidatorsCache(s.TrackedValidatorsCache)
@@ -551,13 +560,11 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
Type: statefeed.PayloadAttributes,
Data: payloadattribute.EventData{
ProposerIndex: 0,
ProposalSlot: 0,
ProposalSlot: mockChainService.CurrentSlot() + 1,
ParentBlockNumber: 0,
ParentBlockRoot: make([]byte, 32),
ParentBlockHash: make([]byte, 32),
HeadState: st,
HeadBlock: b,
HeadRoot: [fieldparams.RootLength]byte{},
HeadRoot: headRoot,
},
},
}
@@ -575,8 +582,6 @@ func TestStreamEvents_OperationsEvents(t *testing.T) {
func TestFillEventData(t *testing.T) {
ctx := context.Background()
t.Run("AlreadyFilledData_ShouldShortCircuitWithoutError", func(t *testing.T) {
st, err := util.NewBeaconStateBellatrix()
require.NoError(t, err)
b, err := blocks.NewSignedBeaconBlock(util.HydrateSignedBeaconBlockBellatrix(&eth.SignedBeaconBlockBellatrix{}))
require.NoError(t, err)
attributor, err := payloadattribute.New(&enginev1.PayloadAttributes{
@@ -584,11 +589,9 @@ func TestFillEventData(t *testing.T) {
})
require.NoError(t, err)
alreadyFilled := payloadattribute.EventData{
HeadState: st,
HeadBlock: b,
HeadRoot: [32]byte{1, 2, 3},
Attributer: attributor,
ParentBlockRoot: []byte{1, 2, 3},
ParentBlockHash: []byte{4, 5, 6},
}
srv := &Server{} // No real HeadFetcher needed here since it won't be called.
@@ -612,12 +615,14 @@ func TestFillEventData(t *testing.T) {
Timestamp: uint64(time.Now().Unix()),
})
require.NoError(t, err)
headRoot, err := b.Block().HashTreeRoot()
require.NoError(t, err)
// Create an event data object missing certain fields:
partial := payloadattribute.EventData{
// The presence of a nil HeadState, nil HeadBlock, zeroed HeadRoot, etc.
// will cause fillEventData to try to fill the values.
ProposalSlot: 42, // different epoch from current slot
Attributer: attributor, // Must be Bellatrix or later
HeadBlock: b,
HeadRoot: headRoot,
}
currentSlot := primitives.Slot(0)
// to avoid slot processing
@@ -629,6 +634,8 @@ func TestFillEventData(t *testing.T) {
Slot: &currentSlot,
}
stategen := mock.NewService()
stategen.AddStateForRoot(st, headRoot)
stn := mockChain.NewEventFeedWrapper()
opn := mockChain.NewEventFeedWrapper()
srv := &Server{
@@ -638,16 +645,15 @@ func TestFillEventData(t *testing.T) {
ChainInfoFetcher: mockChainService,
TrackedValidatorsCache: cache.NewTrackedValidatorsCache(),
EventWriteTimeout: testEventWriteTimeout,
StateGen: stategen,
}
filled, err := srv.fillEventData(ctx, partial)
require.NoError(t, err, "expected successful fill of partial event data")
// Verify that fields have been updated from the mock data:
require.NotNil(t, filled.HeadState, "HeadState should be assigned")
require.NotNil(t, filled.HeadBlock, "HeadBlock should be assigned")
require.NotEqual(t, [32]byte{}, filled.HeadRoot, "HeadRoot should no longer be zero")
require.NotEmpty(t, filled.ParentBlockRoot, "ParentBlockRoot should be filled")
require.NotEmpty(t, filled.ParentBlockHash, "ParentBlockHash should be filled")
require.Equal(t, uint64(0), filled.ParentBlockNumber, "ParentBlockNumber must match mock block")

View File

@@ -10,6 +10,7 @@ import (
"github.com/OffchainLabs/prysm/v6/beacon-chain/cache"
opfeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/operation"
statefeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/state"
"github.com/OffchainLabs/prysm/v6/beacon-chain/state/stategen"
)
// Server defines a server implementation of the http events service,
@@ -23,4 +24,5 @@ type Server struct {
KeepAliveInterval time.Duration
EventFeedDepth int
EventWriteTimeout time.Duration
StateGen stategen.StateManager
}

View File

@@ -18,7 +18,7 @@ import (
const errEpoch = "cannot retrieve information about an epoch in the future, current epoch %d, requesting %d"
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListValidatorAssignments retrieves the validator assignments for a given epoch,
// optional validator indices or public keys may be included to filter validator assignments.

View File

@@ -49,7 +49,7 @@ func mapAttestationsByTargetRoot(atts []ethpb.Att) map[[32]byte][]ethpb.Att {
return attsMap
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListAttestations retrieves attestations by block root, slot, or epoch.
// Attestations are sorted by data slot by default.
@@ -115,7 +115,7 @@ func (bs *Server) ListAttestations(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListAttestationsElectra retrieves attestations by block root, slot, or epoch.
// Attestations are sorted by data slot by default.
@@ -180,7 +180,7 @@ func (bs *Server) ListAttestationsElectra(ctx context.Context, req *ethpb.ListAt
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListIndexedAttestations retrieves indexed attestations by block root.
// IndexedAttestationsForEpoch are sorted by data slot by default. Start-end epoch
@@ -242,7 +242,7 @@ func (bs *Server) ListIndexedAttestations(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListIndexedAttestationsElectra retrieves indexed attestations by block root.
// IndexedAttestationsForEpoch are sorted by data slot by default. Start-end epoch
@@ -305,7 +305,7 @@ func (bs *Server) ListIndexedAttestationsElectra(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// AttestationPool retrieves pending attestations.
//
@@ -350,7 +350,7 @@ func (bs *Server) AttestationPool(_ context.Context, req *ethpb.AttestationPoolR
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
func (bs *Server) AttestationPoolElectra(_ context.Context, req *ethpb.AttestationPoolRequest) (*ethpb.AttestationPoolElectraResponse, error) {
var atts []*ethpb.AttestationElectra
var err error

View File

@@ -26,7 +26,7 @@ type blockContainer struct {
isCanonical bool
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListBeaconBlocks retrieves blocks by root, slot, or epoch.
//
@@ -246,7 +246,7 @@ func (bs *Server) listBlocksForGenesis(ctx context.Context, _ *ethpb.ListBlocksR
}}, 1, strconv.Itoa(0), nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetChainHead retrieves information about the head of the beacon chain from
// the view of the beacon chain node.

View File

@@ -15,7 +15,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListBeaconCommittees for a given epoch.
//

View File

@@ -10,7 +10,7 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetBeaconConfig retrieves the current configuration parameters of the beacon chain.
func (_ *Server) GetBeaconConfig(_ context.Context, _ *emptypb.Empty) (*ethpb.BeaconConfig, error) {

View File

@@ -11,7 +11,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitProposerSlashing receives a proposer slashing object via
// RPC and injects it into the beacon node's operations pool.
@@ -38,12 +38,12 @@ func (bs *Server) SubmitProposerSlashing(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
func (bs *Server) SubmitAttesterSlashing(ctx context.Context, req *ethpb.AttesterSlashing) (*ethpb.SubmitSlashingResponse, error) {
return bs.submitAttesterSlashing(ctx, req)
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitAttesterSlashingElectra receives an attester slashing object via
// RPC and injects it into the beacon node's operations pool.

View File

@@ -24,7 +24,7 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListValidatorBalances retrieves the validator balances for a given set of public keys.
// An optional Epoch parameter is provided to request historical validator balances from
@@ -182,7 +182,7 @@ func (bs *Server) ListValidatorBalances(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListValidators retrieves the current list of active validators with an optional historical epoch flag to
// retrieve validator set in time.
@@ -342,7 +342,7 @@ func (bs *Server) ListValidators(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetValidator information from any validator in the registry by index or public key.
func (bs *Server) GetValidator(
@@ -388,7 +388,7 @@ func (bs *Server) GetValidator(
return nil, status.Error(codes.NotFound, "No validator matched filter criteria")
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetValidatorActiveSetChanges retrieves the active set changes for a given epoch.
//
@@ -416,7 +416,7 @@ func (bs *Server) GetValidatorActiveSetChanges(
return as, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetValidatorParticipation retrieves the validator participation information for a given epoch,
// it returns the information about validator's participation rate in voting on the proof of stake
@@ -443,7 +443,7 @@ func (bs *Server) GetValidatorParticipation(
return vp, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetValidatorQueue retrieves the current validator queue information.
func (bs *Server) GetValidatorQueue(
@@ -536,7 +536,7 @@ func (bs *Server) GetValidatorQueue(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetValidatorPerformance reports the validator's latest balance along with other important metrics on
// rewards and penalties throughout its lifecycle in the beacon chain.
@@ -550,7 +550,7 @@ func (bs *Server) GetValidatorPerformance(
return response, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetIndividualVotes retrieves individual voting status of validators.
func (bs *Server) GetIndividualVotes(

View File

@@ -17,7 +17,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetBlock in an ssz-encoded format by block root.
func (ds *Server) GetBlock(
@@ -41,7 +41,7 @@ func (ds *Server) GetBlock(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetInclusionSlot of an attestation in block.
func (ds *Server) GetInclusionSlot(ctx context.Context, req *pbrpc.InclusionSlotRequest) (*pbrpc.InclusionSlotResponse, error) {

View File

@@ -13,7 +13,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetPeer returns the data known about the peer defined by the provided peer id.
func (ds *Server) GetPeer(_ context.Context, peerReq *ethpb.PeerRequest) (*ethpb.DebugPeerResponse, error) {
@@ -24,7 +24,7 @@ func (ds *Server) GetPeer(_ context.Context, peerReq *ethpb.PeerRequest) (*ethpb
return ds.getPeer(pid)
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListPeers returns all peers known to the host node, regardless of if they are connected/
// disconnected.

View File

@@ -10,7 +10,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetBeaconState retrieves an ssz-encoded beacon state
// from the beacon node by either a slot or block root.

View File

@@ -49,7 +49,7 @@ type Server struct {
BeaconMonitoringPort int
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetHealth checks the health of the node
func (ns *Server) GetHealth(ctx context.Context, request *ethpb.HealthRequest) (*empty.Empty, error) {
@@ -80,7 +80,7 @@ func (ns *Server) GetHealth(ctx context.Context, request *ethpb.HealthRequest) (
return &empty.Empty{}, status.Errorf(codes.Unavailable, "service unavailable")
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetSyncStatus checks the current network sync status of the node.
func (ns *Server) GetSyncStatus(_ context.Context, _ *empty.Empty) (*ethpb.SyncStatus, error) {
@@ -89,7 +89,7 @@ func (ns *Server) GetSyncStatus(_ context.Context, _ *empty.Empty) (*ethpb.SyncS
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetGenesis fetches genesis chain information of Ethereum. Returns unix timestamp 0
// if a genesis time has yet to be determined.
@@ -115,7 +115,7 @@ func (ns *Server) GetGenesis(ctx context.Context, _ *empty.Empty) (*ethpb.Genesi
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetVersion checks the version information of the beacon node.
func (_ *Server) GetVersion(_ context.Context, _ *empty.Empty) (*ethpb.Version, error) {
@@ -124,7 +124,7 @@ func (_ *Server) GetVersion(_ context.Context, _ *empty.Empty) (*ethpb.Version,
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListImplementedServices lists the services implemented and enabled by this node.
//
@@ -143,7 +143,7 @@ func (ns *Server) ListImplementedServices(_ context.Context, _ *empty.Empty) (*e
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetHost returns the p2p data on the current local and host peer.
func (ns *Server) GetHost(_ context.Context, _ *empty.Empty) (*ethpb.HostData, error) {
@@ -168,7 +168,7 @@ func (ns *Server) GetHost(_ context.Context, _ *empty.Empty) (*ethpb.HostData, e
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetPeer returns the data known about the peer defined by the provided peer id.
func (ns *Server) GetPeer(_ context.Context, peerReq *ethpb.PeerRequest) (*ethpb.Peer, error) {
@@ -215,7 +215,7 @@ func (ns *Server) GetPeer(_ context.Context, peerReq *ethpb.PeerRequest) (*ethpb
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ListPeers lists the peers connected to this node.
func (ns *Server) ListPeers(ctx context.Context, _ *empty.Empty) (*ethpb.Peers, error) {
@@ -270,7 +270,7 @@ func (ns *Server) ListPeers(ctx context.Context, _ *empty.Empty) (*ethpb.Peers,
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetETH1ConnectionStatus gets data about the ETH1 endpoints.
func (ns *Server) GetETH1ConnectionStatus(_ context.Context, _ *empty.Empty) (*ethpb.ETH1ConnectionStatus, error) {
@@ -286,7 +286,7 @@ func (ns *Server) GetETH1ConnectionStatus(_ context.Context, _ *empty.Empty) (*e
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// StreamBeaconLogs from the beacon node via a gRPC server-side stream.
// DEPRECATED: This endpoint doesn't appear to be used and have been marked for deprecation.

View File

@@ -17,7 +17,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitAggregateSelectionProof is called by a validator when its assigned to be an aggregator.
// The aggregator submits the selection proof to obtain the aggregated attestation
@@ -55,7 +55,7 @@ func (vs *Server) SubmitAggregateSelectionProof(ctx context.Context, req *ethpb.
return &ethpb.AggregateSelectionResponse{AggregateAndProof: attAndProof}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitAggregateSelectionProofElectra is called by a validator when its assigned to be an aggregator.
// The aggregator submits the selection proof to obtain the aggregated attestation
@@ -149,7 +149,7 @@ func (vs *Server) processAggregateSelection(ctx context.Context, req *ethpb.Aggr
return indexInCommittee, validatorIndex, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitSignedAggregateSelectionProof is called by a validator to broadcast a signed
// aggregated and proof object.
@@ -163,7 +163,7 @@ func (vs *Server) SubmitSignedAggregateSelectionProof(
return &ethpb.SignedAggregateSubmitResponse{}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitSignedAggregateSelectionProofElectra is called by a validator to broadcast a signed
// aggregated and proof object.

View File

@@ -22,7 +22,7 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetAttestationData requests that the beacon node produce an attestation data object,
// which the validator acting as an attester will then sign.
@@ -44,7 +44,7 @@ func (vs *Server) GetAttestationData(ctx context.Context, req *ethpb.Attestation
return res, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ProposeAttestation is a function called by an attester to vote
// on a block via an attestation object as defined in the Ethereum specification.
@@ -74,7 +74,7 @@ func (vs *Server) ProposeAttestation(ctx context.Context, att *ethpb.Attestation
return resp, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ProposeAttestationElectra is a function called by an attester to vote
// on a block via an attestation object as defined in the Ethereum specification.
@@ -114,7 +114,7 @@ func (vs *Server) ProposeAttestationElectra(ctx context.Context, singleAtt *ethp
return resp, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubscribeCommitteeSubnets subscribes to the committee ID subnet given subscribe request.
func (vs *Server) SubscribeCommitteeSubnets(ctx context.Context, req *ethpb.CommitteeSubnetsSubscribeRequest) (*emptypb.Empty, error) {

View File

@@ -82,7 +82,7 @@ func TestProposeAttestation(t *testing.T) {
config := params.BeaconConfig()
config.ElectraForkEpoch = 0
params.OverrideBeaconConfig(config)
state, err := util.NewBeaconState()
require.NoError(t, err)
require.NoError(t, state.SetSlot(params.BeaconConfig().SlotsPerEpoch+1))

View File

@@ -9,13 +9,12 @@ import (
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/time/slots"
"github.com/pkg/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// StreamBlocksAltair to clients every single time a block is received by the beacon node.
func (vs *Server) StreamBlocksAltair(req *ethpb.StreamBlocksRequest, stream ethpb.BeaconNodeValidator_StreamBlocksAltairServer) error {
@@ -50,7 +49,7 @@ func (vs *Server) StreamBlocksAltair(req *ethpb.StreamBlocksRequest, stream ethp
}
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// StreamSlots sends a the block's slot and dependent roots to clients every single time a block is received by the beacon node.
func (vs *Server) StreamSlots(req *ethpb.StreamSlotsRequest, stream ethpb.BeaconNodeValidator_StreamSlotsServer) error {
@@ -67,6 +66,7 @@ func (vs *Server) StreamSlots(req *ethpb.StreamSlotsRequest, stream ethpb.Beacon
select {
case ev := <-ch:
var s primitives.Slot
var currDependentRoot, prevDependentRoot [32]byte
if req.VerifiedOnly {
if ev.Type != statefeed.BlockProcessed {
continue
@@ -76,6 +76,8 @@ func (vs *Server) StreamSlots(req *ethpb.StreamSlotsRequest, stream ethpb.Beacon
continue
}
s = data.Slot
currDependentRoot = data.CurrDependentRoot
prevDependentRoot = data.PrevDependentRoot
} else {
if ev.Type != blockfeed.ReceivedBlock {
continue
@@ -85,24 +87,14 @@ func (vs *Server) StreamSlots(req *ethpb.StreamSlotsRequest, stream ethpb.Beacon
continue
}
s = data.SignedBlock.Block().Slot()
}
currEpoch := slots.ToEpoch(s)
currDepRoot, err := vs.ForkchoiceFetcher.DependentRoot(currEpoch)
if err != nil {
return status.Errorf(codes.Internal, "Could not get dependent root: %v", err)
}
prevDepRoot := currDepRoot
if currEpoch > 0 {
prevDepRoot, err = vs.ForkchoiceFetcher.DependentRoot(currEpoch - 1)
if err != nil {
return status.Errorf(codes.Internal, "Could not get dependent root: %v", err)
}
currDependentRoot = data.CurrDependentRoot
prevDependentRoot = data.PrevDependentRoot
}
if err := stream.Send(
&ethpb.StreamSlotsResponse{
Slot: s,
PreviousDutyDependentRoot: prevDepRoot[:],
CurrentDutyDependentRoot: currDepRoot[:],
PreviousDutyDependentRoot: prevDependentRoot[:],
CurrentDutyDependentRoot: currDependentRoot[:],
}); err != nil {
return status.Errorf(codes.Unavailable, "Could not send over stream: %v", err)
}

View File

@@ -16,7 +16,7 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetDuties returns the duties assigned to a list of validators specified
// in the request object.
@@ -178,7 +178,7 @@ func (vs *Server) duties(ctx context.Context, req *ethpb.DutiesRequest) (*ethpb.
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// AssignValidatorToSubnet checks the status and pubkey of a particular validator
// to discern whether persistent subnets need to be registered for them.

View File

@@ -12,7 +12,7 @@ import (
"google.golang.org/grpc/status"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ProposeExit proposes an exit for a validator.
func (vs *Server) ProposeExit(ctx context.Context, req *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error) {

View File

@@ -45,7 +45,7 @@ const (
defaultBuilderBoostFactor = primitives.Gwei(100)
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetBeaconBlock is called by a proposer during its assigned slot to request a block to sign
// by passing in the slot and the signed randao reveal of the slot.
@@ -271,7 +271,7 @@ func (vs *Server) BuildBlockParallel(ctx context.Context, sBlk interfaces.Signed
return vs.constructGenericBeaconBlock(sBlk, bundle, winningBid)
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ProposeBeaconBlock handles the proposal of beacon blocks.
func (vs *Server) ProposeBeaconBlock(ctx context.Context, req *ethpb.GenericSignedBeaconBlock) (*ethpb.ProposeResponse, error) {
@@ -412,7 +412,7 @@ func (vs *Server) broadcastAndReceiveBlobs(ctx context.Context, sidecars []*ethp
return eg.Wait()
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// PrepareBeaconProposer caches and updates the fee recipient for the given proposer.
func (vs *Server) PrepareBeaconProposer(
@@ -449,7 +449,7 @@ func (vs *Server) PrepareBeaconProposer(
return &emptypb.Empty{}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetFeeRecipientByPubKey returns a fee recipient from the beacon node's settings or db based on a given public key
func (vs *Server) GetFeeRecipientByPubKey(ctx context.Context, request *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) {
@@ -506,7 +506,7 @@ func (vs *Server) computeStateRoot(ctx context.Context, block interfaces.ReadOnl
return root[:], nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitValidatorRegistrations submits validator registrations.
func (vs *Server) SubmitValidatorRegistrations(ctx context.Context, reg *ethpb.SignedValidatorRegistrationsV1) (*emptypb.Empty, error) {

View File

@@ -82,7 +82,7 @@ type Server struct {
AttestationStateFetcher blockchain.AttestationStateFetcher
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// WaitForActivation checks if a validator public key exists in the active validator registry of the current
// beacon state, if not, then it creates a stream which listens for canonical states which contain
@@ -132,7 +132,7 @@ func (vs *Server) WaitForActivation(req *ethpb.ValidatorActivationRequest, strea
}
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ValidatorIndex is called by a validator to get its index location in the beacon state.
func (vs *Server) ValidatorIndex(ctx context.Context, req *ethpb.ValidatorIndexRequest) (*ethpb.ValidatorIndexResponse, error) {
@@ -151,7 +151,7 @@ func (vs *Server) ValidatorIndex(ctx context.Context, req *ethpb.ValidatorIndexR
return &ethpb.ValidatorIndexResponse{Index: index}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// DomainData fetches the current domain version information from the beacon state.
func (vs *Server) DomainData(ctx context.Context, request *ethpb.DomainRequest) (*ethpb.DomainResponse, error) {
@@ -183,7 +183,7 @@ func (vs *Server) DomainData(ctx context.Context, request *ethpb.DomainRequest)
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// WaitForChainStart queries the logs of the Deposit Contract in order to verify the beacon chain
// has started its runtime and validators begin their responsibilities. If it has not, it then

View File

@@ -29,7 +29,7 @@ var nonExistentIndex = primitives.ValidatorIndex(^uint64(0))
var errParticipation = status.Errorf(codes.Internal, "Failed to obtain epoch participation")
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// ValidatorStatus returns the validator status of the current epoch.
// The status response can be one of the following:
@@ -54,7 +54,7 @@ func (vs *Server) ValidatorStatus(
return vStatus, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// MultipleValidatorStatus is the same as ValidatorStatus. Supports retrieval of multiple
// validator statuses. Takes a list of public keys or a list of validator indices.
@@ -104,7 +104,7 @@ func (vs *Server) MultipleValidatorStatus(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// CheckDoppelGanger checks if the provided keys are currently active in the network.
func (vs *Server) CheckDoppelGanger(ctx context.Context, req *ethpb.DoppelGangerRequest) (*ethpb.DoppelGangerResponse, error) {

View File

@@ -12,7 +12,7 @@ import (
"google.golang.org/protobuf/types/known/emptypb"
)
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetSyncMessageBlockRoot retrieves the sync committee block root of the beacon chain.
func (vs *Server) GetSyncMessageBlockRoot(
@@ -34,7 +34,7 @@ func (vs *Server) GetSyncMessageBlockRoot(
}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitSyncMessage submits the sync committee message to the network.
// It also saves the sync committee message into the pending pool for block inclusion.
@@ -45,7 +45,7 @@ func (vs *Server) SubmitSyncMessage(ctx context.Context, msg *ethpb.SyncCommitte
return &emptypb.Empty{}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetSyncSubcommitteeIndex is called by a sync committee participant to get
// its subcommittee index for sync message aggregation duty.
@@ -63,7 +63,7 @@ func (vs *Server) GetSyncSubcommitteeIndex(
return &ethpb.SyncSubcommitteeIndexResponse{Indices: indices}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// GetSyncCommitteeContribution is called by a sync committee aggregator
// to retrieve sync committee contribution object.
@@ -106,7 +106,7 @@ func (vs *Server) GetSyncCommitteeContribution(
return contribution, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// SubmitSignedContributionAndProof is called by a sync committee aggregator
// to submit signed contribution and proof object.
@@ -120,7 +120,7 @@ func (vs *Server) SubmitSignedContributionAndProof(
return &emptypb.Empty{}, nil
}
// Deprecated: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
// Deprecated: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API.
//
// AggregatedSigAndAggregationBits returns the aggregated signature and aggregation bits
// associated with a particular set of sync committee messages.

View File

@@ -23,8 +23,8 @@ func NewService() *StateManager {
}
// StateByRootIfCachedNoCopy --
func (_ *StateManager) StateByRootIfCachedNoCopy(_ [32]byte) state.BeaconState {
panic("implement me")
func (m *StateManager) StateByRootIfCachedNoCopy(root [32]byte) state.BeaconState {
return m.StatesByRoot[root]
}
// Resume --

View File

@@ -38,6 +38,7 @@ go_library(
"subscriber_blob_sidecar.go",
"subscriber_bls_to_execution_change.go",
"subscriber_handlers.go",
"subscriber_light_client.go",
"subscriber_sync_committee_message.go",
"subscriber_sync_contribution_proof.go",
"subscription_topic_handler.go",
@@ -47,6 +48,7 @@ go_library(
"validate_beacon_blocks.go",
"validate_blob.go",
"validate_bls_to_execution_change.go",
"validate_light_client.go",
"validate_proposer_slashing.go",
"validate_sync_committee_message.go",
"validate_sync_contribution_proof.go",
@@ -71,6 +73,7 @@ go_library(
"//beacon-chain/core/feed/operation:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/light-client:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/core/transition/interop:go_default_library",
@@ -101,6 +104,7 @@ go_library(
"//config/params:go_default_library",
"//consensus-types/blocks:go_default_library",
"//consensus-types/interfaces:go_default_library",
"//consensus-types/light-client:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/wrapper:go_default_library",
"//container/leaky-bucket:go_default_library",
@@ -182,6 +186,7 @@ go_test(
"validate_beacon_blocks_test.go",
"validate_blob_test.go",
"validate_bls_to_execution_change_test.go",
"validate_light_client_test.go",
"validate_proposer_slashing_test.go",
"validate_sync_committee_message_test.go",
"validate_sync_contribution_proof_test.go",
@@ -198,6 +203,7 @@ go_test(
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/operation:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/light-client:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/core/transition:go_default_library",
@@ -211,6 +217,7 @@ go_test(
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/blstoexec:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/operations/slashings/mock:go_default_library",
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/p2p/encoder:go_default_library",
"//beacon-chain/p2p/peers:go_default_library",

View File

@@ -89,6 +89,10 @@ func extractValidDataTypeFromTopic(topic string, digest []byte, clock *startup.C
return extractDataTypeFromTypeMap(types.AggregateAttestationMap, digest, clock)
case p2p.AttesterSlashingSubnetTopicFormat:
return extractDataTypeFromTypeMap(types.AttesterSlashingMap, digest, clock)
case p2p.LightClientOptimisticUpdateTopicFormat:
return extractDataTypeFromTypeMap(types.LightClientOptimisticUpdateMap, digest, clock)
case p2p.LightClientFinalityUpdateTopicFormat:
return extractDataTypeFromTypeMap(types.LightClientFinalityUpdateMap, digest, clock)
}
return nil, nil
}

View File

@@ -6,6 +6,7 @@ import (
blockfeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/block"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/operation"
statefeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/state"
lightClient "github.com/OffchainLabs/prysm/v6/beacon-chain/core/light-client"
"github.com/OffchainLabs/prysm/v6/beacon-chain/db"
"github.com/OffchainLabs/prysm/v6/beacon-chain/db/filesystem"
"github.com/OffchainLabs/prysm/v6/beacon-chain/execution"
@@ -196,3 +197,11 @@ func WithSlasherEnabled(enabled bool) Option {
return nil
}
}
// WithLightClientStore allows the sync package to access light client data.
func WithLightClientStore(lcs *lightClient.Store) Option {
return func(s *Service) error {
s.lcStore = lcs
return nil
}
}

View File

@@ -9,6 +9,7 @@ import (
"sync"
"time"
lightClient "github.com/OffchainLabs/prysm/v6/beacon-chain/core/light-client"
lru "github.com/hashicorp/golang-lru"
pubsub "github.com/libp2p/go-libp2p-pubsub"
libp2pcore "github.com/libp2p/go-libp2p/core"
@@ -165,6 +166,7 @@ type Service struct {
availableBlocker coverage.AvailableBlocker
ctxMap ContextByteVersions
slasherEnabled bool
lcStore *lightClient.Store
}
// NewService initializes new regular sync service.

View File

@@ -0,0 +1,66 @@
package sync
import (
"context"
"fmt"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed"
statefeed "github.com/OffchainLabs/prysm/v6/beacon-chain/core/feed/state"
lightclientTypes "github.com/OffchainLabs/prysm/v6/consensus-types/light-client"
"github.com/sirupsen/logrus"
"google.golang.org/protobuf/proto"
)
func (s *Service) lightClientOptimisticUpdateSubscriber(_ context.Context, msg proto.Message) error {
update, err := lightclientTypes.NewWrappedOptimisticUpdate(msg)
if err != nil {
return err
}
attestedHeaderRoot, err := update.AttestedHeader().Beacon().HashTreeRoot()
if err != nil {
return err
}
log.WithFields(logrus.Fields{
"attestedSlot": fmt.Sprintf("%d", update.AttestedHeader().Beacon().Slot),
"signatureSlot": fmt.Sprintf("%d", update.SignatureSlot()),
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
}).Debug("Saving newly received light client optimistic update.")
s.lcStore.SetLastOptimisticUpdate(update)
s.cfg.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.LightClientOptimisticUpdate,
Data: update,
})
return nil
}
func (s *Service) lightClientFinalityUpdateSubscriber(_ context.Context, msg proto.Message) error {
update, err := lightclientTypes.NewWrappedFinalityUpdate(msg)
if err != nil {
return err
}
attestedHeaderRoot, err := update.AttestedHeader().Beacon().HashTreeRoot()
if err != nil {
return err
}
log.WithFields(logrus.Fields{
"attestedSlot": fmt.Sprintf("%d", update.AttestedHeader().Beacon().Slot),
"signatureSlot": fmt.Sprintf("%d", update.SignatureSlot()),
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
}).Debug("Saving newly received light client finality update.")
s.lcStore.SetLastFinalityUpdate(update)
s.cfg.stateNotifier.StateFeed().Send(&feed.Event{
Type: statefeed.LightClientFinalityUpdate,
Data: update,
})
return nil
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/OffchainLabs/prysm/v6/async/abool"
mockChain "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/cache"
lightClient "github.com/OffchainLabs/prysm/v6/beacon-chain/core/light-client"
"github.com/OffchainLabs/prysm/v6/beacon-chain/core/signing"
db "github.com/OffchainLabs/prysm/v6/beacon-chain/db/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/operations/slashings"
@@ -27,6 +28,7 @@ import (
"github.com/OffchainLabs/prysm/v6/encoding/bytesutil"
"github.com/OffchainLabs/prysm/v6/network/forks"
pb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/testing/assert"
"github.com/OffchainLabs/prysm/v6/testing/require"
"github.com/OffchainLabs/prysm/v6/testing/util"
@@ -638,3 +640,137 @@ func createPeer(t *testing.T, topics ...string) *p2ptest.TestP2P {
}
return p
}
func TestSubscribe_ReceivesLCOptimisticUpdate(t *testing.T) {
origNC := params.BeaconConfig()
// restore network config after test completes
defer func() {
params.OverrideBeaconConfig(origNC)
}()
params.SetupTestConfigCleanup(t)
p2pService := p2ptest.NewTestP2P(t)
ctx := context.Background()
cfg := params.BeaconConfig().Copy()
cfg.AltairForkEpoch = 1
cfg.ForkVersionSchedule[[4]byte{1, 0, 0, 0}] = 1
params.OverrideBeaconConfig(cfg)
secondsPerSlot := int(params.BeaconConfig().SecondsPerSlot)
slotIntervals := int(params.BeaconConfig().IntervalsPerSlot)
slotsPerEpoch := int(params.BeaconConfig().SlotsPerEpoch)
genesisDrift := slotsPerEpoch*secondsPerSlot + 2*secondsPerSlot + secondsPerSlot/slotIntervals
chainService := &mockChain.ChainService{
ValidatorsRoot: [32]byte{'A'},
Genesis: time.Unix(time.Now().Unix()-int64(genesisDrift), 0),
}
d := db.SetupDB(t)
r := Service{
ctx: ctx,
cfg: &config{
p2p: p2pService,
initialSync: &mockSync.Sync{IsSyncing: false},
chain: chainService,
beaconDB: d,
clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot),
stateNotifier: &mockChain.MockStateNotifier{},
},
chainStarted: abool.New(),
lcStore: &lightClient.Store{},
subHandler: newSubTopicHandler(),
}
topic := p2p.LightClientOptimisticUpdateTopicFormat
var wg sync.WaitGroup
wg.Add(1)
var err error
p2pService.Digest, err = r.currentForkDigest()
require.NoError(t, err)
r.subscribe(topic, r.validateLightClientOptimisticUpdate, func(ctx context.Context, msg proto.Message) error {
require.NoError(t, r.lightClientOptimisticUpdateSubscriber(ctx, msg))
wg.Done()
return nil
}, p2pService.Digest)
r.markForChainStart()
l := util.NewTestLightClient(t, version.Altair, util.WithSupermajority())
update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock)
require.NoError(t, err, "Error generating light client optimistic update")
p2pService.ReceivePubSub(topic, update.Proto())
if util.WaitTimeout(&wg, time.Second) {
t.Fatal("Did not receive PubSub in 1 second")
}
u := r.lcStore.LastOptimisticUpdate()
assert.DeepEqual(t, update.Proto(), u.Proto())
}
func TestSubscribe_ReceivesLCFinalityUpdate(t *testing.T) {
origNC := params.BeaconConfig()
// restore network config after test completes
defer func() {
params.OverrideBeaconConfig(origNC)
}()
params.SetupTestConfigCleanup(t)
p2pService := p2ptest.NewTestP2P(t)
ctx := context.Background()
cfg := params.BeaconConfig().Copy()
cfg.AltairForkEpoch = 1
cfg.ForkVersionSchedule[[4]byte{1, 0, 0, 0}] = 1
params.OverrideBeaconConfig(cfg)
secondsPerSlot := int(params.BeaconConfig().SecondsPerSlot)
slotIntervals := int(params.BeaconConfig().IntervalsPerSlot)
slotsPerEpoch := int(params.BeaconConfig().SlotsPerEpoch)
genesisDrift := slotsPerEpoch*secondsPerSlot + 2*secondsPerSlot + secondsPerSlot/slotIntervals
chainService := &mockChain.ChainService{
ValidatorsRoot: [32]byte{'A'},
Genesis: time.Unix(time.Now().Unix()-int64(genesisDrift), 0),
}
d := db.SetupDB(t)
r := Service{
ctx: ctx,
cfg: &config{
p2p: p2pService,
initialSync: &mockSync.Sync{IsSyncing: false},
chain: chainService,
beaconDB: d,
clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot),
stateNotifier: &mockChain.MockStateNotifier{},
},
chainStarted: abool.New(),
lcStore: &lightClient.Store{},
subHandler: newSubTopicHandler(),
}
topic := p2p.LightClientFinalityUpdateTopicFormat
var wg sync.WaitGroup
wg.Add(1)
var err error
p2pService.Digest, err = r.currentForkDigest()
require.NoError(t, err)
r.subscribe(topic, r.validateLightClientFinalityUpdate, func(ctx context.Context, msg proto.Message) error {
require.NoError(t, r.lightClientFinalityUpdateSubscriber(ctx, msg))
wg.Done()
return nil
}, p2pService.Digest)
r.markForChainStart()
l := util.NewTestLightClient(t, version.Altair, util.WithSupermajority())
update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
require.NoError(t, err, "Error generating light client finality update")
p2pService.ReceivePubSub(topic, update.Proto())
if util.WaitTimeout(&wg, time.Second) {
t.Fatal("Did not receive PubSub in 1 second")
}
u := r.lcStore.LastFinalityUpdate()
assert.DeepEqual(t, update.Proto(), u.Proto())
}

View File

@@ -21,6 +21,7 @@ import (
"github.com/OffchainLabs/prysm/v6/encoding/bytesutil"
"github.com/OffchainLabs/prysm/v6/monitoring/tracing"
"github.com/OffchainLabs/prysm/v6/monitoring/tracing/trace"
ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v6/runtime/version"
prysmTime "github.com/OffchainLabs/prysm/v6/time"
"github.com/OffchainLabs/prysm/v6/time/slots"
@@ -31,8 +32,9 @@ import (
)
var (
ErrOptimisticParent = errors.New("parent of the block is optimistic")
errRejectCommitmentLen = errors.New("[REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer")
ErrOptimisticParent = errors.New("parent of the block is optimistic")
errRejectCommitmentLen = errors.New("[REJECT] The length of KZG commitments is less than or equal to the limitation defined in Consensus Layer")
ErrSlashingSignatureFailure = errors.New("proposer slashing signature verification failed")
)
// validateBeaconBlockPubSub checks that the incoming block has a valid BLS signature.
@@ -109,6 +111,16 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
// Verify the block is the first block received for the proposer for the slot.
if s.hasSeenBlockIndexSlot(blk.Block().Slot(), blk.Block().ProposerIndex()) {
// Attempt to detect and broadcast equivocation before ignoring
err = s.detectAndBroadcastEquivocation(ctx, blk)
if err != nil {
// If signature verification fails, reject the block
if errors.Is(err, ErrSlashingSignatureFailure) {
return pubsub.ValidationReject, err
}
// In case there is some other error log but don't reject
log.WithError(err).Debug("Could not detect/broadcast equivocation")
}
return pubsub.ValidationIgnore, nil
}
@@ -469,3 +481,74 @@ func getBlockFields(b interfaces.ReadOnlySignedBeaconBlock) logrus.Fields {
"version": b.Block().Version(),
}
}
// detectAndBroadcastEquivocation checks if the given block is an equivocating block by comparing it with
// the head block. If the blocks are from the same slot and proposer but have different signatures,
// it creates and broadcasts a proposer slashing object after verification.
func (s *Service) detectAndBroadcastEquivocation(ctx context.Context, blk interfaces.ReadOnlySignedBeaconBlock) error {
slot := blk.Block().Slot()
proposerIndex := blk.Block().ProposerIndex()
// Get head block for comparison
headBlock, err := s.cfg.chain.HeadBlock(ctx)
if err != nil {
return errors.Wrap(err, "could not get head block")
}
// Only proceed if this block is from same slot and proposer as head
if headBlock.Block().Slot() != slot || headBlock.Block().ProposerIndex() != proposerIndex {
return nil
}
// Compare signatures
sig1 := blk.Signature()
sig2 := headBlock.Signature()
// If signatures match, these are the same block
if sig1 == sig2 {
return nil
}
// Extract headers for slashing
header1, err := blk.Header()
if err != nil {
return errors.Wrap(err, "could not get header from new block")
}
header2, err := headBlock.Header()
if err != nil {
return errors.Wrap(err, "could not get header from head block")
}
slashing := &ethpb.ProposerSlashing{
Header_1: header1,
Header_2: header2,
}
// Get state for verification
headState, err := s.cfg.chain.HeadStateReadOnly(ctx)
if err != nil {
return errors.Wrap(err, "could not get head state")
}
// Verify the slashing against current state
if err := blocks.VerifyProposerSlashing(headState, slashing); err != nil {
if errors.Is(err, blocks.ErrCouldNotVerifyBlockHeader) {
return errors.Wrap(ErrSlashingSignatureFailure, err.Error())
}
return errors.Wrap(err, "could not verify proposer slashing")
}
// Broadcast if verification passes
if !features.Get().DisableBroadcastSlashings {
if err := s.cfg.p2p.Broadcast(ctx, slashing); err != nil {
return errors.Wrap(err, "could not broadcast slashing object")
}
}
// Insert into slashing pool
if err := s.cfg.slashingPool.InsertProposerSlashing(ctx, headState, slashing); err != nil {
return errors.Wrap(err, "could not insert proposer slashing into pool")
}
return nil
}

View File

@@ -18,6 +18,7 @@ import (
dbtest "github.com/OffchainLabs/prysm/v6/beacon-chain/db/testing"
doublylinkedtree "github.com/OffchainLabs/prysm/v6/beacon-chain/forkchoice/doubly-linked-tree"
"github.com/OffchainLabs/prysm/v6/beacon-chain/operations/attestations"
slashingsmock "github.com/OffchainLabs/prysm/v6/beacon-chain/operations/slashings/mock"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p"
p2ptest "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/startup"
@@ -713,8 +714,21 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
msg.Signature, err = signing.ComputeDomainAndSign(beaconState, 0, msg.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[proposerIdx])
require.NoError(t, err)
chainService := &mock.ChainService{Genesis: time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0),
State: beaconState,
// Create a clone of the same block (same signature, not an equivocation)
msgClone := util.NewBeaconBlock()
msgClone.Block.Slot = 1
msgClone.Block.ProposerIndex = proposerIdx
msgClone.Block.ParentRoot = bRoot[:]
msgClone.Signature = msg.Signature // Use the same signature
signedBlock, err := blocks.NewSignedBeaconBlock(msg)
require.NoError(t, err)
slashingPool := &slashingsmock.PoolMock{}
chainService := &mock.ChainService{
Genesis: time.Unix(time.Now().Unix()-int64(params.BeaconConfig().SecondsPerSlot), 0),
State: beaconState,
Block: signedBlock, // Set the first block as the head block
FinalizedCheckPoint: &ethpb.Checkpoint{
Epoch: 0,
Root: make([]byte, 32),
@@ -728,6 +742,7 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
chain: chainService,
clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot),
blockNotifier: chainService.BlockNotifier(),
slashingPool: slashingPool,
},
seenBlockCache: lruwrpr.New(10),
badBlockCache: lruwrpr.New(10),
@@ -735,10 +750,15 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
seenPendingBlocks: make(map[[32]byte]bool),
}
// Mark the proposer/slot as seen
r.setSeenBlockIndexSlot(msg.Block.Slot, msg.Block.ProposerIndex)
time.Sleep(10 * time.Millisecond) // Wait for cached value to pass through buffers
// Prepare and validate the second message (clone)
buf := new(bytes.Buffer)
_, err = p.Encoding().EncodeGossip(buf, msg)
_, err = p.Encoding().EncodeGossip(buf, msgClone)
require.NoError(t, err)
topic := p2p.GossipTypeMapping[reflect.TypeOf(msg)]
topic := p2p.GossipTypeMapping[reflect.TypeOf(msgClone)]
digest, err := r.currentForkDigest()
assert.NoError(t, err)
topic = r.addDigestToTopic(topic, digest)
@@ -748,11 +768,14 @@ func TestValidateBeaconBlockPubSub_SeenProposerSlot(t *testing.T) {
Topic: &topic,
},
}
r.setSeenBlockIndexSlot(msg.Block.Slot, msg.Block.ProposerIndex)
time.Sleep(10 * time.Millisecond) // Wait for cached value to pass through buffers.
// Since this is not an equivocation (same signature), it should be ignored
res, err := r.validateBeaconBlockPubSub(ctx, "", m)
assert.NoError(t, err)
assert.Equal(t, res, pubsub.ValidationIgnore, "seen proposer block should be ignored")
assert.Equal(t, pubsub.ValidationIgnore, res, "block with same signature should be ignored")
// Verify no slashings were created
assert.Equal(t, 0, len(slashingPool.PendingPropSlashings), "Expected no slashings for same signature")
}
func TestValidateBeaconBlockPubSub_FilterByFinalizedEpoch(t *testing.T) {
@@ -1495,3 +1518,218 @@ func Test_validateDenebBeaconBlock(t *testing.T) {
require.NoError(t, err)
require.ErrorIs(t, validateDenebBeaconBlock(bdb.Block()), errRejectCommitmentLen)
}
func TestDetectAndBroadcastEquivocation(t *testing.T) {
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
beaconState, privKeys := util.DeterministicGenesisState(t, 100)
t.Run("no equivocation", func(t *testing.T) {
block := util.NewBeaconBlock()
block.Block.Slot = 1
block.Block.ProposerIndex = 0
sig, err := signing.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
block.Signature = sig
// Create head block with different slot/proposer
headBlock := util.NewBeaconBlock()
headBlock.Block.Slot = 2 // Different slot
headBlock.Block.ProposerIndex = 1 // Different proposer
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
require.NoError(t, err)
chainService := &mock.ChainService{
State: beaconState,
Genesis: time.Now(),
Block: signedHeadBlock,
}
slashingPool := &slashingsmock.PoolMock{}
r := &Service{
cfg: &config{
p2p: p,
chain: chainService,
slashingPool: slashingPool,
},
seenBlockCache: lruwrpr.New(10),
}
signedBlock, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
err = r.detectAndBroadcastEquivocation(ctx, signedBlock)
require.NoError(t, err)
assert.Equal(t, 0, len(slashingPool.PendingPropSlashings), "Expected no slashings")
})
t.Run("equivocation detected", func(t *testing.T) {
// Create head block
headBlock := util.NewBeaconBlock()
headBlock.Block.Slot = 1
headBlock.Block.ProposerIndex = 0
headBlock.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
sig1, err := signing.ComputeDomainAndSign(beaconState, 0, headBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
headBlock.Signature = sig1
// Create second block with same slot/proposer but different contents
newBlock := util.NewBeaconBlock()
newBlock.Block.Slot = 1
newBlock.Block.ProposerIndex = 0
newBlock.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32)
sig2, err := signing.ComputeDomainAndSign(beaconState, 0, newBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
newBlock.Signature = sig2
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
require.NoError(t, err)
slashingPool := &slashingsmock.PoolMock{}
chainService := &mock.ChainService{
State: beaconState,
Genesis: time.Now(),
Block: signedHeadBlock,
}
r := &Service{
cfg: &config{
p2p: p,
chain: chainService,
slashingPool: slashingPool,
},
seenBlockCache: lruwrpr.New(10),
}
signedNewBlock, err := blocks.NewSignedBeaconBlock(newBlock)
require.NoError(t, err)
err = r.detectAndBroadcastEquivocation(ctx, signedNewBlock)
require.NoError(t, err)
// Verify slashing was inserted
require.Equal(t, 1, len(slashingPool.PendingPropSlashings), "Expected a slashing to be inserted")
slashing := slashingPool.PendingPropSlashings[0]
assert.Equal(t, primitives.ValidatorIndex(0), slashing.Header_1.Header.ProposerIndex, "Wrong proposer index")
assert.Equal(t, primitives.Slot(1), slashing.Header_1.Header.Slot, "Wrong slot")
})
t.Run("same signature", func(t *testing.T) {
// Create block
block := util.NewBeaconBlock()
block.Block.Slot = 1
block.Block.ProposerIndex = 0
sig, err := signing.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
block.Signature = sig
signedBlock, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
slashingPool := &slashingsmock.PoolMock{}
chainService := &mock.ChainService{
State: beaconState,
Genesis: time.Now(),
Block: signedBlock,
}
r := &Service{
cfg: &config{
p2p: p,
chain: chainService,
slashingPool: slashingPool,
},
seenBlockCache: lruwrpr.New(10),
}
err = r.detectAndBroadcastEquivocation(ctx, signedBlock)
require.NoError(t, err)
assert.Equal(t, 0, len(slashingPool.PendingPropSlashings), "Expected no slashings for same signature")
})
t.Run("head state error", func(t *testing.T) {
block := util.NewBeaconBlock()
block.Block.Slot = 1
block.Block.ProposerIndex = 0
block.Block.ParentRoot = bytesutil.PadTo([]byte("parent1"), 32)
sig1, err := signing.ComputeDomainAndSign(beaconState, 0, block.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
block.Signature = sig1
headBlock := util.NewBeaconBlock()
headBlock.Block.Slot = 1 // Same slot
headBlock.Block.ProposerIndex = 0 // Same proposer
headBlock.Block.ParentRoot = bytesutil.PadTo([]byte("parent2"), 32) // Different parent root
sig2, err := signing.ComputeDomainAndSign(beaconState, 0, headBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
headBlock.Signature = sig2
signedBlock, err := blocks.NewSignedBeaconBlock(block)
require.NoError(t, err)
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
require.NoError(t, err)
chainService := &mock.ChainService{
State: nil,
Block: signedHeadBlock,
HeadStateErr: errors.New("could not get head state"),
}
r := &Service{
cfg: &config{
p2p: p,
chain: chainService,
slashingPool: &slashingsmock.PoolMock{},
},
seenBlockCache: lruwrpr.New(10),
}
err = r.detectAndBroadcastEquivocation(ctx, signedBlock)
require.ErrorContains(t, "could not get head state", err)
})
t.Run("signature verification failure", func(t *testing.T) {
// Create head block
headBlock := util.NewBeaconBlock()
headBlock.Block.Slot = 1
headBlock.Block.ProposerIndex = 0
sig1, err := signing.ComputeDomainAndSign(beaconState, 0, headBlock.Block, params.BeaconConfig().DomainBeaconProposer, privKeys[0])
require.NoError(t, err)
headBlock.Signature = sig1
// Create test block with invalid signature
newBlock := util.NewBeaconBlock()
newBlock.Block.Slot = 1
newBlock.Block.ProposerIndex = 0
newBlock.Block.ParentRoot = bytesutil.PadTo([]byte("different"), 32)
// generate invalid signature
invalidSig := make([]byte, 96)
copy(invalidSig, []byte("invalid signature"))
newBlock.Signature = invalidSig
signedHeadBlock, err := blocks.NewSignedBeaconBlock(headBlock)
require.NoError(t, err)
signedNewBlock, err := blocks.NewSignedBeaconBlock(newBlock)
require.NoError(t, err)
slashingPool := &slashingsmock.PoolMock{}
chainService := &mock.ChainService{
State: beaconState,
Genesis: time.Now(),
Block: signedHeadBlock,
}
r := &Service{
cfg: &config{
p2p: p,
chain: chainService,
slashingPool: slashingPool,
},
seenBlockCache: lruwrpr.New(10),
}
err = r.detectAndBroadcastEquivocation(ctx, signedNewBlock)
require.ErrorIs(t, err, ErrSlashingSignatureFailure)
})
}

View File

@@ -0,0 +1,160 @@
package sync
import (
"context"
"fmt"
"time"
lightClient "github.com/OffchainLabs/prysm/v6/beacon-chain/core/light-client"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/interfaces"
"github.com/OffchainLabs/prysm/v6/monitoring/tracing"
"github.com/OffchainLabs/prysm/v6/monitoring/tracing/trace"
"github.com/OffchainLabs/prysm/v6/time/slots"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/sirupsen/logrus"
)
func (s *Service) validateLightClientOptimisticUpdate(ctx context.Context, pid peer.ID, msg *pubsub.Message) (pubsub.ValidationResult, error) {
// Validation runs on publish (not just subscriptions), so we should approve any message from
// ourselves.
if pid == s.cfg.p2p.PeerID() {
return pubsub.ValidationAccept, nil
}
// Ignore updates while syncing
if s.cfg.initialSync.Syncing() {
return pubsub.ValidationIgnore, nil
}
_, span := trace.StartSpan(ctx, "sync.validateLightClientOptimisticUpdate")
defer span.End()
m, err := s.decodePubsubMessage(msg)
if err != nil {
tracing.AnnotateError(span, err)
return pubsub.ValidationReject, err
}
newUpdate, ok := m.(interfaces.LightClientOptimisticUpdate)
if !ok {
return pubsub.ValidationReject, errWrongMessage
}
attestedHeaderRoot, err := newUpdate.AttestedHeader().Beacon().HashTreeRoot()
if err != nil {
return pubsub.ValidationIgnore, err
}
// [IGNORE] The optimistic_update is received after the block at signature_slot was given enough time
// to propagate through the network -- i.e. validate that one-third of optimistic_update.signature_slot
// has transpired (SECONDS_PER_SLOT / INTERVALS_PER_SLOT seconds after the start of the slot,
// with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance)
earliestValidTime := slots.StartTime(uint64(s.cfg.clock.GenesisTime().Unix()), newUpdate.SignatureSlot()).
Add(time.Second * time.Duration(params.BeaconConfig().SecondsPerSlot/params.BeaconConfig().IntervalsPerSlot)).
Add(-params.BeaconConfig().MaximumGossipClockDisparityDuration())
if s.cfg.clock.Now().Before(earliestValidTime) {
log.Debug("Newly received light client optimistic update ignored. not enough time passed for block to propagate")
return pubsub.ValidationIgnore, nil
}
lastStoredUpdate := s.lcStore.LastOptimisticUpdate()
if lastStoredUpdate != nil {
lastUpdateSlot := lastStoredUpdate.AttestedHeader().Beacon().Slot
newUpdateSlot := newUpdate.AttestedHeader().Beacon().Slot
// [IGNORE] The attested_header.beacon.slot is greater than that of all previously forwarded optimistic_updates
if newUpdateSlot <= lastUpdateSlot {
log.Debug("Newly received light client optimistic update ignored. new update is older than stored update")
return pubsub.ValidationIgnore, nil
}
}
log.WithFields(logrus.Fields{
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
}).Debug("New gossiped light client optimistic update validated.")
msg.ValidatorData = newUpdate.Proto()
return pubsub.ValidationAccept, nil
}
func (s *Service) validateLightClientFinalityUpdate(ctx context.Context, pid peer.ID, msg *pubsub.Message) (pubsub.ValidationResult, error) {
// Validation runs on publish (not just subscriptions), so we should approve any message from
// ourselves.
if pid == s.cfg.p2p.PeerID() {
return pubsub.ValidationAccept, nil
}
// Ignore updates while syncing
if s.cfg.initialSync.Syncing() {
return pubsub.ValidationIgnore, nil
}
_, span := trace.StartSpan(ctx, "sync.validateLightClientFinalityUpdate")
defer span.End()
m, err := s.decodePubsubMessage(msg)
if err != nil {
tracing.AnnotateError(span, err)
return pubsub.ValidationReject, err
}
newUpdate, ok := m.(interfaces.LightClientFinalityUpdate)
if !ok {
return pubsub.ValidationReject, errWrongMessage
}
attestedHeaderRoot, err := newUpdate.AttestedHeader().Beacon().HashTreeRoot()
if err != nil {
return pubsub.ValidationIgnore, err
}
// [IGNORE] The optimistic_update is received after the block at signature_slot was given enough time
// to propagate through the network -- i.e. validate that one-third of optimistic_update.signature_slot
// has transpired (SECONDS_PER_SLOT / INTERVALS_PER_SLOT seconds after the start of the slot,
// with a MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance)
earliestValidTime := slots.StartTime(uint64(s.cfg.clock.GenesisTime().Unix()), newUpdate.SignatureSlot()).
Add(time.Second * time.Duration(params.BeaconConfig().SecondsPerSlot/params.BeaconConfig().IntervalsPerSlot)).
Add(-params.BeaconConfig().MaximumGossipClockDisparityDuration())
if s.cfg.clock.Now().Before(earliestValidTime) {
log.Debug("Newly received light client finality update ignored. not enough time passed for block to propagate")
return pubsub.ValidationIgnore, nil
}
lastStoredUpdate := s.lcStore.LastFinalityUpdate()
if lastStoredUpdate != nil {
lastUpdateSlot := lastStoredUpdate.FinalizedHeader().Beacon().Slot
newUpdateSlot := newUpdate.FinalizedHeader().Beacon().Slot
// [IGNORE] The finalized_header.beacon.slot is greater than that of all previously forwarded finality_updates,
// or it matches the highest previously forwarded slot and also has a sync_aggregate indicating supermajority (> 2/3)
// sync committee participation while the previously forwarded finality_update for that slot did not indicate supermajority
lastUpdateHasSupermajority := lightClient.UpdateHasSupermajority(lastStoredUpdate.SyncAggregate())
newUpdateHasSupermajority := lightClient.UpdateHasSupermajority(newUpdate.SyncAggregate())
if newUpdateSlot < lastUpdateSlot {
log.Debug("Newly received light client finality update ignored. new update is older than stored update")
return pubsub.ValidationIgnore, nil
}
if newUpdateSlot == lastUpdateSlot && (lastUpdateHasSupermajority || !newUpdateHasSupermajority) {
log.WithFields(logrus.Fields{
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
}).Debug("Newly received light client finality update ignored. no supermajority advantage.")
return pubsub.ValidationIgnore, nil
}
}
log.WithFields(logrus.Fields{
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
}).Debug("New gossiped light client finality update validated.")
msg.ValidatorData = newUpdate.Proto()
return pubsub.ValidationAccept, nil
}

View File

@@ -0,0 +1,284 @@
package sync
import (
"bytes"
"context"
"testing"
"time"
mock "github.com/OffchainLabs/prysm/v6/beacon-chain/blockchain/testing"
lightClient "github.com/OffchainLabs/prysm/v6/beacon-chain/core/light-client"
"github.com/OffchainLabs/prysm/v6/beacon-chain/p2p"
p2ptest "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/testing"
"github.com/OffchainLabs/prysm/v6/beacon-chain/startup"
mockSync "github.com/OffchainLabs/prysm/v6/beacon-chain/sync/initial-sync/testing"
"github.com/OffchainLabs/prysm/v6/config/params"
"github.com/OffchainLabs/prysm/v6/consensus-types/interfaces"
"github.com/OffchainLabs/prysm/v6/runtime/version"
"github.com/OffchainLabs/prysm/v6/testing/require"
"github.com/OffchainLabs/prysm/v6/testing/util"
pubsub "github.com/libp2p/go-libp2p-pubsub"
pb "github.com/libp2p/go-libp2p-pubsub/pb"
)
func TestValidateLightClientOptimisticUpdate_NilMessageOrTopic(t *testing.T) {
params.SetupTestConfigCleanup(t)
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
s := &Service{cfg: &config{p2p: p, initialSync: &mockSync.Sync{}}}
_, err := s.validateLightClientOptimisticUpdate(ctx, "", nil)
require.ErrorIs(t, err, errNilPubsubMessage)
_, err = s.validateLightClientOptimisticUpdate(ctx, "", &pubsub.Message{Message: &pb.Message{}})
require.ErrorIs(t, err, errNilPubsubMessage)
emptyTopic := ""
_, err = s.validateLightClientOptimisticUpdate(ctx, "", &pubsub.Message{Message: &pb.Message{
Topic: &emptyTopic,
}})
require.ErrorIs(t, err, errNilPubsubMessage)
}
func TestValidateLightClientOptimisticUpdate(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig().Copy()
cfg.AltairForkEpoch = 1
cfg.BellatrixForkEpoch = 2
cfg.CapellaForkEpoch = 3
cfg.DenebForkEpoch = 4
cfg.ElectraForkEpoch = 5
cfg.ForkVersionSchedule[[4]byte{1, 0, 0, 0}] = 1
cfg.ForkVersionSchedule[[4]byte{2, 0, 0, 0}] = 2
cfg.ForkVersionSchedule[[4]byte{3, 0, 0, 0}] = 3
cfg.ForkVersionSchedule[[4]byte{4, 0, 0, 0}] = 4
cfg.ForkVersionSchedule[[4]byte{5, 0, 0, 0}] = 5
params.OverrideBeaconConfig(cfg)
secondsPerSlot := int(params.BeaconConfig().SecondsPerSlot)
slotIntervals := int(params.BeaconConfig().IntervalsPerSlot)
slotsPerEpoch := int(params.BeaconConfig().SlotsPerEpoch)
tests := []struct {
name string
genesisDrift int
oldUpdateOptions []util.LightClientOption
newUpdateOptions []util.LightClientOption
expectedResult pubsub.ValidationResult
expectedErr error
}{
{
name: "no previous update",
oldUpdateOptions: nil,
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationAccept,
},
{
name: "not enough time passed",
genesisDrift: -secondsPerSlot / slotIntervals,
oldUpdateOptions: nil,
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationIgnore,
},
{
name: "new update has no age advantage",
oldUpdateOptions: []util.LightClientOption{},
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationIgnore,
},
{
name: "new update is better - younger",
genesisDrift: secondsPerSlot,
oldUpdateOptions: []util.LightClientOption{},
newUpdateOptions: []util.LightClientOption{util.WithIncreasedAttestedSlot(1)},
expectedResult: pubsub.ValidationAccept,
},
}
for _, test := range tests {
for v := 1; v < 6; v++ {
t.Run(test.name+"_"+version.String(v), func(t *testing.T) {
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
// drift back appropriate number of epochs based on fork + 2 slots for signature slot + time for gossip propagation + any extra drift
genesisDrift := v*slotsPerEpoch*secondsPerSlot + 2*secondsPerSlot + secondsPerSlot/slotIntervals + test.genesisDrift
chainService := &mock.ChainService{Genesis: time.Unix(time.Now().Unix()-int64(genesisDrift), 0)}
s := &Service{cfg: &config{p2p: p, initialSync: &mockSync.Sync{}, clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot)}, lcStore: &lightClient.Store{}}
var oldUpdate interfaces.LightClientOptimisticUpdate
var err error
if test.oldUpdateOptions != nil {
l := util.NewTestLightClient(t, v, test.oldUpdateOptions...)
oldUpdate, err = lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock)
require.NoError(t, err)
s.lcStore.SetLastOptimisticUpdate(oldUpdate)
}
l := util.NewTestLightClient(t, v, test.newUpdateOptions...)
newUpdate, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock)
require.NoError(t, err)
buf := new(bytes.Buffer)
_, err = p.Encoding().EncodeGossip(buf, newUpdate)
require.NoError(t, err)
topic := p2p.LightClientOptimisticUpdateTopicFormat
digest, err := s.currentForkDigest()
require.NoError(t, err)
topic = s.addDigestToTopic(topic, digest)
r, err := s.validateLightClientOptimisticUpdate(ctx, "", &pubsub.Message{
Message: &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
}})
if test.expectedErr != nil {
require.ErrorIs(t, err, test.expectedErr)
} else {
require.NoError(t, err)
require.Equal(t, test.expectedResult, r)
}
})
}
}
}
func TestValidateLightClientFinalityUpdate_NilMessageOrTopic(t *testing.T) {
params.SetupTestConfigCleanup(t)
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
s := &Service{cfg: &config{p2p: p, initialSync: &mockSync.Sync{}}}
_, err := s.validateLightClientFinalityUpdate(ctx, "", nil)
require.ErrorIs(t, err, errNilPubsubMessage)
_, err = s.validateLightClientFinalityUpdate(ctx, "", &pubsub.Message{Message: &pb.Message{}})
require.ErrorIs(t, err, errNilPubsubMessage)
emptyTopic := ""
_, err = s.validateLightClientFinalityUpdate(ctx, "", &pubsub.Message{Message: &pb.Message{
Topic: &emptyTopic,
}})
require.ErrorIs(t, err, errNilPubsubMessage)
}
func TestValidateLightClientFinalityUpdate(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig().Copy()
cfg.AltairForkEpoch = 1
cfg.BellatrixForkEpoch = 2
cfg.CapellaForkEpoch = 3
cfg.DenebForkEpoch = 4
cfg.ElectraForkEpoch = 5
cfg.ForkVersionSchedule[[4]byte{1, 0, 0, 0}] = 1
cfg.ForkVersionSchedule[[4]byte{2, 0, 0, 0}] = 2
cfg.ForkVersionSchedule[[4]byte{3, 0, 0, 0}] = 3
cfg.ForkVersionSchedule[[4]byte{4, 0, 0, 0}] = 4
cfg.ForkVersionSchedule[[4]byte{5, 0, 0, 0}] = 5
params.OverrideBeaconConfig(cfg)
secondsPerSlot := int(params.BeaconConfig().SecondsPerSlot)
slotIntervals := int(params.BeaconConfig().IntervalsPerSlot)
slotsPerEpoch := int(params.BeaconConfig().SlotsPerEpoch)
tests := []struct {
name string
genesisDrift int
oldUpdateOptions []util.LightClientOption
newUpdateOptions []util.LightClientOption
expectedResult pubsub.ValidationResult
expectedErr error
}{
{
name: "no previous update",
oldUpdateOptions: nil,
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationAccept,
},
{
name: "not enough time passed",
genesisDrift: -secondsPerSlot / slotIntervals,
oldUpdateOptions: nil,
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationIgnore,
},
{
name: "new update has no advantage",
oldUpdateOptions: []util.LightClientOption{},
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationIgnore,
},
{
name: "new update is better - age",
genesisDrift: secondsPerSlot,
oldUpdateOptions: []util.LightClientOption{},
newUpdateOptions: []util.LightClientOption{util.WithIncreasedFinalizedSlot(1)},
expectedResult: pubsub.ValidationAccept,
},
{
name: "new update is better - supermajority",
oldUpdateOptions: []util.LightClientOption{},
newUpdateOptions: []util.LightClientOption{util.WithSupermajority()},
expectedResult: pubsub.ValidationAccept,
},
{
name: "old update is better - supermajority",
oldUpdateOptions: []util.LightClientOption{util.WithSupermajority()},
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationIgnore,
},
{
name: "old update is better - age",
oldUpdateOptions: []util.LightClientOption{util.WithIncreasedAttestedSlot(1)},
newUpdateOptions: []util.LightClientOption{},
expectedResult: pubsub.ValidationIgnore,
},
}
for _, test := range tests {
for v := 1; v < 6; v++ {
t.Run(test.name+"_"+version.String(v), func(t *testing.T) {
ctx := context.Background()
p := p2ptest.NewTestP2P(t)
// drift back appropriate number of epochs based on fork + 2 slots for signature slot + time for gossip propagation + any extra drift
genesisDrift := v*slotsPerEpoch*secondsPerSlot + 2*secondsPerSlot + secondsPerSlot/slotIntervals + test.genesisDrift
chainService := &mock.ChainService{Genesis: time.Unix(time.Now().Unix()-int64(genesisDrift), 0)}
s := &Service{cfg: &config{p2p: p, initialSync: &mockSync.Sync{}, clock: startup.NewClock(chainService.Genesis, chainService.ValidatorsRoot)}, lcStore: &lightClient.Store{}}
var oldUpdate interfaces.LightClientFinalityUpdate
var err error
if test.oldUpdateOptions != nil {
l := util.NewTestLightClient(t, v, test.oldUpdateOptions...)
oldUpdate, err = lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
require.NoError(t, err)
s.lcStore.SetLastFinalityUpdate(oldUpdate)
}
l := util.NewTestLightClient(t, v, test.newUpdateOptions...)
newUpdate, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State.Slot(), l.State, l.Block, l.AttestedState, l.AttestedBlock, l.FinalizedBlock)
require.NoError(t, err)
buf := new(bytes.Buffer)
_, err = p.Encoding().EncodeGossip(buf, newUpdate)
require.NoError(t, err)
topic := p2p.LightClientFinalityUpdateTopicFormat
digest, err := s.currentForkDigest()
require.NoError(t, err)
topic = s.addDigestToTopic(topic, digest)
r, err := s.validateLightClientFinalityUpdate(ctx, "", &pubsub.Message{
Message: &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
}})
if test.expectedErr != nil {
require.ErrorIs(t, err, test.expectedErr)
} else {
require.NoError(t, err)
require.Equal(t, test.expectedResult, r)
}
})
}
}
}

View File

@@ -0,0 +1,3 @@
### Added
- Add light client p2p validator and subscriber functions.

View File

@@ -0,0 +1,3 @@
### Ignored
- update deprecation message for gRPC to be less scary.

View File

@@ -0,0 +1,2 @@
### Fixed
- Ensure that the `payload_attributes` event has a consistent view of the head state by passing the head block in the event and using stategen to retrieve the corresponding state.

View File

@@ -0,0 +1,2 @@
### Fixed
- extend the payload attribute computation deadline to the beginning of the proposal slot.

View File

@@ -0,0 +1,3 @@
### Added
- Added immediate broadcasting of proposer slashings when equivocating blocks are detected during block processing.
- Added 2 new errors: `HeadStateErr` and `ErrCouldNotVerifyBlockHeader`

View File

@@ -0,0 +1,3 @@
### Added
- PeerDAS: Add needed proto files and corresponding generated code.

View File

@@ -0,0 +1,3 @@
### Fixed
- Fixes our blob sidecar by root request lists for electra.

View File

@@ -0,0 +1,3 @@
### Ignored
- Check for uninitialized duties on `checkDependentRoot`

View File

@@ -0,0 +1,3 @@
### Fixed
- Pass parent context to update duties when dependent roots change

View File

@@ -0,0 +1,3 @@
### Ignored
- Add dependent roots in block events.

View File

@@ -0,0 +1,3 @@
### Changed
- Removed the slot from `UpdateDuties`.

View File

@@ -0,0 +1,3 @@
### Changed
- Updated geth to v1.15.9

View File

@@ -0,0 +1,3 @@
### Added
- Implement pending consolidations Beacon API endpoint.

3
changelog/tt_burger.md Normal file
View File

@@ -0,0 +1,3 @@
### Changed
- Update hoodie bootnodes

3
changelog/tt_ramen.md Normal file
View File

@@ -0,0 +1,3 @@
### Fixed
- Process slots across epoch for payload attribute event.

View File

@@ -236,7 +236,7 @@ var (
// GrpcMaxCallRecvMsgSizeFlag defines the max call message size for GRPC
GrpcMaxCallRecvMsgSizeFlag = &cli.IntFlag{
Name: "grpc-max-msg-size",
Usage: `WARNING: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
Usage: `WARNING: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API..
Integer to define max receive message call size (in bytes).
If serving a public gRPC server, set this to a more reasonable size to avoid
resource exhaustion from large messages.

View File

@@ -32,7 +32,7 @@ var (
// BeaconRPCProviderFlag defines a beacon node RPC endpoint.
BeaconRPCProviderFlag = &cli.StringFlag{
Name: "beacon-rpc-provider",
Usage: `WARNING: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
Usage: `WARNING: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API..
Beacon node RPC provider endpoint.`,
Value: "127.0.0.1:4000",
}
@@ -90,21 +90,21 @@ var (
// GRPCRetriesFlag defines the number of times to retry a failed gRPC request.
GRPCRetriesFlag = &cli.UintFlag{
Name: "grpc-retries",
Usage: `WARNING: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
Usage: `WARNING: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API..
Number of attempts to retry gRPC requests.`,
Value: 5,
}
// GRPCRetryDelayFlag defines the interval to retry a failed gRPC request.
GRPCRetryDelayFlag = &cli.DurationFlag{
Name: "grpc-retry-delay",
Usage: `WARNING: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
Usage: `WARNING: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API..
Amount of time between gRPC retry requests.`,
Value: 1 * time.Second,
}
// GRPCHeadersFlag defines a list of headers to send with all gRPC requests.
GRPCHeadersFlag = &cli.StringFlag{
Name: "grpc-headers",
Usage: `WARNING: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
Usage: `WARNING: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API..
Comma separated list of key value pairs to pass as gRPC headers for all gRPC calls.
Example: --grpc-headers=key=value`,
}

View File

@@ -51,7 +51,7 @@ var (
}
disableGRPCConnectionLogging = &cli.BoolFlag{
Name: "disable-grpc-connection-logging",
Usage: `WARNING: gRPC API will still be supported for some time, most likely until v8 in 2026, but will be eventually removed in favor of REST API.
Usage: `WARNING: The gRPC API will remain the default and fully supported through v8 (expected in 2026) but will be eventually removed in favor of REST API..
Disables displaying logs for newly connected grpc clients.`,
}
disablePeerScorer = &cli.BoolFlag{

View File

@@ -2,5 +2,5 @@ package params
// Re-exports for blackbox testing.
const MainnetDenebForkEpoch = mainnetDenebForkEpoch
var MainnetBeaconConfig = mainnetBeaconConfig
var MainnetBeaconConfig = mainnetBeaconConfig

View File

@@ -12,10 +12,14 @@ func UseHoodiNetworkConfig() {
"enr:-Mq4QLkmuSwbGBUph1r7iHopzRpdqE-gcm5LNZfcE-6T37OCZbRHi22bXZkaqnZ6XdIyEDTelnkmMEQB8w6NbnJUt9GGAZWaowaYh2F0dG5ldHOIABgAAAAAAACEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhNEmfKCEcXVpY4IyyIlzZWNwMjU2azGhA0hGa4jZJZYQAS-z6ZFK-m4GCFnWS8wfjO0bpSQn6hyEiHN5bmNuZXRzAIN0Y3CCIyiDdWRwgiMo",
"enr:-Ku4QLVumWTwyOUVS4ajqq8ZuZz2ik6t3Gtq0Ozxqecj0qNZWpMnudcvTs-4jrlwYRQMQwBS8Pvtmu4ZPP2Lx3i2t7YBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhNEmfKCJc2VjcDI1NmsxoQLdRlI8aCa_ELwTJhVN8k7km7IDc3pYu-FMYBs5_FiigIN1ZHCCIyk",
"enr:-LK4QAYuLujoiaqCAs0-qNWj9oFws1B4iy-Hff1bRB7wpQCYSS-IIMxLWCn7sWloTJzC1SiH8Y7lMQ5I36ynGV1ASj4Eh2F0dG5ldHOIYAAAAAAAAACEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhIbRilSJc2VjcDI1NmsxoQOmI5MlAu3f5WEThAYOqoygpS2wYn0XS5NV2aYq7T0a04N0Y3CCIyiDdWRwgiMo",
"enr:-Ku4QNkWjw5tNzo8DtWqKm7CnDdIq_y7xppD6c1EZSwjB8rMOkSFA1wJPLoKrq5UvA7wcxIotH6Usx3PAugEN2JMncIBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbHuBeJc2VjcDI1NmsxoQP3FwrhFYB60djwRjAoOjttq6du94DtkQuaN99wvgqaIYN1ZHCCIyk",
"enr:-Ku4QIC89sMC0o-irosD4_23lJJ4qCGOvdUz7SmoShWx0k6AaxCFTKviEHa-sa7-EzsiXpDp0qP0xzX6nKdXJX3X-IQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbRilSJc2VjcDI1NmsxoQK_m0f1DzDc9Cjrspm36zuRa7072HSiMGYWLsKiVSbP34N1ZHCCIyk",
"enr:-Ku4QNkWjw5tNzo8DtWqKm7CnDdIq_y7xppD6c1EZSwjB8rMOkSFA1wJPLoKrq5UvA7wcxIotH6Usx3PAugEN2JMncIBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBd9cEGEAAJEP__________gmlkgnY0gmlwhIbHuBeJc2VjcDI1NmsxoQP3FwrhFYB60djwRjAoOjttq6du94DtkQuaN99wvgqaIYN1ZHCCIyk",
"enr:-OS4QMJGE13xEROqvKN1xnnt7U-noc51VXyM6wFMuL9LMhQDfo1p1dF_zFdS4OsnXz_vIYk-nQWnqJMWRDKvkSK6_CwDh2F0dG5ldHOIAAAAADAAAACGY2xpZW502IpMaWdodGhvdXNljDcuMC4wLWJldGEuM4RldGgykNLxmX9gAAkQAAgAAAAAAACCaWSCdjSCaXCEhse4F4RxdWljgiMqiXNlY3AyNTZrMaECef77P8k5l3PC_raLw42OAzdXfxeQ-58BJriNaqiRGJSIc3luY25ldHMAg3RjcIIjKIN1ZHCCIyg",
"enr:-LK4QDwhXMitMbC8xRiNL-XGMhRyMSOnxej-zGifjv9Nm5G8EF285phTU-CAsMHRRefZimNI7eNpAluijMQP7NDC8kEMh2F0dG5ldHOIAAAAAAAABgCEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhAOIT_SJc2VjcDI1NmsxoQMoHWNL4MAvh6YpQeM2SUjhUrLIPsAVPB8nyxbmckC6KIN0Y3CCIyiDdWRwgiMo",
"enr:-LK4QPYl2HnMPQ7b1es6Nf_tFYkyya5bj9IqAKOEj2cmoqVkN8ANbJJJK40MX4kciL7pZszPHw6vLNyeC-O3HUrLQv8Mh2F0dG5ldHOIAAAAAAAAAMCEZXRoMpDS8Zl_YAAJEAAIAAAAAAAAgmlkgnY0gmlwhAMYRG-Jc2VjcDI1NmsxoQPQ35tjr6q1qUqwAnegQmYQyfqxC_6437CObkZneI9n34N0Y3CCIyiDdWRwgiMo",
"enr:-KG4QJk_4IQHQw3DAdKIuGcEauKU8-nmRPPMj_hIQPRHmsFGMPPeOj6_xX09aHCndOzLnOZimVRzNM56_EQWYVbEpJMBgmlkgnY0gmlwhLkvrBODaXA2kP6AAAAAAAAAAhY-__4PR6OJc2VjcDI1NmsxoQPU7g2jQGTz8BYbB2vLTb39S_PrcZAehwMM0b3bWsM5rIN1ZHCCIyiEdWRwNoIjKA",
}
OverrideBeaconNetworkConfig(cfg)
}

View File

@@ -99,6 +99,12 @@ type finalityUpdateAltair struct {
finalityBranch interfaces.LightClientFinalityBranch
}
// NewEmptyFinalityUpdateAltair normally should never be called and NewFinalityUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyFinalityUpdateAltair() interfaces.LightClientFinalityUpdate {
return &finalityUpdateAltair{}
}
func (u *finalityUpdateAltair) IsNil() bool {
return u == nil || u.p == nil
}
@@ -205,6 +211,12 @@ type finalityUpdateCapella struct {
finalityBranch interfaces.LightClientFinalityBranch
}
// NewEmptyFinalityUpdateCapella normally should never be called and NewFinalityUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyFinalityUpdateCapella() interfaces.LightClientFinalityUpdate {
return &finalityUpdateCapella{}
}
func (u *finalityUpdateCapella) IsNil() bool {
return u == nil || u.p == nil
}
@@ -311,6 +323,12 @@ type finalityUpdateDeneb struct {
finalityBranch interfaces.LightClientFinalityBranch
}
// NewEmptyFinalityUpdateDeneb normally should never be called and NewFinalityUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyFinalityUpdateDeneb() interfaces.LightClientFinalityUpdate {
return &finalityUpdateDeneb{}
}
func (u *finalityUpdateDeneb) IsNil() bool {
return u == nil || u.p == nil
}
@@ -417,6 +435,12 @@ type finalityUpdateElectra struct {
finalityBranch interfaces.LightClientFinalityBranchElectra
}
// NewEmptyFinalityUpdateElectra normally should never be called and NewFinalityUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyFinalityUpdateElectra() interfaces.LightClientFinalityUpdate {
return &finalityUpdateElectra{}
}
func (u *finalityUpdateElectra) IsNil() bool {
return u == nil || u.p == nil
}

View File

@@ -78,6 +78,12 @@ type optimisticUpdateAltair struct {
attestedHeader interfaces.LightClientHeader
}
// NewEmptyOptimisticUpdateAltair normally should never be called and NewOptimisticUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyOptimisticUpdateAltair() interfaces.LightClientOptimisticUpdate {
return &optimisticUpdateAltair{}
}
func (u *optimisticUpdateAltair) IsNil() bool {
return u == nil || u.p == nil
}
@@ -156,6 +162,12 @@ type optimisticUpdateCapella struct {
attestedHeader interfaces.LightClientHeader
}
// NewEmptyOptimisticUpdateCapella normally should never be called and NewOptimisticUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyOptimisticUpdateCapella() interfaces.LightClientOptimisticUpdate {
return &optimisticUpdateCapella{}
}
func (u *optimisticUpdateCapella) IsNil() bool {
return u == nil || u.p == nil
}
@@ -234,6 +246,12 @@ type optimisticUpdateDeneb struct {
attestedHeader interfaces.LightClientHeader
}
// NewEmptyOptimisticUpdateDeneb normally should never be called and NewOptimisticUpdateFromUpdate should be used instead.
// This function exists only for scenarios where an empty struct is required.
func NewEmptyOptimisticUpdateDeneb() interfaces.LightClientOptimisticUpdate {
return &optimisticUpdateDeneb{}
}
func (u *optimisticUpdateDeneb) IsNil() bool {
return u == nil || u.p == nil
}

View File

@@ -10,7 +10,6 @@ go_library(
importpath = "github.com/OffchainLabs/prysm/v6/consensus-types/payload-attribute",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/state:go_default_library",
"//config/fieldparams:go_default_library",
"//consensus-types:go_default_library",
"//consensus-types/blocks:go_default_library",

View File

@@ -1,7 +1,6 @@
package payloadattribute
import (
"github.com/OffchainLabs/prysm/v6/beacon-chain/state"
field_params "github.com/OffchainLabs/prysm/v6/config/fieldparams"
"github.com/OffchainLabs/prysm/v6/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v6/consensus-types/interfaces"
@@ -100,10 +99,8 @@ type EventData struct {
ProposerIndex primitives.ValidatorIndex
ProposalSlot primitives.Slot
ParentBlockNumber uint64
ParentBlockRoot []byte
ParentBlockHash []byte
Attributer Attributer
HeadState state.BeaconState
HeadBlock interfaces.ReadOnlySignedBeaconBlock
HeadRoot [field_params.RootLength]byte
}

View File

@@ -427,8 +427,8 @@ def prysm_deps():
go_repository(
name = "com_github_cloudflare_cloudflare_go",
importpath = "github.com/cloudflare/cloudflare-go",
sum = "h1:ErwCYDjFCYppDJlDJ/5WhsSmzegAUe2+K9qgFyQDg3M=",
version = "v0.79.0",
sum = "h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgiM+tyKtf0HUA=",
version = "v0.114.0",
)
go_repository(
name = "com_github_cloudykit_fastprinter",
@@ -555,8 +555,8 @@ def prysm_deps():
go_repository(
name = "com_github_cpuguy83_go_md2man_v2",
importpath = "github.com/cpuguy83/go-md2man/v2",
sum = "h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=",
version = "v2.0.3",
sum = "h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=",
version = "v2.0.5",
)
go_repository(
name = "com_github_crate_crypto_go_ipa",
@@ -772,8 +772,8 @@ def prysm_deps():
patches = [
"//third_party:com_github_ethereum_go_ethereum_secp256k1.patch",
],
sum = "h1:LLb2jCPsbJZcB4INw+E/MgzUX5wlR6SdwXcv09/1ME4=",
version = "v1.15.0",
sum = "h1:bRra1zi+/q+qyXZ6fylZOrlaF8kDdnlTtzNTmNHfX+g=",
version = "v1.15.9",
)
go_repository(
name = "com_github_ethereum_go_verkle",
@@ -1108,8 +1108,8 @@ def prysm_deps():
go_repository(
name = "com_github_goccy_go_json",
importpath = "github.com/goccy/go-json",
sum = "h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=",
version = "v0.10.2",
sum = "h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=",
version = "v0.10.4",
)
go_repository(
name = "com_github_godbus_dbus_v5",
@@ -1410,8 +1410,8 @@ def prysm_deps():
go_repository(
name = "com_github_hashicorp_go_cleanhttp",
importpath = "github.com/hashicorp/go-cleanhttp",
sum = "h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=",
version = "v0.5.2",
sum = "h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=",
version = "v0.5.1",
)
go_repository(
name = "com_github_hashicorp_go_immutable_radix",
@@ -1437,12 +1437,6 @@ def prysm_deps():
sum = "h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw=",
version = "v0.0.1",
)
go_repository(
name = "com_github_hashicorp_go_retryablehttp",
importpath = "github.com/hashicorp/go-retryablehttp",
sum = "h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=",
version = "v0.7.4",
)
go_repository(
name = "com_github_hashicorp_go_rootcerts",
importpath = "github.com/hashicorp/go-rootcerts",
@@ -2830,8 +2824,8 @@ def prysm_deps():
go_repository(
name = "com_github_protolambda_zrnt",
importpath = "github.com/protolambda/zrnt",
sum = "h1:KZ48T+3UhsPXNdtE/5QEvGc9DGjUaRI17nJaoznoIaM=",
version = "v0.32.2",
sum = "h1:qW55rnhZJDnOb3TwFiFRJZi3yTXFrJdGOFQM7vCwYGg=",
version = "v0.34.1",
)
go_repository(
name = "com_github_protolambda_ztyp",
@@ -3393,8 +3387,8 @@ def prysm_deps():
go_repository(
name = "com_github_urfave_cli_v2",
importpath = "github.com/urfave/cli/v2",
sum = "h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=",
version = "v2.27.1",
sum = "h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=",
version = "v2.27.5",
)
go_repository(
name = "com_github_urfave_negroni",
@@ -3534,8 +3528,8 @@ def prysm_deps():
go_repository(
name = "com_github_xrash_smetrics",
importpath = "github.com/xrash/smetrics",
sum = "h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=",
version = "v0.0.0-20201216005158-039620a65673",
sum = "h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=",
version = "v0.0.0-20240521201337-686a1a2994c1",
)
go_repository(
name = "com_github_xtaci_kcp_go",
@@ -4829,8 +4823,8 @@ def prysm_deps():
go_repository(
name = "org_golang_x_time",
importpath = "golang.org/x/time",
sum = "h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=",
version = "v0.5.0",
sum = "h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=",
version = "v0.9.0",
)
go_repository(
name = "org_golang_x_tools",

10
go.mod
View File

@@ -15,7 +15,7 @@ require (
github.com/dustin/go-humanize v1.0.0
github.com/emicklei/dot v0.11.0
github.com/ethereum/c-kzg-4844/v2 v2.1.1
github.com/ethereum/go-ethereum v1.15.0
github.com/ethereum/go-ethereum v1.15.9
github.com/fsnotify/fsnotify v1.6.0
github.com/ghodss/yaml v1.0.0
github.com/go-yaml/yaml v2.1.0+incompatible
@@ -74,7 +74,7 @@ require (
github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e
github.com/trailofbits/go-mutexasserts v0.0.0-20250212181730-4c2b8e9e784b
github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.27.1
github.com/urfave/cli/v2 v2.27.5
github.com/uudashr/gocognit v1.0.5
github.com/wealdtech/go-bytesutil v1.1.1
github.com/wealdtech/go-eth2-util v1.6.3
@@ -125,7 +125,7 @@ require (
github.com/consensys/bavard v0.1.22 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
@@ -249,7 +249,7 @@ require (
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/wealdtech/go-eth2-types/v2 v2.8.2 // indirect
github.com/wlynxg/anet v0.0.4 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
@@ -265,7 +265,7 @@ require (
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/term v0.30.0 // indirect
golang.org/x/text v0.23.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/time v0.9.0 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect

20
go.sum
View File

@@ -172,8 +172,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg=
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM=
github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4=
@@ -239,8 +239,8 @@ github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHE
github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
github.com/ethereum/c-kzg-4844/v2 v2.1.1 h1:KhzBVjmURsfr1+S3k/VE35T02+AW2qU9t9gr4R6YpSo=
github.com/ethereum/c-kzg-4844/v2 v2.1.1/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E=
github.com/ethereum/go-ethereum v1.15.0 h1:LLb2jCPsbJZcB4INw+E/MgzUX5wlR6SdwXcv09/1ME4=
github.com/ethereum/go-ethereum v1.15.0/go.mod h1:4q+4t48P2C03sjqGvTXix5lEOplf5dz4CTosbjt5tGs=
github.com/ethereum/go-ethereum v1.15.9 h1:bRra1zi+/q+qyXZ6fylZOrlaF8kDdnlTtzNTmNHfX+g=
github.com/ethereum/go-ethereum v1.15.9/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0=
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -1048,8 +1048,8 @@ github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4=
github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@@ -1074,8 +1074,8 @@ github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguH
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -1432,8 +1432,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@@ -2,14 +2,13 @@
# Common
##############################################################################
load("@rules_proto//proto:defs.bzl", "proto_library")
##############################################################################
# Go
##############################################################################
# gazelle:ignore
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("//proto:ssz_proto_library.bzl", "ssz_proto_files")
load("//tools:ssz.bzl", "SSZ_DEPS", "ssz_gen_marshal")
@@ -30,8 +29,8 @@ proto_library(
##############################################################################
ssz_gen_marshal(
name = "ssz_generated_files",
go_proto = ":go_proto",
out = "engine.ssz.go",
go_proto = ":go_proto",
includes = [
"//consensus-types/primitives:go_default_library",
],
@@ -42,9 +41,10 @@ ssz_gen_marshal(
"ExecutionPayloadHeaderCapella",
"ExecutionPayloadHeaderDeneb",
"ExecutionPayloadDeneb",
'ExecutionPayloadDenebAndBlobsBundle',
"ExecutionPayloadDenebAndBlobsBundle",
"BlindedBlobsBundle",
"BlobsBundle",
"BlobsBundleV2",
"Withdrawal",
"WithdrawalRequest",
"DepositRequest",
@@ -75,8 +75,10 @@ go_proto_library(
go_library(
name = "go_default_library",
srcs = [
"blobs_bundle.go",
"electra.go",
"execution_engine.go",
"fulu.go",
"json_marshal_unmarshal.go",
":ssz_generated_files", # keep
],
@@ -111,8 +113,9 @@ go_library(
ssz_proto_files(
name = "ssz_proto_files",
srcs = [
"electra.proto",
"execution_engine.proto",
"electra.proto",
"fulu.proto",
],
config = select({
"//conditions:default": "mainnet",
@@ -124,8 +127,8 @@ ssz_proto_files(
go_test(
name = "go_default_test",
srcs = [
"export_test.go",
"execution_engine_fuzz_test.go",
"export_test.go",
"json_marshal_unmarshal_test.go",
],
embed = [":go_default_library"],
@@ -135,10 +138,10 @@ go_test(
"//consensus-types/primitives:go_default_library",
"//encoding/bytesutil:go_default_library",
"//testing/require:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_google_gofuzz//:go_default_library",
"@com_github_holiman_uint256//:go_default_library",
],
)

View File

@@ -0,0 +1,7 @@
package enginev1
type BlobsBundler interface {
GetKzgCommitments() [][]byte
GetProofs() [][]byte
GetBlobs() [][]byte
}

View File

@@ -3222,3 +3222,233 @@ func (b *BlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) {
hh.Merkleize(indx)
return
}
// MarshalSSZ ssz marshals the BlobsBundleV2 object
func (b *BlobsBundleV2) MarshalSSZ() ([]byte, error) {
return ssz.MarshalSSZ(b)
}
// MarshalSSZTo ssz marshals the BlobsBundleV2 object to a target array
func (b *BlobsBundleV2) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
offset := int(12)
// Offset (0) 'KzgCommitments'
dst = ssz.WriteOffset(dst, offset)
offset += len(b.KzgCommitments) * 48
// Offset (1) 'Proofs'
dst = ssz.WriteOffset(dst, offset)
offset += len(b.Proofs) * 48
// Offset (2) 'Blobs'
dst = ssz.WriteOffset(dst, offset)
offset += len(b.Blobs) * 131072
// Field (0) 'KzgCommitments'
if size := len(b.KzgCommitments); size > 4096 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4096)
return
}
for ii := 0; ii < len(b.KzgCommitments); ii++ {
if size := len(b.KzgCommitments[ii]); size != 48 {
err = ssz.ErrBytesLengthFn("--.KzgCommitments[ii]", size, 48)
return
}
dst = append(dst, b.KzgCommitments[ii]...)
}
// Field (1) 'Proofs'
if size := len(b.Proofs); size > 524288 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 524288)
return
}
for ii := 0; ii < len(b.Proofs); ii++ {
if size := len(b.Proofs[ii]); size != 48 {
err = ssz.ErrBytesLengthFn("--.Proofs[ii]", size, 48)
return
}
dst = append(dst, b.Proofs[ii]...)
}
// Field (2) 'Blobs'
if size := len(b.Blobs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 4096)
return
}
for ii := 0; ii < len(b.Blobs); ii++ {
if size := len(b.Blobs[ii]); size != 131072 {
err = ssz.ErrBytesLengthFn("--.Blobs[ii]", size, 131072)
return
}
dst = append(dst, b.Blobs[ii]...)
}
return
}
// UnmarshalSSZ ssz unmarshals the BlobsBundleV2 object
func (b *BlobsBundleV2) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
if size < 12 {
return ssz.ErrSize
}
tail := buf
var o0, o1, o2 uint64
// Offset (0) 'KzgCommitments'
if o0 = ssz.ReadOffset(buf[0:4]); o0 > size {
return ssz.ErrOffset
}
if o0 != 12 {
return ssz.ErrInvalidVariableOffset
}
// Offset (1) 'Proofs'
if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 {
return ssz.ErrOffset
}
// Offset (2) 'Blobs'
if o2 = ssz.ReadOffset(buf[8:12]); o2 > size || o1 > o2 {
return ssz.ErrOffset
}
// Field (0) 'KzgCommitments'
{
buf = tail[o0:o1]
num, err := ssz.DivideInt2(len(buf), 48, 4096)
if err != nil {
return err
}
b.KzgCommitments = make([][]byte, num)
for ii := 0; ii < num; ii++ {
if cap(b.KzgCommitments[ii]) == 0 {
b.KzgCommitments[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48]))
}
b.KzgCommitments[ii] = append(b.KzgCommitments[ii], buf[ii*48:(ii+1)*48]...)
}
}
// Field (1) 'Proofs'
{
buf = tail[o1:o2]
num, err := ssz.DivideInt2(len(buf), 48, 524288)
if err != nil {
return err
}
b.Proofs = make([][]byte, num)
for ii := 0; ii < num; ii++ {
if cap(b.Proofs[ii]) == 0 {
b.Proofs[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48]))
}
b.Proofs[ii] = append(b.Proofs[ii], buf[ii*48:(ii+1)*48]...)
}
}
// Field (2) 'Blobs'
{
buf = tail[o2:]
num, err := ssz.DivideInt2(len(buf), 131072, 4096)
if err != nil {
return err
}
b.Blobs = make([][]byte, num)
for ii := 0; ii < num; ii++ {
if cap(b.Blobs[ii]) == 0 {
b.Blobs[ii] = make([]byte, 0, len(buf[ii*131072:(ii+1)*131072]))
}
b.Blobs[ii] = append(b.Blobs[ii], buf[ii*131072:(ii+1)*131072]...)
}
}
return err
}
// SizeSSZ returns the ssz encoded size in bytes for the BlobsBundleV2 object
func (b *BlobsBundleV2) SizeSSZ() (size int) {
size = 12
// Field (0) 'KzgCommitments'
size += len(b.KzgCommitments) * 48
// Field (1) 'Proofs'
size += len(b.Proofs) * 48
// Field (2) 'Blobs'
size += len(b.Blobs) * 131072
return
}
// HashTreeRoot ssz hashes the BlobsBundleV2 object
func (b *BlobsBundleV2) HashTreeRoot() ([32]byte, error) {
return ssz.HashWithDefaultHasher(b)
}
// HashTreeRootWith ssz hashes the BlobsBundleV2 object with a hasher
func (b *BlobsBundleV2) HashTreeRootWith(hh *ssz.Hasher) (err error) {
indx := hh.Index()
// Field (0) 'KzgCommitments'
{
if size := len(b.KzgCommitments); size > 4096 {
err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4096)
return
}
subIndx := hh.Index()
for _, i := range b.KzgCommitments {
if len(i) != 48 {
err = ssz.ErrBytesLength
return
}
hh.PutBytes(i)
}
numItems := uint64(len(b.KzgCommitments))
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
// Field (1) 'Proofs'
{
if size := len(b.Proofs); size > 524288 {
err = ssz.ErrListTooBigFn("--.Proofs", size, 524288)
return
}
subIndx := hh.Index()
for _, i := range b.Proofs {
if len(i) != 48 {
err = ssz.ErrBytesLength
return
}
hh.PutBytes(i)
}
numItems := uint64(len(b.Proofs))
hh.MerkleizeWithMixin(subIndx, numItems, 524288)
}
// Field (2) 'Blobs'
{
if size := len(b.Blobs); size > 4096 {
err = ssz.ErrListTooBigFn("--.Blobs", size, 4096)
return
}
subIndx := hh.Index()
for _, i := range b.Blobs {
if len(i) != 131072 {
err = ssz.ErrBytesLength
return
}
hh.PutBytes(i)
}
numItems := uint64(len(b.Blobs))
hh.MerkleizeWithMixin(subIndx, numItems, 4096)
}
hh.Merkleize(indx)
return
}

View File

@@ -1705,6 +1705,69 @@ func (x *BlobsBundle) GetBlobs() [][]byte {
return nil
}
type BlobsBundleV2 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"`
Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"524288" ssz-size:"?,48"`
Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4096" ssz-size:"?,131072"`
}
func (x *BlobsBundleV2) Reset() {
*x = BlobsBundleV2{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BlobsBundleV2) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BlobsBundleV2) ProtoMessage() {}
func (x *BlobsBundleV2) ProtoReflect() protoreflect.Message {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BlobsBundleV2.ProtoReflect.Descriptor instead.
func (*BlobsBundleV2) Descriptor() ([]byte, []int) {
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16}
}
func (x *BlobsBundleV2) GetKzgCommitments() [][]byte {
if x != nil {
return x.KzgCommitments
}
return nil
}
func (x *BlobsBundleV2) GetProofs() [][]byte {
if x != nil {
return x.Proofs
}
return nil
}
func (x *BlobsBundleV2) GetBlobs() [][]byte {
if x != nil {
return x.Blobs
}
return nil
}
type Blob struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1716,7 +1779,7 @@ type Blob struct {
func (x *Blob) Reset() {
*x = Blob{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1729,7 +1792,7 @@ func (x *Blob) String() string {
func (*Blob) ProtoMessage() {}
func (x *Blob) ProtoReflect() protoreflect.Message {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16]
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1742,7 +1805,7 @@ func (x *Blob) ProtoReflect() protoreflect.Message {
// Deprecated: Use Blob.ProtoReflect.Descriptor instead.
func (*Blob) Descriptor() ([]byte, []int) {
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16}
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17}
}
func (x *Blob) GetData() []byte {
@@ -1764,7 +1827,7 @@ type BlobAndProof struct {
func (x *BlobAndProof) Reset() {
*x = BlobAndProof{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1777,7 +1840,7 @@ func (x *BlobAndProof) String() string {
func (*BlobAndProof) ProtoMessage() {}
func (x *BlobAndProof) ProtoReflect() protoreflect.Message {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17]
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1790,7 +1853,7 @@ func (x *BlobAndProof) ProtoReflect() protoreflect.Message {
// Deprecated: Use BlobAndProof.ProtoReflect.Descriptor instead.
func (*BlobAndProof) Descriptor() ([]byte, []int) {
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17}
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{18}
}
func (x *BlobAndProof) GetBlob() []byte {
@@ -1807,6 +1870,61 @@ func (x *BlobAndProof) GetKzgProof() []byte {
return nil
}
type BlobAndProofV2 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Blob []byte `protobuf:"bytes,1,opt,name=blob,proto3" json:"blob,omitempty" ssz-size:"131072"`
KzgProofs [][]byte `protobuf:"bytes,2,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"524288" ssz-size:"48"`
}
func (x *BlobAndProofV2) Reset() {
*x = BlobAndProofV2{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BlobAndProofV2) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BlobAndProofV2) ProtoMessage() {}
func (x *BlobAndProofV2) ProtoReflect() protoreflect.Message {
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BlobAndProofV2.ProtoReflect.Descriptor instead.
func (*BlobAndProofV2) Descriptor() ([]byte, []int) {
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{19}
}
func (x *BlobAndProofV2) GetBlob() []byte {
if x != nil {
return x.Blob
}
return nil
}
func (x *BlobAndProofV2) GetKzgProofs() [][]byte {
if x != nil {
return x.KzgProofs
}
return nil
}
var File_proto_engine_v1_execution_engine_proto protoreflect.FileDescriptor
var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{
@@ -2191,24 +2309,41 @@ var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{
0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33,
0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x05, 0x62, 0x6c,
0x6f, 0x62, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1e, 0x0a, 0x04, 0x64,
0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31,
0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x53, 0x0a, 0x0c, 0x42,
0x6c, 0x6f, 0x62, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1e, 0x0a, 0x04, 0x62,
0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31,
0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, 0x23, 0x0a, 0x09, 0x6b,
0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06,
0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x08, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66,
0x42, 0x95, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x14, 0x45, 0x78, 0x65,
0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69,
0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x76, 0x31, 0xaa, 0x02,
0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65,
0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45,
0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6f, 0x62, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e,
0x64, 0x6c, 0x65, 0x56, 0x32, 0x12, 0x39, 0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d,
0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10,
0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36,
0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73,
0x12, 0x2a, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c,
0x42, 0x12, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x06, 0x35, 0x32,
0x34, 0x32, 0x38, 0x38, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05,
0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18,
0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39,
0x36, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x62,
0x12, 0x1e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a,
0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
0x22, 0x53, 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x62, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66,
0x12, 0x1e, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a,
0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62,
0x12, 0x23, 0x0a, 0x09, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x08, 0x6b, 0x7a, 0x67,
0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x61, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x62, 0x41, 0x6e, 0x64,
0x50, 0x72, 0x6f, 0x6f, 0x66, 0x56, 0x32, 0x12, 0x1e, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37,
0x32, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, 0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67, 0x5f, 0x70,
0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18,
0x02, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x06, 0x35, 0x32, 0x34, 0x32, 0x38, 0x38, 0x52, 0x09, 0x6b,
0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x42, 0x95, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65,
0x2e, 0x76, 0x31, 0x42, 0x14, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e,
0x67, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,
0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e,
0x67, 0x69, 0x6e, 0x65, 0x76, 0x31, 0xaa, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x45, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -2224,7 +2359,7 @@ func file_proto_engine_v1_execution_engine_proto_rawDescGZIP() []byte {
}
var file_proto_engine_v1_execution_engine_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{
(PayloadStatus_Status)(0), // 0: ethereum.engine.v1.PayloadStatus.Status
(*ExecutionPayload)(nil), // 1: ethereum.engine.v1.ExecutionPayload
@@ -2243,8 +2378,10 @@ var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{
(*ForkchoiceState)(nil), // 14: ethereum.engine.v1.ForkchoiceState
(*Withdrawal)(nil), // 15: ethereum.engine.v1.Withdrawal
(*BlobsBundle)(nil), // 16: ethereum.engine.v1.BlobsBundle
(*Blob)(nil), // 17: ethereum.engine.v1.Blob
(*BlobAndProof)(nil), // 18: ethereum.engine.v1.BlobAndProof
(*BlobsBundleV2)(nil), // 17: ethereum.engine.v1.BlobsBundleV2
(*Blob)(nil), // 18: ethereum.engine.v1.Blob
(*BlobAndProof)(nil), // 19: ethereum.engine.v1.BlobAndProof
(*BlobAndProofV2)(nil), // 20: ethereum.engine.v1.BlobAndProofV2
}
var file_proto_engine_v1_execution_engine_proto_depIdxs = []int32{
15, // 0: ethereum.engine.v1.ExecutionPayloadCapella.withdrawals:type_name -> ethereum.engine.v1.Withdrawal
@@ -2463,7 +2600,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
}
}
file_proto_engine_v1_execution_engine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Blob); i {
switch v := v.(*BlobsBundleV2); i {
case 0:
return &v.state
case 1:
@@ -2475,6 +2612,18 @@ func file_proto_engine_v1_execution_engine_proto_init() {
}
}
file_proto_engine_v1_execution_engine_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Blob); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_engine_v1_execution_engine_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BlobAndProof); i {
case 0:
return &v.state
@@ -2486,6 +2635,18 @@ func file_proto_engine_v1_execution_engine_proto_init() {
return nil
}
}
file_proto_engine_v1_execution_engine_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BlobAndProofV2); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -2493,7 +2654,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_engine_v1_execution_engine_proto_rawDesc,
NumEnums: 1,
NumMessages: 18,
NumMessages: 20,
NumExtensions: 0,
NumServices: 0,
},

View File

@@ -227,8 +227,8 @@ message Withdrawal {
}
// BlobsBundle is retrieved through engine-api from the execution layer client.
// It consists of the necessary components for constructing a blobs sidecar
// object to gossip through p2p.
// It consists of the necessary components for constructing blob sidecars
// objects to gossip through p2p.
message BlobsBundle {
// The KZG commitments of the blobs.
repeated bytes kzg_commitments = 1 [
@@ -249,13 +249,45 @@ message BlobsBundle {
];
}
// BlobsBundleV2 is retrieved through engine-api from the execution layer client.
// It consists of the necessary components for constructing data column sidecars
// objects to gossip through p2p.
// It is introduced in Fulu network upgrade.
message BlobsBundleV2 {
repeated bytes kzg_commitments = 1 [
(ethereum.eth.ext.ssz_size) = "?,48",
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
repeated bytes proofs = 2 [
(ethereum.eth.ext.ssz_size) = "?,48",
(ethereum.eth.ext.ssz_max) = "max_cell_proofs_length.size" // Changed in EIP-7594
];
repeated bytes blobs = 3 [
(ethereum.eth.ext.ssz_size) = "?,blob.size",
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
}
// Blob contains the data that is to be committed on chain.
message Blob {
// The blob bytes.
bytes data = 1 [ (ethereum.eth.ext.ssz_size) = "blob.size" ];
}
// BlobAndProofV2 consists of the blob and the cell proofs for each cell in the blob.
message BlobAndProof {
bytes blob = 1 [ (ethereum.eth.ext.ssz_size) = "blob.size" ];
bytes kzg_proof = 2 [ (ethereum.eth.ext.ssz_size) = "48" ];
}
// BlobAndProofV2 consists of the blob and the cell proofs for each cell in the blob.
// It is introduced in Fulu network upgrade.
message BlobAndProofV2 {
bytes blob = 1 [ (ethereum.eth.ext.ssz_size) = "blob.size" ];
repeated bytes kzg_proofs = 2 [
(ethereum.eth.ext.ssz_size) = "48",
(ethereum.eth.ext.ssz_max) = "max_cell_proofs_length.size"
];
}

43
proto/engine/v1/fulu.go Normal file
View File

@@ -0,0 +1,43 @@
package enginev1
import (
"github.com/pkg/errors"
)
func (ebe *ExecutionBundleFulu) GetDecodedExecutionRequests() (*ExecutionRequests, error) {
requests := &ExecutionRequests{}
var prevTypeNum *uint8
for i := range ebe.ExecutionRequests {
requestType, requestListInSSZBytes, err := decodeExecutionRequest(ebe.ExecutionRequests[i])
if err != nil {
return nil, err
}
if prevTypeNum != nil && *prevTypeNum >= requestType {
return nil, errors.New("invalid execution request type order or duplicate requests, requests should be in sorted order and unique")
}
prevTypeNum = &requestType
switch requestType {
case DepositRequestType:
drs, err := unmarshalDeposits(requestListInSSZBytes)
if err != nil {
return nil, err
}
requests.Deposits = drs
case WithdrawalRequestType:
wrs, err := unmarshalWithdrawals(requestListInSSZBytes)
if err != nil {
return nil, err
}
requests.Withdrawals = wrs
case ConsolidationRequestType:
crs, err := unmarshalConsolidations(requestListInSSZBytes)
if err != nil {
return nil, err
}
requests.Consolidations = crs
default:
return nil, errors.Errorf("unsupported request type %d", requestType)
}
}
return requests, nil
}

210
proto/engine/v1/fulu.pb.go generated Executable file
View File

@@ -0,0 +1,210 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.33.0
// protoc v3.21.7
// source: proto/engine/v1/fulu.proto
package enginev1
import (
reflect "reflect"
sync "sync"
_ "github.com/OffchainLabs/prysm/v6/proto/eth/ext"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ExecutionBundleFulu struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Payload *ExecutionPayloadDeneb `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
BlobsBundle *BlobsBundleV2 `protobuf:"bytes,3,opt,name=blobs_bundle,json=blobsBundle,proto3" json:"blobs_bundle,omitempty"`
ShouldOverrideBuilder bool `protobuf:"varint,4,opt,name=should_override_builder,json=shouldOverrideBuilder,proto3" json:"should_override_builder,omitempty"`
ExecutionRequests [][]byte `protobuf:"bytes,5,rep,name=execution_requests,json=executionRequests,proto3" json:"execution_requests,omitempty"`
}
func (x *ExecutionBundleFulu) Reset() {
*x = ExecutionBundleFulu{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_engine_v1_fulu_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ExecutionBundleFulu) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ExecutionBundleFulu) ProtoMessage() {}
func (x *ExecutionBundleFulu) ProtoReflect() protoreflect.Message {
mi := &file_proto_engine_v1_fulu_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ExecutionBundleFulu.ProtoReflect.Descriptor instead.
func (*ExecutionBundleFulu) Descriptor() ([]byte, []int) {
return file_proto_engine_v1_fulu_proto_rawDescGZIP(), []int{0}
}
func (x *ExecutionBundleFulu) GetPayload() *ExecutionPayloadDeneb {
if x != nil {
return x.Payload
}
return nil
}
func (x *ExecutionBundleFulu) GetValue() []byte {
if x != nil {
return x.Value
}
return nil
}
func (x *ExecutionBundleFulu) GetBlobsBundle() *BlobsBundleV2 {
if x != nil {
return x.BlobsBundle
}
return nil
}
func (x *ExecutionBundleFulu) GetShouldOverrideBuilder() bool {
if x != nil {
return x.ShouldOverrideBuilder
}
return false
}
func (x *ExecutionBundleFulu) GetExecutionRequests() [][]byte {
if x != nil {
return x.ExecutionRequests
}
return nil
}
var File_proto_engine_v1_fulu_proto protoreflect.FileDescriptor
var file_proto_engine_v1_fulu_proto_rawDesc = []byte{
0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76,
0x31, 0x2f, 0x66, 0x75, 0x6c, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31,
0x1a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f,
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65,
0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x02, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74,
0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x43, 0x0a,
0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x44, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62,
0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x56,
0x32, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36,
0x0a, 0x17, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
0x15, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42,
0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03,
0x28, 0x0c, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x73, 0x42, 0x8e, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31,
0x42, 0x0c, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65,
0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x76, 0x31, 0xaa, 0x02, 0x12, 0x45,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x56,
0x31, 0xca, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x6e, 0x67,
0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proto_engine_v1_fulu_proto_rawDescOnce sync.Once
file_proto_engine_v1_fulu_proto_rawDescData = file_proto_engine_v1_fulu_proto_rawDesc
)
func file_proto_engine_v1_fulu_proto_rawDescGZIP() []byte {
file_proto_engine_v1_fulu_proto_rawDescOnce.Do(func() {
file_proto_engine_v1_fulu_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_engine_v1_fulu_proto_rawDescData)
})
return file_proto_engine_v1_fulu_proto_rawDescData
}
var file_proto_engine_v1_fulu_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_proto_engine_v1_fulu_proto_goTypes = []interface{}{
(*ExecutionBundleFulu)(nil), // 0: ethereum.engine.v1.ExecutionBundleFulu
(*ExecutionPayloadDeneb)(nil), // 1: ethereum.engine.v1.ExecutionPayloadDeneb
(*BlobsBundleV2)(nil), // 2: ethereum.engine.v1.BlobsBundleV2
}
var file_proto_engine_v1_fulu_proto_depIdxs = []int32{
1, // 0: ethereum.engine.v1.ExecutionBundleFulu.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb
2, // 1: ethereum.engine.v1.ExecutionBundleFulu.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundleV2
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proto_engine_v1_fulu_proto_init() }
func file_proto_engine_v1_fulu_proto_init() {
if File_proto_engine_v1_fulu_proto != nil {
return
}
file_proto_engine_v1_execution_engine_proto_init()
if !protoimpl.UnsafeEnabled {
file_proto_engine_v1_fulu_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ExecutionBundleFulu); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_engine_v1_fulu_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_engine_v1_fulu_proto_goTypes,
DependencyIndexes: file_proto_engine_v1_fulu_proto_depIdxs,
MessageInfos: file_proto_engine_v1_fulu_proto_msgTypes,
}.Build()
File_proto_engine_v1_fulu_proto = out.File
file_proto_engine_v1_fulu_proto_rawDesc = nil
file_proto_engine_v1_fulu_proto_goTypes = nil
file_proto_engine_v1_fulu_proto_depIdxs = nil
}

View File

@@ -0,0 +1,21 @@
syntax = "proto3";
package ethereum.engine.v1;
import "proto/eth/ext/options.proto";
import "proto/engine/v1/execution_engine.proto";
option csharp_namespace = "Ethereum.Engine.V1";
option go_package = "github.com/prysmaticlabs/prysm/v5/proto/engine/v1;enginev1";
option java_multiple_files = true;
option java_outer_classname = "ElectraProto";
option java_package = "org.ethereum.engine.v1";
option php_namespace = "Ethereum\\Engine\\v1";
message ExecutionBundleFulu {
ExecutionPayloadDeneb payload = 1;
bytes value = 2;
BlobsBundleV2 blobs_bundle = 3;
bool should_override_builder = 4;
repeated bytes execution_requests = 5;
}

View File

@@ -305,6 +305,14 @@ type GetPayloadV4ResponseJson struct {
ExecutionRequests []hexutil.Bytes `json:"executionRequests"`
}
type GetPayloadV5ResponseJson struct {
ExecutionPayload *ExecutionPayloadDenebJSON `json:"executionPayload"`
BlockValue string `json:"blockValue"`
BlobsBundle *BlobBundleV2JSON `json:"blobsBundle"`
ShouldOverrideBuilder bool `json:"shouldOverrideBuilder"`
ExecutionRequests []hexutil.Bytes `json:"executionRequests"`
}
// ExecutionPayloadBody represents the engine API ExecutionPayloadV1 or ExecutionPayloadV2 type.
type ExecutionPayloadBody struct {
Transactions []hexutil.Bytes `json:"transactions"`
@@ -838,6 +846,20 @@ func (b BlobBundleJSON) ToProto() *BlobsBundle {
}
}
type BlobBundleV2JSON struct {
Commitments []hexutil.Bytes `json:"commitments"`
Proofs []hexutil.Bytes `json:"proofs"`
Blobs []hexutil.Bytes `json:"blobs"`
}
func (b BlobBundleV2JSON) ToProto() *BlobsBundleV2 {
return &BlobsBundleV2{
KzgCommitments: bytesutil.SafeCopy2dHexUtilBytes(b.Commitments),
Proofs: bytesutil.SafeCopy2dHexUtilBytes(b.Proofs),
Blobs: bytesutil.SafeCopy2dHexUtilBytes(b.Blobs),
}
}
type BlobAndProofJson struct {
Blob hexutil.Bytes `json:"blob"`
KzgProof hexutil.Bytes `json:"proof"`
@@ -1256,6 +1278,137 @@ func (e *ExecutionBundleElectra) UnmarshalJSON(enc []byte) error {
return nil
}
func (e *ExecutionBundleFulu) UnmarshalJSON(enc []byte) error {
dec := GetPayloadV5ResponseJson{}
if err := json.Unmarshal(enc, &dec); err != nil {
return err
}
if dec.ExecutionPayload.ParentHash == nil {
return errors.New("missing required field 'parentHash' for ExecutionPayload")
}
if dec.ExecutionPayload.FeeRecipient == nil {
return errors.New("missing required field 'feeRecipient' for ExecutionPayload")
}
if dec.ExecutionPayload.StateRoot == nil {
return errors.New("missing required field 'stateRoot' for ExecutionPayload")
}
if dec.ExecutionPayload.ReceiptsRoot == nil {
return errors.New("missing required field 'receiptsRoot' for ExecutableDataV1")
}
if dec.ExecutionPayload.LogsBloom == nil {
return errors.New("missing required field 'logsBloom' for ExecutionPayload")
}
if dec.ExecutionPayload.PrevRandao == nil {
return errors.New("missing required field 'prevRandao' for ExecutionPayload")
}
if dec.ExecutionPayload.ExtraData == nil {
return errors.New("missing required field 'extraData' for ExecutionPayload")
}
if dec.ExecutionPayload.BlockHash == nil {
return errors.New("missing required field 'blockHash' for ExecutionPayload")
}
if dec.ExecutionPayload.Transactions == nil {
return errors.New("missing required field 'transactions' for ExecutionPayload")
}
if dec.ExecutionPayload.BlockNumber == nil {
return errors.New("missing required field 'blockNumber' for ExecutionPayload")
}
if dec.ExecutionPayload.Timestamp == nil {
return errors.New("missing required field 'timestamp' for ExecutionPayload")
}
if dec.ExecutionPayload.GasUsed == nil {
return errors.New("missing required field 'gasUsed' for ExecutionPayload")
}
if dec.ExecutionPayload.GasLimit == nil {
return errors.New("missing required field 'gasLimit' for ExecutionPayload")
}
if dec.ExecutionPayload.BlobGasUsed == nil {
return errors.New("missing required field 'blobGasUsed' for ExecutionPayload")
}
if dec.ExecutionPayload.ExcessBlobGas == nil {
return errors.New("missing required field 'excessBlobGas' for ExecutionPayload")
}
*e = ExecutionBundleFulu{Payload: &ExecutionPayloadDeneb{}}
e.Payload.ParentHash = dec.ExecutionPayload.ParentHash.Bytes()
e.Payload.FeeRecipient = dec.ExecutionPayload.FeeRecipient.Bytes()
e.Payload.StateRoot = dec.ExecutionPayload.StateRoot.Bytes()
e.Payload.ReceiptsRoot = dec.ExecutionPayload.ReceiptsRoot.Bytes()
e.Payload.LogsBloom = *dec.ExecutionPayload.LogsBloom
e.Payload.PrevRandao = dec.ExecutionPayload.PrevRandao.Bytes()
e.Payload.BlockNumber = uint64(*dec.ExecutionPayload.BlockNumber)
e.Payload.GasLimit = uint64(*dec.ExecutionPayload.GasLimit)
e.Payload.GasUsed = uint64(*dec.ExecutionPayload.GasUsed)
e.Payload.Timestamp = uint64(*dec.ExecutionPayload.Timestamp)
e.Payload.ExtraData = dec.ExecutionPayload.ExtraData
baseFee, err := hexutil.DecodeBig(dec.ExecutionPayload.BaseFeePerGas)
if err != nil {
return err
}
e.Payload.BaseFeePerGas = bytesutil.PadTo(bytesutil.ReverseByteOrder(baseFee.Bytes()), fieldparams.RootLength)
e.Payload.ExcessBlobGas = uint64(*dec.ExecutionPayload.ExcessBlobGas)
e.Payload.BlobGasUsed = uint64(*dec.ExecutionPayload.BlobGasUsed)
e.Payload.BlockHash = dec.ExecutionPayload.BlockHash.Bytes()
transactions := make([][]byte, len(dec.ExecutionPayload.Transactions))
for i, tx := range dec.ExecutionPayload.Transactions {
transactions[i] = tx
}
e.Payload.Transactions = transactions
if dec.ExecutionPayload.Withdrawals == nil {
dec.ExecutionPayload.Withdrawals = make([]*Withdrawal, 0)
}
e.Payload.Withdrawals = dec.ExecutionPayload.Withdrawals
v, err := hexutil.DecodeBig(dec.BlockValue)
if err != nil {
return err
}
e.Value = bytesutil.PadTo(bytesutil.ReverseByteOrder(v.Bytes()), fieldparams.RootLength)
if dec.BlobsBundle == nil {
return nil
}
e.BlobsBundle = &BlobsBundleV2{}
commitments := make([][]byte, len(dec.BlobsBundle.Commitments))
for i, kzg := range dec.BlobsBundle.Commitments {
k := kzg
commitments[i] = bytesutil.PadTo(k[:], fieldparams.BLSPubkeyLength)
}
e.BlobsBundle.KzgCommitments = commitments
proofs := make([][]byte, len(dec.BlobsBundle.Proofs))
for i, proof := range dec.BlobsBundle.Proofs {
p := proof
proofs[i] = bytesutil.PadTo(p[:], fieldparams.BLSPubkeyLength)
}
e.BlobsBundle.Proofs = proofs
blobs := make([][]byte, len(dec.BlobsBundle.Blobs))
for i, blob := range dec.BlobsBundle.Blobs {
b := make([]byte, fieldparams.BlobLength)
copy(b, blob)
blobs[i] = b
}
e.BlobsBundle.Blobs = blobs
e.ShouldOverrideBuilder = dec.ShouldOverrideBuilder
requests := make([][]byte, len(dec.ExecutionRequests))
for i, request := range dec.ExecutionRequests {
r := make([]byte, len(request))
copy(r, request)
requests[i] = r
}
e.ExecutionRequests = requests
return nil
}
// RecastHexutilByteSlice converts a []hexutil.Bytes to a [][]byte
func RecastHexutilByteSlice(h []hexutil.Bytes) [][]byte {
r := make([][]byte, len(h))
@@ -1282,3 +1435,28 @@ func (b *BlobAndProof) UnmarshalJSON(enc []byte) error {
return nil
}
type BlobAndProofV2Json struct {
Blob hexutil.Bytes `json:"blob"`
KzgProofs []hexutil.Bytes `json:"proofs"`
}
func (b *BlobAndProofV2) UnmarshalJSON(enc []byte) error {
var dec *BlobAndProofV2Json
if err := json.Unmarshal(enc, &dec); err != nil {
return err
}
blob := make([]byte, fieldparams.BlobLength)
copy(blob, dec.Blob)
b.Blob = blob
proofs := make([][]byte, len(dec.KzgProofs))
for i, proof := range dec.KzgProofs {
p := proof
proofs[i] = bytesutil.PadTo(p[:], fieldparams.BLSPubkeyLength)
}
b.KzgProofs = proofs
return nil
}

View File

@@ -0,0 +1,36 @@
// Copyright 2024 Offchain Labs.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package ethereum.eth.v1alpha1;
import "proto/eth/ext/options.proto";
import "proto/prysm/v1alpha1/beacon_block.proto";
option csharp_namespace = "Ethereum.Eth.v1alpha1";
option go_package = "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1;eth";
option java_multiple_files = true;
option java_outer_classname = "DataColumnsProto";
option java_package = "org.ethereum.eth.v1alpha1";
option php_namespace = "Ethereum\\Eth\\v1alpha1";
message DataColumnSidecar {
uint64 index = 1;
repeated bytes column = 2 [(ethereum.eth.ext.ssz_size) = "?,bytes_per_cell.size", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
repeated bytes kzg_commitments = 3 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
repeated bytes kzg_proofs = 4 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"];
SignedBeaconBlockHeader signed_block_header = 5;
repeated bytes kzg_commitments_inclusion_proof = 6 [(ethereum.eth.ext.ssz_size) = "kzg_commitments_inclusion_proof_depth.size,32"];
}

View File

@@ -4865,7 +4865,7 @@ type SignedBeaconBlockContentsFulu struct {
unknownFields protoimpl.UnknownFields
Block *SignedBeaconBlockFulu `protobuf:"bytes,1,opt,name=block,proto3" json:"block,omitempty"`
KzgProofs [][]byte `protobuf:"bytes,2,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"`
KzgProofs [][]byte `protobuf:"bytes,2,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"524288" ssz-size:"?,48"`
Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4096" ssz-size:"?,131072"`
}
@@ -4983,7 +4983,7 @@ type BeaconBlockContentsFulu struct {
unknownFields protoimpl.UnknownFields
Block *BeaconBlockElectra `protobuf:"bytes,1,opt,name=block,proto3" json:"block,omitempty"`
KzgProofs [][]byte `protobuf:"bytes,2,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"`
KzgProofs [][]byte `protobuf:"bytes,2,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"524288" ssz-size:"?,48"`
Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4096" ssz-size:"?,131072"`
}
@@ -6598,83 +6598,83 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_rawDesc = []byte{
0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64,
0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x1d, 0x53, 0x69,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xc2, 0x01, 0x0a, 0x1d, 0x53, 0x69,
0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x42, 0x0a, 0x05, 0x62,
0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x75, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12,
0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18,
0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x09, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73,
0x12, 0x2a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42,
0x14, 0x8a, 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18,
0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x7e, 0x0a, 0x15,
0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x3f, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x65, 0x61,
0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52,
0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39,
0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb7, 0x01, 0x0a,
0x17, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6f, 0x6e, 0x74,
0x65, 0x6e, 0x74, 0x73, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x3f, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63,
0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6c, 0x65, 0x63, 0x74,
0x72, 0x61, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67,
0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a,
0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52,
0x09, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x62, 0x6c,
0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x08, 0x3f,
0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52,
0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x1c, 0x53, 0x69, 0x67, 0x6e, 0x65,
0x64, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x47, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x75, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67,
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x83, 0x03, 0x0a, 0x16, 0x42, 0x6c, 0x69, 0x6e, 0x64,
0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c,
0x75, 0x12, 0x58, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42,
0x44, 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d,
0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73,
0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x75, 0x0a, 0x0e, 0x70,
0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20,
0x01, 0x28, 0x04, 0x42, 0x4e, 0x82, 0xb5, 0x18, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x31, 0x0a, 0x0a, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0c, 0x42, 0x12, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18,
0x06, 0x35, 0x32, 0x34, 0x32, 0x38, 0x38, 0x52, 0x09, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f,
0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92,
0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x7e,
0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c,
0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x3f, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42,
0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72,
0x61, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xb9,
0x01, 0x0a, 0x17, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x3f, 0x0a, 0x05, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x45, 0x6c, 0x65,
0x63, 0x74, 0x72, 0x61, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x31, 0x0a, 0x0a, 0x6b,
0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42,
0x12, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x06, 0x35, 0x32, 0x34,
0x32, 0x38, 0x38, 0x52, 0x09, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a,
0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a,
0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34,
0x30, 0x39, 0x36, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x8d, 0x01, 0x0a, 0x1c, 0x53,
0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63,
0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x47, 0x0a, 0x07, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63,
0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x75, 0x6c, 0x75, 0x52, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52,
0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x83, 0x03, 0x0a, 0x16, 0x42,
0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x58, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73,
0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e,
0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74,
0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e,
0x64, 0x65, 0x78, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x6f, 0x6f,
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73,
0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42,
0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f,
0x6f, 0x74, 0x12, 0x48, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64,
0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x6f, 0x64, 0x79, 0x45,
0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x9a, 0x01, 0x0a,
0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63,
0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68,
0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68,
0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12,
0x75, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65,
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4e, 0x82, 0xb5, 0x18, 0x4a, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,
0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x63, 0x6f,
0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72,
0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
0x02, 0x33, 0x32, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12,
0x25, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x73, 0x74, 0x61,
0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x48, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x05,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69,
0x6e, 0x64, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42,
0x6f, 0x64, 0x79, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79,
0x42, 0x9a, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10,
0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f,
0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15,
0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -1188,11 +1188,11 @@ message SignedBeaconBlockContentsFulu {
SignedBeaconBlockFulu block = 1;
repeated bytes kzg_proofs = 2 [
(ethereum.eth.ext.ssz_size) = "?,48",
(ethereum.eth.ext.ssz_max) = "4096"
(ethereum.eth.ext.ssz_max) = "max_cell_proofs_length.size"
];
repeated bytes blobs = 3 [
(ethereum.eth.ext.ssz_size) = "?,blob.size",
(ethereum.eth.ext.ssz_max) = "4096"
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
}
@@ -1208,11 +1208,11 @@ message BeaconBlockContentsFulu {
BeaconBlockElectra block = 1;
repeated bytes kzg_proofs = 2 [
(ethereum.eth.ext.ssz_size) = "?,48",
(ethereum.eth.ext.ssz_max) = "4096"
(ethereum.eth.ext.ssz_max) = "max_cell_proofs_length.size"
];
repeated bytes blobs = 3 [
(ethereum.eth.ext.ssz_size) = "?,blob.size",
(ethereum.eth.ext.ssz_max) = "4096"
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
}
@@ -1245,4 +1245,3 @@ message BlindedBeaconBlockFulu {
// The blinded beacon block body.
BlindedBeaconBlockBodyElectra body = 5;
}

View File

@@ -27,10 +27,10 @@ type DataColumnSidecar struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ColumnIndex uint64 `protobuf:"varint,1,opt,name=column_index,json=columnIndex,proto3" json:"column_index,omitempty"`
DataColumn [][]byte `protobuf:"bytes,2,rep,name=data_column,json=dataColumn,proto3" json:"data_column,omitempty" ssz-max:"4096" ssz-size:"?,2048"`
Index uint64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
Column [][]byte `protobuf:"bytes,2,rep,name=column,proto3" json:"column,omitempty" ssz-max:"4096" ssz-size:"?,2048"`
KzgCommitments [][]byte `protobuf:"bytes,3,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"`
KzgProof [][]byte `protobuf:"bytes,4,rep,name=kzg_proof,json=kzgProof,proto3" json:"kzg_proof,omitempty" ssz-max:"4096" ssz-size:"?,48"`
KzgProofs [][]byte `protobuf:"bytes,4,rep,name=kzg_proofs,json=kzgProofs,proto3" json:"kzg_proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"`
SignedBlockHeader *SignedBeaconBlockHeader `protobuf:"bytes,5,opt,name=signed_block_header,json=signedBlockHeader,proto3" json:"signed_block_header,omitempty"`
KzgCommitmentsInclusionProof [][]byte `protobuf:"bytes,6,rep,name=kzg_commitments_inclusion_proof,json=kzgCommitmentsInclusionProof,proto3" json:"kzg_commitments_inclusion_proof,omitempty" ssz-size:"4,32"`
}
@@ -67,16 +67,16 @@ func (*DataColumnSidecar) Descriptor() ([]byte, []int) {
return file_proto_prysm_v1alpha1_data_columns_proto_rawDescGZIP(), []int{0}
}
func (x *DataColumnSidecar) GetColumnIndex() uint64 {
func (x *DataColumnSidecar) GetIndex() uint64 {
if x != nil {
return x.ColumnIndex
return x.Index
}
return 0
}
func (x *DataColumnSidecar) GetDataColumn() [][]byte {
func (x *DataColumnSidecar) GetColumn() [][]byte {
if x != nil {
return x.DataColumn
return x.Column
}
return nil
}
@@ -88,9 +88,9 @@ func (x *DataColumnSidecar) GetKzgCommitments() [][]byte {
return nil
}
func (x *DataColumnSidecar) GetKzgProof() [][]byte {
func (x *DataColumnSidecar) GetKzgProofs() [][]byte {
if x != nil {
return x.KzgProof
return x.KzgProofs
}
return nil
}
@@ -114,8 +114,8 @@ type DataColumnIdentifier struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
BlockRoot []byte `protobuf:"bytes,1,opt,name=block_root,json=blockRoot,proto3" json:"block_root,omitempty" ssz-size:"32"`
ColumnIndex uint64 `protobuf:"varint,2,opt,name=column_index,json=columnIndex,proto3" json:"column_index,omitempty"`
BlockRoot []byte `protobuf:"bytes,1,opt,name=block_root,json=blockRoot,proto3" json:"block_root,omitempty" ssz-size:"32"`
Index uint64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"`
}
func (x *DataColumnIdentifier) Reset() {
@@ -157,9 +157,9 @@ func (x *DataColumnIdentifier) GetBlockRoot() []byte {
return nil
}
func (x *DataColumnIdentifier) GetColumnIndex() uint64 {
func (x *DataColumnIdentifier) GetIndex() uint64 {
if x != nil {
return x.ColumnIndex
return x.Index
}
return 0
}
@@ -175,48 +175,46 @@ var file_proto_prysm_v1alpha1_data_columns_proto_rawDesc = []byte{
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x86, 0x03, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x43,
0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x12, 0x21, 0x0a, 0x0c,
0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01,
0x28, 0x04, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
0x33, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0c, 0x42, 0x12, 0x8a, 0xb5, 0x18, 0x06, 0x3f, 0x2c, 0x32, 0x30, 0x34, 0x38,
0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x43, 0x6f,
0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x39, 0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf2, 0x02, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x43,
0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05,
0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x12, 0x2a, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0c, 0x42, 0x12, 0x8a, 0xb5, 0x18, 0x06, 0x3f, 0x2c, 0x32, 0x30, 0x34, 0x38, 0x92, 0xb5,
0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x39,
0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34,
0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f,
0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67,
0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a,
0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52,
0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12,
0x2d, 0x0a, 0x09, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03,
0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04,
0x34, 0x30, 0x39, 0x36, 0x52, 0x08, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x5e,
0x0a, 0x13, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68,
0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x11, 0x73, 0x69, 0x67,
0x6e, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4f,
0x0a, 0x1f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
0x73, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f,
0x66, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x34, 0x2c, 0x33,
0x32, 0x52, 0x1c, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
0x73, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22,
0x60, 0x0a, 0x14, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x64, 0x65,
0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x21,
0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x42, 0x9a, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42,
0x10, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74,
0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79,
0x73, 0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02,
0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x09, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x5e, 0x0a, 0x13, 0x73, 0x69,
0x67, 0x6e, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x1f, 0x6b, 0x7a,
0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x69, 0x6e,
0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x06, 0x20,
0x03, 0x28, 0x0c, 0x42, 0x08, 0x8a, 0xb5, 0x18, 0x04, 0x34, 0x2c, 0x33, 0x32, 0x52, 0x1c, 0x6b,
0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x49, 0x6e, 0x63,
0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x53, 0x0a, 0x14, 0x44,
0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
0x69, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f,
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52,
0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78,
0x42, 0x9a, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10,
0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f,
0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
0x6d, 0x2f, 0x76, 0x36, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15,
0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -26,8 +26,8 @@ option java_package = "org.ethereum.eth.v1alpha1";
option php_namespace = "Ethereum\\Eth\\v1alpha1";
message DataColumnSidecar {
uint64 column_index = 1;
repeated bytes data_column = 2 [
uint64 index = 1;
repeated bytes column = 2 [
(ethereum.eth.ext.ssz_size) = "?,bytes_per_cell.size",
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
@@ -35,7 +35,7 @@ message DataColumnSidecar {
(ethereum.eth.ext.ssz_size) = "?,48",
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
repeated bytes kzg_proof = 4 [
repeated bytes kzg_proofs = 4 [
(ethereum.eth.ext.ssz_size) = "?,48",
(ethereum.eth.ext.ssz_max) = "max_blob_commitments.size"
];
@@ -47,5 +47,5 @@ message DataColumnSidecar {
message DataColumnIdentifier {
bytes block_root = 1 [ (ethereum.eth.ext.ssz_size) = "32" ];
uint64 column_index = 2;
uint64 index = 2;
}

Some files were not shown because too many files have changed in this diff Show More