Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix network sharding eclipse attack #1201

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions cmd/node/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,20 @@
Size = 75000
Type = "LRU"

[PublicKeyShardId]
#PublicKeyPeerId represents the main cache used to map Elrond block signing public keys to their associated peer id's.
[PublicKeyPeerId]
Size = 30000
Type = "LRU"

[PublicKeyPeerId]
Size = 30000
#PublicKeyShardId is the fallback cache used to map public keys to the shard they belong.
[PublicKeyShardId]
Size = 100
Type = "LRU"

#PeerIdShardId is the fallback cache used in network sharding to allow direct connection between peer id and shard.
# Used for observers, size should be kept low.
[PeerIdShardId]
Size = 30000
Size = 5
Type = "LRU"

[Address]
Expand Down
2 changes: 1 addition & 1 deletion integrationTests/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type BlockProcessorInitializer interface {

// NetworkShardingUpdater defines the updating methods used by the network sharding component
type NetworkShardingUpdater interface {
ByID(pid p2p.PeerID) (shardId uint32)
GetShardID(pid p2p.PeerID) (shardId uint32)
UpdatePeerIdPublicKey(pid p2p.PeerID, pk []byte)
UpdatePublicKeyShardId(pk []byte, shardId uint32)
UpdatePeerIdShardId(pid p2p.PeerID, shardId uint32)
Expand Down
4 changes: 2 additions & 2 deletions p2p/libp2p/netMessenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ func (netMes *networkMessenger) GetConnectedPeersInfo() *p2p.ConnectedPeersInfo
IntraShardPeers: make([]string, 0),
CrossShardPeers: make([]string, 0),
}
selfShardId := netMes.peerShardResolver.ByID(netMes.ID())
selfShardId := netMes.peerShardResolver.GetShardID(netMes.ID())

for _, p := range peers {
conns := netMes.p2pHost.Network().ConnsToPeer(p)
Expand All @@ -693,7 +693,7 @@ func (netMes *networkMessenger) GetConnectedPeersInfo() *p2p.ConnectedPeersInfo
connString = conns[0].RemoteMultiaddr().String() + "/p2p/" + p.Pretty()
}

shardId := netMes.peerShardResolver.ByID(p2p.PeerID(p))
shardId := netMes.peerShardResolver.GetShardID(p2p.PeerID(p))
switch shardId {
case core.UnknownShardId:
peerInfo.UnknownPeers = append(peerInfo.UnknownPeers, connString)
Expand Down
4 changes: 2 additions & 2 deletions p2p/libp2p/networksharding/listsSharder.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func has(pid peer.ID, list []peer.ID) bool {
//TODO study if we need to hve a dedicated section for metanodes
func (ls *listsSharder) splitPeerIds(peers []peer.ID) (sorting.PeerDistances, sorting.PeerDistances, sorting.PeerDistances) {
ls.mutResolver.RLock()
selfId := ls.peerShardResolver.ByID(p2p.PeerID(ls.selfPeerId))
selfId := ls.peerShardResolver.GetShardID(p2p.PeerID(ls.selfPeerId))
ls.mutResolver.RUnlock()

intraShard := sorting.PeerDistances{}
Expand All @@ -154,7 +154,7 @@ func (ls *listsSharder) splitPeerIds(peers []peer.ID) (sorting.PeerDistances, so
}
pid := p2p.PeerID(p)
ls.mutResolver.RLock()
shardId := ls.peerShardResolver.ByID(pid)
shardId := ls.peerShardResolver.GetShardID(pid)
ls.mutResolver.RUnlock()

switch shardId {
Expand Down
2 changes: 1 addition & 1 deletion p2p/libp2p/networksharding/listsSharder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var crtPid = peer.ID(fmt.Sprintf("%d pid", crtShardId))

func createStringPeersShardResolver() *mock.PeerShardResolverStub {
return &mock.PeerShardResolverStub{
ByIDCalled: func(pid p2p.PeerID) uint32 {
GetShardIDCalled: func(pid p2p.PeerID) uint32 {
strPid := string(pid)
if strings.Contains(strPid, fmt.Sprintf("%d", crtShardId)) {
return crtShardId
Expand Down
2 changes: 1 addition & 1 deletion p2p/libp2p/networksharding/prioBitsSharder.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (pbs *prioBitsSharder) GetShard(id peer.ID) uint32 {
pbs.mutResolver.RLock()
defer pbs.mutResolver.RUnlock()

return pbs.resolver.ByID(p2p.PeerID(id))
return pbs.resolver.GetShardID(p2p.PeerID(id))
}

// Resets distance bits
Expand Down
2 changes: 1 addition & 1 deletion p2p/libp2p/networksharding/prioBitsSharder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type testKadResolver struct {
f func(p2p.PeerID) uint32
}

func (tkr *testKadResolver) ByID(peer p2p.PeerID) uint32 {
func (tkr *testKadResolver) GetShardID(peer p2p.PeerID) uint32 {
return tkr.f(peer)
}

Expand Down
4 changes: 2 additions & 2 deletions p2p/libp2p/unknownPeerShardResolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
type unknownPeerShardResolver struct {
}

// ByID returns the sharding.UnknownShardId value
func (upsr *unknownPeerShardResolver) ByID(_ p2p.PeerID) uint32 {
// GetShardID returns the sharding.UnknownShardId value
func (upsr *unknownPeerShardResolver) GetShardID(_ p2p.PeerID) uint32 {
return core.UnknownShardId
}

Expand Down
4 changes: 2 additions & 2 deletions p2p/libp2p/unknownPeerShardResolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ func TestUnknownPeerShardResolver_IsInterfaceNil(t *testing.T) {
assert.False(t, check.IfNil(upsr))
}

func TestUnknownPeerShardResolver_ByIDShouldReturnUnknownId(t *testing.T) {
func TestUnknownPeerShardResolver_GetShardIDShouldReturnUnknownId(t *testing.T) {
t.Parallel()

upsr := &unknownPeerShardResolver{}

assert.Equal(t, core.UnknownShardId, upsr.ByID(""))
assert.Equal(t, core.UnknownShardId, upsr.GetShardID(""))
}
9 changes: 6 additions & 3 deletions p2p/mock/peerShardResolverStub.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package mock

import "github.com/ElrondNetwork/elrond-go/p2p"

// PeerShardResolverStub -
type PeerShardResolverStub struct {
ByIDCalled func(pid p2p.PeerID) uint32
GetShardIDCalled func(pid p2p.PeerID) uint32
}

func (psrs *PeerShardResolverStub) ByID(pid p2p.PeerID) uint32 {
return psrs.ByIDCalled(pid)
// GetShardID -
func (psrs *PeerShardResolverStub) GetShardID(pid p2p.PeerID) uint32 {
return psrs.GetShardIDCalled(pid)
}

// IsInterfaceNil -
func (psrs *PeerShardResolverStub) IsInterfaceNil() bool {
return psrs == nil
}
4 changes: 2 additions & 2 deletions p2p/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ func MessageOriginatorSeq(msg MessageP2P) string {

// PeerShardResolver is able to resolve the link between the provided PeerID and the shardID
type PeerShardResolver interface {
ByID(pid PeerID) uint32 //ByID get the shard id of the given peer.ID
IsInterfaceNil() bool //IsInterfaceNil returns true if there is no value under the interface
GetShardID(pid PeerID) uint32 //GetShardID get the shard id of the given peer.ID
IsInterfaceNil() bool //IsInterfaceNil returns true if there is no value under the interface
}

// ConnectedPeersInfo represents the DTO structure used to output the metrics for connected peers
Expand Down
37 changes: 35 additions & 2 deletions sharding/networksharding/export_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package networksharding

import "github.com/ElrondNetwork/elrond-go/p2p"
import (
"github.com/ElrondNetwork/elrond-go/p2p"
"github.com/ElrondNetwork/elrond-go/storage"
)

const MaxNumPidsPerPk = maxNumPidsPerPk

func (psm *PeerShardMapper) GetPkFromPidPk(pid p2p.PeerID) []byte {
pk, _ := psm.peerIdPk.Get([]byte(pid))
pk, ok := psm.peerIdPk.Get([]byte(pid))
if !ok {
return nil
}

return pk.([]byte)
}
Expand All @@ -19,3 +27,28 @@ func (psm *PeerShardMapper) GetShardIdFromPidShardId(pid p2p.PeerID) uint32 {

return shard.(uint32)
}

func (psm *PeerShardMapper) GetFromPkPeerId(pk []byte) []p2p.PeerID {
objsPidsQueue, found := psm.pkPeerId.Get(pk)
if !found {
return nil
}

return objsPidsQueue.(*pidQueue).data
}

func (psm *PeerShardMapper) PeerIdPk() storage.Cacher {
return psm.peerIdPk
}

func (psm *PeerShardMapper) PkPeerId() storage.Cacher {
return psm.pkPeerId
}

func (psm *PeerShardMapper) FallbackPkShard() storage.Cacher {
return psm.fallbackPkShard
}

func (psm *PeerShardMapper) FallbackPidShard() storage.Cacher {
return psm.fallbackPidShard
}
Loading