@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/harmony-one/harmony/p2p"
libp2p "github.com/libp2p/go-libp2p"
p2p_crypto "github.com/libp2p/go-libp2p-crypto"
libp2phost "github.com/libp2p/go-libp2p-host"
net "github.com/libp2p/go-libp2p-net"
peer "github.com/libp2p/go-libp2p-peer"
@ -23,8 +24,38 @@ const (
// HostV2 is the version 2 p2p host
type HostV2 struct {
h libp2phost . Host
self p2p . Peer
h libp2phost . Host
self p2p . Peer
priKey p2p_crypto . PrivKey
}
// AddPeer add p2p.Peer into Peerstore
func ( host * HostV2 ) AddPeer ( p * p2p . Peer ) error {
if p . PeerID != "" && len ( p . Addrs ) != 0 {
host . Peerstore ( ) . AddAddrs ( p . PeerID , p . Addrs , peerstore . PermanentAddrTTL )
return nil
}
if p . PeerID == "" {
log . Error ( "AddPeer PeerID is EMPTY" )
return nil
}
// reconstruct the multiaddress based on ip/port
// PeerID has to be known for the ip/port
addr := fmt . Sprintf ( "/ip4/%s/tcp/%s" , p . IP , p . Port )
targetAddr , err := multiaddr . NewMultiaddr ( addr )
if err != nil {
log . Error ( "AddPeer NewMultiaddr error" , "error" , err )
return err
}
p . Addrs = append ( p . Addrs , targetAddr )
host . Peerstore ( ) . AddAddrs ( p . PeerID , p . Addrs , peerstore . PermanentAddrTTL )
fmt . Printf ( "AddPeer add to peerstore: %v\n" , * p )
return nil
}
// Peerstore returns the peer store
@ -33,24 +64,34 @@ func (host *HostV2) Peerstore() peerstore.Peerstore {
}
// New creates a host for p2p communication
func New ( self p2p . Peer ) * HostV2 {
sourceAddr , err := multiaddr . NewMultiaddr ( fmt . Sprintf ( "/ip4/0.0.0.0/tcp/%s" , self . Port ) )
catchError ( err )
func New ( self p2p . Peer , priKey p2p_crypto . PrivKey ) * HostV2 {
// TODO (leo), use the [0] of Addrs for now, need to find a reliable way of using listenAddr
p2pHost , err := libp2p . New ( context . Background ( ) ,
libp2p . ListenAddrs ( sourc eAddr ) ,
libp2p . NoSecurity , // The security (signature generation and verification) is, for now, taken care by ourselves.
libp2p . ListenAddrs ( self . Addrs [ 0 ] ) ,
libp2p . Identity ( priKey ) ,
// TODO(ricl): Other features to probe
// libp2p.EnableRelay; libp2p.Routing;
)
catchError ( err )
log . Debug ( "HostV2 is up!" , "port" , self . Port , "id" , p2pHost . ID ( ) . Pretty ( ) , "addr" , sourceAddr )
log . Debug ( "HostV2 is up!" , "port" , self . Port , "id" , p2pHost . ID ( ) . Pretty ( ) , "addr" , self . Addrs )
// has to save the private key for host
h := & HostV2 {
h : p2pHost ,
self : self ,
h : p2pHost ,
self : self ,
priKey : priKey ,
}
return h
}
// GetID returns ID.Pretty
func ( host * HostV2 ) GetID ( ) peer . ID {
return host . h . ID ( )
}
// GetSelfPeer gets self peer
func ( host * HostV2 ) GetSelfPeer ( ) p2p . Peer {
return host . self
@ -67,14 +108,9 @@ func (host *HostV2) BindHandlerAndServe(handler p2p.StreamHandler) {
// SendMessage a p2p message sending function with signature compatible to p2pv1.
func ( host * HostV2 ) SendMessage ( p p2p . Peer , message [ ] byte ) error {
addr := fmt . Sprintf ( "/ip4/%s/tcp/%s" , p . IP , p . Port )
targetAddr , err := multiaddr . NewMultiaddr ( addr )
catchError ( err )
peerID := peer . ID ( addr )
host . Peerstore ( ) . AddAddrs ( peerID , [ ] multiaddr . Multiaddr { targetAddr } , peerstore . PermanentAddrTTL )
s , err := host . h . NewStream ( context . Background ( ) , peerID , ProtocolID )
s , err := host . h . NewStream ( context . Background ( ) , p . PeerID , ProtocolID )
if err != nil {
log . Error ( "Failed to send message" , "from" , host . self , "to" , p , "error" , err )
log . Error ( "Failed to send message" , "from" , host . self , "to" , p , "error" , err , "PeerID" , p . PeerID )
return err
}