package peers import ( "strconv" "testing" "github.com/multiformats/go-multiaddr" crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-node/pkg/core/netmap" loggertest "github.com/nspcc-dev/neofs-node/pkg/util/logger/test" "github.com/nspcc-dev/neofs-node/pkg/util/test" "github.com/stretchr/testify/require" "go.uber.org/zap" ) type testSign struct { ID ID Sign []byte } const debug = false func createNetworkMap(t *testing.T) *netmap.NetMap { var ( Region = []string{"America", "Europe", "Asia"} Country = map[string][]string{ "America": {"USA", "Canada", "Brazil"}, "Europe": {"France", "Germany", "Sweden"}, "Asia": {"Russia", "China", "Korea", "Japan"}, } City = map[string][]string{ "USA": {"Washington", "New-York", "Seattle", "Chicago", "Detroit"}, "Canada": {"Toronto", "Ottawa", "Quebec", "Winnipeg"}, "Brazil": {"Rio-de-Janeiro", "San-Paulo", "Salvador"}, "France": {"Paris", "Lion", "Nice", "Marseille"}, "Germany": {"Berlin", "Munich", "Dortmund", "Hamburg", "Cologne"}, "Sweden": {"Stockholm", "Malmo", "Uppsala"}, "Russia": {"Moscow", "Saint-Petersburg", "Ekaterinburg", "Novosibirsk"}, "China": {"Beijing", "Shanghai", "Shenzhen", "Guangzhou"}, "Korea": {"Seoul", "Busan"}, "Japan": {"Tokyo", "Kyoto", "Yokohama", "Osaka"}, } nm = netmap.New() port int64 = 4000 i = 0 ) for _, r := range Region { for _, co := range Country[r] { for _, ci := range City[co] { addr := "/ip4/127.0.0.1/tcp/" + strconv.FormatInt(port, 10) port++ option := "/Region:" + r + "/Country:" + co + "/City:" + ci pk := crypto.MarshalPublicKey(&test.DecodeKey(i).PublicKey) i++ info := netmap.Info{} info.SetAddress(addr) info.SetPublicKey(pk) info.SetOptions([]string{option}) require.NoError(t, nm.AddNode(info)) } } } return nm } func testMultiAddress(t *testing.T) multiaddr.Multiaddr { addr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/0") require.NoError(t, err) return addr } func TestPeerstore(t *testing.T) { var ( l = loggertest.NewLogger(false) key = test.DecodeKey(1) ) t.Run("it should creates new store", func(t *testing.T) { ps, err := NewStore(StoreParams{ Key: key, Logger: l, Addr: testMultiAddress(t), }) require.NoError(t, err) require.NotNil(t, ps) maddr, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/4000") require.NoError(t, err) expect := crypto.MarshalPublicKey(&key.PublicKey) id, err := ps.AddPeer(maddr, &key.PublicKey, key) require.NoError(t, err) pub, err := ps.GetPublicKey(id) require.NoError(t, err) actual := crypto.MarshalPublicKey(pub) require.Equal(t, expect, actual) addr1, err := ps.GetAddr(id) require.NoError(t, err) require.True(t, maddr.Equal(addr1)) ps.DeletePeer(id) addr1, err = ps.GetAddr(id) require.Nil(t, addr1) require.Error(t, err) }) t.Run("it should creates new store based on netmap", func(t *testing.T) { var nm = createNetworkMap(t) ps, err := NewStore(StoreParams{ Key: key, Logger: l, Addr: testMultiAddress(t), }) require.NoError(t, err) require.NotNil(t, ps) err = ps.Update(nm) require.NoError(t, err) expect := nm.Nodes()[0].PublicKey() id := IDFromBinary(expect) addr, err := ps.GetAddr(id) require.NoError(t, err) require.Equal(t, nm.Nodes()[0].Address(), addr.String()) pub, err := ps.GetPublicKey(id) require.NoError(t, err) actual := crypto.MarshalPublicKey(pub) require.Equal(t, expect, actual) }) t.Run("multiple store's", func(t *testing.T) { var ( count = 10 items = make([]Store, 0, count) data = []byte("Hello world") peers = make([]Peer, 0, count) signs = make([]*testSign, 0, count) ) for i := 0; i < count; i++ { key := test.DecodeKey(i) addr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/0") require.NoError(t, err) peers = append(peers, NewLocalPeer(addr, key)) } for i := 0; i < count; i++ { key, err := peers[i].PrivateKey() require.NoError(t, err) store, err := NewStore(StoreParams{ Addr: peers[i].Address(), Key: key, Logger: zap.L(), }) require.NoError(t, err) items = append(items, store) hash, err := store.Sign(data) require.NoError(t, err) sign := &testSign{ ID: peers[i].ID(), Sign: hash, } signs = append(signs, sign) l.Info("add peer", zap.Stringer("id", peers[i].ID())) } for i := 0; i < count; i++ { signature, err := items[i].Sign(data) require.NoError(t, err) // check the newly generated signature err = items[i].Verify(peers[i].ID(), data, signature) require.NoError(t, err) for j := 0; j < count; j++ { // check previously generated signature addr, pub := peers[j].Address(), peers[j].PublicKey() key, err := peers[j].PrivateKey() require.NoError(t, err) _, err = items[i].AddPeer(addr, pub, key) require.NoError(t, err) err = items[i].Verify(signs[j].ID, data, signs[j].Sign) require.NoError(t, err) } } }) t.Run("Get self address", func(t *testing.T) { addr := testMultiAddress(t) ps, err := NewStore(StoreParams{ Key: key, Logger: l, Addr: addr, }) require.NoError(t, err) require.NotNil(t, ps) selfAddr, err := ps.GetAddr(ps.SelfID()) require.NoError(t, err) require.Equal(t, selfAddr, addr) }) t.Run("Get ID for multi address", func(t *testing.T) { addr := testMultiAddress(t) ps, err := NewStore(StoreParams{ Key: key, Logger: l, Addr: addr, }) require.NoError(t, err) require.NotNil(t, ps) maddr, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/4000") require.NoError(t, err) id, err := ps.AddPeer(maddr, &key.PublicKey, key) require.NoError(t, err) res, err := ps.AddressID(maddr) require.NoError(t, err) require.True(t, id.Equal(res)) maddr2, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/4001") require.NoError(t, err) res, err = ps.AddressID(maddr2) require.EqualError(t, err, errPeerNotFound.Error()) }) }