github.com/annchain/OG@v0.0.9/og/peer.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package og
    15  
    16  import (
    17  	"errors"
    18  	"fmt"
    19  	"github.com/annchain/OG/arefactor/common/goroutine"
    20  	"github.com/annchain/OG/arefactor/og/types"
    21  	"github.com/annchain/OG/common/math"
    22  	"github.com/annchain/OG/og/message_archive"
    23  	"github.com/annchain/OG/types/msg"
    24  	"sync"
    25  	"time"
    26  
    27  	"github.com/annchain/OG/p2p"
    28  	"github.com/deckarep/golang-set"
    29  )
    30  
    31  var (
    32  	errClosed            = errors.New("peer set is closed")
    33  	errAlreadyRegistered = errors.New("peer is already registered")
    34  	errNotRegistered     = errors.New("peer is not registered")
    35  )
    36  
    37  const (
    38  	maxknownMsg = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS)
    39  
    40  	// maxqueuedMsg is the maximum number of transaction lists to queue up before
    41  	// dropping broadcasts. This is a sensitive number as a transaction list might
    42  	// contain a single transaction, or thousands.
    43  	maxqueuedMsg = 128
    44  
    45  	// maxQueuedProps is the maximum number of block propagations to queue up before
    46  	// dropping broadcasts. There's not much point in queueing stale blocks, so a few
    47  	// that might cover uncles should be enough.
    48  	maxQueuedProps = 4
    49  
    50  	// maxQueuedAnns is the maximum number of block announcements to queue up before
    51  	// dropping broadcasts. Similarly to block propagations, there's no point to queue
    52  	// above some healthy uncle limit, so use that.
    53  	maxQueuedAnns = 4
    54  
    55  	handshakeTimeout = 5 * time.Second
    56  )
    57  
    58  type peer struct {
    59  	id string
    60  
    61  	*p2p.Peer
    62  	rw p2p.MsgReadWriter
    63  
    64  	version  int         // Protocol Version negotiated
    65  	forkDrop *time.Timer // Timed connection dropper if forks aren't validated in time
    66  
    67  	head      types.Hash
    68  	seqId     uint64
    69  	lock      sync.RWMutex
    70  	knownMsg  mapset.Set           // Set of transaction hashes known to be known by this peer
    71  	queuedMsg chan []msg.OgMessage // Queue of transactions to broadcast to the peer
    72  	term      chan struct{}        // Termination channel to stop the broadcaster
    73  	outPath   bool
    74  	inPath    bool
    75  	inBound   bool
    76  }
    77  
    78  type PeerInfo struct {
    79  	Version     int    `json:"Version"`      // Ethereum protocol Version negotiated
    80  	SequencerId uint64 `json:"sequencer_id"` // Total difficulty of the peer's blockchain
    81  	Head        string `json:"head"`         // SHA3 Hash of the peer's best owned block
    82  	ShortId     string `json:"short_id"`
    83  	Link        bool   `json:"link"`
    84  	Addrs       string `json:"addrs"`
    85  	InBound     bool   `json:"in_bound"`
    86  }
    87  
    88  func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
    89  	return &peer{
    90  		Peer:      p,
    91  		rw:        rw,
    92  		version:   version,
    93  		id:        fmt.Sprintf("%x", p.ID().Bytes()[:8]),
    94  		knownMsg:  mapset.NewSet(),
    95  		queuedMsg: make(chan []msg.OgMessage, maxqueuedMsg),
    96  		term:      make(chan struct{}),
    97  		outPath:   true,
    98  		inPath:    true,
    99  		inBound:   p.Inbound(),
   100  	}
   101  }
   102  
   103  // broadcast is a write loop that multiplexes block propagations, announcements
   104  // and transaction broadcasts into the remote peer. The goal is to have an async
   105  // writer that does not lock up node internals.
   106  func (p *peer) broadcast() {
   107  	for {
   108  		select {
   109  		case msg := <-p.queuedMsg:
   110  			if err := p.SendMessages(msg); err != nil {
   111  				msgLog.WithError(err).Warn("send msg failed,quiting")
   112  				return
   113  			}
   114  			msgLog.WithField("count", len(msg)).Trace("Multicast messages")
   115  
   116  		case <-p.term:
   117  			msgLog.Debug("peer terminating,quiting")
   118  			return
   119  		}
   120  	}
   121  }
   122  
   123  func (p *peer) SetOutPath(v bool) bool {
   124  	if p.outPath == v {
   125  		return false
   126  	}
   127  	p.outPath = v
   128  	return true
   129  }
   130  
   131  func (p *peer) SetInPath(v bool) {
   132  	p.inPath = v
   133  }
   134  
   135  func (p *peer) CheckPath() (outPath, inpath bool) {
   136  	return p.outPath, p.inPath
   137  }
   138  
   139  // close signals the broadcast goroutine to terminate.
   140  func (p *peer) close() {
   141  	close(p.term)
   142  }
   143  
   144  // Info gathers and returns a collection of metadata known about a peer.
   145  func (p *peer) Info() *PeerInfo {
   146  	hash, seqId := p.Head()
   147  
   148  	return &PeerInfo{
   149  		Version:     p.version,
   150  		Head:        hash.Hex(),
   151  		SequencerId: seqId,
   152  		ShortId:     p.id,
   153  		Link:        p.outPath,
   154  		Addrs:       p.RemoteAddr().String(),
   155  		InBound:     p.inBound,
   156  	}
   157  }
   158  
   159  // Head retrieves a copy of the current head Hash and total difficulty of the
   160  // peer.
   161  func (p *peer) Head() (hash types.Hash, seqId uint64) {
   162  	p.lock.RLock()
   163  	defer p.lock.RUnlock()
   164  
   165  	copy(hash.Bytes[:], p.head.Bytes[:])
   166  	return hash, p.seqId
   167  }
   168  
   169  // SetHead updates the head Hash and total difficulty of the peer.
   170  func (p *peer) SetHead(hash types.Hash, seqId uint64) {
   171  	p.lock.Lock()
   172  	defer p.lock.Unlock()
   173  
   174  	copy(p.head.Bytes[:], hash.Bytes[:])
   175  	p.seqId = seqId
   176  }
   177  
   178  // MarkMessage marks a Message as known for the peer, ensuring that it
   179  // will never be propagated to this particular peer.
   180  func (p *peer) MarkMessage(m message_archive.BinaryMessageType, hash types.Hash) {
   181  	// If we reached the memory allowance, drop a previously known transaction Hash
   182  	for p.knownMsg.Cardinality() >= maxknownMsg {
   183  		p.knownMsg.Pop()
   184  	}
   185  	key := message_archive.NewMsgKey(m, hash)
   186  	p.knownMsg.Add(key)
   187  }
   188  
   189  // SendTransactions sends transactions to the peer and includes the hashes
   190  // in its transaction Hash set for future reference.
   191  func (p *peer) SendMessages(messages []msg.OgMessage) error {
   192  	var msgType msg.BinaryMessageType
   193  	var msgBytes []byte
   194  	if len(messages) == 0 {
   195  		return nil
   196  	}
   197  	for _, msg := range messages {
   198  		//duplicated
   199  		//key := msg.MsgKey()
   200  		//p.knownMsg.Add(key)
   201  		msgType = msg.MessageType
   202  		msgBytes = append(msgBytes, msg.Data...)
   203  	}
   204  	return p.sendRawMessage(msgType, msgBytes)
   205  }
   206  
   207  func (p *peer) sendRawMessage(msgType msg.BinaryMessageType, msgBytes []byte) error {
   208  	msgLog.WithField("to ", p.id).WithField("type ", msgType).WithField("size", len(msgBytes)).Trace("send msg")
   209  	return p2p.Send(p.rw, msgType.Code(), msgBytes)
   210  
   211  }
   212  
   213  // AsyncSendTransactions queues list of transactions propagation to a remote
   214  // peer. If the peer's broadcast queue is full, the event is silently dropped.
   215  func (p *peer) AsyncSendMessages(messages []*message_archive.types) {
   216  	select {
   217  	case p.queuedMsg <- messages:
   218  		for _, msg := range messages {
   219  			key := msg.MsgKey()
   220  			p.knownMsg.Add(key)
   221  		}
   222  	default:
   223  		msgLog.WithField("count", len(messages)).Debug("Dropping transaction propagation")
   224  	}
   225  }
   226  
   227  func (p *peer) AsyncSendMessage(msg *message_archive.types) {
   228  	var messages []*message_archive.types
   229  	messages = append(messages, msg)
   230  	select {
   231  	case p.queuedMsg <- messages:
   232  		key := msg.MsgKey()
   233  		p.knownMsg.Add(key)
   234  	default:
   235  		msgLog.Debug("Dropping transaction propagation")
   236  	}
   237  }
   238  
   239  // SendNodeData sends a batch of arbitrary internal Data, corresponding to the
   240  // hashes requested.
   241  func (p *peer) SendNodeData(data []byte) error {
   242  	return p.sendRawMessage(message_archive.NodeDataMsg, data)
   243  }
   244  
   245  // RequestNodeData fetches a batch of arbitrary Data from a node's known state
   246  // Data, corresponding to the specified hashes.
   247  func (p *peer) RequestNodeData(hashes types.Hashes) error {
   248  	msgLog.WithField("count", len(hashes)).Debug("Fetching batch of state Data")
   249  	hashsStruct := types.Hashes(hashes)
   250  	b, _ := hashsStruct.MarshalMsg(nil)
   251  	return p.sendRawMessage(message_archive.GetNodeDataMsg, b)
   252  }
   253  
   254  // RequestReceipts fetches a batch of transaction receipts from a remote node.
   255  func (p *peer) RequestReceipts(hashes types.Hashes) error {
   256  	msgLog.WithField("count", len(hashes)).Debug("Fetching batch of receipts")
   257  	b, _ := hashes.MarshalMsg(nil)
   258  	return p.sendRawMessage(message_archive.GetReceiptsMsg, b)
   259  }
   260  
   261  // RequestHeadersByHash fetches a batch of blocks' headers corresponding to the
   262  // specified header query, based on the Hash of an origin block.
   263  func (p *peer) RequestTxsByHash(seqHash types.Hash, seqId uint64) error {
   264  	hash := seqHash
   265  	msg := &p2p_message.MessageTxsRequest{
   266  		SeqHash:   &hash,
   267  		Id:        &seqId,
   268  		RequestId: message_archive.MsgCounter.Get(),
   269  	}
   270  	return p.sendRequest(message_archive.MessageTypeTxsRequest, msg)
   271  }
   272  
   273  func (p *peer) RequestTxs(hashs types.Hashes) error {
   274  	msg := &p2p_message.MessageTxsRequest{
   275  		Hashes:    &hashs,
   276  		RequestId: message_archive.MsgCounter.Get(),
   277  	}
   278  
   279  	return p.sendRequest(message_archive.MessageTypeTxsRequest, msg)
   280  }
   281  
   282  func (p *peer) RequestTxsById(seqId uint64) error {
   283  	msg := &p2p_message.MessageTxsRequest{
   284  		Id:        &seqId,
   285  		RequestId: message_archive.MsgCounter.Get(),
   286  	}
   287  	return p.sendRequest(message_archive.MessageTypeTxsRequest, msg)
   288  }
   289  
   290  func (p *peer) RequestBodies(seqHashs types.Hashes) error {
   291  	msg := &p2p_message.MessageBodiesRequest{
   292  		SeqHashes: seqHashs,
   293  		RequestId: message_archive.MsgCounter.Get(),
   294  	}
   295  	return p.sendRequest(message_archive.MessageTypeBodiesRequest, msg)
   296  }
   297  
   298  func (h *Hub) RequestOneHeader(peerId string, hash types.Hash) error {
   299  	p := h.peers.Peer(peerId)
   300  	if p == nil {
   301  		return fmt.Errorf("peer not found")
   302  	}
   303  	return p.RequestOneHeader(hash)
   304  }
   305  
   306  func (h *Hub) RequestBodies(peerId string, hashs types.Hashes) error {
   307  	p := h.peers.Peer(peerId)
   308  	if p == nil {
   309  		return fmt.Errorf("peer not found")
   310  	}
   311  	return p.RequestBodies(hashs)
   312  }
   313  
   314  func (p *peer) RequestOneHeader(hash types.Hash) error {
   315  	tmpHash := hash
   316  	msg := &p2p_message.MessageHeaderRequest{
   317  		Origin: p2p_message.HashOrNumber{
   318  			Hash: &tmpHash,
   319  		},
   320  		Amount:    uint64(1),
   321  		Skip:      uint64(0),
   322  		Reverse:   false,
   323  		RequestId: message_archive.MsgCounter.Get(),
   324  	}
   325  	return p.sendRequest(message_archive.MessageTypeHeaderRequest, msg)
   326  }
   327  
   328  // RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the
   329  // specified header query, based on the number of an origin block.
   330  func (p *peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error {
   331  	msg := &p2p_message.MessageHeaderRequest{
   332  		Origin: p2p_message.HashOrNumber{
   333  			Number: &origin,
   334  		},
   335  		Amount:    uint64(amount),
   336  		Skip:      uint64(skip),
   337  		Reverse:   reverse,
   338  		RequestId: message_archive.MsgCounter.Get(),
   339  	}
   340  	return p.sendRequest(message_archive.MessageTypeHeaderRequest, msg)
   341  }
   342  
   343  func (p *peer) RequestHeadersByHash(hash types.Hash, amount int, skip int, reverse bool) error {
   344  	tmpHash := hash
   345  	msg := &p2p_message.MessageHeaderRequest{
   346  		Origin: p2p_message.HashOrNumber{
   347  			Hash: &tmpHash,
   348  		},
   349  		Amount:    uint64(amount),
   350  		Skip:      uint64(skip),
   351  		Reverse:   reverse,
   352  		RequestId: message_archive.MsgCounter.Get(),
   353  	}
   354  	return p.sendRequest(message_archive.MessageTypeHeaderRequest, msg)
   355  }
   356  
   357  func (p *peer) sendRequest(msgType message_archive.BinaryMessageType, request p2p_message.Message) error {
   358  	clog := msgLog.WithField("msgType", msgType).WithField("request ", request).WithField("to", p.id)
   359  	data, err := request.MarshalMsg(nil)
   360  	if err != nil {
   361  		clog.WithError(err).Warn("encode request error")
   362  		return err
   363  	}
   364  	clog.WithField("size", len(data)).Debug("send")
   365  	err = p2p.Send(p.rw, p2p.MsgCodeType(msgType), data)
   366  	if err != nil {
   367  		clog.WithError(err).Warn("send failed")
   368  	}
   369  	return err
   370  }
   371  
   372  // String implements fmt.Stringer.
   373  func (p *peer) String() string {
   374  	return fmt.Sprintf("Sender-%s-[%s]-[%s]", p.id,
   375  		fmt.Sprintf("og/%2d", p.version), p.RemoteAddr().String(),
   376  	)
   377  }
   378  
   379  // peerSet represents the collection of active peers currently participating in
   380  // the Ethereum sub-protocol.
   381  type peerSet struct {
   382  	peers  map[string]*peer
   383  	lock   sync.RWMutex
   384  	closed bool
   385  }
   386  
   387  // newPeerSet creates a new peer set to track the active participants.
   388  func newPeerSet() *peerSet {
   389  	return &peerSet{
   390  		peers: make(map[string]*peer),
   391  	}
   392  }
   393  
   394  // Register injects a new peer into the working set, or returns an error if the
   395  // peer is already known. If a new peer it registered, its broadcast loop is also
   396  // started.
   397  func (ps *peerSet) Register(p *peer) error {
   398  	ps.lock.Lock()
   399  	defer ps.lock.Unlock()
   400  
   401  	if ps.closed {
   402  		return errClosed
   403  	}
   404  	if _, ok := ps.peers[p.id]; ok {
   405  		return errAlreadyRegistered
   406  	}
   407  	ps.peers[p.id] = p
   408  	goroutine.New(p.broadcast)
   409  
   410  	return nil
   411  }
   412  
   413  // Unregister removes a remote peer from the active set, disabling any further
   414  // actions to/from that particular entity.
   415  func (ps *peerSet) Unregister(id string) error {
   416  	ps.lock.Lock()
   417  	defer ps.lock.Unlock()
   418  
   419  	p, ok := ps.peers[id]
   420  	if !ok {
   421  		return errNotRegistered
   422  	}
   423  	delete(ps.peers, id)
   424  	p.close()
   425  
   426  	return nil
   427  }
   428  
   429  // Sender retrieves the registered peer with the given id.
   430  func (ps *peerSet) Peer(id string) *peer {
   431  	ps.lock.RLock()
   432  	defer ps.lock.RUnlock()
   433  
   434  	return ps.peers[id]
   435  }
   436  
   437  // Len returns if the current number of peers in the set.
   438  func (ps *peerSet) Len() int {
   439  	ps.lock.RLock()
   440  	defer ps.lock.RUnlock()
   441  
   442  	return len(ps.peers)
   443  }
   444  
   445  func (ps *peerSet) Peers() []*peer {
   446  	ps.lock.RLock()
   447  	defer ps.lock.RUnlock()
   448  	list := make([]*peer, 0, len(ps.peers))
   449  	for _, p := range ps.peers {
   450  		list = append(list, p)
   451  	}
   452  	return list
   453  }
   454  
   455  func (ps *peerSet) ValidPathNum() (outPath, inPath int) {
   456  	ps.lock.RLock()
   457  	defer ps.lock.RUnlock()
   458  	var out, in int
   459  	for _, p := range ps.peers {
   460  		if p.outPath {
   461  			out++
   462  		}
   463  		if p.inPath {
   464  			in++
   465  		}
   466  	}
   467  	return out, in
   468  }
   469  
   470  func (ps *peerSet) GetPeers(ids []string, n int) []*peer {
   471  	if len(ids) == 0 || n <= 0 {
   472  		return nil
   473  	}
   474  	ps.lock.RLock()
   475  	defer ps.lock.RUnlock()
   476  	all := make([]*peer, 0, len(ids))
   477  	list := make([]*peer, 0, n)
   478  	for _, id := range ids {
   479  		peer := ps.peers[id]
   480  		if peer != nil {
   481  			all = append(all, peer)
   482  		}
   483  	}
   484  	indices := math.GenerateRandomIndices(n, len(all))
   485  	for _, i := range indices {
   486  		list = append(list, all[i])
   487  	}
   488  	return list
   489  }
   490  
   491  func (ps *peerSet) GetRandomPeers(n int) []*peer {
   492  	ps.lock.RLock()
   493  	defer ps.lock.RUnlock()
   494  	all := make([]*peer, 0, len(ps.peers))
   495  	list := make([]*peer, 0, n)
   496  	for _, p := range ps.peers {
   497  		all = append(all, p)
   498  	}
   499  	indices := math.GenerateRandomIndices(n, len(all))
   500  	for _, i := range indices {
   501  		list = append(list, all[i])
   502  	}
   503  	return list
   504  }
   505  
   506  // PeersWithoutTx retrieves a list of peers that do not have a given transaction
   507  // in their set of known hashes.
   508  func (ps *peerSet) PeersWithoutMsg(hash types.Hash, m message_archive.BinaryMessageType) []*peer {
   509  	ps.lock.RLock()
   510  	defer ps.lock.RUnlock()
   511  
   512  	list := make([]*peer, 0, len(ps.peers))
   513  	if m == message_archive.MessageTypeNewTx || m == message_archive.MessageTypeNewSequencer {
   514  		keyControl := message_archive.NewMsgKey(message_archive.MessageTypeControl, hash)
   515  		key := message_archive.NewMsgKey(m, hash)
   516  		for _, p := range ps.peers {
   517  			if !p.knownMsg.Contains(key) && !p.knownMsg.Contains(keyControl) {
   518  				list = append(list, p)
   519  			}
   520  		}
   521  		return list
   522  	}
   523  	key := message_archive.NewMsgKey(m, hash)
   524  	for _, p := range ps.peers {
   525  		if !p.knownMsg.Contains(key) {
   526  			list = append(list, p)
   527  		}
   528  	}
   529  	return list
   530  }
   531  
   532  // BestPeer retrieves the known peer with the currently highest total difficulty.
   533  func (ps *peerSet) BestPeer() *peer {
   534  	ps.lock.RLock()
   535  	defer ps.lock.RUnlock()
   536  
   537  	var (
   538  		bestPeer *peer
   539  		bestId   uint64
   540  	)
   541  	for _, p := range ps.peers {
   542  		if _, seqId := p.Head(); bestPeer == nil || seqId > bestId {
   543  			bestPeer, bestId = p, seqId
   544  		}
   545  	}
   546  	return bestPeer
   547  }
   548  
   549  // Close disconnects all peers.
   550  // No new peers can be registered after Close has returned.
   551  func (ps *peerSet) Close() {
   552  	ps.lock.Lock()
   553  	defer ps.lock.Unlock()
   554  
   555  	for _, p := range ps.peers {
   556  		p.Disconnect(p2p.DiscQuitting)
   557  	}
   558  	ps.closed = true
   559  }
   560  
   561  // Handshake executes the og protocol handshake, negotiating Version number,
   562  // network IDs, head and genesis blocks.
   563  func (p *peer) Handshake(network uint64, head types.Hash, seqId uint64, genesis types.Hash) error {
   564  	// Send out own handshake in a new thread
   565  	errc := make(chan error, 2)
   566  	var status message_archive.StatusData // safe to read after two values have been received from errc
   567  
   568  	sendStatusFunc := func() {
   569  		s := message_archive.StatusData{
   570  			ProtocolVersion: uint32(p.version),
   571  			NetworkId:       network,
   572  			CurrentBlock:    head,
   573  			CurrentId:       seqId,
   574  			GenesisBlock:    genesis,
   575  		}
   576  		data, _ := s.MarshalMsg(nil)
   577  		errc <- p2p.Send(p.rw, p2p.MsgCodeType(message_archive.StatusMsg), data)
   578  	}
   579  	goroutine.New(sendStatusFunc)
   580  	readFunc := func() {
   581  		errc <- p.readStatus(network, &status, genesis)
   582  	}
   583  	goroutine.New(readFunc)
   584  	timeout := time.NewTimer(handshakeTimeout)
   585  	defer timeout.Stop()
   586  	for i := 0; i < 2; i++ {
   587  		select {
   588  		case err := <-errc:
   589  			if err != nil {
   590  				return err
   591  			}
   592  		case <-timeout.C:
   593  			return p2p.DiscReadTimeout
   594  		}
   595  	}
   596  	p.head = status.CurrentBlock
   597  	p.seqId = status.CurrentId
   598  	return nil
   599  }