mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 05:47:59 -05:00
Compare commits
15 Commits
event-stru
...
v6.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
204302a821 | ||
|
|
8a22df902f | ||
|
|
5e3a5b877a | ||
|
|
b69c71d65a | ||
|
|
1298dc3a46 | ||
|
|
3c463d8171 | ||
|
|
0a48fafc71 | ||
|
|
28cd59c9b7 | ||
|
|
efaf6649e7 | ||
|
|
a1c1edf285 | ||
|
|
bde7a57ec9 | ||
|
|
c223957751 | ||
|
|
f7eddedd1d | ||
|
|
7887ebbc4a | ||
|
|
1b13520270 |
@@ -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"`
|
||||
|
||||
@@ -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},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -20,6 +20,7 @@ func testServiceOptsWithDB(t *testing.T) []Option {
|
||||
WithForkChoiceStore(fcs),
|
||||
WithClockSynchronizer(cs),
|
||||
WithStateNotifier(&mock.MockStateNotifier{RecordEvents: true}),
|
||||
WithSyncChecker(&mock.MockSyncChecker{}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -75,4 +75,6 @@ func TestLoggingParameters(_ *testing.T) {
|
||||
logGossipParameters("testing", defaultAttesterSlashingTopicParams())
|
||||
logGossipParameters("testing", defaultProposerSlashingTopicParams())
|
||||
logGossipParameters("testing", defaultVoluntaryExitTopicParams())
|
||||
logGossipParameters("testing", defaultLightClientOptimisticUpdateTopicParams())
|
||||
logGossipParameters("testing", defaultLightClientFinalityUpdateTopicParams())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 ðpb.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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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] = ð.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 := (ð.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)
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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: ¤tSlot,
|
||||
Root: make([]byte, 32),
|
||||
State: st,
|
||||
Block: b,
|
||||
Slot: ¤tSlot,
|
||||
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(ð.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: ¤tSlot,
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
//
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 ðpb.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 ðpb.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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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(
|
||||
ðpb.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)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ðpb.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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ðpb.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.
|
||||
|
||||
@@ -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 --
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
66
beacon-chain/sync/subscriber_light_client.go
Normal file
66
beacon-chain/sync/subscriber_light_client.go
Normal 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
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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 := ðpb.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
|
||||
}
|
||||
|
||||
@@ -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: ðpb.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)
|
||||
})
|
||||
}
|
||||
|
||||
160
beacon-chain/sync/validate_light_client.go
Normal file
160
beacon-chain/sync/validate_light_client.go
Normal 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
|
||||
}
|
||||
284
beacon-chain/sync/validate_light_client_test.go
Normal file
284
beacon-chain/sync/validate_light_client_test.go
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Add light client p2p validator and subscriber functions.
|
||||
3
changelog/james-prysm_update-grpc-deprecation-message.md
Normal file
3
changelog/james-prysm_update-grpc-deprecation-message.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Ignored
|
||||
|
||||
- update deprecation message for gRPC to be less scary.
|
||||
2
changelog/kasey_payload-attributes-stategen.md
Normal file
2
changelog/kasey_payload-attributes-stategen.md
Normal 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.
|
||||
2
changelog/kasey_relax-event-deadline.md
Normal file
2
changelog/kasey_relax-event-deadline.md
Normal file
@@ -0,0 +1,2 @@
|
||||
### Fixed
|
||||
- extend the payload attribute computation deadline to the beginning of the proposal slot.
|
||||
3
changelog/kira_broadcast_slashings.md
Normal file
3
changelog/kira_broadcast_slashings.md
Normal 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`
|
||||
3
changelog/manu-peerdas-proto.md
Normal file
3
changelog/manu-peerdas-proto.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- PeerDAS: Add needed proto files and corresponding generated code.
|
||||
3
changelog/nisdas_fix_p2p_req_ssz.md
Normal file
3
changelog/nisdas_fix_p2p_req_ssz.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Fixes our blob sidecar by root request lists for electra.
|
||||
3
changelog/potuz_nil_checkroot.md
Normal file
3
changelog/potuz_nil_checkroot.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Ignored
|
||||
|
||||
- Check for uninitialized duties on `checkDependentRoot`
|
||||
3
changelog/potuz_pass_parent_context.md
Normal file
3
changelog/potuz_pass_parent_context.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Pass parent context to update duties when dependent roots change
|
||||
3
changelog/potuz_pass_roots_in_block_events.md
Normal file
3
changelog/potuz_pass_roots_in_block_events.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Ignored
|
||||
|
||||
- Add dependent roots in block events.
|
||||
3
changelog/potuz_remove_slot_update_duties.md
Normal file
3
changelog/potuz_remove_slot_update_duties.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Changed
|
||||
|
||||
- Removed the slot from `UpdateDuties`.
|
||||
3
changelog/pvl_geth_update.md
Normal file
3
changelog/pvl_geth_update.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Changed
|
||||
|
||||
- Updated geth to v1.15.9
|
||||
3
changelog/radek_api-pending-consolidations.md
Normal file
3
changelog/radek_api-pending-consolidations.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Added
|
||||
|
||||
- Implement pending consolidations Beacon API endpoint.
|
||||
3
changelog/tt_burger.md
Normal file
3
changelog/tt_burger.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Changed
|
||||
|
||||
- Update hoodie bootnodes
|
||||
3
changelog/tt_ramen.md
Normal file
3
changelog/tt_ramen.md
Normal file
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- Process slots across epoch for payload attribute event.
|
||||
@@ -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.
|
||||
|
||||
@@ -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`,
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -2,5 +2,5 @@ package params
|
||||
|
||||
// Re-exports for blackbox testing.
|
||||
const MainnetDenebForkEpoch = mainnetDenebForkEpoch
|
||||
var MainnetBeaconConfig = mainnetBeaconConfig
|
||||
|
||||
var MainnetBeaconConfig = mainnetBeaconConfig
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
42
deps.bzl
42
deps.bzl
@@ -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
10
go.mod
@@ -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
20
go.sum
@@ -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=
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
7
proto/engine/v1/blobs_bundle.go
Normal file
7
proto/engine/v1/blobs_bundle.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package enginev1
|
||||
|
||||
type BlobsBundler interface {
|
||||
GetKzgCommitments() [][]byte
|
||||
GetProofs() [][]byte
|
||||
GetBlobs() [][]byte
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
219
proto/engine/v1/execution_engine.pb.go
generated
219
proto/engine/v1/execution_engine.pb.go
generated
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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
43
proto/engine/v1/fulu.go
Normal 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
210
proto/engine/v1/fulu.pb.go
generated
Executable 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
|
||||
}
|
||||
21
proto/engine/v1/fulu.proto
Normal file
21
proto/engine/v1/fulu.proto
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
36
proto/eth/v1/data_columns.proto
Normal file
36
proto/eth/v1/data_columns.proto
Normal 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"];
|
||||
}
|
||||
140
proto/prysm/v1alpha1/beacon_block.pb.go
generated
140
proto/prysm/v1alpha1/beacon_block.pb.go
generated
@@ -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 (
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
106
proto/prysm/v1alpha1/data_columns.pb.go
generated
106
proto/prysm/v1alpha1/data_columns.pb.go
generated
@@ -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 (
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user