diff --git a/beacon-chain/blockchain/BUILD.bazel b/beacon-chain/blockchain/BUILD.bazel index b087fe9e71..4dd566c6c5 100644 --- a/beacon-chain/blockchain/BUILD.bazel +++ b/beacon-chain/blockchain/BUILD.bazel @@ -163,6 +163,7 @@ go_test( "//beacon-chain/operations/slashings:go_default_library", "//beacon-chain/operations/voluntaryexits:go_default_library", "//beacon-chain/p2p:go_default_library", + "//beacon-chain/p2p/testing:go_default_library", "//beacon-chain/startup:go_default_library", "//beacon-chain/state:go_default_library", "//beacon-chain/state/state-native:go_default_library", diff --git a/beacon-chain/blockchain/process_block_helpers.go b/beacon-chain/blockchain/process_block_helpers.go index 19cc523a83..b603e4c973 100644 --- a/beacon-chain/blockchain/process_block_helpers.go +++ b/beacon-chain/blockchain/process_block_helpers.go @@ -309,6 +309,11 @@ func (s *Service) processLightClientFinalityUpdate( Type: statefeed.LightClientFinalityUpdate, Data: newUpdate, }) + + if err = s.cfg.P2p.BroadcastLightClientFinalityUpdate(ctx, newUpdate); err != nil { + return errors.Wrap(err, "could not broadcast light client finality update") + } + return nil } @@ -358,6 +363,10 @@ func (s *Service) processLightClientOptimisticUpdate(ctx context.Context, signed Data: newUpdate, }) + if err = s.cfg.P2p.BroadcastLightClientOptimisticUpdate(ctx, newUpdate); err != nil { + return errors.Wrap(err, "could not broadcast light client optimistic update") + } + return nil } diff --git a/beacon-chain/blockchain/process_block_test.go b/beacon-chain/blockchain/process_block_test.go index c055fbd403..0894a36e29 100644 --- a/beacon-chain/blockchain/process_block_test.go +++ b/beacon-chain/blockchain/process_block_test.go @@ -24,6 +24,7 @@ import ( doublylinkedtree "github.com/OffchainLabs/prysm/v6/beacon-chain/forkchoice/doubly-linked-tree" forkchoicetypes "github.com/OffchainLabs/prysm/v6/beacon-chain/forkchoice/types" "github.com/OffchainLabs/prysm/v6/beacon-chain/operations/attestations/kv" + mockp2p "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/testing" "github.com/OffchainLabs/prysm/v6/beacon-chain/state" "github.com/OffchainLabs/prysm/v6/config/features" fieldparams "github.com/OffchainLabs/prysm/v6/config/fieldparams" @@ -3309,6 +3310,7 @@ func TestProcessLightClientOptimisticUpdate(t *testing.T) { params.OverrideBeaconConfig(beaconCfg) s, tr := minimalTestService(t) + s.cfg.P2p = &mockp2p.FakeP2P{} ctx := tr.ctx testCases := []struct { @@ -3444,6 +3446,7 @@ func TestProcessLightClientFinalityUpdate(t *testing.T) { params.OverrideBeaconConfig(beaconCfg) s, tr := minimalTestService(t) + s.cfg.P2p = &mockp2p.FakeP2P{} ctx := tr.ctx testCases := []struct { diff --git a/beacon-chain/blockchain/setup_test.go b/beacon-chain/blockchain/setup_test.go index 7ca7e757b7..5b74595cfe 100644 --- a/beacon-chain/blockchain/setup_test.go +++ b/beacon-chain/blockchain/setup_test.go @@ -22,6 +22,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p" "github.com/OffchainLabs/prysm/v6/beacon-chain/startup" "github.com/OffchainLabs/prysm/v6/beacon-chain/state/stategen" + "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/OffchainLabs/prysm/v6/testing/require" "google.golang.org/protobuf/proto" @@ -66,6 +67,16 @@ func (mb *mockBroadcaster) BroadcastBlob(_ context.Context, _ uint64, _ *ethpb.B return nil } +func (mb *mockBroadcaster) BroadcastLightClientOptimisticUpdate(_ context.Context, _ interfaces.LightClientOptimisticUpdate) error { + mb.broadcastCalled = true + return nil +} + +func (mb *mockBroadcaster) BroadcastLightClientFinalityUpdate(_ context.Context, _ interfaces.LightClientFinalityUpdate) error { + mb.broadcastCalled = true + return nil +} + func (mb *mockBroadcaster) BroadcastBLSChanges(_ context.Context, _ []*ethpb.SignedBLSToExecutionChange) { } diff --git a/beacon-chain/p2p/broadcaster.go b/beacon-chain/p2p/broadcaster.go index b984e249a9..bc47f297bd 100644 --- a/beacon-chain/p2p/broadcaster.go +++ b/beacon-chain/p2p/broadcaster.go @@ -285,13 +285,13 @@ func (s *Service) BroadcastLightClientOptimisticUpdate(ctx context.Context, upda return err } - // TODO: should we check if the update is too early or too late to broadcast? - if err := s.broadcastObject(ctx, update, lcOptimisticToTopic(forkDigest)); err != nil { + log.WithError(err).Debug("Failed to broadcast light client optimistic update") err := errors.Wrap(err, "could not publish message") tracing.AnnotateError(span, err) return err } + log.Debug("Successfully broadcast light client optimistic update") return nil } @@ -311,13 +311,13 @@ func (s *Service) BroadcastLightClientFinalityUpdate(ctx context.Context, update return err } - // TODO: should we check if the update is too early or too late to broadcast? - if err := s.broadcastObject(ctx, update, lcFinalityToTopic(forkDigest)); err != nil { + log.WithError(err).Debug("Failed to broadcast light client finality update") err := errors.Wrap(err, "could not publish message") tracing.AnnotateError(span, err) return err } + log.Debug("Successfully broadcast light client finality update") return nil } diff --git a/beacon-chain/p2p/interfaces.go b/beacon-chain/p2p/interfaces.go index 224d720f8e..ee0142a04f 100644 --- a/beacon-chain/p2p/interfaces.go +++ b/beacon-chain/p2p/interfaces.go @@ -5,6 +5,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" + "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1/metadata" "github.com/ethereum/go-ethereum/p2p/enr" @@ -36,6 +37,8 @@ type Broadcaster interface { BroadcastAttestation(ctx context.Context, subnet uint64, att ethpb.Att) error BroadcastSyncCommitteeMessage(ctx context.Context, subnet uint64, sMsg *ethpb.SyncCommitteeMessage) error BroadcastBlob(ctx context.Context, subnet uint64, blob *ethpb.BlobSidecar) error + BroadcastLightClientOptimisticUpdate(ctx context.Context, update interfaces.LightClientOptimisticUpdate) error + BroadcastLightClientFinalityUpdate(ctx context.Context, update interfaces.LightClientFinalityUpdate) error } // SetStreamHandler configures p2p to handle streams of a certain topic ID. diff --git a/beacon-chain/p2p/testing/BUILD.bazel b/beacon-chain/p2p/testing/BUILD.bazel index a64d5b7f8a..665bef06fc 100644 --- a/beacon-chain/p2p/testing/BUILD.bazel +++ b/beacon-chain/p2p/testing/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//beacon-chain/p2p/encoder:go_default_library", "//beacon-chain/p2p/peers:go_default_library", "//beacon-chain/p2p/peers/scorers:go_default_library", + "//consensus-types/interfaces:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/metadata:go_default_library", "//testing/require:go_default_library", diff --git a/beacon-chain/p2p/testing/fuzz_p2p.go b/beacon-chain/p2p/testing/fuzz_p2p.go index a0c03ba61e..5e0b808d34 100644 --- a/beacon-chain/p2p/testing/fuzz_p2p.go +++ b/beacon-chain/p2p/testing/fuzz_p2p.go @@ -5,6 +5,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" + "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1/metadata" "github.com/ethereum/go-ethereum/p2p/enr" @@ -148,6 +149,16 @@ func (*FakeP2P) BroadcastBlob(_ context.Context, _ uint64, _ *ethpb.BlobSidecar) return nil } +// BroadcastLightClientOptimisticUpdate -- fake. +func (*FakeP2P) BroadcastLightClientOptimisticUpdate(_ context.Context, _ interfaces.LightClientOptimisticUpdate) error { + return nil +} + +// BroadcastLightClientFinalityUpdate -- fake. +func (*FakeP2P) BroadcastLightClientFinalityUpdate(_ context.Context, _ interfaces.LightClientFinalityUpdate) error { + return nil +} + // InterceptPeerDial -- fake. func (*FakeP2P) InterceptPeerDial(peer.ID) (allow bool) { return true diff --git a/beacon-chain/p2p/testing/mock_broadcaster.go b/beacon-chain/p2p/testing/mock_broadcaster.go index de6dac01c8..bbf5fc29bc 100644 --- a/beacon-chain/p2p/testing/mock_broadcaster.go +++ b/beacon-chain/p2p/testing/mock_broadcaster.go @@ -5,6 +5,7 @@ import ( "sync" "sync/atomic" + "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "google.golang.org/protobuf/proto" ) @@ -48,6 +49,18 @@ func (m *MockBroadcaster) BroadcastBlob(context.Context, uint64, *ethpb.BlobSide return nil } +// BroadcastLightClientOptimisticUpdate records a broadcast occurred. +func (m *MockBroadcaster) BroadcastLightClientOptimisticUpdate(_ context.Context, _ interfaces.LightClientOptimisticUpdate) error { + m.BroadcastCalled.Store(true) + return nil +} + +// BroadcastLightClientFinalityUpdate records a broadcast occurred. +func (m *MockBroadcaster) BroadcastLightClientFinalityUpdate(_ context.Context, _ interfaces.LightClientFinalityUpdate) error { + m.BroadcastCalled.Store(true) + return nil +} + // NumMessages returns the number of messages broadcasted. func (m *MockBroadcaster) NumMessages() int { m.msgLock.Lock() diff --git a/beacon-chain/p2p/testing/p2p.go b/beacon-chain/p2p/testing/p2p.go index 823c7e7c05..d0bef801f3 100644 --- a/beacon-chain/p2p/testing/p2p.go +++ b/beacon-chain/p2p/testing/p2p.go @@ -13,6 +13,7 @@ import ( "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/encoder" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers" "github.com/OffchainLabs/prysm/v6/beacon-chain/p2p/peers/scorers" + "github.com/OffchainLabs/prysm/v6/consensus-types/interfaces" ethpb "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1" "github.com/OffchainLabs/prysm/v6/proto/prysm/v1alpha1/metadata" "github.com/OffchainLabs/prysm/v6/testing/require" @@ -207,6 +208,18 @@ func (p *TestP2P) BroadcastBlob(context.Context, uint64, *ethpb.BlobSidecar) err return nil } +// BroadcastLightClientOptimisticUpdate broadcasts an optimistic update for mock. +func (p *TestP2P) BroadcastLightClientOptimisticUpdate(_ context.Context, _ interfaces.LightClientOptimisticUpdate) error { + p.BroadcastCalled.Store(true) + return nil +} + +// BroadcastLightClientFinalityUpdate broadcasts a finality update for mock. +func (p *TestP2P) BroadcastLightClientFinalityUpdate(_ context.Context, _ interfaces.LightClientFinalityUpdate) error { + p.BroadcastCalled.Store(true) + return nil +} + // SetStreamHandler for RPC. func (p *TestP2P) SetStreamHandler(topic string, handler network.StreamHandler) { p.BHost.SetStreamHandler(protocol.ID(topic), handler) diff --git a/beacon-chain/sync/subscriber.go b/beacon-chain/sync/subscriber.go index ceab06c359..a44e47ce43 100644 --- a/beacon-chain/sync/subscriber.go +++ b/beacon-chain/sync/subscriber.go @@ -133,6 +133,20 @@ func (s *Service) registerSubscribers(epoch primitives.Epoch, digest [4]byte) { s.activeSyncSubnetIndices, func(currentSlot primitives.Slot) []uint64 { return []uint64{} }, ) + if features.Get().EnableLightClient { + s.subscribe( + p2p.LightClientOptimisticUpdateTopicFormat, + s.validateLightClientOptimisticUpdate, + s.lightClientOptimisticUpdateSubscriber, + digest, + ) + s.subscribe( + p2p.LightClientFinalityUpdateTopicFormat, + s.validateLightClientFinalityUpdate, + s.lightClientFinalityUpdateSubscriber, + digest, + ) + } } // New gossip topic in Capella diff --git a/changelog/bastin_enable-light-client-gossip.md b/changelog/bastin_enable-light-client-gossip.md new file mode 100644 index 0000000000..5ff0e1dce6 --- /dev/null +++ b/changelog/bastin_enable-light-client-gossip.md @@ -0,0 +1,3 @@ +### Added + +- Enable light client gossip for optimistic and finality updates. \ No newline at end of file