From 5d60110477a1275f238752d83a9de7d2c5a9f12e Mon Sep 17 00:00:00 2001 From: Aliexe-code Date: Sat, 14 Feb 2026 10:55:11 +0200 Subject: [PATCH 1/2] feat(dot/network): introduce translation shim type for Network and Syncing interfaces Add foundation implementation of translation shim that implements both gossip.Network and gossip.Syncing interfaces. This shim serves as a bridge between the new interface definitions and the existing Gossamer network implementation. The shim is placed in a separate package (dot/network/shim) to avoid circular dependencies between internal/client/network and dot/network packages. Both TranslationShim and syncShim types are provided: - TranslationShim implements gossip.Network with 19 methods - syncShim implements gossip.Syncing[common.Hash, uint] with 4 methods - All methods currently panic as this is a foundational implementation - Future PRs will replace panic implementations with actual translations This implementation addresses issue #4798 and provides the foundation for subsequent network layer refactoring work. Acceptance criteria met: - Implements Network interface - Implements Syncing interface - All methods panic as required for foundation implementation - 100% test coverage with 26 test cases - Passes all linting checks --- dot/network/shim/translation_shim.go | 185 ++++++++++++++++ dot/network/shim/translation_shim_test.go | 250 ++++++++++++++++++++++ 2 files changed, 435 insertions(+) create mode 100644 dot/network/shim/translation_shim.go create mode 100644 dot/network/shim/translation_shim_test.go diff --git a/dot/network/shim/translation_shim.go b/dot/network/shim/translation_shim.go new file mode 100644 index 0000000000..481fa5a866 --- /dev/null +++ b/dot/network/shim/translation_shim.go @@ -0,0 +1,185 @@ +// Copyright 2025 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package shim + +import ( + "github.com/ChainSafe/gossamer/internal/client/network" + gossip "github.com/ChainSafe/gossamer/internal/client/network-gossip" + "github.com/ChainSafe/gossamer/internal/client/network/config" + "github.com/ChainSafe/gossamer/internal/client/network/event" + "github.com/ChainSafe/gossamer/internal/client/network/role" + "github.com/ChainSafe/gossamer/internal/client/network/sync" + "github.com/ChainSafe/gossamer/internal/client/network/types/multiaddr" + peerid "github.com/ChainSafe/gossamer/internal/client/network/types/peer-id" + "github.com/ChainSafe/gossamer/lib/common" +) + +// TranslationShim implements the gossip.Network and gossip.Syncing interfaces. +// This shim type provides a bridge between the new Network and Syncing interfaces +// and the existing Gossamer network implementation. Currently, all methods panic +// as this is a foundation implementation that will be expanded incrementally. +// +// The shim is placed in a separate package to avoid circular dependencies between +// internal/client/network and dot/network packages. +// +// Since both Network and Syncing interfaces have an EventStream method with different +// return types, we cannot implement both in the same type directly. Instead, we provide +// two separate types that can be used together. +type TranslationShim struct{} + +// NewTranslationShim creates a new TranslationShim instance. +func NewTranslationShim() *TranslationShim { + return &TranslationShim{} +} + +// Compile-time interface check for Network +var _ gossip.Network = (*TranslationShim)(nil) + +// Compile-time interface check for Syncing +var _ gossip.Syncing[common.Hash, uint] = (*syncShim)(nil) + +// ===== NetworkPeers Methods ===== + +// SetAuthorizedPeers sets the authorized peers. +func (s *TranslationShim) SetAuthorizedPeers(peers map[peerid.PeerID]struct{}) { + panic("SetAuthorizedPeers: not implemented yet") +} + +// SetAuthorizedOnly sets the authorized_only flag. +func (s *TranslationShim) SetAuthorizedOnly(reservedOnly bool) { + panic("SetAuthorizedOnly: not implemented yet") +} + +// AddKnownAddress adds an address known to a node. +func (s *TranslationShim) AddKnownAddress(peerID peerid.PeerID, addr multiaddr.Multiaddr) { + panic("AddKnownAddress: not implemented yet") +} + +// ReportPeer reports a given peer as either beneficial (+) or costly (-). +func (s *TranslationShim) ReportPeer(peerID peerid.PeerID, costBenefit network.ReputationChange) { + panic("ReportPeer: not implemented yet") +} + +// PeerReputation gets the reputation of a peer. +func (s *TranslationShim) PeerReputation(peerID peerid.PeerID) int32 { + panic("PeerReputation: not implemented yet") +} + +// DisconnectPeer disconnects from a node as soon as possible. +func (s *TranslationShim) DisconnectPeer(who peerid.PeerID, protocol network.ProtocolName) { + panic("DisconnectPeer: not implemented yet") +} + +// AcceptUnreservedPeers connects to unreserved peers. +func (s *TranslationShim) AcceptUnreservedPeers() { + panic("AcceptUnreservedPeers: not implemented yet") +} + +// DenyUnreservedPeers disconnects from unreserved peers. +func (s *TranslationShim) DenyUnreservedPeers() { + panic("DenyUnreservedPeers: not implemented yet") +} + +// AddReservedPeer adds a PeerID and its MultiAddr as reserved. +func (s *TranslationShim) AddReservedPeer(peer config.MultiaddrPeerId) error { + panic("AddReservedPeer: not implemented yet") +} + +// RemoveReservedPeer removes a PeerID from the list of reserved peers. +func (s *TranslationShim) RemoveReservedPeer(peerID peerid.PeerID) { + panic("RemoveReservedPeer: not implemented yet") +} + +// SetReservedPeers sets the reserved set of a protocol. +func (s *TranslationShim) SetReservedPeers( + protocol network.ProtocolName, + peers map[multiaddr.Multiaddr]struct{}, +) error { + panic("SetReservedPeers: not implemented yet") +} + +// AddPeersToReservedSet adds peers to a peer set. +func (s *TranslationShim) AddPeersToReservedSet( + protocol network.ProtocolName, + peers map[multiaddr.Multiaddr]struct{}, +) error { + panic("AddPeersToReservedSet: not implemented yet") +} + +// RemovePeersFromReservedSet removes peers from a peer set. +func (s *TranslationShim) RemovePeersFromReservedSet( + protocol network.ProtocolName, + peers []peerid.PeerID, +) { + panic("RemovePeersFromReservedSet: not implemented yet") +} + +// SyncNumConnected returns the number of connected sync peers. +func (s *TranslationShim) SyncNumConnected() uint { + panic("SyncNumConnected: not implemented yet") +} + +// PeerRole attempts to get peer role from handshake. +func (s *TranslationShim) PeerRole(peerID peerid.PeerID, handshake []byte) *role.ObservedRole { + panic("PeerRole: not implemented yet") +} + +// ReservedPeers returns the list of reserved peers. +func (s *TranslationShim) ReservedPeers() <-chan struct { + Peers []peerid.PeerID + Error error +} { + panic("ReservedPeers: not implemented yet") +} + +// ===== NetworkEventStream Methods ===== + +// EventStream returns a stream containing network events. +func (s *TranslationShim) EventStream(name string) chan event.Event { + panic("EventStream (NetworkEventStream): not implemented yet") +} + +// ===== Network Methods ===== + +// AddSetReserved adds a peer to the reserved set. +func (s *TranslationShim) AddSetReserved(who peerid.PeerID, protocol network.ProtocolName) { + panic("AddSetReserved: not implemented yet") +} + +// RemoveSetReserved removes a peer from the reserved set. +func (s *TranslationShim) RemoveSetReserved(who peerid.PeerID, protocol network.ProtocolName) { + panic("RemoveSetReserved: not implemented yet") +} + +// syncShim implements the gossip.Syncing interface. +// This is a separate type to avoid method name conflicts with Network. +type syncShim struct { + *TranslationShim +} + +// NewSyncShim creates a new syncShim instance. +func NewSyncShim() *syncShim { + return &syncShim{ + TranslationShim: NewTranslationShim(), + } +} + +// ===== SyncEventStream Methods ===== + +// EventStream subscribes to syncing related events. +func (s *syncShim) EventStream(name string) chan sync.SyncEvent { + panic("EventStream (SyncEventStream): not implemented yet") +} + +// ===== NetworkBlock Methods ===== + +// AnnounceBlock announces a block to the network. +func (s *syncShim) AnnounceBlock(hash common.Hash, data []byte) { + panic("AnnounceBlock: not implemented yet") +} + +// NewBestBlockImported informs the network about a new best imported block. +func (s *syncShim) NewBestBlockImported(hash common.Hash, number uint) { + panic("NewBestBlockImported: not implemented yet") +} diff --git a/dot/network/shim/translation_shim_test.go b/dot/network/shim/translation_shim_test.go new file mode 100644 index 0000000000..d1016e871b --- /dev/null +++ b/dot/network/shim/translation_shim_test.go @@ -0,0 +1,250 @@ +// Copyright 2025 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package shim + +import ( + "testing" + + "github.com/ChainSafe/gossamer/internal/client/network" + gossip "github.com/ChainSafe/gossamer/internal/client/network-gossip" + "github.com/ChainSafe/gossamer/internal/client/network/config" + "github.com/ChainSafe/gossamer/internal/client/network/types/multiaddr" + peerid "github.com/ChainSafe/gossamer/internal/client/network/types/peer-id" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/stretchr/testify/require" +) + +// TestTranslationShImplementsInterfaces verifies that TranslationShim +// implements the required interfaces at compile time. +func TestTranslationShImplementsInterfaces(t *testing.T) { + var _ gossip.Network = (*TranslationShim)(nil) + var _ gossip.Syncing[common.Hash, uint] = (*syncShim)(nil) + + require.NotNil(t, NewTranslationShim()) + require.NotNil(t, NewSyncShim()) +} + +// TestNewTranslationShim tests the constructor. +func TestNewTranslationShim(t *testing.T) { + shim := NewTranslationShim() + require.NotNil(t, shim) + require.IsType(t, &TranslationShim{}, shim) +} + +// TestSetAuthorizedPeers tests that SetAuthorizedPeers panics. +func TestSetAuthorizedPeers(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.SetAuthorizedPeers(map[peerid.PeerID]struct{}{}) + }) +} + +// TestSetAuthorizedOnly tests that SetAuthorizedOnly panics. +func TestSetAuthorizedOnly(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.SetAuthorizedOnly(true) + }) + require.Panics(t, func() { + shim.SetAuthorizedOnly(false) + }) +} + +// TestAddKnownAddress tests that AddKnownAddress panics. +func TestAddKnownAddress(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + var addr multiaddr.Multiaddr + + require.Panics(t, func() { + shim.AddKnownAddress(peerID, addr) + }) +} + +// TestReportPeer tests that ReportPeer panics. +func TestReportPeer(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.ReportPeer(peerID, network.ReputationChange{}) + }) +} + +// TestPeerReputation tests that PeerReputation panics. +func TestPeerReputation(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.PeerReputation(peerID) + }) +} + +// TestDisconnectPeer tests that DisconnectPeer panics. +func TestDisconnectPeer(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.DisconnectPeer(peerID, network.ProtocolName("")) + }) +} + +// TestAcceptUnreservedPeers tests that AcceptUnreservedPeers panics. +func TestAcceptUnreservedPeers(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.AcceptUnreservedPeers() + }) +} + +// TestDenyUnreservedPeers tests that DenyUnreservedPeers panics. +func TestDenyUnreservedPeers(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.DenyUnreservedPeers() + }) +} + +// TestAddReservedPeer tests that AddReservedPeer panics. +func TestAddReservedPeer(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.AddReservedPeer(config.MultiaddrPeerId{}) + }) +} + +// TestRemoveReservedPeer tests that RemoveReservedPeer panics. +func TestRemoveReservedPeer(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.RemoveReservedPeer(peerID) + }) +} + +// TestSetReservedPeers tests that SetReservedPeers panics. +func TestSetReservedPeers(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.SetReservedPeers(network.ProtocolName(""), map[multiaddr.Multiaddr]struct{}{}) + }) +} + +// TestAddPeersToReservedSet tests that AddPeersToReservedSet panics. +func TestAddPeersToReservedSet(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.AddPeersToReservedSet(network.ProtocolName(""), map[multiaddr.Multiaddr]struct{}{}) + }) +} + +// TestRemovePeersFromReservedSet tests that RemovePeersFromReservedSet panics. +func TestRemovePeersFromReservedSet(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.RemovePeersFromReservedSet(network.ProtocolName(""), []peerid.PeerID{peerID}) + }) +} + +// TestSyncNumConnected tests that SyncNumConnected panics. +func TestSyncNumConnected(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.SyncNumConnected() + }) +} + +// TestPeerRole tests that PeerRole panics. +func TestPeerRole(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.PeerRole(peerID, []byte{}) + }) +} + +// TestReservedPeers tests that ReservedPeers panics. +func TestReservedPeers(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.ReservedPeers() + }) +} + +// TestEventStreamNetwork tests that EventStream (NetworkEventStream) panics. +func TestEventStreamNetwork(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.EventStream("test") + }) +} + +// TestAddSetReserved tests that AddSetReserved panics. +func TestAddSetReserved(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.AddSetReserved(peerID, network.ProtocolName("")) + }) +} + +// TestRemoveSetReserved tests that RemoveSetReserved panics. +func TestRemoveSetReserved(t *testing.T) { + shim := NewTranslationShim() + peerID := peerid.NewRandomPeerID() + + require.Panics(t, func() { + shim.RemoveSetReserved(peerID, network.ProtocolName("")) + }) +} + +// TestEventStreamSync tests that EventStream (SyncEventStream) panics. +func TestEventStreamSync(t *testing.T) { + shim := NewTranslationShim() + require.Panics(t, func() { + shim.EventStream("test") + }) +} + +// TestNewSyncShim tests the syncShim constructor. +func TestNewSyncShim(t *testing.T) { + syncShim := NewSyncShim() + require.NotNil(t, syncShim) + require.NotNil(t, syncShim.TranslationShim) +} + +// TestEventStreamSyncShim tests that EventStream (SyncEventStream) panics on syncShim. +func TestEventStreamSyncShim(t *testing.T) { + syncShim := NewSyncShim() + require.Panics(t, func() { + syncShim.EventStream("test") + }) +} + +// TestAnnounceBlockSyncShim tests that AnnounceBlock panics on syncShim. +func TestAnnounceBlockSyncShim(t *testing.T) { + syncShim := NewSyncShim() + hash := common.Hash{} + + require.Panics(t, func() { + syncShim.AnnounceBlock(hash, []byte{}) + }) +} + +// TestNewBestBlockImportedSyncShim tests that NewBestBlockImported panics on syncShim. +func TestNewBestBlockImportedSyncShim(t *testing.T) { + syncShim := NewSyncShim() + hash := common.Hash{} + + require.Panics(t, func() { + syncShim.NewBestBlockImported(hash, 0) + }) +} From 946877d8f9671c40cda40a14c70dddcf49ac6a3f Mon Sep 17 00:00:00 2001 From: Aliexe-code Date: Sat, 14 Feb 2026 11:01:39 +0200 Subject: [PATCH 2/2] fix(dot/network/shim): remove duplicate TestEventStreamSync test --- dot/network/shim/translation_shim_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/dot/network/shim/translation_shim_test.go b/dot/network/shim/translation_shim_test.go index d1016e871b..cb2c119b06 100644 --- a/dot/network/shim/translation_shim_test.go +++ b/dot/network/shim/translation_shim_test.go @@ -206,14 +206,6 @@ func TestRemoveSetReserved(t *testing.T) { }) } -// TestEventStreamSync tests that EventStream (SyncEventStream) panics. -func TestEventStreamSync(t *testing.T) { - shim := NewTranslationShim() - require.Panics(t, func() { - shim.EventStream("test") - }) -} - // TestNewSyncShim tests the syncShim constructor. func TestNewSyncShim(t *testing.T) { syncShim := NewSyncShim()