Commit 4eeb6fee authored by Petar Radovic's avatar Petar Radovic Committed by GitHub

Hive with signature + use Bzz address accross Bee (#227)

* Use bzz address accross bee

* Hive with signature
parent 36b3c5f3
...@@ -5,14 +5,12 @@ ...@@ -5,14 +5,12 @@
package addressbook package addressbook
import ( import (
"encoding/json"
"fmt" "fmt"
"strings" "strings"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
ma "github.com/multiformats/go-multiaddr"
) )
const keyPrefix = "addressbook_entry_" const keyPrefix = "addressbook_entry_"
...@@ -22,7 +20,7 @@ var _ Interface = (*store)(nil) ...@@ -22,7 +20,7 @@ var _ Interface = (*store)(nil)
type Interface interface { type Interface interface {
GetPutter GetPutter
Overlays() ([]swarm.Address, error) Overlays() ([]swarm.Address, error)
Multiaddresses() ([]ma.Multiaddr, error) Addresses() ([]bzz.Address, error)
} }
type GetPutter interface { type GetPutter interface {
...@@ -31,11 +29,11 @@ type GetPutter interface { ...@@ -31,11 +29,11 @@ type GetPutter interface {
} }
type Getter interface { type Getter interface {
Get(overlay swarm.Address) (addr ma.Multiaddr, err error) Get(overlay swarm.Address) (addr bzz.Address, err error)
} }
type Putter interface { type Putter interface {
Put(overlay swarm.Address, addr ma.Multiaddr) (err error) Put(overlay swarm.Address, addr bzz.Address) (err error)
} }
type store struct { type store struct {
...@@ -48,22 +46,19 @@ func New(storer storage.StateStorer) Interface { ...@@ -48,22 +46,19 @@ func New(storer storage.StateStorer) Interface {
} }
} }
func (s *store) Get(overlay swarm.Address) (ma.Multiaddr, error) { func (s *store) Get(overlay swarm.Address) (bzz.Address, error) {
key := keyPrefix + overlay.String() key := keyPrefix + overlay.String()
v := PeerEntry{} v := bzz.Address{}
err := s.store.Get(key, &v) err := s.store.Get(key, &v)
if err != nil { if err != nil {
return nil, err return bzz.Address{}, err
} }
return v.Multiaddr, nil return v, nil
} }
func (s *store) Put(overlay swarm.Address, addr ma.Multiaddr) (err error) { func (s *store) Put(overlay swarm.Address, addr bzz.Address) (err error) {
key := keyPrefix + overlay.String() key := keyPrefix + overlay.String()
pe := &PeerEntry{Overlay: overlay, Multiaddr: addr} return s.store.Put(key, &addr)
return s.store.Put(key, pe)
} }
func (s *store) Overlays() (overlays []swarm.Address, err error) { func (s *store) Overlays() (overlays []swarm.Address, err error) {
...@@ -90,63 +85,20 @@ func (s *store) Overlays() (overlays []swarm.Address, err error) { ...@@ -90,63 +85,20 @@ func (s *store) Overlays() (overlays []swarm.Address, err error) {
return overlays, nil return overlays, nil
} }
func (s *store) Multiaddresses() (multis []ma.Multiaddr, err error) { func (s *store) Addresses() (addresses []bzz.Address, err error) {
err = s.store.Iterate(keyPrefix, func(_, value []byte) (stop bool, err error) { err = s.store.Iterate(keyPrefix, func(_, value []byte) (stop bool, err error) {
entry := &PeerEntry{} entry := &bzz.Address{}
err = entry.UnmarshalJSON(value) err = entry.UnmarshalJSON(value)
if err != nil { if err != nil {
return true, err return true, err
} }
multis = append(multis, entry.Multiaddr) addresses = append(addresses, *entry)
return false, nil return false, nil
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
return multis, nil return addresses, nil
}
type PeerEntry struct {
Overlay swarm.Address
Multiaddr ma.Multiaddr
}
func (p *PeerEntry) MarshalJSON() ([]byte, error) {
v := struct {
Overlay string
Multiaddr string
}{
Overlay: p.Overlay.String(),
Multiaddr: p.Multiaddr.String(),
}
return json.Marshal(&v)
}
func (p *PeerEntry) UnmarshalJSON(b []byte) error {
v := struct {
Overlay string
Multiaddr string
}{}
err := json.Unmarshal(b, &v)
if err != nil {
return err
}
a, err := swarm.ParseHexAddress(v.Overlay)
if err != nil {
return err
}
p.Overlay = a
m, err := ma.NewMultiaddr(v.Multiaddr)
if err != nil {
return err
}
p.Multiaddr = m
return nil
} }
...@@ -8,16 +8,18 @@ import ( ...@@ -8,16 +8,18 @@ import (
"testing" "testing"
"github.com/ethersphere/bee/pkg/addressbook" "github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/statestore/mock" "github.com/ethersphere/bee/pkg/statestore/mock"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
type bookFunc func(t *testing.T) (book addressbook.GetPutter) type bookFunc func(t *testing.T) (book addressbook.Interface)
func TestInMem(t *testing.T) { func TestInMem(t *testing.T) {
run(t, func(t *testing.T) addressbook.GetPutter { run(t, func(t *testing.T) addressbook.Interface {
store := mock.NewStateStore() store := mock.NewStateStore()
book := addressbook.New(store) book := addressbook.New(store)
...@@ -27,7 +29,6 @@ func TestInMem(t *testing.T) { ...@@ -27,7 +29,6 @@ func TestInMem(t *testing.T) {
func run(t *testing.T, f bookFunc) { func run(t *testing.T, f bookFunc) {
store := f(t) store := f(t)
addr1 := swarm.NewAddress([]byte{0, 1, 2, 3}) addr1 := swarm.NewAddress([]byte{0, 1, 2, 3})
addr2 := swarm.NewAddress([]byte{0, 1, 2, 4}) addr2 := swarm.NewAddress([]byte{0, 1, 2, 4})
multiaddr, err := ma.NewMultiaddr("/ip4/1.1.1.1") multiaddr, err := ma.NewMultiaddr("/ip4/1.1.1.1")
...@@ -35,7 +36,17 @@ func run(t *testing.T, f bookFunc) { ...@@ -35,7 +36,17 @@ func run(t *testing.T, f bookFunc) {
t.Fatal(err) t.Fatal(err)
} }
err = store.Put(addr1, multiaddr) pk, err := crypto.GenerateSecp256k1Key()
if err != nil {
t.Fatal(err)
}
bzzAddr, err := bzz.NewAddress(crypto.NewDefaultSigner(pk), multiaddr, addr1, 1)
if err != nil {
t.Fatal(err)
}
err = store.Put(addr1, *bzzAddr)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -50,7 +61,25 @@ func run(t *testing.T, f bookFunc) { ...@@ -50,7 +61,25 @@ func run(t *testing.T, f bookFunc) {
t.Fatal("value found in store but should not have been") t.Fatal("value found in store but should not have been")
} }
if multiaddr.String() != v.String() { if !bzzAddr.Equal(&v) {
t.Fatalf("value retrieved from store not equal to original stored address: %v, want %v", v, multiaddr) t.Fatalf("value retrieved from store not equal to original stored address: %v, want %v", v, multiaddr)
} }
overlays, err := store.Overlays()
if err != nil {
t.Fatal(err)
}
if len(overlays) != 1 {
t.Fatalf("expected overlay len %v, got %v", 1, len(overlays))
}
addresses, err := store.Addresses()
if err != nil {
t.Fatal(err)
}
if len(addresses) != 1 {
t.Fatalf("expected addresses len %v, got %v", 1, len(addresses))
}
} }
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bzz
import (
"bytes"
"encoding/base64"
"encoding/binary"
"encoding/json"
"errors"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/swarm"
ma "github.com/multiformats/go-multiaddr"
)
var ErrInvalidAddress = errors.New("invalid address")
// Address represents the bzz address in swarm.
// It consists of a peers underlay (physical) address, overlay (topology) address and signature.
// Signature is used to verify the `Overlay/Underlay` pair, as it is based on `underlay|networkID`, signed with the public key of Overlay address
type Address struct {
Underlay ma.Multiaddr
Overlay swarm.Address
Signature []byte
}
type addressJSON struct {
Overlay string `json:"overlay"`
Underlay string `json:"underlay"`
Signature string `json:"signature"`
}
func NewAddress(signer crypto.Signer, underlay ma.Multiaddr, overlay swarm.Address, networkID uint64) (*Address, error) {
networkIDBytes := make([]byte, 8)
binary.BigEndian.PutUint64(networkIDBytes, networkID)
signature, err := signer.Sign(append(underlay.Bytes(), networkIDBytes...))
if err != nil {
return nil, err
}
return &Address{
Underlay: underlay,
Overlay: overlay,
Signature: signature,
}, nil
}
func ParseAddress(underlay, overlay, signature []byte, networkID uint64) (*Address, error) {
networkIDBytes := make([]byte, 8)
binary.BigEndian.PutUint64(networkIDBytes, networkID)
recoveredPK, err := crypto.Recover(signature, append(underlay, networkIDBytes...))
if err != nil {
return nil, ErrInvalidAddress
}
recoveredOverlay := crypto.NewOverlayAddress(*recoveredPK, networkID)
if !bytes.Equal(recoveredOverlay.Bytes(), overlay) {
return nil, ErrInvalidAddress
}
multiUnderlay, err := ma.NewMultiaddrBytes(underlay)
if err != nil {
return nil, ErrInvalidAddress
}
return &Address{
Underlay: multiUnderlay,
Overlay: swarm.NewAddress(overlay),
Signature: signature,
}, nil
}
func (a *Address) Equal(b *Address) bool {
return a.Overlay.Equal(b.Overlay) && a.Underlay.Equal(b.Underlay) && bytes.Equal(a.Signature, b.Signature)
}
func (p *Address) MarshalJSON() ([]byte, error) {
return json.Marshal(&addressJSON{
Overlay: p.Overlay.String(),
Underlay: p.Underlay.String(),
Signature: base64.StdEncoding.EncodeToString(p.Signature),
})
}
func (p *Address) UnmarshalJSON(b []byte) error {
v := &addressJSON{}
err := json.Unmarshal(b, v)
if err != nil {
return err
}
a, err := swarm.ParseHexAddress(v.Overlay)
if err != nil {
return err
}
p.Overlay = a
m, err := ma.NewMultiaddr(v.Underlay)
if err != nil {
return err
}
p.Underlay = m
p.Signature, err = base64.StdEncoding.DecodeString(v.Signature)
return err
}
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bzz_test
import (
"testing"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto"
ma "github.com/multiformats/go-multiaddr"
)
func TestBzzAddress(t *testing.T) {
node1ma, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/7070/p2p/16Uiu2HAkx8ULY8cTXhdVAcMmLcH9AsTKz6uBQ7DPLKRjMLgBVYkA")
if err != nil {
t.Fatal(err)
}
privateKey1, err := crypto.GenerateSecp256k1Key()
if err != nil {
t.Fatal(err)
}
overlay := crypto.NewOverlayAddress(privateKey1.PublicKey, 3)
signer1 := crypto.NewDefaultSigner(privateKey1)
bzzAddress, err := bzz.NewAddress(signer1, node1ma, overlay, 3)
if err != nil {
t.Fatal(err)
}
bzzAddress2, err := bzz.ParseAddress(node1ma.Bytes(), overlay.Bytes(), bzzAddress.Signature, 3)
if err != nil {
t.Fatal(err)
}
if !bzzAddress.Equal(bzzAddress2) {
t.Fatalf("got %s expected %s", bzzAddress2, bzzAddress)
}
bytes, err := bzzAddress.MarshalJSON()
if err != nil {
t.Fatal(err)
}
var newbzz bzz.Address
if err := newbzz.UnmarshalJSON(bytes); err != nil {
t.Fatal(err)
}
if !newbzz.Equal(bzzAddress) {
t.Fatalf("got %s expected %s", newbzz, bzzAddress)
}
}
...@@ -48,8 +48,8 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer { ...@@ -48,8 +48,8 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer {
P2P: o.P2P, P2P: o.P2P,
Logger: logging.New(ioutil.Discard, 0), Logger: logging.New(ioutil.Discard, 0),
Addressbook: addrbook, Addressbook: addrbook,
TopologyDriver: topologyDriver,
Storer: o.Storer, Storer: o.Storer,
TopologyDriver: topologyDriver,
}) })
ts := httptest.NewServer(s) ts := httptest.NewServer(s)
t.Cleanup(ts.Close) t.Cleanup(ts.Close)
...@@ -65,9 +65,8 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer { ...@@ -65,9 +65,8 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer {
}), }),
} }
return &testServer{ return &testServer{
Client: client, Client: client,
Addressbook: addrbook, Addressbook: addrbook,
TopologyDriver: topologyDriver,
} }
} }
......
...@@ -35,21 +35,6 @@ func (s *server) peerConnectHandler(w http.ResponseWriter, r *http.Request) { ...@@ -35,21 +35,6 @@ func (s *server) peerConnectHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
err = s.Addressbook.Put(address, addr)
if err != nil {
s.Logger.Debugf("debug api: addressbook.put %s: %v", addr, err)
s.Logger.Errorf("unable to persist peer %s", addr)
jsonhttp.InternalServerError(w, err)
return
}
if err := s.TopologyDriver.Connected(r.Context(), address); err != nil {
_ = s.P2P.Disconnect(address)
s.Logger.Debugf("debug api: topologyDriver.Connected %s: %v", addr, err)
s.Logger.Errorf("unable to connect to peer %s", addr)
jsonhttp.InternalServerError(w, err)
return
}
jsonhttp.OK(w, peerConnectResponse{ jsonhttp.OK(w, peerConnectResponse{
Address: address.String(), Address: address.String(),
}) })
......
...@@ -15,9 +15,7 @@ import ( ...@@ -15,9 +15,7 @@ import (
"github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest" "github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest"
"github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/p2p/mock" "github.com/ethersphere/bee/pkg/p2p/mock"
"github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
topmock "github.com/ethersphere/bee/pkg/topology/mock"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
...@@ -40,11 +38,6 @@ func TestConnect(t *testing.T) { ...@@ -40,11 +38,6 @@ func TestConnect(t *testing.T) {
jsonhttptest.ResponseDirect(t, testServer.Client, http.MethodPost, "/connect"+underlay, nil, http.StatusOK, debugapi.PeerConnectResponse{ jsonhttptest.ResponseDirect(t, testServer.Client, http.MethodPost, "/connect"+underlay, nil, http.StatusOK, debugapi.PeerConnectResponse{
Address: overlay.String(), Address: overlay.String(),
}) })
multia, err := testServer.Addressbook.Get(overlay)
if err != nil && errors.Is(err, storage.ErrNotFound) && underlay != multia.String() {
t.Fatalf("found wrong underlay. expected: %s, found: %s", underlay, multia.String())
}
}) })
t.Run("error", func(t *testing.T) { t.Run("error", func(t *testing.T) {
...@@ -60,36 +53,6 @@ func TestConnect(t *testing.T) { ...@@ -60,36 +53,6 @@ func TestConnect(t *testing.T) {
Message: http.StatusText(http.StatusMethodNotAllowed), Message: http.StatusText(http.StatusMethodNotAllowed),
}) })
}) })
t.Run("error - add peer", func(t *testing.T) {
disconnectCalled := false
testServer := newTestServer(t, testServerOptions{
P2P: mock.New(mock.WithConnectFunc(func(ctx context.Context, addr ma.Multiaddr) (swarm.Address, error) {
if addr.String() == errorUnderlay {
return swarm.Address{}, testErr
}
return overlay, nil
}), mock.WithDisconnectFunc(func(addr swarm.Address) error {
disconnectCalled = true
return nil
})),
TopologyOpts: []topmock.Option{topmock.WithAddPeerErr(testErr)},
})
jsonhttptest.ResponseDirect(t, testServer.Client, http.MethodPost, "/connect"+underlay, nil, http.StatusInternalServerError, jsonhttp.StatusResponse{
Code: http.StatusInternalServerError,
Message: testErr.Error(),
})
multia, err := testServer.Addressbook.Get(overlay)
if err != nil && errors.Is(err, storage.ErrNotFound) && underlay != multia.String() {
t.Fatalf("found wrong underlay. expected: %s, found: %s", underlay, multia.String())
}
if !disconnectCalled {
t.Fatalf("disconnect not called.")
}
})
} }
func TestDisconnect(t *testing.T) { func TestDisconnect(t *testing.T) {
...@@ -143,7 +106,6 @@ func TestDisconnect(t *testing.T) { ...@@ -143,7 +106,6 @@ func TestDisconnect(t *testing.T) {
func TestPeer(t *testing.T) { func TestPeer(t *testing.T) {
overlay := swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c") overlay := swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c")
testServer := newTestServer(t, testServerOptions{ testServer := newTestServer(t, testServerOptions{
P2P: mock.New(mock.WithPeersFunc(func() []p2p.Peer { P2P: mock.New(mock.WithPeersFunc(func() []p2p.Peer {
return []p2p.Peer{{Address: overlay}} return []p2p.Peer{{Address: overlay}}
......
...@@ -11,14 +11,13 @@ import ( ...@@ -11,14 +11,13 @@ import (
"time" "time"
"github.com/ethersphere/bee/pkg/addressbook" "github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/hive/pb" "github.com/ethersphere/bee/pkg/hive/pb"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/p2p/protobuf" "github.com/ethersphere/bee/pkg/p2p/protobuf"
"github.com/ethersphere/bee/pkg/storage" "github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
ma "github.com/multiformats/go-multiaddr"
) )
const ( const (
...@@ -26,19 +25,21 @@ const ( ...@@ -26,19 +25,21 @@ const (
protocolVersion = "1.0.0" protocolVersion = "1.0.0"
peersStreamName = "peers" peersStreamName = "peers"
messageTimeout = 1 * time.Minute // maximum allowed time for a message to be read or written. messageTimeout = 1 * time.Minute // maximum allowed time for a message to be read or written.
maxBatchSize = 50 maxBatchSize = 30
) )
type Service struct { type Service struct {
streamer p2p.Streamer streamer p2p.Streamer
addressBook addressbook.GetPutter addressBook addressbook.GetPutter
peerHandler func(context.Context, swarm.Address) error peerHandler func(context.Context, swarm.Address) error
networkID uint64
logger logging.Logger logger logging.Logger
} }
type Options struct { type Options struct {
Streamer p2p.Streamer Streamer p2p.Streamer
AddressBook addressbook.GetPutter AddressBook addressbook.GetPutter
NetworkID uint64
Logger logging.Logger Logger logging.Logger
} }
...@@ -47,6 +48,7 @@ func New(o Options) *Service { ...@@ -47,6 +48,7 @@ func New(o Options) *Service {
streamer: o.Streamer, streamer: o.Streamer,
logger: o.Logger, logger: o.Logger,
addressBook: o.AddressBook, addressBook: o.AddressBook,
networkID: o.NetworkID,
} }
} }
...@@ -96,15 +98,16 @@ func (s *Service) sendPeers(ctx context.Context, peer swarm.Address, peers []swa ...@@ -96,15 +98,16 @@ func (s *Service) sendPeers(ctx context.Context, peer swarm.Address, peers []swa
addr, err := s.addressBook.Get(p) addr, err := s.addressBook.Get(p)
if err != nil { if err != nil {
if errors.Is(err, storage.ErrNotFound) { if errors.Is(err, storage.ErrNotFound) {
s.logger.Debugf("Peer not found %s", peer, err) s.logger.Debugf("Peer not found %s", p)
continue continue
} }
return err return err
} }
peersRequest.Peers = append(peersRequest.Peers, &pb.BzzAddress{ peersRequest.Peers = append(peersRequest.Peers, &pb.BzzAddress{
Overlay: p.Bytes(), Overlay: addr.Overlay.Bytes(),
Underlay: addr.String(), Underlay: addr.Underlay.Bytes(),
Signature: addr.Signature,
}) })
} }
...@@ -127,18 +130,20 @@ func (s *Service) peersHandler(_ context.Context, peer p2p.Peer, stream p2p.Stre ...@@ -127,18 +130,20 @@ func (s *Service) peersHandler(_ context.Context, peer p2p.Peer, stream p2p.Stre
return fmt.Errorf("close stream: %w", err) return fmt.Errorf("close stream: %w", err)
} }
for _, newPeer := range peersReq.Peers { for _, newPeer := range peersReq.Peers {
addr, err := ma.NewMultiaddr(newPeer.Underlay) bzzAddress, err := bzz.ParseAddress(newPeer.Underlay, newPeer.Overlay, newPeer.Signature, s.networkID)
if err != nil { if err != nil {
s.logger.Infof("Skipping peer in response %s: %w", newPeer, err) s.logger.Warningf("skipping peer in response %s: %w", newPeer, err)
continue continue
} }
err = s.addressBook.Put(swarm.NewAddress(newPeer.Overlay), addr) err = s.addressBook.Put(bzzAddress.Overlay, *bzzAddress)
if err != nil { if err != nil {
return err s.logger.Warningf("skipping peer in response %s: %w", newPeer, err)
continue
} }
if s.peerHandler != nil { if s.peerHandler != nil {
if err := s.peerHandler(context.Background(), swarm.NewAddress(newPeer.Overlay)); err != nil { if err := s.peerHandler(context.Background(), bzzAddress.Overlay); err != nil {
return err return err
} }
} }
......
...@@ -19,6 +19,8 @@ import ( ...@@ -19,6 +19,8 @@ import (
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
ab "github.com/ethersphere/bee/pkg/addressbook" ab "github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/hive" "github.com/ethersphere/bee/pkg/hive"
"github.com/ethersphere/bee/pkg/hive/pb" "github.com/ethersphere/bee/pkg/hive/pb"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
...@@ -33,11 +35,12 @@ func TestBroadcastPeers(t *testing.T) { ...@@ -33,11 +35,12 @@ func TestBroadcastPeers(t *testing.T) {
logger := logging.New(ioutil.Discard, 0) logger := logging.New(ioutil.Discard, 0)
statestore := mock.NewStateStore() statestore := mock.NewStateStore()
addressbook := ab.New(statestore) addressbook := ab.New(statestore)
networkID := uint64(1)
// populate all expected and needed random resources for 2 full batches // populate all expected and needed random resources for 2 full batches
// tests cases that uses fewer resources can use sub-slices of this data // tests cases that uses fewer resources can use sub-slices of this data
var multiaddrs []ma.Multiaddr var bzzAddresses []bzz.Address
var addrs []swarm.Address var overlays []swarm.Address
var wantMsgs []pb.Peers var wantMsgs []pb.Peers
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
...@@ -45,61 +48,71 @@ func TestBroadcastPeers(t *testing.T) { ...@@ -45,61 +48,71 @@ func TestBroadcastPeers(t *testing.T) {
} }
for i := 0; i < 2*hive.MaxBatchSize; i++ { for i := 0; i < 2*hive.MaxBatchSize; i++ {
ma, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/" + strconv.Itoa(i)) underlay, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/" + strconv.Itoa(i))
if err != nil {
t.Fatal(err)
}
pk, err := crypto.GenerateSecp256k1Key()
if err != nil {
t.Fatal(err)
}
signer := crypto.NewDefaultSigner(pk)
overlay := crypto.NewOverlayAddress(pk.PublicKey, networkID)
bzzAddr, err := bzz.NewAddress(signer, underlay, overlay, networkID)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
multiaddrs = append(multiaddrs, ma) bzzAddresses = append(bzzAddresses, *bzzAddr)
addrs = append(addrs, swarm.NewAddress(createRandomBytes())) overlays = append(overlays, bzzAddr.Overlay)
err = addressbook.Put(addrs[i], multiaddrs[i]) err = addressbook.Put(bzzAddr.Overlay, *bzzAddr)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
wantMsgs[i/hive.MaxBatchSize].Peers = append(wantMsgs[i/hive.MaxBatchSize].Peers, &pb.BzzAddress{Overlay: addrs[i].Bytes(), Underlay: multiaddrs[i].String()}) wantMsgs[i/hive.MaxBatchSize].Peers = append(wantMsgs[i/hive.MaxBatchSize].Peers, &pb.BzzAddress{Overlay: bzzAddresses[i].Overlay.Bytes(), Underlay: bzzAddresses[i].Underlay.Bytes(), Signature: bzzAddresses[i].Signature})
} }
testCases := map[string]struct { testCases := map[string]struct {
addresee swarm.Address addresee swarm.Address
peers []swarm.Address peers []swarm.Address
wantMsgs []pb.Peers wantMsgs []pb.Peers
wantOverlays []swarm.Address wantOverlays []swarm.Address
wantMultiAddresses []ma.Multiaddr wantBzzAddresses []bzz.Address
}{ }{
"OK - single record": { "OK - single record": {
addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"), addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"),
peers: []swarm.Address{addrs[0]}, peers: []swarm.Address{overlays[0]},
wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers[:1]}}, wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers[:1]}},
wantOverlays: []swarm.Address{addrs[0]}, wantOverlays: []swarm.Address{overlays[0]},
wantMultiAddresses: []ma.Multiaddr{multiaddrs[0]}, wantBzzAddresses: []bzz.Address{bzzAddresses[0]},
}, },
"OK - single batch - multiple records": { "OK - single batch - multiple records": {
addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"), addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"),
peers: addrs[:15], peers: overlays[:15],
wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers[:15]}}, wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers[:15]}},
wantOverlays: addrs[:15], wantOverlays: overlays[:15],
wantMultiAddresses: multiaddrs[:15], wantBzzAddresses: bzzAddresses[:15],
}, },
"OK - single batch - max number of records": { "OK - single batch - max number of records": {
addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"), addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"),
peers: addrs[:hive.MaxBatchSize], peers: overlays[:hive.MaxBatchSize],
wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers[:hive.MaxBatchSize]}}, wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers[:hive.MaxBatchSize]}},
wantOverlays: addrs[:hive.MaxBatchSize], wantOverlays: overlays[:hive.MaxBatchSize],
wantMultiAddresses: multiaddrs[:hive.MaxBatchSize], wantBzzAddresses: bzzAddresses[:hive.MaxBatchSize],
}, },
"OK - multiple batches": { "OK - multiple batches": {
addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"), addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"),
peers: addrs[:hive.MaxBatchSize+10], peers: overlays[:hive.MaxBatchSize+10],
wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers}, {Peers: wantMsgs[1].Peers[:10]}}, wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers}, {Peers: wantMsgs[1].Peers[:10]}},
wantOverlays: addrs[:hive.MaxBatchSize+10], wantOverlays: overlays[:hive.MaxBatchSize+10],
wantMultiAddresses: multiaddrs[:hive.MaxBatchSize+10], wantBzzAddresses: bzzAddresses[:hive.MaxBatchSize+10],
}, },
"OK - multiple batches - max number of records": { "OK - multiple batches - max number of records": {
addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"), addresee: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59c"),
peers: addrs[:2*hive.MaxBatchSize], peers: overlays[:2*hive.MaxBatchSize],
wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers}, {Peers: wantMsgs[1].Peers}}, wantMsgs: []pb.Peers{{Peers: wantMsgs[0].Peers}, {Peers: wantMsgs[1].Peers}},
wantOverlays: addrs[:2*hive.MaxBatchSize], wantOverlays: overlays[:2*hive.MaxBatchSize],
wantMultiAddresses: multiaddrs[:2*hive.MaxBatchSize], wantBzzAddresses: bzzAddresses[:2*hive.MaxBatchSize],
}, },
} }
...@@ -111,6 +124,7 @@ func TestBroadcastPeers(t *testing.T) { ...@@ -111,6 +124,7 @@ func TestBroadcastPeers(t *testing.T) {
server := hive.New(hive.Options{ server := hive.New(hive.Options{
Logger: logger, Logger: logger,
AddressBook: addressbookclean, AddressBook: addressbookclean,
NetworkID: networkID,
}) })
// setup the stream recorder to record stream data // setup the stream recorder to record stream data
...@@ -123,6 +137,7 @@ func TestBroadcastPeers(t *testing.T) { ...@@ -123,6 +137,7 @@ func TestBroadcastPeers(t *testing.T) {
Streamer: recorder, Streamer: recorder,
Logger: logger, Logger: logger,
AddressBook: addressbook, AddressBook: addressbook,
NetworkID: networkID,
}) })
if err := client.BroadcastPeers(context.Background(), tc.addresee, tc.peers...); err != nil { if err := client.BroadcastPeers(context.Background(), tc.addresee, tc.peers...); err != nil {
...@@ -151,7 +166,7 @@ func TestBroadcastPeers(t *testing.T) { ...@@ -151,7 +166,7 @@ func TestBroadcastPeers(t *testing.T) {
} }
expectOverlaysEventually(t, addressbookclean, tc.wantOverlays) expectOverlaysEventually(t, addressbookclean, tc.wantOverlays)
expectMultiaddresessEventually(t, addressbookclean, tc.wantMultiAddresses) expectBzzAddresessEventually(t, addressbookclean, tc.wantBzzAddresses)
}) })
} }
} }
...@@ -189,37 +204,33 @@ func expectOverlaysEventually(t *testing.T, exporter ab.Interface, wantOverlays ...@@ -189,37 +204,33 @@ func expectOverlaysEventually(t *testing.T, exporter ab.Interface, wantOverlays
t.Errorf("Overlays got %v, want %v", o, wantOverlays) t.Errorf("Overlays got %v, want %v", o, wantOverlays)
} }
func expectMultiaddresessEventually(t *testing.T, exporter ab.Interface, wantMultiaddresses []ma.Multiaddr) { func expectBzzAddresessEventually(t *testing.T, exporter ab.Interface, wantBzzAddresses []bzz.Address) {
for i := 0; i < 10; i++ { for i := 0; i < 100; i++ {
var stringMultiaddresses []string time.Sleep(50 * time.Millisecond)
m, err := exporter.Multiaddresses() addresses, err := exporter.Addresses()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
for _, v := range m {
stringMultiaddresses = append(stringMultiaddresses, v.String())
}
var stringWantMultiAddresses []string if len(addresses) != len(wantBzzAddresses) {
for _, v := range wantMultiaddresses { continue
stringWantMultiAddresses = append(stringWantMultiAddresses, v.String())
} }
sort.Strings(stringMultiaddresses) for i, v := range addresses {
sort.Strings(stringWantMultiAddresses) if !v.Equal(&wantBzzAddresses[i]) {
if reflect.DeepEqual(stringMultiaddresses, stringWantMultiAddresses) { continue
return }
} }
time.Sleep(50 * time.Millisecond) return
} }
m, err := exporter.Multiaddresses() m, err := exporter.Addresses()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Errorf("Multiaddresses got %v, want %v", m, wantMultiaddresses) t.Errorf("Bzz addresses got %v, want %v", m, wantBzzAddresses)
} }
func readAndAssertPeersMsgs(in []byte, expectedLen int) ([]pb.Peers, error) { func readAndAssertPeersMsgs(in []byte, expectedLen int) ([]pb.Peers, error) {
...@@ -239,16 +250,9 @@ func readAndAssertPeersMsgs(in []byte, expectedLen int) ([]pb.Peers, error) { ...@@ -239,16 +250,9 @@ func readAndAssertPeersMsgs(in []byte, expectedLen int) ([]pb.Peers, error) {
} }
var peers []pb.Peers var peers []pb.Peers
for _, m := range messages { for _, m := range messages {
peers = append(peers, *m.(*pb.Peers)) peers = append(peers, *m.(*pb.Peers))
} }
return peers, nil return peers, nil
} }
func createRandomBytes() []byte {
randBytes := make([]byte, 32)
rand.Read(randBytes)
return randBytes
}
...@@ -67,8 +67,9 @@ func (m *Peers) GetPeers() []*BzzAddress { ...@@ -67,8 +67,9 @@ func (m *Peers) GetPeers() []*BzzAddress {
} }
type BzzAddress struct { type BzzAddress struct {
Overlay []byte `protobuf:"bytes,1,opt,name=Overlay,proto3" json:"Overlay,omitempty"` Underlay []byte `protobuf:"bytes,1,opt,name=Underlay,proto3" json:"Underlay,omitempty"`
Underlay string `protobuf:"bytes,2,opt,name=Underlay,proto3" json:"Underlay,omitempty"` Signature []byte `protobuf:"bytes,2,opt,name=Signature,proto3" json:"Signature,omitempty"`
Overlay []byte `protobuf:"bytes,3,opt,name=Overlay,proto3" json:"Overlay,omitempty"`
} }
func (m *BzzAddress) Reset() { *m = BzzAddress{} } func (m *BzzAddress) Reset() { *m = BzzAddress{} }
...@@ -104,18 +105,25 @@ func (m *BzzAddress) XXX_DiscardUnknown() { ...@@ -104,18 +105,25 @@ func (m *BzzAddress) XXX_DiscardUnknown() {
var xxx_messageInfo_BzzAddress proto.InternalMessageInfo var xxx_messageInfo_BzzAddress proto.InternalMessageInfo
func (m *BzzAddress) GetOverlay() []byte { func (m *BzzAddress) GetUnderlay() []byte {
if m != nil { if m != nil {
return m.Overlay return m.Underlay
} }
return nil return nil
} }
func (m *BzzAddress) GetUnderlay() string { func (m *BzzAddress) GetSignature() []byte {
if m != nil { if m != nil {
return m.Underlay return m.Signature
}
return nil
}
func (m *BzzAddress) GetOverlay() []byte {
if m != nil {
return m.Overlay
} }
return "" return nil
} }
func init() { func init() {
...@@ -126,17 +134,18 @@ func init() { ...@@ -126,17 +134,18 @@ func init() {
func init() { proto.RegisterFile("hive.proto", fileDescriptor_d635d1ead41ba02c) } func init() { proto.RegisterFile("hive.proto", fileDescriptor_d635d1ead41ba02c) }
var fileDescriptor_d635d1ead41ba02c = []byte{ var fileDescriptor_d635d1ead41ba02c = []byte{
// 158 bytes of a gzipped FileDescriptorProto // 174 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xca, 0xc8, 0x2c, 0x4b, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xca, 0xc8, 0x2c, 0x4b,
0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x01, 0xb1, 0x95, 0xf4, 0xb9, 0x58, 0x03, 0x52, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x01, 0xb1, 0x95, 0xf4, 0xb9, 0x58, 0x03, 0x52,
0x53, 0x8b, 0x8a, 0x85, 0xd4, 0xb8, 0x58, 0x0b, 0x40, 0x0c, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e, 0x53, 0x8b, 0x8a, 0x85, 0xd4, 0xb8, 0x58, 0x0b, 0x40, 0x0c, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e,
0x23, 0x01, 0x3d, 0xb0, 0x52, 0xa7, 0xaa, 0x2a, 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2, 0xe2, 0x20, 0x23, 0x01, 0x3d, 0xb0, 0x52, 0xa7, 0xaa, 0x2a, 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2, 0xe2, 0x20,
0x88, 0xb4, 0x92, 0x13, 0x17, 0x17, 0x42, 0x50, 0x48, 0x82, 0x8b, 0xdd, 0xbf, 0x2c, 0xb5, 0x28, 0x88, 0xb4, 0x52, 0x02, 0x17, 0x17, 0x42, 0x50, 0x48, 0x8a, 0x8b, 0x23, 0x34, 0x2f, 0x25, 0xb5,
0x27, 0xb1, 0x52, 0x82, 0x51, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc6, 0x15, 0x92, 0xe2, 0xe2, 0x08, 0x28, 0x27, 0xb1, 0x52, 0x82, 0x51, 0x81, 0x51, 0x83, 0x27, 0x08, 0xce, 0x17, 0x92, 0xe1, 0xe2,
0xcd, 0x4b, 0x81, 0x48, 0x31, 0x29, 0x30, 0x6a, 0x70, 0x06, 0xc1, 0xf9, 0x4e, 0x32, 0x27, 0x1e, 0x0c, 0xce, 0x4c, 0xcf, 0x4b, 0x2c, 0x29, 0x2d, 0x4a, 0x95, 0x60, 0x02, 0x4b, 0x22, 0x04, 0x84,
0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x24, 0xb8, 0xd8, 0xfd, 0xcb, 0x20, 0x1a, 0x99, 0xc1, 0x72, 0x30, 0xae, 0x93, 0xcc, 0x89, 0x47,
0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xc5, 0x54, 0x90, 0x94, 0xc4, 0x06, 0x76, 0x9f, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85,
0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xed, 0x0e, 0xc1, 0x96, 0xad, 0x00, 0x00, 0x00, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x31, 0x15, 0x24, 0x25, 0xb1, 0x81, 0x5d, 0x6f,
0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x11, 0xc0, 0xe9, 0xcb, 0x00, 0x00, 0x00,
} }
func (m *Peers) Marshal() (dAtA []byte, err error) { func (m *Peers) Marshal() (dAtA []byte, err error) {
...@@ -196,18 +205,25 @@ func (m *BzzAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { ...@@ -196,18 +205,25 @@ func (m *BzzAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if len(m.Underlay) > 0 {
i -= len(m.Underlay)
copy(dAtA[i:], m.Underlay)
i = encodeVarintHive(dAtA, i, uint64(len(m.Underlay)))
i--
dAtA[i] = 0x12
}
if len(m.Overlay) > 0 { if len(m.Overlay) > 0 {
i -= len(m.Overlay) i -= len(m.Overlay)
copy(dAtA[i:], m.Overlay) copy(dAtA[i:], m.Overlay)
i = encodeVarintHive(dAtA, i, uint64(len(m.Overlay))) i = encodeVarintHive(dAtA, i, uint64(len(m.Overlay)))
i-- i--
dAtA[i] = 0x1a
}
if len(m.Signature) > 0 {
i -= len(m.Signature)
copy(dAtA[i:], m.Signature)
i = encodeVarintHive(dAtA, i, uint64(len(m.Signature)))
i--
dAtA[i] = 0x12
}
if len(m.Underlay) > 0 {
i -= len(m.Underlay)
copy(dAtA[i:], m.Underlay)
i = encodeVarintHive(dAtA, i, uint64(len(m.Underlay)))
i--
dAtA[i] = 0xa dAtA[i] = 0xa
} }
return len(dAtA) - i, nil return len(dAtA) - i, nil
...@@ -245,11 +261,15 @@ func (m *BzzAddress) Size() (n int) { ...@@ -245,11 +261,15 @@ func (m *BzzAddress) Size() (n int) {
} }
var l int var l int
_ = l _ = l
l = len(m.Overlay) l = len(m.Underlay)
if l > 0 { if l > 0 {
n += 1 + l + sovHive(uint64(l)) n += 1 + l + sovHive(uint64(l))
} }
l = len(m.Underlay) l = len(m.Signature)
if l > 0 {
n += 1 + l + sovHive(uint64(l))
}
l = len(m.Overlay)
if l > 0 { if l > 0 {
n += 1 + l + sovHive(uint64(l)) n += 1 + l + sovHive(uint64(l))
} }
...@@ -380,7 +400,7 @@ func (m *BzzAddress) Unmarshal(dAtA []byte) error { ...@@ -380,7 +400,7 @@ func (m *BzzAddress) Unmarshal(dAtA []byte) error {
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Overlay", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Underlay", wireType)
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
...@@ -407,16 +427,50 @@ func (m *BzzAddress) Unmarshal(dAtA []byte) error { ...@@ -407,16 +427,50 @@ func (m *BzzAddress) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Overlay = append(m.Overlay[:0], dAtA[iNdEx:postIndex]...) m.Underlay = append(m.Underlay[:0], dAtA[iNdEx:postIndex]...)
if m.Overlay == nil { if m.Underlay == nil {
m.Overlay = []byte{} m.Underlay = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Underlay", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowHive
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthHive
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthHive
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...)
if m.Signature == nil {
m.Signature = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Overlay", wireType)
} }
var stringLen uint64 var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflowHive return ErrIntOverflowHive
...@@ -426,23 +480,25 @@ func (m *BzzAddress) Unmarshal(dAtA []byte) error { ...@@ -426,23 +480,25 @@ func (m *BzzAddress) Unmarshal(dAtA []byte) error {
} }
b := dAtA[iNdEx] b := dAtA[iNdEx]
iNdEx++ iNdEx++
stringLen |= uint64(b&0x7F) << shift byteLen |= int(b&0x7F) << shift
if b < 0x80 { if b < 0x80 {
break break
} }
} }
intStringLen := int(stringLen) if byteLen < 0 {
if intStringLen < 0 {
return ErrInvalidLengthHive return ErrInvalidLengthHive
} }
postIndex := iNdEx + intStringLen postIndex := iNdEx + byteLen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLengthHive return ErrInvalidLengthHive
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Underlay = string(dAtA[iNdEx:postIndex]) m.Overlay = append(m.Overlay[:0], dAtA[iNdEx:postIndex]...)
if m.Overlay == nil {
m.Overlay = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
......
...@@ -13,6 +13,7 @@ message Peers { ...@@ -13,6 +13,7 @@ message Peers {
} }
message BzzAddress { message BzzAddress {
bytes Overlay = 1; bytes Underlay = 1;
string Underlay = 2; bytes Signature = 2;
bytes Overlay = 3;
} }
...@@ -121,7 +121,7 @@ func (k *Kad) manage() { ...@@ -121,7 +121,7 @@ func (k *Kad) manage() {
return false, true, nil // bin is saturated, skip to next bin return false, true, nil // bin is saturated, skip to next bin
} }
ma, err := k.addressBook.Get(peer) bzzAddr, err := k.addressBook.Get(peer)
if err != nil { if err != nil {
// either a peer is not known in the address book, in which case it // either a peer is not known in the address book, in which case it
// should be removed, or that some severe I/O problem is at hand // should be removed, or that some severe I/O problem is at hand
...@@ -136,7 +136,7 @@ func (k *Kad) manage() { ...@@ -136,7 +136,7 @@ func (k *Kad) manage() {
} }
k.logger.Debugf("kademlia dialing to peer %s", peer.String()) k.logger.Debugf("kademlia dialing to peer %s", peer.String())
err = k.connect(ctx, peer, ma, po) err = k.connect(ctx, peer, bzzAddr.Underlay, po)
if err != nil { if err != nil {
k.logger.Errorf("error connecting to peer %s: %v", peer, err) k.logger.Errorf("error connecting to peer %s: %v", peer, err)
// continue to next // continue to next
......
...@@ -16,6 +16,9 @@ import ( ...@@ -16,6 +16,9 @@ import (
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
"github.com/ethersphere/bee/pkg/addressbook" "github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto"
beeCrypto "github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/discovery/mock" "github.com/ethersphere/bee/pkg/discovery/mock"
"github.com/ethersphere/bee/pkg/kademlia" "github.com/ethersphere/bee/pkg/kademlia"
"github.com/ethersphere/bee/pkg/kademlia/pslice" "github.com/ethersphere/bee/pkg/kademlia/pslice"
...@@ -42,9 +45,9 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -42,9 +45,9 @@ func TestNeighborhoodDepth(t *testing.T) {
var ( var (
conns int32 // how many connect calls were made to the p2p mock conns int32 // how many connect calls were made to the p2p mock
base, kad, ab, _ = newTestKademlia(&conns, nil) base, kad, ab, _, signer = newTestKademlia(&conns, nil)
peers []swarm.Address peers []swarm.Address
binEight []swarm.Address binEight []swarm.Address
) )
defer kad.Close() defer kad.Close()
...@@ -63,11 +66,11 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -63,11 +66,11 @@ func TestNeighborhoodDepth(t *testing.T) {
kDepth(t, kad, 0) kDepth(t, kad, 0)
// add two bin 8 peers, verify depth still 0 // add two bin 8 peers, verify depth still 0
add(t, kad, ab, binEight, 0, 2) add(t, signer, kad, ab, binEight, 0, 2)
kDepth(t, kad, 0) kDepth(t, kad, 0)
// add two first peers (po0,po1) // add two first peers (po0,po1)
add(t, kad, ab, peers, 0, 2) add(t, signer, kad, ab, peers, 0, 2)
// wait for 4 connections // wait for 4 connections
waitConns(t, &conns, 4) waitConns(t, &conns, 4)
...@@ -76,7 +79,7 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -76,7 +79,7 @@ func TestNeighborhoodDepth(t *testing.T) {
kDepth(t, kad, 2) kDepth(t, kad, 2)
for i := 2; i < len(peers)-1; i++ { for i := 2; i < len(peers)-1; i++ {
addOne(t, kad, ab, peers[i]) addOne(t, signer, kad, ab, peers[i])
// wait for one connection // wait for one connection
waitConn(t, &conns) waitConn(t, &conns)
...@@ -86,7 +89,7 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -86,7 +89,7 @@ func TestNeighborhoodDepth(t *testing.T) {
} }
// the last peer in bin 7 which is empty we insert manually, // the last peer in bin 7 which is empty we insert manually,
addOne(t, kad, ab, peers[len(peers)-1]) addOne(t, signer, kad, ab, peers[len(peers)-1])
waitConn(t, &conns) waitConn(t, &conns)
// depth is 8 because we have nnLowWatermark neighbors in bin 8 // depth is 8 because we have nnLowWatermark neighbors in bin 8
...@@ -96,14 +99,14 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -96,14 +99,14 @@ func TestNeighborhoodDepth(t *testing.T) {
// stay 8, because the counter for nnLowWatermark would be reached only at the next // stay 8, because the counter for nnLowWatermark would be reached only at the next
// depth iteration when calculating depth // depth iteration when calculating depth
addr := test.RandomAddressAt(base, 9) addr := test.RandomAddressAt(base, 9)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConn(t, &conns) waitConn(t, &conns)
kDepth(t, kad, 8) kDepth(t, kad, 8)
// fill the rest up to the bin before last and check that everything works at the edges // fill the rest up to the bin before last and check that everything works at the edges
for i := 10; i < kademlia.MaxBins-1; i++ { for i := 10; i < kademlia.MaxBins-1; i++ {
addr := test.RandomAddressAt(base, i) addr := test.RandomAddressAt(base, i)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConn(t, &conns) waitConn(t, &conns)
kDepth(t, kad, i-1) kDepth(t, kad, i-1)
} }
...@@ -111,7 +114,7 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -111,7 +114,7 @@ func TestNeighborhoodDepth(t *testing.T) {
// add a whole bunch of peers in bin 13, expect depth to stay at 13 // add a whole bunch of peers in bin 13, expect depth to stay at 13
for i := 0; i < 15; i++ { for i := 0; i < 15; i++ {
addr = test.RandomAddressAt(base, 13) addr = test.RandomAddressAt(base, 13)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
} }
waitConns(t, &conns, 15) waitConns(t, &conns, 15)
...@@ -119,15 +122,15 @@ func TestNeighborhoodDepth(t *testing.T) { ...@@ -119,15 +122,15 @@ func TestNeighborhoodDepth(t *testing.T) {
// add one at 14 - depth should be now 14 // add one at 14 - depth should be now 14
addr = test.RandomAddressAt(base, 14) addr = test.RandomAddressAt(base, 14)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
kDepth(t, kad, 14) kDepth(t, kad, 14)
addr2 := test.RandomAddressAt(base, 15) addr2 := test.RandomAddressAt(base, 15)
addOne(t, kad, ab, addr2) addOne(t, signer, kad, ab, addr2)
kDepth(t, kad, 14) kDepth(t, kad, 14)
addr3 := test.RandomAddressAt(base, 15) addr3 := test.RandomAddressAt(base, 15)
addOne(t, kad, ab, addr3) addOne(t, signer, kad, ab, addr3)
kDepth(t, kad, 15) kDepth(t, kad, 15)
// now remove that peer and check that the depth is back at 14 // now remove that peer and check that the depth is back at 14
...@@ -159,13 +162,13 @@ func TestManage(t *testing.T) { ...@@ -159,13 +162,13 @@ func TestManage(t *testing.T) {
saturationFunc = func(bin, depth uint8, peers *pslice.PSlice) bool { saturationFunc = func(bin, depth uint8, peers *pslice.PSlice) bool {
return saturationVal return saturationVal
} }
base, kad, ab, _ = newTestKademlia(&conns, saturationFunc) base, kad, ab, _, signer = newTestKademlia(&conns, saturationFunc)
) )
// first, saturationFunc returns always false, this means that the bin is not saturated, // first, saturationFunc returns always false, this means that the bin is not saturated,
// hence we expect that every peer we add to kademlia will be connected to // hence we expect that every peer we add to kademlia will be connected to
for i := 0; i < 50; i++ { for i := 0; i < 50; i++ {
addr := test.RandomAddressAt(base, 0) addr := test.RandomAddressAt(base, 0)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
} }
waitConns(t, &conns, 50) waitConns(t, &conns, 50)
...@@ -174,7 +177,7 @@ func TestManage(t *testing.T) { ...@@ -174,7 +177,7 @@ func TestManage(t *testing.T) {
// now since the bin is "saturated", no new connections should be made // now since the bin is "saturated", no new connections should be made
for i := 0; i < 50; i++ { for i := 0; i < 50; i++ {
addr := test.RandomAddressAt(base, 0) addr := test.RandomAddressAt(base, 0)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
} }
waitConns(t, &conns, 0) waitConns(t, &conns, 0)
...@@ -183,7 +186,7 @@ func TestManage(t *testing.T) { ...@@ -183,7 +186,7 @@ func TestManage(t *testing.T) {
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
for j := 0; j < 10; j++ { for j := 0; j < 10; j++ {
addr := test.RandomAddressAt(base, i) addr := test.RandomAddressAt(base, i)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
} }
} }
waitConns(t, &conns, 0) waitConns(t, &conns, 0)
...@@ -197,9 +200,9 @@ func TestManage(t *testing.T) { ...@@ -197,9 +200,9 @@ func TestManage(t *testing.T) {
// in shallower depth for the rest of the function to be executed // in shallower depth for the rest of the function to be executed
func TestBinSaturation(t *testing.T) { func TestBinSaturation(t *testing.T) {
var ( var (
conns int32 // how many connect calls were made to the p2p mock conns int32 // how many connect calls were made to the p2p mock
base, kad, ab, _ = newTestKademlia(&conns, nil) base, kad, ab, _, signer = newTestKademlia(&conns, nil)
peers []swarm.Address peers []swarm.Address
) )
// add two peers in a few bins to generate some depth >= 0, this will // add two peers in a few bins to generate some depth >= 0, this will
...@@ -208,7 +211,7 @@ func TestBinSaturation(t *testing.T) { ...@@ -208,7 +211,7 @@ func TestBinSaturation(t *testing.T) {
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
for j := 0; j < 2; j++ { for j := 0; j < 2; j++ {
addr := test.RandomAddressAt(base, i) addr := test.RandomAddressAt(base, i)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
peers = append(peers, addr) peers = append(peers, addr)
} }
} }
...@@ -219,19 +222,19 @@ func TestBinSaturation(t *testing.T) { ...@@ -219,19 +222,19 @@ func TestBinSaturation(t *testing.T) {
// depth, the short circuit will be hit and we will connect to the peer // depth, the short circuit will be hit and we will connect to the peer
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
addr := test.RandomAddressAt(base, i) addr := test.RandomAddressAt(base, i)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
} }
waitConns(t, &conns, 0) waitConns(t, &conns, 0)
// add one peer in a bin higher (unsaturated) and expect one connection // add one peer in a bin higher (unsaturated) and expect one connection
addr := test.RandomAddressAt(base, 6) addr := test.RandomAddressAt(base, 6)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConns(t, &conns, 1) waitConns(t, &conns, 1)
// again, one bin higher // again, one bin higher
addr = test.RandomAddressAt(base, 7) addr = test.RandomAddressAt(base, 7)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConns(t, &conns, 1) waitConns(t, &conns, 1)
...@@ -244,12 +247,12 @@ func TestBinSaturation(t *testing.T) { ...@@ -244,12 +247,12 @@ func TestBinSaturation(t *testing.T) {
// result in the correct behavior once called. // result in the correct behavior once called.
func TestNotifierHooks(t *testing.T) { func TestNotifierHooks(t *testing.T) {
var ( var (
base, kad, ab, _ = newTestKademlia(nil, nil) base, kad, ab, _, signer = newTestKademlia(nil, nil)
peer = test.RandomAddressAt(base, 3) peer = test.RandomAddressAt(base, 3)
addr = test.RandomAddressAt(peer, 4) // address which is closer to peer addr = test.RandomAddressAt(peer, 4) // address which is closer to peer
) )
connectOne(t, kad, ab, peer) connectOne(t, signer, kad, ab, peer)
p, err := kad.ClosestPeer(addr) p, err := kad.ClosestPeer(addr)
if err != nil { if err != nil {
...@@ -273,17 +276,17 @@ func TestNotifierHooks(t *testing.T) { ...@@ -273,17 +276,17 @@ func TestNotifierHooks(t *testing.T) {
// us proactively dialing in to a peer, or when a peer dials in. // us proactively dialing in to a peer, or when a peer dials in.
func TestDiscoveryHooks(t *testing.T) { func TestDiscoveryHooks(t *testing.T) {
var ( var (
conns int32 conns int32
_, kad, ab, disc = newTestKademlia(&conns, nil) _, kad, ab, disc, signer = newTestKademlia(&conns, nil)
p1, p2, p3 = test.RandomAddress(), test.RandomAddress(), test.RandomAddress() p1, p2, p3 = test.RandomAddress(), test.RandomAddress(), test.RandomAddress()
) )
// first add a peer from AddPeer, wait for the connection // first add a peer from AddPeer, wait for the connection
addOne(t, kad, ab, p1) addOne(t, signer, kad, ab, p1)
waitConn(t, &conns) waitConn(t, &conns)
// add another peer from AddPeer, wait for the connection // add another peer from AddPeer, wait for the connection
// then check that peers are gossiped to each other via discovery // then check that peers are gossiped to each other via discovery
addOne(t, kad, ab, p2) addOne(t, signer, kad, ab, p2)
waitConn(t, &conns) waitConn(t, &conns)
waitBcast(t, disc, p1, p2) waitBcast(t, disc, p1, p2)
waitBcast(t, disc, p2, p1) waitBcast(t, disc, p2, p1)
...@@ -292,7 +295,7 @@ func TestDiscoveryHooks(t *testing.T) { ...@@ -292,7 +295,7 @@ func TestDiscoveryHooks(t *testing.T) {
// add another peer that dialed in, check that all peers gossiped // add another peer that dialed in, check that all peers gossiped
// correctly to each other // correctly to each other
connectOne(t, kad, ab, p3) connectOne(t, signer, kad, ab, p3)
waitBcast(t, disc, p1, p3) waitBcast(t, disc, p1, p3)
waitBcast(t, disc, p2, p3) waitBcast(t, disc, p2, p3)
waitBcast(t, disc, p3, p1, p2) waitBcast(t, disc, p3, p1, p2)
...@@ -309,12 +312,12 @@ func TestBackoff(t *testing.T) { ...@@ -309,12 +312,12 @@ func TestBackoff(t *testing.T) {
var ( var (
conns int32 // how many connect calls were made to the p2p mock conns int32 // how many connect calls were made to the p2p mock
base, kad, ab, _ = newTestKademlia(&conns, nil) base, kad, ab, _, signer = newTestKademlia(&conns, nil)
) )
// add one peer, wait for connection // add one peer, wait for connection
addr := test.RandomAddressAt(base, 1) addr := test.RandomAddressAt(base, 1)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConns(t, &conns, 1) waitConns(t, &conns, 1)
...@@ -324,14 +327,14 @@ func TestBackoff(t *testing.T) { ...@@ -324,14 +327,14 @@ func TestBackoff(t *testing.T) {
// wait for 100ms, add another peer, expect just one more connection // wait for 100ms, add another peer, expect just one more connection
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
addr = test.RandomAddressAt(base, 1) addr = test.RandomAddressAt(base, 1)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConns(t, &conns, 1) waitConns(t, &conns, 1)
// wait for another 400ms, add another, expect 2 connections // wait for another 400ms, add another, expect 2 connections
time.Sleep(400 * time.Millisecond) time.Sleep(400 * time.Millisecond)
addr = test.RandomAddressAt(base, 1) addr = test.RandomAddressAt(base, 1)
addOne(t, kad, ab, addr) addOne(t, signer, kad, ab, addr)
waitConns(t, &conns, 2) waitConns(t, &conns, 2)
} }
...@@ -359,8 +362,9 @@ func TestClosestPeer(t *testing.T) { ...@@ -359,8 +362,9 @@ func TestClosestPeer(t *testing.T) {
kad := kademlia.New(kademlia.Options{Base: base, Discovery: disc, AddressBook: ab, P2P: p2pMock(&conns), Logger: logger}) kad := kademlia.New(kademlia.Options{Base: base, Discovery: disc, AddressBook: ab, P2P: p2pMock(&conns), Logger: logger})
defer kad.Close() defer kad.Close()
pk, _ := crypto.GenerateSecp256k1Key()
for _, v := range connectedPeers { for _, v := range connectedPeers {
addOne(t, kad, ab, v.Address) addOne(t, beeCrypto.NewDefaultSigner(pk), kad, ab, v.Address)
} }
waitConns(t, &conns, 3) waitConns(t, &conns, 3)
...@@ -415,17 +419,17 @@ func TestClosestPeer(t *testing.T) { ...@@ -415,17 +419,17 @@ func TestClosestPeer(t *testing.T) {
func TestMarshal(t *testing.T) { func TestMarshal(t *testing.T) {
var ( var (
_, kad, ab, _ = newTestKademlia(nil, nil) _, kad, ab, _, signer = newTestKademlia(nil, nil)
) )
a := test.RandomAddress() a := test.RandomAddress()
addOne(t, kad, ab, a) addOne(t, signer, kad, ab, a)
_, err := kad.MarshalJSON() _, err := kad.MarshalJSON()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
func newTestKademlia(connCounter *int32, f func(bin, depth uint8, peers *pslice.PSlice) bool) (swarm.Address, *kademlia.Kad, addressbook.Interface, *mock.Discovery) { func newTestKademlia(connCounter *int32, f func(bin, depth uint8, peers *pslice.PSlice) bool) (swarm.Address, *kademlia.Kad, addressbook.Interface, *mock.Discovery, beeCrypto.Signer) {
var ( var (
base = test.RandomAddress() // base address base = test.RandomAddress() // base address
p2p = p2pMock(connCounter) p2p = p2pMock(connCounter)
...@@ -434,7 +438,9 @@ func newTestKademlia(connCounter *int32, f func(bin, depth uint8, peers *pslice. ...@@ -434,7 +438,9 @@ func newTestKademlia(connCounter *int32, f func(bin, depth uint8, peers *pslice.
disc = mock.NewDiscovery() // mock discovery disc = mock.NewDiscovery() // mock discovery
kad = kademlia.New(kademlia.Options{Base: base, Discovery: disc, AddressBook: ab, P2P: p2p, Logger: logger, SaturationFunc: f}) // kademlia instance kad = kademlia.New(kademlia.Options{Base: base, Discovery: disc, AddressBook: ab, P2P: p2p, Logger: logger, SaturationFunc: f}) // kademlia instance
) )
return base, kad, ab, disc
pk, _ := crypto.GenerateSecp256k1Key()
return base, kad, ab, disc, beeCrypto.NewDefaultSigner(pk)
} }
func p2pMock(counter *int32) p2p.Service { func p2pMock(counter *int32) p2p.Service {
...@@ -454,34 +460,47 @@ func removeOne(k *kademlia.Kad, peer swarm.Address) { ...@@ -454,34 +460,47 @@ func removeOne(k *kademlia.Kad, peer swarm.Address) {
const underlayBase = "/ip4/127.0.0.1/tcp/7070/dns/" const underlayBase = "/ip4/127.0.0.1/tcp/7070/dns/"
func connectOne(t *testing.T, k *kademlia.Kad, ab addressbook.Putter, peer swarm.Address) { func connectOne(t *testing.T, signer beeCrypto.Signer, k *kademlia.Kad, ab addressbook.Putter, peer swarm.Address) {
t.Helper() t.Helper()
multiaddr, err := ma.NewMultiaddr(underlayBase + peer.String()) multiaddr, err := ma.NewMultiaddr(underlayBase + peer.String())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ab.Put(peer, multiaddr); err != nil {
bzzAddr, err := bzz.NewAddress(signer, multiaddr, peer, 0)
if err != nil {
t.Fatal(err)
}
if err := ab.Put(peer, *bzzAddr); err != nil {
t.Fatal(err) t.Fatal(err)
} }
_ = k.Connected(context.Background(), peer) _ = k.Connected(context.Background(), peer)
} }
func addOne(t *testing.T, k *kademlia.Kad, ab addressbook.Putter, peer swarm.Address) { func addOne(t *testing.T, signer beeCrypto.Signer, k *kademlia.Kad, ab addressbook.Putter, peer swarm.Address) {
t.Helper() t.Helper()
multiaddr, err := ma.NewMultiaddr(underlayBase + peer.String()) multiaddr, err := ma.NewMultiaddr(underlayBase + peer.String())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := ab.Put(peer, multiaddr); err != nil { bzzAddr, err := bzz.NewAddress(signer, multiaddr, peer, 0)
if err != nil {
t.Fatal(err)
}
if err := ab.Put(peer, *bzzAddr); err != nil {
t.Fatal(err)
}
if err := ab.Put(peer, *bzzAddr); err != nil {
t.Fatal(err) t.Fatal(err)
} }
_ = k.AddPeer(context.Background(), peer) _ = k.AddPeer(context.Background(), peer)
} }
func add(t *testing.T, k *kademlia.Kad, ab addressbook.Putter, peers []swarm.Address, offset, number int) { func add(t *testing.T, signer beeCrypto.Signer, k *kademlia.Kad, ab addressbook.Putter, peers []swarm.Address, offset, number int) {
t.Helper() t.Helper()
for i := offset; i < offset+number; i++ { for i := offset; i < offset+number; i++ {
addOne(t, k, ab, peers[i]) addOne(t, signer, k, ab, peers[i])
} }
} }
......
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"github.com/ethersphere/bee/pkg/addressbook" "github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/api" "github.com/ethersphere/bee/pkg/api"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto" "github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/debugapi" "github.com/ethersphere/bee/pkg/debugapi"
"github.com/ethersphere/bee/pkg/hive" "github.com/ethersphere/bee/pkg/hive"
...@@ -133,8 +134,9 @@ func NewBee(o Options) (*Bee, error) { ...@@ -133,8 +134,9 @@ func NewBee(o Options) (*Bee, error) {
} }
b.stateStoreCloser = stateStore b.stateStoreCloser = stateStore
addressbook := addressbook.New(stateStore) addressbook := addressbook.New(stateStore)
signer := crypto.NewDefaultSigner(swarmPrivateKey)
p2ps, err := libp2p.New(p2pCtx, crypto.NewDefaultSigner(swarmPrivateKey), o.NetworkID, address, o.Addr, libp2p.Options{ p2ps, err := libp2p.New(p2pCtx, signer, o.NetworkID, address, o.Addr, libp2p.Options{
PrivateKey: libp2pPrivateKey, PrivateKey: libp2pPrivateKey,
DisableWS: o.DisableWS, DisableWS: o.DisableWS,
DisableQUIC: o.DisableQUIC, DisableQUIC: o.DisableQUIC,
...@@ -161,6 +163,7 @@ func NewBee(o Options) (*Bee, error) { ...@@ -161,6 +163,7 @@ func NewBee(o Options) (*Bee, error) {
hive := hive.New(hive.Options{ hive := hive.New(hive.Options{
Streamer: p2ps, Streamer: p2ps,
AddressBook: addressbook, AddressBook: addressbook,
NetworkID: o.NetworkID,
Logger: logger, Logger: logger,
}) })
...@@ -350,11 +353,19 @@ func NewBee(o Options) (*Bee, error) { ...@@ -350,11 +353,19 @@ func NewBee(o Options) (*Bee, error) {
return return
} }
err = addressbook.Put(overlay, addr) bzzAddr, err := bzz.NewAddress(signer, addr, overlay, o.NetworkID)
if err != nil {
_ = p2ps.Disconnect(overlay)
logger.Debugf("new bzz address error %s %s: %v", a, overlay, err)
logger.Errorf("connect to bootnode %s", a)
return
}
err = addressbook.Put(overlay, *bzzAddr)
if err != nil { if err != nil {
_ = p2ps.Disconnect(overlay) _ = p2ps.Disconnect(overlay)
logger.Debugf("addressbook error persisting %s %s: %v", a, overlay, err) logger.Debugf("addressbook error persisting %s %s: %v", a, overlay, err)
logger.Errorf("persisting node %s", a) logger.Errorf("connect to bootnode %s", a)
return return
} }
......
...@@ -6,12 +6,12 @@ package handshake ...@@ -6,12 +6,12 @@ package handshake
import ( import (
"bytes" "bytes"
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"sync" "sync"
"time" "time"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto" "github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/p2p"
...@@ -21,6 +21,7 @@ import ( ...@@ -21,6 +21,7 @@ import (
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
libp2ppeer "github.com/libp2p/go-libp2p-core/peer" libp2ppeer "github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
) )
const ( const (
...@@ -37,8 +38,8 @@ var ( ...@@ -37,8 +38,8 @@ var (
// ErrHandshakeDuplicate is returned if the handshake response has been received by an already processed peer. // ErrHandshakeDuplicate is returned if the handshake response has been received by an already processed peer.
ErrHandshakeDuplicate = errors.New("duplicate handshake") ErrHandshakeDuplicate = errors.New("duplicate handshake")
// ErrInvalidSignature is returned if peer info was received with invalid signature // ErrInvalidBzzAddress is returned if peer info was received with invalid bzz address
ErrInvalidSignature = errors.New("invalid signature") ErrInvalidBzzAddress = errors.New("invalid bzz address")
// ErrInvalidAck is returned if ack does not match the syn provided // ErrInvalidAck is returned if ack does not match the syn provided
ErrInvalidAck = errors.New("invalid ack") ErrInvalidAck = errors.New("invalid ack")
...@@ -50,39 +51,24 @@ type PeerFinder interface { ...@@ -50,39 +51,24 @@ type PeerFinder interface {
} }
type Service struct { type Service struct {
overlay swarm.Address bzzAddress bzz.Address
underlay []byte
signature []byte
signer crypto.Signer
networkID uint64 networkID uint64
networkIDBytes []byte
receivedHandshakes map[libp2ppeer.ID]struct{} receivedHandshakes map[libp2ppeer.ID]struct{}
receivedHandshakesMu sync.Mutex receivedHandshakesMu sync.Mutex
logger logging.Logger logger logging.Logger
network.Notifiee // handhsake service can be the receiver for network.Notify network.Notifiee // handshake service can be the receiver for network.Notify
} }
func New(overlay swarm.Address, peerID libp2ppeer.ID, signer crypto.Signer, networkID uint64, logger logging.Logger) (*Service, error) { func New(overlay swarm.Address, underlay ma.Multiaddr, signer crypto.Signer, networkID uint64, logger logging.Logger) (*Service, error) {
underlay, err := peerID.MarshalBinary() bzzAddress, err := bzz.NewAddress(signer, underlay, overlay, networkID)
if err != nil {
return nil, err
}
networkIDBytes := make([]byte, 8)
binary.BigEndian.PutUint64(networkIDBytes, networkID)
signature, err := signer.Sign(append(underlay, networkIDBytes...))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Service{ return &Service{
overlay: overlay, bzzAddress: *bzzAddress,
underlay: underlay,
signature: signature,
signer: signer,
networkID: networkID, networkID: networkID,
networkIDBytes: networkIDBytes,
receivedHandshakes: make(map[libp2ppeer.ID]struct{}), receivedHandshakes: make(map[libp2ppeer.ID]struct{}),
logger: logger, logger: logger,
Notifiee: new(network.NoopNotifiee), Notifiee: new(network.NoopNotifiee),
...@@ -93,9 +79,9 @@ func (s *Service) Handshake(stream p2p.Stream) (i *Info, err error) { ...@@ -93,9 +79,9 @@ func (s *Service) Handshake(stream p2p.Stream) (i *Info, err error) {
w, r := protobuf.NewWriterAndReader(stream) w, r := protobuf.NewWriterAndReader(stream)
if err := w.WriteMsgWithTimeout(messageTimeout, &pb.Syn{ if err := w.WriteMsgWithTimeout(messageTimeout, &pb.Syn{
BzzAddress: &pb.BzzAddress{ BzzAddress: &pb.BzzAddress{
Underlay: s.underlay, Underlay: s.bzzAddress.Underlay.Bytes(),
Signature: s.signature, Signature: s.bzzAddress.Signature,
Overlay: s.overlay.Bytes(), Overlay: s.bzzAddress.Overlay.Bytes(),
}, },
NetworkID: s.networkID, NetworkID: s.networkID,
}); err != nil { }); err != nil {
...@@ -111,8 +97,13 @@ func (s *Service) Handshake(stream p2p.Stream) (i *Info, err error) { ...@@ -111,8 +97,13 @@ func (s *Service) Handshake(stream p2p.Stream) (i *Info, err error) {
return nil, err return nil, err
} }
if err := s.checkSyn(resp.Syn); err != nil { if resp.Syn.NetworkID != s.networkID {
return nil, err return nil, ErrNetworkIDIncompatible
}
bzzAddress, err := bzz.ParseAddress(resp.Syn.BzzAddress.Underlay, resp.Syn.BzzAddress.Overlay, resp.Syn.BzzAddress.Signature, resp.Syn.NetworkID)
if err != nil {
return nil, ErrInvalidBzzAddress
} }
if err := w.WriteMsgWithTimeout(messageTimeout, &pb.Ack{ if err := w.WriteMsgWithTimeout(messageTimeout, &pb.Ack{
...@@ -123,10 +114,8 @@ func (s *Service) Handshake(stream p2p.Stream) (i *Info, err error) { ...@@ -123,10 +114,8 @@ func (s *Service) Handshake(stream p2p.Stream) (i *Info, err error) {
s.logger.Tracef("handshake finished for peer %s", swarm.NewAddress(resp.Syn.BzzAddress.Overlay).String()) s.logger.Tracef("handshake finished for peer %s", swarm.NewAddress(resp.Syn.BzzAddress.Overlay).String())
return &Info{ return &Info{
Overlay: swarm.NewAddress(resp.Syn.BzzAddress.Overlay), BzzAddress: bzzAddress,
Underlay: resp.Syn.BzzAddress.Underlay, Light: resp.Syn.Light,
NetworkID: resp.Syn.NetworkID,
Light: resp.Syn.Light,
}, nil }, nil
} }
...@@ -146,16 +135,21 @@ func (s *Service) Handle(stream p2p.Stream, peerID libp2ppeer.ID) (i *Info, err ...@@ -146,16 +135,21 @@ func (s *Service) Handle(stream p2p.Stream, peerID libp2ppeer.ID) (i *Info, err
return nil, fmt.Errorf("read syn message: %w", err) return nil, fmt.Errorf("read syn message: %w", err)
} }
if err := s.checkSyn(&req); err != nil { if req.NetworkID != s.networkID {
return nil, err return nil, ErrNetworkIDIncompatible
}
bzzAddress, err := bzz.ParseAddress(req.BzzAddress.Underlay, req.BzzAddress.Overlay, req.BzzAddress.Signature, req.NetworkID)
if err != nil {
return nil, ErrInvalidBzzAddress
} }
if err := w.WriteMsgWithTimeout(messageTimeout, &pb.SynAck{ if err := w.WriteMsgWithTimeout(messageTimeout, &pb.SynAck{
Syn: &pb.Syn{ Syn: &pb.Syn{
BzzAddress: &pb.BzzAddress{ BzzAddress: &pb.BzzAddress{
Underlay: s.underlay, Underlay: s.bzzAddress.Underlay.Bytes(),
Signature: s.signature, Signature: s.bzzAddress.Signature,
Overlay: s.overlay.Bytes(), Overlay: s.bzzAddress.Overlay.Bytes(),
}, },
NetworkID: s.networkID, NetworkID: s.networkID,
}, },
...@@ -173,12 +167,10 @@ func (s *Service) Handle(stream p2p.Stream, peerID libp2ppeer.ID) (i *Info, err ...@@ -173,12 +167,10 @@ func (s *Service) Handle(stream p2p.Stream, peerID libp2ppeer.ID) (i *Info, err
return nil, err return nil, err
} }
s.logger.Tracef("handshake finished for peer %s", req.BzzAddress.Overlay) s.logger.Tracef("handshake finished for peer %s", swarm.NewAddress(req.BzzAddress.Overlay).String())
return &Info{ return &Info{
Overlay: swarm.NewAddress(req.BzzAddress.Overlay), BzzAddress: bzzAddress,
Underlay: req.BzzAddress.Underlay, Light: req.Light,
NetworkID: req.NetworkID,
Light: req.Light,
}, nil }, nil
} }
...@@ -188,28 +180,10 @@ func (s *Service) Disconnected(_ network.Network, c network.Conn) { ...@@ -188,28 +180,10 @@ func (s *Service) Disconnected(_ network.Network, c network.Conn) {
delete(s.receivedHandshakes, c.RemotePeer()) delete(s.receivedHandshakes, c.RemotePeer())
} }
func (s *Service) checkSyn(syn *pb.Syn) error {
if syn.NetworkID != s.networkID {
return ErrNetworkIDIncompatible
}
recoveredPK, err := crypto.Recover(syn.BzzAddress.Signature, append(syn.BzzAddress.Underlay, s.networkIDBytes...))
if err != nil {
return ErrInvalidSignature
}
recoveredOverlay := crypto.NewOverlayAddress(*recoveredPK, syn.NetworkID)
if !bytes.Equal(recoveredOverlay.Bytes(), syn.BzzAddress.Overlay) {
return ErrInvalidSignature
}
return nil
}
func (s *Service) checkAck(ack *pb.Ack) error { func (s *Service) checkAck(ack *pb.Ack) error {
if !bytes.Equal(ack.BzzAddress.Overlay, s.overlay.Bytes()) || if !bytes.Equal(ack.BzzAddress.Overlay, s.bzzAddress.Overlay.Bytes()) ||
!bytes.Equal(ack.BzzAddress.Underlay, s.underlay) || !bytes.Equal(ack.BzzAddress.Underlay, s.bzzAddress.Underlay.Bytes()) ||
!bytes.Equal(ack.BzzAddress.Signature, s.signature) { !bytes.Equal(ack.BzzAddress.Signature, s.bzzAddress.Signature) {
return ErrInvalidAck return ErrInvalidAck
} }
...@@ -217,8 +191,6 @@ func (s *Service) checkAck(ack *pb.Ack) error { ...@@ -217,8 +191,6 @@ func (s *Service) checkAck(ack *pb.Ack) error {
} }
type Info struct { type Info struct {
Overlay swarm.Address BzzAddress *bzz.Address
Underlay []byte Light bool
NetworkID uint64
Light bool
} }
...@@ -6,26 +6,26 @@ package handshake_test ...@@ -6,26 +6,26 @@ package handshake_test
import ( import (
"bytes" "bytes"
"encoding/binary"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"testing" "testing"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto" "github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake" "github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake/mock" "github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake/mock"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake/pb" "github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake/pb"
"github.com/ethersphere/bee/pkg/p2p/protobuf" "github.com/ethersphere/bee/pkg/p2p/protobuf"
"github.com/ethersphere/bee/pkg/swarm"
"github.com/libp2p/go-libp2p-core/peer"
libp2ppeer "github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr"
) )
func TestHandshake(t *testing.T) { func TestHandshake(t *testing.T) {
logger := logging.New(ioutil.Discard, 0) logger := logging.New(ioutil.Discard, 0)
networkID := uint64(3)
node1ma, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/7070/p2p/16Uiu2HAkx8ULY8cTXhdVAcMmLcH9AsTKz6uBQ7DPLKRjMLgBVYkA") node1ma, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/7070/p2p/16Uiu2HAkx8ULY8cTXhdVAcMmLcH9AsTKz6uBQ7DPLKRjMLgBVYkA")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
...@@ -35,20 +35,7 @@ func TestHandshake(t *testing.T) { ...@@ -35,20 +35,7 @@ func TestHandshake(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
node1Addr, err := peer.AddrInfoFromP2pAddr(node1ma) node2AddrInfo, err := libp2ppeer.AddrInfoFromP2pAddr(node2ma)
if err != nil {
t.Fatal(err)
}
node2Addr, err := peer.AddrInfoFromP2pAddr(node2ma)
if err != nil {
t.Fatal(err)
}
node1Underlay, err := node1Addr.ID.MarshalBinary()
if err != nil {
t.Fatal(err)
}
node2Underlay, err := node2Addr.ID.MarshalBinary()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -62,48 +49,27 @@ func TestHandshake(t *testing.T) { ...@@ -62,48 +49,27 @@ func TestHandshake(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
node1Overlay := crypto.NewOverlayAddress(privateKey1.PublicKey, 3)
node2Overlay := crypto.NewOverlayAddress(privateKey2.PublicKey, 3)
node1Info := handshake.Info{
Overlay: node1Overlay,
Underlay: node1Underlay,
NetworkID: 3,
Light: false,
}
node2Info := handshake.Info{
Overlay: node2Overlay,
Underlay: node2Underlay,
NetworkID: 3,
Light: false,
}
signer1 := crypto.NewDefaultSigner(privateKey1) signer1 := crypto.NewDefaultSigner(privateKey1)
signer2 := crypto.NewDefaultSigner(privateKey2) signer2 := crypto.NewDefaultSigner(privateKey2)
networkIDBytes := make([]byte, 8) node1BzzAddress, err := bzz.NewAddress(signer1, node1ma, crypto.NewOverlayAddress(privateKey1.PublicKey, networkID), networkID)
binary.BigEndian.PutUint64(networkIDBytes, node1Info.NetworkID)
signature1, err := signer1.Sign(append(node1Underlay, networkIDBytes...))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
node2BzzAddress, err := bzz.NewAddress(signer2, node2ma, crypto.NewOverlayAddress(privateKey2.PublicKey, networkID), networkID)
signature2, err := signer2.Sign(append(node2Underlay, networkIDBytes...))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
node1BzzAddress := &pb.BzzAddress{ node1Info := handshake.Info{
Overlay: node1Info.Overlay.Bytes(), BzzAddress: node1BzzAddress,
Underlay: node1Info.Underlay, Light: false,
Signature: signature1,
} }
node2BzzAddress := &pb.BzzAddress{ node2Info := handshake.Info{
Overlay: node2Info.Overlay.Bytes(), BzzAddress: node2BzzAddress,
Underlay: node2Info.Underlay, Light: false,
Signature: signature2,
} }
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -117,11 +83,19 @@ func TestHandshake(t *testing.T) { ...@@ -117,11 +83,19 @@ func TestHandshake(t *testing.T) {
w, r := protobuf.NewWriterAndReader(stream2) w, r := protobuf.NewWriterAndReader(stream2)
if err := w.WriteMsg(&pb.SynAck{ if err := w.WriteMsg(&pb.SynAck{
Syn: &pb.Syn{ Syn: &pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}, },
Ack: &pb.Ack{BzzAddress: node1BzzAddress}, Ack: &pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node1BzzAddress.Underlay.Bytes(),
Overlay: node1BzzAddress.Overlay.Bytes(),
Signature: node1BzzAddress.Signature,
}},
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -179,11 +153,19 @@ func TestHandshake(t *testing.T) { ...@@ -179,11 +153,19 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.SynAck{ if err := w.WriteMsg(&pb.SynAck{
Syn: &pb.Syn{ Syn: &pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}, },
Ack: &pb.Ack{BzzAddress: node1BzzAddress}, Ack: &pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node1BzzAddress.Underlay.Bytes(),
Overlay: node1BzzAddress.Overlay.Bytes(),
Signature: node1BzzAddress.Signature,
}},
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -207,11 +189,19 @@ func TestHandshake(t *testing.T) { ...@@ -207,11 +189,19 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.SynAck{ if err := w.WriteMsg(&pb.SynAck{
Syn: &pb.Syn{ Syn: &pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: 5, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
NetworkID: 5,
Light: node2Info.Light,
}, },
Ack: &pb.Ack{BzzAddress: node1BzzAddress}, Ack: &pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node1BzzAddress.Underlay.Bytes(),
Overlay: node1BzzAddress.Overlay.Bytes(),
Signature: node1BzzAddress.Signature,
}},
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -235,11 +225,19 @@ func TestHandshake(t *testing.T) { ...@@ -235,11 +225,19 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.SynAck{ if err := w.WriteMsg(&pb.SynAck{
Syn: &pb.Syn{ Syn: &pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}, },
Ack: &pb.Ack{BzzAddress: node2BzzAddress}, Ack: &pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node2BzzAddress.Underlay.Bytes(),
Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
}},
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -264,14 +262,18 @@ func TestHandshake(t *testing.T) { ...@@ -264,14 +262,18 @@ func TestHandshake(t *testing.T) {
if err := w.WriteMsg(&pb.SynAck{ if err := w.WriteMsg(&pb.SynAck{
Syn: &pb.Syn{ Syn: &pb.Syn{
BzzAddress: &pb.BzzAddress{ BzzAddress: &pb.BzzAddress{
Underlay: node2BzzAddress.Underlay, Underlay: node2BzzAddress.Underlay.Bytes(),
Signature: []byte("wrong signature"), Overlay: []byte("wrong signature"),
Overlay: node2BzzAddress.Overlay, Signature: node2BzzAddress.Signature,
}, },
NetworkID: node2Info.NetworkID,
Light: node2Info.Light, Light: node2Info.Light,
NetworkID: networkID,
}, },
Ack: &pb.Ack{BzzAddress: node1BzzAddress}, Ack: &pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node1BzzAddress.Underlay.Bytes(),
Overlay: node1BzzAddress.Overlay.Bytes(),
Signature: node1BzzAddress.Signature,
}},
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -281,13 +283,13 @@ func TestHandshake(t *testing.T) { ...@@ -281,13 +283,13 @@ func TestHandshake(t *testing.T) {
t.Fatal("res should be nil") t.Fatal("res should be nil")
} }
if err != handshake.ErrInvalidSignature { if err != handshake.ErrInvalidBzzAddress {
t.Fatalf("expected %s, got %s", handshake.ErrInvalidSignature, err) t.Fatalf("expected %s, got %s", handshake.ErrInvalidBzzAddress, err)
} }
}) })
t.Run("Handle - OK", func(t *testing.T) { t.Run("Handle - OK", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -298,18 +300,26 @@ func TestHandshake(t *testing.T) { ...@@ -298,18 +300,26 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := w.WriteMsg(&pb.Ack{BzzAddress: node1BzzAddress}); err != nil { if err := w.WriteMsg(&pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node1BzzAddress.Underlay.Bytes(),
Overlay: node1BzzAddress.Overlay.Bytes(),
Signature: node1BzzAddress.Signature,
}}); err != nil {
t.Fatal(err) t.Fatal(err)
} }
res, err := handshakeService.Handle(stream1, node2Addr.ID) res, err := handshakeService.Handle(stream1, node2AddrInfo.ID)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -322,16 +332,19 @@ func TestHandshake(t *testing.T) { ...@@ -322,16 +332,19 @@ func TestHandshake(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
bzzAddress, err := bzz.ParseAddress(got.Syn.BzzAddress.Underlay, got.Syn.BzzAddress.Overlay, got.Syn.BzzAddress.Signature, got.Syn.NetworkID)
if err != nil {
t.Fatal(err)
}
testInfo(t, node1Info, handshake.Info{ testInfo(t, node1Info, handshake.Info{
Overlay: swarm.NewAddress(got.Syn.BzzAddress.Overlay), BzzAddress: bzzAddress,
Underlay: got.Syn.BzzAddress.Underlay, Light: got.Syn.Light,
NetworkID: got.Syn.NetworkID,
Light: got.Syn.Light,
}) })
}) })
t.Run("Handle - read error ", func(t *testing.T) { t.Run("Handle - read error ", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -339,7 +352,7 @@ func TestHandshake(t *testing.T) { ...@@ -339,7 +352,7 @@ func TestHandshake(t *testing.T) {
expectedErr := fmt.Errorf("read syn message: %w", testErr) expectedErr := fmt.Errorf("read syn message: %w", testErr)
stream := &mock.Stream{} stream := &mock.Stream{}
stream.SetReadErr(testErr, 0) stream.SetReadErr(testErr, 0)
res, err := handshakeService.Handle(stream, node2Addr.ID) res, err := handshakeService.Handle(stream, node2AddrInfo.ID)
if err == nil || err.Error() != expectedErr.Error() { if err == nil || err.Error() != expectedErr.Error() {
t.Fatal("expected:", expectedErr, "got:", err) t.Fatal("expected:", expectedErr, "got:", err)
} }
...@@ -350,7 +363,7 @@ func TestHandshake(t *testing.T) { ...@@ -350,7 +363,7 @@ func TestHandshake(t *testing.T) {
}) })
t.Run("Handle - write error ", func(t *testing.T) { t.Run("Handle - write error ", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -361,14 +374,18 @@ func TestHandshake(t *testing.T) { ...@@ -361,14 +374,18 @@ func TestHandshake(t *testing.T) {
stream.SetWriteErr(testErr, 1) stream.SetWriteErr(testErr, 1)
w := protobuf.NewWriter(stream) w := protobuf.NewWriter(stream)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
res, err := handshakeService.Handle(stream, node2Addr.ID) res, err := handshakeService.Handle(stream, node2AddrInfo.ID)
if err == nil || err.Error() != expectedErr.Error() { if err == nil || err.Error() != expectedErr.Error() {
t.Fatal("expected:", expectedErr, "got:", err) t.Fatal("expected:", expectedErr, "got:", err)
} }
...@@ -379,7 +396,7 @@ func TestHandshake(t *testing.T) { ...@@ -379,7 +396,7 @@ func TestHandshake(t *testing.T) {
}) })
t.Run("Handle - ack read error ", func(t *testing.T) { t.Run("Handle - ack read error ", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -392,14 +409,18 @@ func TestHandshake(t *testing.T) { ...@@ -392,14 +409,18 @@ func TestHandshake(t *testing.T) {
stream1.SetReadErr(testErr, 1) stream1.SetReadErr(testErr, 1)
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
res, err := handshakeService.Handle(stream1, node2Addr.ID) res, err := handshakeService.Handle(stream1, node2AddrInfo.ID)
if err == nil || err.Error() != expectedErr.Error() { if err == nil || err.Error() != expectedErr.Error() {
t.Fatal("expected:", expectedErr, "got:", err) t.Fatal("expected:", expectedErr, "got:", err)
} }
...@@ -410,7 +431,7 @@ func TestHandshake(t *testing.T) { ...@@ -410,7 +431,7 @@ func TestHandshake(t *testing.T) {
}) })
t.Run("Handle - networkID mismatch ", func(t *testing.T) { t.Run("Handle - networkID mismatch ", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -421,14 +442,18 @@ func TestHandshake(t *testing.T) { ...@@ -421,14 +442,18 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: 5, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
NetworkID: 5,
Light: node2Info.Light,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
res, err := handshakeService.Handle(stream1, node2Addr.ID) res, err := handshakeService.Handle(stream1, node2AddrInfo.ID)
if res != nil { if res != nil {
t.Fatal("res should be nil") t.Fatal("res should be nil")
} }
...@@ -439,7 +464,7 @@ func TestHandshake(t *testing.T) { ...@@ -439,7 +464,7 @@ func TestHandshake(t *testing.T) {
}) })
t.Run("Handle - duplicate handshake", func(t *testing.T) { t.Run("Handle - duplicate handshake", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -450,18 +475,26 @@ func TestHandshake(t *testing.T) { ...@@ -450,18 +475,26 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := w.WriteMsg(&pb.Ack{BzzAddress: node1BzzAddress}); err != nil { if err := w.WriteMsg(&pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node1BzzAddress.Underlay.Bytes(),
Overlay: node1BzzAddress.Overlay.Bytes(),
Signature: node1BzzAddress.Signature,
}}); err != nil {
t.Fatal(err) t.Fatal(err)
} }
res, err := handshakeService.Handle(stream1, node2Addr.ID) res, err := handshakeService.Handle(stream1, node2AddrInfo.ID)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -474,21 +507,24 @@ func TestHandshake(t *testing.T) { ...@@ -474,21 +507,24 @@ func TestHandshake(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
bzzAddress, err := bzz.ParseAddress(got.Syn.BzzAddress.Underlay, got.Syn.BzzAddress.Overlay, got.Syn.BzzAddress.Signature, got.Syn.NetworkID)
if err != nil {
t.Fatal(err)
}
testInfo(t, node1Info, handshake.Info{ testInfo(t, node1Info, handshake.Info{
Overlay: swarm.NewAddress(got.Syn.BzzAddress.Overlay), BzzAddress: bzzAddress,
Underlay: got.Syn.BzzAddress.Underlay, Light: got.Syn.Light,
NetworkID: got.Syn.NetworkID,
Light: got.Syn.Light,
}) })
_, err = handshakeService.Handle(stream1, node2Addr.ID) _, err = handshakeService.Handle(stream1, node2AddrInfo.ID)
if err != handshake.ErrHandshakeDuplicate { if err != handshake.ErrHandshakeDuplicate {
t.Fatalf("expected %s, got %s", handshake.ErrHandshakeDuplicate, err) t.Fatalf("expected %s, got %s", handshake.ErrHandshakeDuplicate, err)
} }
}) })
t.Run("Handle - invalid ack", func(t *testing.T) { t.Run("Handle - invalid ack", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -499,25 +535,33 @@ func TestHandshake(t *testing.T) { ...@@ -499,25 +535,33 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: node2BzzAddress, BzzAddress: &pb.BzzAddress{
NetworkID: node2Info.NetworkID, Underlay: node2BzzAddress.Underlay.Bytes(),
Light: node2Info.Light, Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
},
Light: node2Info.Light,
NetworkID: networkID,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := w.WriteMsg(&pb.Ack{BzzAddress: node2BzzAddress}); err != nil { if err := w.WriteMsg(&pb.Ack{BzzAddress: &pb.BzzAddress{
Underlay: node2BzzAddress.Underlay.Bytes(),
Overlay: node2BzzAddress.Overlay.Bytes(),
Signature: node2BzzAddress.Signature,
}}); err != nil {
t.Fatal(err) t.Fatal(err)
} }
_, err = handshakeService.Handle(stream1, node2Addr.ID) _, err = handshakeService.Handle(stream1, node2AddrInfo.ID)
if err != handshake.ErrInvalidAck { if err != handshake.ErrInvalidAck {
t.Fatalf("expected %s, got %s", handshake.ErrInvalidAck, err) t.Fatalf("expected %s, got %s", handshake.ErrInvalidAck, err)
} }
}) })
t.Run("Handle - invalid signature ", func(t *testing.T) { t.Run("Handle - invalid signature ", func(t *testing.T) {
handshakeService, err := handshake.New(node1Info.Overlay, node1Addr.ID, signer1, node1Info.NetworkID, logger) handshakeService, err := handshake.New(node1Info.BzzAddress.Overlay, node1Info.BzzAddress.Underlay, signer1, networkID, logger)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -529,23 +573,23 @@ func TestHandshake(t *testing.T) { ...@@ -529,23 +573,23 @@ func TestHandshake(t *testing.T) {
w := protobuf.NewWriter(stream2) w := protobuf.NewWriter(stream2)
if err := w.WriteMsg(&pb.Syn{ if err := w.WriteMsg(&pb.Syn{
BzzAddress: &pb.BzzAddress{ BzzAddress: &pb.BzzAddress{
Underlay: node2BzzAddress.Underlay, Underlay: node2BzzAddress.Underlay.Bytes(),
Signature: []byte("wrong signature"), Overlay: []byte("wrong signature"),
Overlay: node2BzzAddress.Overlay, Signature: node2BzzAddress.Signature,
}, },
NetworkID: node2Info.NetworkID, NetworkID: networkID,
Light: node2Info.Light, Light: node2Info.Light,
}); err != nil { }); err != nil {
t.Fatal(err) t.Fatal(err)
} }
res, err := handshakeService.Handle(stream1, node2Addr.ID) res, err := handshakeService.Handle(stream1, node2AddrInfo.ID)
if res != nil { if res != nil {
t.Fatal("res should be nil") t.Fatal("res should be nil")
} }
if err != handshake.ErrInvalidSignature { if err != handshake.ErrInvalidBzzAddress {
t.Fatalf("expected %s, got %s", handshake.ErrInvalidSignature, err) t.Fatalf("expected %s, got %s", handshake.ErrInvalidBzzAddress, err)
} }
}) })
} }
...@@ -553,7 +597,7 @@ func TestHandshake(t *testing.T) { ...@@ -553,7 +597,7 @@ func TestHandshake(t *testing.T) {
// testInfo validates if two Info instances are equal. // testInfo validates if two Info instances are equal.
func testInfo(t *testing.T, got, want handshake.Info) { func testInfo(t *testing.T, got, want handshake.Info) {
t.Helper() t.Helper()
if !got.Overlay.Equal(want.Overlay) || !bytes.Equal(got.Underlay, want.Underlay) || got.NetworkID != want.NetworkID || got.Light != want.Light { if !got.BzzAddress.Equal(want.BzzAddress) || got.Light != want.Light {
t.Fatalf("got info %+v, want %+v", got, want) t.Fatalf("got info %+v, want %+v", got, want)
} }
} }
...@@ -155,7 +155,13 @@ func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay ...@@ -155,7 +155,13 @@ func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay
return nil, fmt.Errorf("autonat: %w", err) return nil, fmt.Errorf("autonat: %w", err)
} }
handshakeService, err := handshake.New(overlay, h.ID(), signer, networkID, o.Logger) // todo: handle different underlays
underlay, err := buildUnderlayAddress(h.Addrs()[0], h.ID())
if err != nil {
return nil, fmt.Errorf("build host multiaddress: %w", err)
}
handshakeService, err := handshake.New(overlay, underlay, signer, networkID, o.Logger)
if err != nil { if err != nil {
return nil, fmt.Errorf("handshake service: %w", err) return nil, fmt.Errorf("handshake service: %w", err)
} }
...@@ -193,21 +199,14 @@ func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay ...@@ -193,21 +199,14 @@ func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay
return return
} }
if exists := s.peers.addIfNotExists(stream.Conn(), i.Overlay); exists { if exists := s.peers.addIfNotExists(stream.Conn(), i.BzzAddress.Overlay); exists {
_ = stream.Close() _ = stream.Close()
return return
} }
_ = stream.Close() _ = stream.Close()
remoteMultiaddr, err := ma.NewMultiaddr(fmt.Sprintf("%s/p2p/%s", stream.Conn().RemoteMultiaddr().String(), peerID.Pretty()))
if err != nil {
s.logger.Debugf("multiaddr error: handle %s: %v", peerID, err)
s.logger.Errorf("unable to connect with peer %v", peerID)
_ = s.disconnect(peerID)
return
}
err = s.addressbook.Put(i.Overlay, remoteMultiaddr) err = s.addressbook.Put(i.BzzAddress.Overlay, *i.BzzAddress)
if err != nil { if err != nil {
s.logger.Debugf("handshake: addressbook put error %s: %v", peerID, err) s.logger.Debugf("handshake: addressbook put error %s: %v", peerID, err)
s.logger.Errorf("unable to persist peer %v", peerID) s.logger.Errorf("unable to persist peer %v", peerID)
...@@ -216,13 +215,13 @@ func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay ...@@ -216,13 +215,13 @@ func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay
} }
if s.topologyNotifier != nil { if s.topologyNotifier != nil {
if err := s.topologyNotifier.Connected(ctx, i.Overlay); err != nil { if err := s.topologyNotifier.Connected(ctx, i.BzzAddress.Overlay); err != nil {
s.logger.Debugf("peerhandler error: %s: %v", peerID, err) s.logger.Debugf("topology notifier: %s: %v", peerID, err)
} }
} }
s.metrics.HandledStreamCount.Inc() s.metrics.HandledStreamCount.Inc()
s.logger.Infof("peer %s connected", i.Overlay) s.logger.Infof("peer %s connected", i.BzzAddress.Overlay)
}) })
h.Network().SetConnHandler(func(_ network.Conn) { h.Network().SetConnHandler(func(_ network.Conn) {
...@@ -287,19 +286,27 @@ func (s *Service) AddProtocol(p p2p.ProtocolSpec) (err error) { ...@@ -287,19 +286,27 @@ func (s *Service) AddProtocol(p p2p.ProtocolSpec) (err error) {
return nil return nil
} }
func (s *Service) Addresses() (addrs []ma.Multiaddr, err error) { func (s *Service) Addresses() (addreses []ma.Multiaddr, err error) {
for _, addr := range s.host.Addrs() {
a, err := buildUnderlayAddress(addr, s.host.ID())
if err != nil {
return nil, err
}
addreses = append(addreses, a)
}
return addreses, nil
}
func buildUnderlayAddress(addr ma.Multiaddr, peerID libp2ppeer.ID) (ma.Multiaddr, error) {
// Build host multiaddress // Build host multiaddress
hostAddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", s.host.ID().Pretty())) hostAddr, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", peerID.Pretty()))
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Now we can build a full multiaddress to reach this host return addr.Encapsulate(hostAddr), nil
// by encapsulating both addresses:
for _, addr := range s.host.Addrs() {
addrs = append(addrs, addr.Encapsulate(hostAddr))
}
return addrs, nil
} }
func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm.Address, err error) { func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm.Address, err error) {
...@@ -332,12 +339,12 @@ func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm ...@@ -332,12 +339,12 @@ func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm
return swarm.Address{}, fmt.Errorf("handshake: %w", err) return swarm.Address{}, fmt.Errorf("handshake: %w", err)
} }
if exists := s.peers.addIfNotExists(stream.Conn(), i.Overlay); exists { if exists := s.peers.addIfNotExists(stream.Conn(), i.BzzAddress.Overlay); exists {
if err := helpers.FullClose(stream); err != nil { if err := helpers.FullClose(stream); err != nil {
return swarm.Address{}, err return swarm.Address{}, err
} }
return i.Overlay, nil return i.BzzAddress.Overlay, nil
} }
if err := helpers.FullClose(stream); err != nil { if err := helpers.FullClose(stream); err != nil {
...@@ -345,8 +352,8 @@ func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm ...@@ -345,8 +352,8 @@ func (s *Service) Connect(ctx context.Context, addr ma.Multiaddr) (overlay swarm
} }
s.metrics.CreatedConnectionCount.Inc() s.metrics.CreatedConnectionCount.Inc()
s.logger.Infof("peer %s connected", i.Overlay) s.logger.Infof("peer %s connected", i.BzzAddress.Overlay)
return i.Overlay, nil return i.BzzAddress.Overlay, nil
} }
func (s *Service) Disconnect(overlay swarm.Address) error { func (s *Service) Disconnect(overlay swarm.Address) error {
......
...@@ -68,9 +68,8 @@ func (d *driver) AddPeer(ctx context.Context, addr swarm.Address) error { ...@@ -68,9 +68,8 @@ func (d *driver) AddPeer(ctx context.Context, addr swarm.Address) error {
d.receivedPeers[addr.ByteString()] = struct{}{} d.receivedPeers[addr.ByteString()] = struct{}{}
d.mtx.Unlock() d.mtx.Unlock()
connectedPeers := d.p2pService.Peers() connectedPeers := d.p2pService.Peers()
ma, err := d.addressBook.Get(addr) bzzAddress, err := d.addressBook.Get(addr)
if err != nil { if err != nil {
if errors.Is(err, storage.ErrNotFound) { if errors.Is(err, storage.ErrNotFound) {
return topology.ErrNotFound return topology.ErrNotFound
...@@ -79,7 +78,7 @@ func (d *driver) AddPeer(ctx context.Context, addr swarm.Address) error { ...@@ -79,7 +78,7 @@ func (d *driver) AddPeer(ctx context.Context, addr swarm.Address) error {
} }
if !isConnected(addr, connectedPeers) { if !isConnected(addr, connectedPeers) {
peerAddr, err := d.p2pService.Connect(ctx, ma) _, err := d.p2pService.Connect(ctx, bzzAddress.Underlay)
if err != nil { if err != nil {
d.mtx.Lock() d.mtx.Lock()
delete(d.receivedPeers, addr.ByteString()) delete(d.receivedPeers, addr.ByteString())
...@@ -91,15 +90,6 @@ func (d *driver) AddPeer(ctx context.Context, addr swarm.Address) error { ...@@ -91,15 +90,6 @@ func (d *driver) AddPeer(ctx context.Context, addr swarm.Address) error {
} }
return err return err
} }
// update addr if it is wrong or it has been changed
if !addr.Equal(peerAddr) {
addr = peerAddr
err := d.addressBook.Put(peerAddr, ma)
if err != nil {
return err
}
}
} }
connectedAddrs := []swarm.Address{} connectedAddrs := []swarm.Address{}
...@@ -192,7 +182,6 @@ func (d *driver) backoff(tryAfter time.Time) { ...@@ -192,7 +182,6 @@ func (d *driver) backoff(tryAfter time.Time) {
} }
d.backoffActive = true d.backoffActive = true
done := make(chan struct{}) done := make(chan struct{})
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
go func() { go func() {
...@@ -205,13 +194,11 @@ func (d *driver) backoff(tryAfter time.Time) { ...@@ -205,13 +194,11 @@ func (d *driver) backoff(tryAfter time.Time) {
go func() { go func() {
defer func() { close(done) }() defer func() { close(done) }()
select { select {
case <-time.After(time.Until(tryAfter)): case <-time.After(time.Until(tryAfter)):
d.mtx.Lock() d.mtx.Lock()
d.backoffActive = false d.backoffActive = false
d.mtx.Unlock() d.mtx.Unlock()
addresses, _ := d.addressBook.Overlays() addresses, _ := d.addressBook.Overlays()
for _, addr := range addresses { for _, addr := range addresses {
select { select {
......
...@@ -12,6 +12,8 @@ import ( ...@@ -12,6 +12,8 @@ import (
"testing" "testing"
"github.com/ethersphere/bee/pkg/addressbook" "github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/discovery/mock" "github.com/ethersphere/bee/pkg/discovery/mock"
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/p2p"
...@@ -25,8 +27,21 @@ import ( ...@@ -25,8 +27,21 @@ import (
func TestAddPeer(t *testing.T) { func TestAddPeer(t *testing.T) {
logger := logging.New(ioutil.Discard, 0) logger := logging.New(ioutil.Discard, 0)
underlay := "/ip4/127.0.0.1/tcp/7070/p2p/16Uiu2HAkx8ULY8cTXhdVAcMmLcH9AsTKz6uBQ7DPLKRjMLgBVYkS" underlay, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/7070/p2p/16Uiu2HAkx8ULY8cTXhdVAcMmLcH9AsTKz6uBQ7DPLKRjMLgBVYkS")
if err != nil {
t.Fatal(err)
}
overlay := swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59a") overlay := swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59a")
pk, err := crypto.GenerateSecp256k1Key()
if err != nil {
t.Fatal(err)
}
bzzAddr, err := bzz.NewAddress(crypto.NewDefaultSigner(pk), underlay, overlay, 1)
if err != nil {
t.Fatal(err)
}
connectedPeers := []p2p.Peer{ connectedPeers := []p2p.Peer{
{ {
Address: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59b"), Address: swarm.MustParseHexAddress("ca1e9f3938cc1425c6061b96ad9eb93e134dfe8734ad490164ef20af9d1cf59b"),
...@@ -43,23 +58,18 @@ func TestAddPeer(t *testing.T) { ...@@ -43,23 +58,18 @@ func TestAddPeer(t *testing.T) {
discovery := mock.NewDiscovery() discovery := mock.NewDiscovery()
statestore := mockstate.NewStateStore() statestore := mockstate.NewStateStore()
ab := addressbook.New(statestore) ab := addressbook.New(statestore)
p2p := p2pmock.New(p2pmock.WithConnectFunc(func(_ context.Context, addr ma.Multiaddr) (swarm.Address, error) { p2p := p2pmock.New(p2pmock.WithConnectFunc(func(_ context.Context, addr ma.Multiaddr) (swarm.Address, error) {
if addr.String() != underlay { if !addr.Equal(underlay) {
t.Fatalf("expected multiaddr %s, got %s", addr.String(), underlay) t.Fatalf("expected multiaddr %s, got %s", addr, underlay)
} }
return overlay, nil return overlay, nil
})) }))
fullDriver := full.New(discovery, ab, p2p, logger, overlay) fullDriver := full.New(discovery, ab, p2p, logger, overlay)
defer fullDriver.Close() defer fullDriver.Close()
multiaddr, err := ma.NewMultiaddr(underlay)
if err != nil {
t.Fatal(err)
}
err = ab.Put(overlay, multiaddr) if err := ab.Put(overlay, *bzzAddr); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -99,6 +109,10 @@ func TestAddPeer(t *testing.T) { ...@@ -99,6 +109,10 @@ func TestAddPeer(t *testing.T) {
statestore := mockstate.NewStateStore() statestore := mockstate.NewStateStore()
ab := addressbook.New(statestore) ab := addressbook.New(statestore)
alreadyConnected := connectedPeers[0].Address alreadyConnected := connectedPeers[0].Address
addrAlreadyConnected, err := bzz.NewAddress(crypto.NewDefaultSigner(pk), underlay, alreadyConnected, 1)
if err != nil {
t.Fatal(err)
}
p2p := p2pmock.New(p2pmock.WithConnectFunc(func(ctx context.Context, addr ma.Multiaddr) (swarm.Address, error) { p2p := p2pmock.New(p2pmock.WithConnectFunc(func(ctx context.Context, addr ma.Multiaddr) (swarm.Address, error) {
t.Fatal("should not be called") t.Fatal("should not be called")
...@@ -109,12 +123,8 @@ func TestAddPeer(t *testing.T) { ...@@ -109,12 +123,8 @@ func TestAddPeer(t *testing.T) {
fullDriver := full.New(discovery, ab, p2p, logger, overlay) fullDriver := full.New(discovery, ab, p2p, logger, overlay)
defer fullDriver.Close() defer fullDriver.Close()
multiaddr, err := ma.NewMultiaddr(underlay)
if err != nil {
t.Fatal("error creating multiaddr")
}
err = ab.Put(alreadyConnected, multiaddr) err = ab.Put(alreadyConnected, *addrAlreadyConnected)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -147,9 +157,10 @@ func TestAddPeer(t *testing.T) { ...@@ -147,9 +157,10 @@ func TestAddPeer(t *testing.T) {
ab := addressbook.New(statestore) ab := addressbook.New(statestore)
p2ps := p2pmock.New(p2pmock.WithConnectFunc(func(ctx context.Context, addr ma.Multiaddr) (swarm.Address, error) { p2ps := p2pmock.New(p2pmock.WithConnectFunc(func(ctx context.Context, addr ma.Multiaddr) (swarm.Address, error) {
if addr.String() != underlay { if !addr.Equal(underlay) {
t.Fatalf("expected multiaddr %s, got %s", addr.String(), underlay) t.Fatalf("expected multiaddr %s, got %s", addr.String(), underlay)
} }
return overlay, nil return overlay, nil
}), p2pmock.WithPeersFunc(func() []p2p.Peer { }), p2pmock.WithPeersFunc(func() []p2p.Peer {
return connectedPeers return connectedPeers
...@@ -157,13 +168,7 @@ func TestAddPeer(t *testing.T) { ...@@ -157,13 +168,7 @@ func TestAddPeer(t *testing.T) {
fullDriver := full.New(discovery, ab, p2ps, logger, overlay) fullDriver := full.New(discovery, ab, p2ps, logger, overlay)
defer fullDriver.Close() defer fullDriver.Close()
multiaddr, err := ma.NewMultiaddr(underlay) if err := ab.Put(overlay, *bzzAddr); err != nil {
if err != nil {
t.Fatal(err)
}
err = ab.Put(overlay, multiaddr)
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment