github.com/annchain/OG@v0.0.9/og/hub.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/og/message_archive"
    22  	"github.com/annchain/OG/types/p2p_message"
    23  	"math/big"
    24  
    25  	"github.com/annchain/OG/common/crypto"
    26  	"github.com/annchain/OG/og/downloader"
    27  	"github.com/annchain/OG/og/fetcher"
    28  	"github.com/annchain/OG/p2p"
    29  	log "github.com/sirupsen/logrus"
    30  
    31  	"sync"
    32  	"time"
    33  
    34  	"github.com/annchain/OG/p2p/onode"
    35  	"github.com/annchain/gcache"
    36  )
    37  
    38  const (
    39  	softResponseLimit = 4 * 1024 * 1024 // Target maximum size of returned blocks, headers or node Data.
    40  	estHeaderRlpSize  = 500             // Approximate size of an RLP encoded block header
    41  
    42  	// txChanSize is the size of channel listening to NewTxsEvent.
    43  	// The number is referenced from the size of tx pool.
    44  	txChanSize          = 4096
    45  	DuplicateMsgPeerNum = 5
    46  )
    47  
    48  var errIncompatibleConfig = errors.New("incompatible configuration")
    49  
    50  // Hub is the middle layer between p2p and business layer
    51  // When there is a general request coming from the upper layer, Hub will find the appropriate peer to handle.
    52  // When there is a Message coming from p2p, Hub will unmarshall this Message and give it to Message router.
    53  // Hub will also prevent duplicate requests/responses.
    54  // If there is any failure, Hub is NOT responsible for changing a peer and retry. (maybe enhanced in the future.)
    55  // DO NOT INVOLVE ANY BUSINESS LOGICS HERE.
    56  type Hub struct {
    57  	outgoing chan *message_archive.types
    58  	incoming chan *message_archive.types
    59  	quit     chan bool
    60  	//CallbackRegistry     map[message.BinaryMessageType]func(*message.types) // All callbacks
    61  	//CallbackRegistryOG02 map[message.BinaryMessageType]func(*message.types) // All callbacks of OG02
    62  	StatusDataProvider NodeStatusDataProvider
    63  	peers              *peerSet
    64  	SubProtocols       []p2p.Protocol
    65  
    66  	wg sync.WaitGroup // wait group is used for graceful shutdowns during downloading and processing
    67  
    68  	messageCache gcache.Cache // cache for duplicate responses/msg to prevent storm
    69  	maxPeers     int
    70  	newPeerCh    chan *peer
    71  	noMorePeers  chan struct{}
    72  	quitSync     chan bool
    73  
    74  	// new peer event
    75  	OnNewPeerConnected []chan string
    76  	Downloader         *downloader.Downloader
    77  	Fetcher            *fetcher.Fetcher
    78  
    79  	NodeInfo             func() *p2p.NodeInfo
    80  	IsReceivedHash       func(hash types.Hash) bool
    81  	broadCastMode        uint8
    82  	encryptionPrivKey    *crypto.PrivateKey
    83  	encryptionPubKey     *crypto.PublicKey
    84  	disableEncryptGossip bool
    85  	MessageUnmarshaller  message_archive.typesUnmarshalManager
    86  }
    87  
    88  func (h *Hub) GetBenchmarks() map[string]interface{} {
    89  	m := map[string]interface{}{
    90  		"outgoing":     len(h.outgoing),
    91  		"incoming":     len(h.incoming),
    92  		"newPeerCh":    len(h.newPeerCh),
    93  		"messageCache": h.messageCache.Len(true),
    94  	}
    95  	peers := h.peers.Peers()
    96  	for _, p := range peers {
    97  		if p != nil {
    98  			key := "peer_" + p.id + "_knownMsg"
    99  			m[key] = p.knownMsg.Cardinality()
   100  		}
   101  	}
   102  	return m
   103  }
   104  
   105  type PeerProvider interface {
   106  	BestPeerInfo() (peerId string, hash types.Hash, seqId uint64, err error)
   107  	GetPeerHead(peerId string) (hash types.Hash, seqId uint64, err error)
   108  }
   109  
   110  type EncryptionLayer interface {
   111  	SetEncryptionKey(priv *crypto.PrivateKey)
   112  }
   113  
   114  type HubConfig struct {
   115  	OutgoingBufferSize            int
   116  	IncomingBufferSize            int
   117  	MessageCacheMaxSize           int
   118  	MessageCacheExpirationSeconds int
   119  	MaxPeers                      int
   120  	BroadCastMode                 uint8
   121  	DisableEncryptGossip          bool
   122  }
   123  
   124  const (
   125  	NormalMode uint8 = iota
   126  	FeedBackMode
   127  )
   128  
   129  func DefaultHubConfig() HubConfig {
   130  	config := HubConfig{
   131  		OutgoingBufferSize:            40,
   132  		IncomingBufferSize:            40,
   133  		MessageCacheMaxSize:           60,
   134  		MessageCacheExpirationSeconds: 3000,
   135  		MaxPeers:                      50,
   136  		BroadCastMode:                 NormalMode,
   137  		DisableEncryptGossip:          false,
   138  	}
   139  	return config
   140  }
   141  
   142  func (h *Hub) Init(config *HubConfig) {
   143  	h.outgoing = make(chan *message_archive.types, config.OutgoingBufferSize)
   144  	h.incoming = make(chan *message_archive.types, config.IncomingBufferSize)
   145  	h.peers = newPeerSet()
   146  	h.newPeerCh = make(chan *peer)
   147  	h.noMorePeers = make(chan struct{})
   148  	h.quit = make(chan bool)
   149  	h.maxPeers = config.MaxPeers
   150  	h.quitSync = make(chan bool)
   151  	h.messageCache = gcache.New(config.MessageCacheMaxSize).LRU().
   152  		Expiration(time.Second * time.Duration(config.MessageCacheExpirationSeconds)).Build()
   153  
   154  	//h.CallbackRegistryOG02 = make(map[message.BinaryMessageType]func(*message.types))
   155  	h.broadCastMode = config.BroadCastMode
   156  	h.disableEncryptGossip = config.DisableEncryptGossip
   157  }
   158  
   159  func NewHub(config *HubConfig) *Hub {
   160  	h := &Hub{}
   161  	h.Init(config)
   162  
   163  	h.SubProtocols = make([]p2p.Protocol, 0, len(ProtocolVersions))
   164  	for _, version := range ProtocolVersions {
   165  		// Skip protocol Version if incompatible with the mode of operation
   166  		// h.mode == downloader.FastSync &&
   167  		//if Version < OG32 {
   168  		//	continue
   169  		//}
   170  		//Compatible; initialise the sub-protocol
   171  		version := version // Closure for the run
   172  		h.SubProtocols = append(h.SubProtocols, p2p.Protocol{
   173  			Name:    ProtocolName,
   174  			Version: version,
   175  			// TODO: fix 777
   176  			//Length:  p2p.MsgCodeType(ProtocolLengths[i]),
   177  			Length:  p2p.MsgCodeType(777),
   178  			Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   179  				peer := h.newPeer(int(version), p, rw)
   180  				select {
   181  				case <-h.quitSync:
   182  					return p2p.DiscQuitting
   183  				default:
   184  					h.wg.Add(1)
   185  					defer h.wg.Done()
   186  					return h.handle(peer)
   187  				}
   188  			},
   189  			NodeInfo: func() interface{} {
   190  				return h.NodeStatus()
   191  			},
   192  			PeerInfo: func(id onode.ID) interface{} {
   193  				if p := h.peers.Peer(fmt.Sprintf("%x", id[:8])); p != nil {
   194  					return p.Info()
   195  				}
   196  				return nil
   197  			},
   198  		})
   199  	}
   200  
   201  	if len(h.SubProtocols) == 0 {
   202  		log.Error(errIncompatibleConfig)
   203  		return nil
   204  	}
   205  
   206  	return h
   207  }
   208  
   209  func (h *Hub) SetEncryptionKey(priv *crypto.PrivateKey) {
   210  	h.encryptionPrivKey = priv
   211  	h.encryptionPubKey = priv.PublicKey()
   212  }
   213  
   214  func (h *Hub) newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
   215  	return newPeer(version, p, rw)
   216  }
   217  
   218  // handle is the callback invoked to manage the life cycle of an eth peer. When
   219  // this function terminates, the peer is disconnected.
   220  func (h *Hub) handle(p *peer) error {
   221  	// Ignore maxPeers if this is a trusted peer
   222  	if h.peers.Len() >= h.maxPeers && !p.Peer.Info().Network.Trusted {
   223  		return p2p.DiscTooManyPeers
   224  	}
   225  	log.WithField("name", p.Name()).WithField("id", p.id).Info("OG peer connected")
   226  	// Execute the og handshake
   227  	statusData := h.StatusDataProvider.GetCurrentNodeStatus()
   228  	//if statusData.CurrentBlock == nil{
   229  	//	panic("Last sequencer is nil")
   230  	//}
   231  
   232  	if err := p.Handshake(statusData.NetworkId, statusData.CurrentBlock,
   233  		statusData.CurrentId, statusData.GenesisBlock); err != nil {
   234  		log.WithError(err).WithField("peer ", p.id).Debug("OG handshake failed")
   235  		return err
   236  	}
   237  	// Register the peer locally
   238  	if err := h.peers.Register(p); err != nil {
   239  		log.WithError(err).Error("og peer registration failed")
   240  		return err
   241  	}
   242  
   243  	log.Debug("register peer locally")
   244  
   245  	defer h.RemovePeer(p.id)
   246  	// Register the peer in the downloader. If the downloader considers it banned, we disconnect
   247  	if err := h.Downloader.RegisterPeer(p.id, p.version, p); err != nil {
   248  		return err
   249  	}
   250  	//announce new peer
   251  	h.newPeerCh <- p
   252  	// main loop. handle incoming messages.
   253  	for {
   254  		if err := h.handleMsg(p); err != nil {
   255  			log.WithError(err).Debug("og Message handling failed")
   256  			return err
   257  		}
   258  	}
   259  }
   260  
   261  
   262  // handleMsg is invoked whenever an inbound Message is received from a remote
   263  // peer. The remote connection is torn down upon returning any error.
   264  func (h *Hub) handleMsg(p *peer) error {
   265  	// Read the next Message from the remote peer, and ensure it's fully consumed
   266  	msg, err := p.rw.ReadMsg()
   267  	if err != nil {
   268  		return err
   269  	}
   270  	if msg.Size > ProtocolMaxMsgSize {
   271  		return message_archive.ErrResp(message_archive.ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
   272  	}
   273  	defer msg.Discard()
   274  	// Handle the Message depending on its contents
   275  	data, err := msg.GetPayLoad()
   276  	m := message_archive.types{MessageType: message_archive.BinaryMessageType(msg.Code), Data: data, SourceID: p.id, Version: p.version}
   277  	//log.Debug("start handle p2p Message ",p2pMsg.MessageType)
   278  	switch m.MessageType {
   279  	case message_archive.StatusMsg:
   280  		// Handle the Message depending on its contents
   281  
   282  		// Status messages should never arrive after the handshake
   283  		return message_archive.ErrResp(message_archive.ErrExtraStatusMsg, "uncontrolled status Message")
   284  		// Block header query, collect the requested headers and reply
   285  	case message_archive.MessageTypeDuplicate:
   286  		msgLog.WithField("got msg", m.MessageType).WithField("peer ", p.String()).Trace("set path to false")
   287  		if !p.SetOutPath(false) {
   288  			msgLog.WithField("got msg again ", m.MessageType).WithField("peer ", p.String()).Warn("set path to false")
   289  		}
   290  		return nil
   291  	case message_archive.MessageTypeSecret:
   292  		if h.disableEncryptGossip {
   293  			m.DisableEncrypt = true
   294  		}
   295  		if !m.CheckRequiredSize() {
   296  			return fmt.Errorf("msg len error")
   297  		}
   298  		m.CalculateHash()
   299  		p.MarkMessage(m.MessageType, *m.Hash)
   300  		oldMsg := m
   301  		if duplicate := h.cacheMessage(&m); !duplicate {
   302  			var isForMe bool
   303  			if isForMe = m.MaybeIsforMe(h.encryptionPubKey); isForMe {
   304  				var e error
   305  				//if encryption  gossip is disabled , just check the target
   306  				//else decrypt
   307  				if h.disableEncryptGossip {
   308  					e = m.RemoveGossipTarget()
   309  				} else {
   310  					e = m.Decrypt(h.encryptionPrivKey)
   311  				}
   312  				if e == nil {
   313  					err := h.MessageUnmarshaller.Unmarshal(&m)
   314  					//err = m.Unmarshal()
   315  					if err != nil {
   316  						// TODO delete
   317  						log.Errorf("unmarshal  error msg: %x", m.Data)
   318  						log.WithField("type ", m.MessageType).WithError(err).Warn("handle msg error")
   319  						return err
   320  					}
   321  					msgLog.WithField("type", m.MessageType.String()).WithField("from", p.String()).WithField(
   322  						"Message", m.Message.String()).WithField("len ", len(m.Data)).Debug("received a Message")
   323  					h.incoming <- &m
   324  				} else {
   325  					log.WithError(e).Debug("this msg is not for me, will relay")
   326  					isForMe = false
   327  				}
   328  			}
   329  			log.Debug("this msg is not for me, will relay")
   330  			h.RelayMessage(&oldMsg)
   331  
   332  		} else {
   333  			out, in := p.CheckPath()
   334  			log.WithField("type", m.MessageType).WithField("size", len(m.Data)).WithField(
   335  				"Hash", m.Hash).WithField("from ", p.String()).WithField("out ", out).WithField(
   336  				"in ", in).Debug("duplicate msg ,discard")
   337  
   338  		}
   339  		return nil
   340  	default:
   341  		//for incoming msg
   342  		err := h.MessageUnmarshaller.Unmarshal(&m)
   343  		//err = m.Unmarshal()
   344  		if err != nil {
   345  			log.WithField("type ", m.MessageType).WithError(err).Warn("handle msg error")
   346  			return err
   347  		}
   348  		m.CalculateHash()
   349  		p.MarkMessage(m.MessageType, *m.Hash)
   350  		hashes := m.GetMarkHashes()
   351  		if len(hashes) != 0 {
   352  			msgLog.WithField("len hahses", len(hashes)).Trace("before mark msg")
   353  			for _, hash := range hashes {
   354  				p.MarkMessage(message_archive.MessageTypeNewTx, hash)
   355  			}
   356  			msgLog.WithField("len ", len(hashes)).Trace("after mark msg")
   357  		}
   358  		if duplicate := h.cacheMessage(&m); duplicate {
   359  			out, in := p.CheckPath()
   360  			log.WithField("type", m.MessageType).WithField("msg", m.Message.String()).WithField(
   361  				"Hash", m.Hash).WithField("from ", p.String()).WithField("out ", out).WithField(
   362  				"in ", in).Debug("duplicate msg ,discard")
   363  			if h.broadCastMode == FeedBackMode && m.AllowSendDuplicateMsg() {
   364  				if outNum, inNum := h.peers.ValidPathNum(); inNum <= 1 {
   365  					log.WithField("outNum ", outNum).WithField("inNum", inNum).Debug("not enough valid path")
   366  					//return nil
   367  				}
   368  				var dup p2p_message.MessageDuplicate
   369  				p.SetInPath(false)
   370  				return h.SendToPeer(message_archive.MessageTypeDuplicate, &dup, p.id)
   371  			}
   372  			return nil
   373  		}
   374  	}
   375  
   376  	msgLog.WithField("type", m.MessageType.String()).WithField("from", p.String()).WithField(
   377  		"Message", m.Message.String()).WithField("len ", len(m.Data)).Debug("received a Message")
   378  
   379  	h.incoming <- &m
   380  	return nil
   381  }
   382  
   383  func (h *Hub) RemovePeer(id string) {
   384  	// Short circuit if the peer was already removed
   385  	peer := h.peers.Peer(id)
   386  	if peer == nil {
   387  		log.Debug("peer not found id")
   388  		return
   389  	}
   390  	log.WithField("peer", id).Debug("Removing og peer")
   391  
   392  	// Unregister the peer from the downloader (should already done) and OG peer set
   393  	h.Downloader.UnregisterPeer(id)
   394  	if err := h.peers.Unregister(id); err != nil {
   395  		log.WithField("peer", "id").WithError(err).
   396  			Error("Sender removal failed")
   397  	}
   398  	// Hard disconnect at the networking layer
   399  	if peer != nil {
   400  		peer.Peer.Disconnect(p2p.DiscUselessPeer)
   401  	}
   402  }
   403  
   404  func (h *Hub) Start() {
   405  	h.Fetcher.Start()
   406  	goroutine.New(h.loopSend)
   407  	goroutine.New(h.loopReceive)
   408  	goroutine.New(h.loopNotify)
   409  }
   410  
   411  func (h *Hub) Stop() {
   412  	// Quit the sync loop.
   413  	// After this send has completed, no new peers will be accepted.
   414  	//h.noMorePeers <- struct{}{}
   415  	log.Info("quit notifying")
   416  	close(h.quitSync)
   417  	log.Info("quit notified")
   418  	h.peers.Close()
   419  	log.Info("peers closing")
   420  	h.wg.Wait()
   421  	log.Info("peers closed")
   422  	h.Fetcher.Stop()
   423  	log.Info("fetcher stopped")
   424  	log.Info("hub stopped")
   425  }
   426  
   427  func (h *Hub) Name() string {
   428  	return "Hub"
   429  }
   430  
   431  func (h *Hub) loopNotify() {
   432  	for {
   433  		select {
   434  		case p := <-h.newPeerCh:
   435  			for _, listener := range h.OnNewPeerConnected {
   436  				listener <- p.id
   437  			}
   438  		case <-h.quit:
   439  			log.Info("Hub-loopNotify received quit Message. Quitting...")
   440  			return
   441  		}
   442  	}
   443  }
   444  
   445  func (h *Hub) loopSend() {
   446  	for {
   447  		select {
   448  		case m := <-h.outgoing:
   449  			//bug fix , don't use go routine to send here
   450  			// start a new routine in order not to block other communications
   451  			switch m.SendingType {
   452  			case sendingTypeBroadcast:
   453  				h.broadcastMessage(m)
   454  			case sendingTypeMulticast:
   455  				h.multicastMessage(m)
   456  			case sendingTypeMulticastToSource:
   457  				h.multicastMessageToSource(m)
   458  			case sendingTypeBroacastWithFilter:
   459  				h.broadcastMessage(m)
   460  			case sendingTypeBroacastWithLink:
   461  				h.broadcastMessageWithLink(m)
   462  
   463  			default:
   464  				log.WithField("type ", m.SendingType).Error("unknown sending  type")
   465  				panic(m)
   466  			}
   467  		case <-h.quit:
   468  			log.Info("Hub-loopSend received quit Message. Quitting...")
   469  			return
   470  		}
   471  	}
   472  }
   473  
   474  func (h *Hub) loopReceive() {
   475  	for {
   476  		select {
   477  		case m := <-h.incoming:
   478  			// start a new routine in order not to block other communications
   479  			// bug fix ; don't use go routine
   480  			h.receiveMessage(m)
   481  		case <-h.quit:
   482  			log.Info("Hub-loopReceive received quit Message. Quitting...")
   483  			return
   484  		}
   485  	}
   486  }
   487  
   488  //MulticastToSource  multicast msg to source , for example , send tx request to the peer which Hash the tx
   489  func (h *Hub) MulticastToSource(messageType message_archive.BinaryMessageType, msg p2p_message.Message, sourceMsgHash *types.Hash) {
   490  	msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeMulticastToSource, SourceHash: sourceMsgHash}
   491  	err := msgOut.Marshal()
   492  	if err != nil {
   493  		msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg  err")
   494  		return
   495  	}
   496  	msgOut.CalculateHash()
   497  	msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("multicast msg to source")
   498  	h.outgoing <- msgOut
   499  }
   500  
   501  //BroadcastMessage broadcast to whole network
   502  func (h *Hub) BroadcastMessage(messageType message_archive.BinaryMessageType, msg p2p_message.Message) {
   503  	msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroadcast}
   504  	err := msgOut.Marshal()
   505  	if err != nil {
   506  		msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg err")
   507  		return
   508  	}
   509  	msgOut.CalculateHash()
   510  	msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("broadcast Message")
   511  	h.outgoing <- msgOut
   512  }
   513  
   514  //BroadcastMessage broadcast to whole network
   515  func (h *Hub) BroadcastMessageWithLink(messageType message_archive.BinaryMessageType, msg p2p_message.Message) {
   516  	if h.broadCastMode != FeedBackMode {
   517  		msgLog.WithField("type", messageType).Trace("broadcast withlink disabled")
   518  		h.BroadcastMessage(messageType, msg)
   519  		return
   520  	}
   521  	msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroacastWithLink}
   522  	err := msgOut.Marshal()
   523  	if err != nil {
   524  		msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg  err")
   525  		return
   526  	}
   527  	msgOut.CalculateHash()
   528  	msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("broadcast Message")
   529  	h.outgoing <- msgOut
   530  }
   531  
   532  //BroadcastMessage broadcast to whole network
   533  func (h *Hub) BroadcastMessageWithFilter(messageType message_archive.BinaryMessageType, msg p2p_message.Message) {
   534  	msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroacastWithFilter}
   535  	err := msgOut.Marshal()
   536  	if err != nil {
   537  		msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg  err")
   538  		return
   539  	}
   540  	msgOut.CalculateHash()
   541  	msgLog.WithField("size ", len(msgOut.Data)).WithField("type", messageType).Debug("broadcast Message")
   542  	h.outgoing <- msgOut
   543  }
   544  
   545  //MulticastMessage multicast Message to some peer
   546  func (h *Hub) MulticastMessage(messageType message_archive.BinaryMessageType, msg p2p_message.Message) {
   547  	msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeMulticast}
   548  	err := msgOut.Marshal()
   549  	if err != nil {
   550  		msgLog.WithError(err).WithField("type", messageType).Warn("broadcast Message init msg  err")
   551  		return
   552  	}
   553  	msgOut.CalculateHash()
   554  	msgLog.WithField("size", len(msgOut.Data)).WithField("type", messageType).Trace("multicast Message")
   555  	h.outgoing <- msgOut
   556  }
   557  
   558  // AnonymousSendMessage use a pubkey to encrypt the Message and then broadcast it
   559  // Only the one who has the private key can decrypt the Message and become the receiver.
   560  // the Message will append the target receiver pubkey to accelerate filtering on the target side.
   561  // TODO: support multi encryption keys in one Message
   562  // TODO: encrypt the Message whatever disableEncryptGossip is on or not
   563  func (h *Hub) AnonymousSendMessage(messageType message_archive.BinaryMessageType, msg p2p_message.Message, encryptionKey *crypto.PublicKey) {
   564  	msgOut := &message_archive.types{MessageType: messageType, Message: msg, SendingType: message_archive.SendingTypeBroadcast}
   565  	if h.disableEncryptGossip {
   566  		msgOut.DisableEncrypt = true
   567  	}
   568  	err := msgOut.Marshal()
   569  	if err != nil {
   570  		msgLog.WithError(err).WithField("type", messageType).Warn("AnonymousSendMessage Message init msg err")
   571  		return
   572  	}
   573  	beforeEncSize := len(msgOut.Data)
   574  	if h.disableEncryptGossip {
   575  		err = msgOut.AppendGossipTarget(encryptionKey)
   576  	} else {
   577  		err = msgOut.Encrypt(encryptionKey)
   578  	}
   579  	if err != nil {
   580  		msgLog.WithError(err).WithField("type", messageType).Warn("AnonymousSendMessage Message encrypt msg err")
   581  		return
   582  	}
   583  	msgOut.CalculateHash()
   584  	msgLog.WithField("before enc size ", beforeEncSize).WithField("size", len(msgOut.Data)).WithField("type", messageType).Trace("AnonymousSendMessage Message")
   585  	h.outgoing <- msgOut
   586  
   587  }
   588  
   589  func (h *Hub) RelayMessage(msgOut *message_archive.types) {
   590  	msgLog.WithField("size", len(msgOut.Data)).WithField("type", msgOut.MessageType).Trace("relay Message")
   591  	h.outgoing <- msgOut
   592  }
   593  
   594  func (h *Hub) SendToPeer(messageType message_archive.BinaryMessageType, msg p2p_message.Message, peerId string) error {
   595  	p := h.peers.Peer(peerId)
   596  	if p == nil {
   597  		return fmt.Errorf("peer not found")
   598  	}
   599  	return p.sendRequest(messageType, msg)
   600  }
   601  
   602  func (h *Hub) SendGetMsg(peerId string, msg *p2p_message.MessageGetMsg) error {
   603  	p := h.peers.Peer(peerId)
   604  	if p == nil {
   605  		ids := h.getMsgFromCache(message_archive.MessageTypeControl, *msg.Hash)
   606  		ps := h.peers.GetPeers(ids, 1)
   607  		if len(ps) != 0 {
   608  			p = ps[0]
   609  		}
   610  	}
   611  	if p == nil {
   612  		h.MulticastMessage(message_archive.MessageTypeGetMsg, msg)
   613  		return nil
   614  	} else {
   615  		p.SetInPath(true)
   616  	}
   617  	return p.sendRequest(message_archive.MessageTypeGetMsg, msg)
   618  }
   619  
   620  func (h *Hub) SendBytesToPeer(peerId string, messageType message_archive.BinaryMessageType, msg []byte) error {
   621  	p := h.peers.Peer(peerId)
   622  	if p == nil {
   623  		return fmt.Errorf("peer not found")
   624  	}
   625  	return p.sendRawMessage(messageType, msg)
   626  }
   627  
   628  // SetPeerHead is just a hack to set the latest seq number known of the peer
   629  // This value ought not to be stored in peer, but an outside map.
   630  // This has nothing related to p2p.
   631  func (h *Hub) SetPeerHead(peerId string, hash types.Hash, number uint64) error {
   632  	p := h.peers.Peer(peerId)
   633  	if p == nil {
   634  		return fmt.Errorf("peer not found")
   635  	}
   636  	p.SetHead(hash, number)
   637  	return nil
   638  }
   639  
   640  func (h *Hub) BestPeerInfo() (peerId string, hash types.Hash, seqId uint64, err error) {
   641  	p := h.peers.BestPeer()
   642  	if p != nil {
   643  		peerId = p.id
   644  		hash, seqId = p.Head()
   645  		return
   646  	}
   647  	err = fmt.Errorf("no best peer")
   648  	return
   649  }
   650  
   651  func (h *Hub) GetPeerHead(peerId string) (hash types.Hash, seqId uint64, err error) {
   652  	p := h.peers.Peer(peerId)
   653  	if p != nil {
   654  		hash, seqId = p.Head()
   655  		return
   656  	}
   657  	err = fmt.Errorf("no such peer")
   658  	return
   659  }
   660  
   661  func (h *Hub) BestPeerId() (peerId string, err error) {
   662  	p := h.peers.BestPeer()
   663  	if p != nil {
   664  		peerId = p.id
   665  		return
   666  	}
   667  	err = fmt.Errorf("no best peer")
   668  	return
   669  }
   670  
   671  //broadcastMessage
   672  func (h *Hub) broadcastMessage(msg *message_archive.types) {
   673  	var peers []*peer
   674  	// choose all  peer and then send.
   675  	peers = h.peers.PeersWithoutMsg(*msg.Hash, msg.MessageType)
   676  	for _, peer := range peers {
   677  		peer.AsyncSendMessage(msg)
   678  	}
   679  	return
   680  }
   681  
   682  func (h *Hub) broadcastMessageWithLink(msg *message_archive.types) {
   683  	var peers []*peer
   684  	// choose all  peer and then send.
   685  	var hash types.Hash
   686  	hash = *msg.Hash
   687  	c := p2p_message.MessageControl{Hash: &hash}
   688  	var pMsg = &message_archive.types{MessageType: message_archive.MessageTypeControl, Message: &c}
   689  	//outgoing msg
   690  	if err := pMsg.Marshal(); err != nil {
   691  		msgLog.Error(err)
   692  	}
   693  	pMsg.CalculateHash()
   694  	peers = h.peers.PeersWithoutMsg(*msg.Hash, msg.MessageType)
   695  	for _, peer := range peers {
   696  		//if  len(peers) == 1 {
   697  		if out, _ := peer.CheckPath(); out {
   698  			msgLog.WithField("peer ", peer.String()).Debug("send original tx to peer")
   699  			peer.AsyncSendMessage(msg)
   700  		} else {
   701  			msgLog.WithField("to peer ", peer.String()).WithField("Hash ", hash).Debug("send MessageTypeControl")
   702  			peer.AsyncSendMessage(pMsg)
   703  		}
   704  	}
   705  	return
   706  }
   707  
   708  /*
   709  func (h *Hub) broadcastMessageWithFilter(msg *message.types) {
   710  	newSeq := msg.Message.(*p2p_message.MessageNewSequencer)
   711  	if newSeq.Filter == nil {
   712  		newSeq.Filter = types.NewDefaultBloomFilter()
   713  	} else if len(newSeq.Filter.Data) != 0 {
   714  		err := newSeq.Filter.Decode()
   715  		if err != nil {
   716  			msgLog.WithError(err).Warn("encode bloom filter error")
   717  			return
   718  		}
   719  	}
   720  	var allpeers []*peer
   721  	var peers []*peer
   722  	allpeers = h.peers.PeersWithoutMsg(msg.Hash)
   723  	for _, peer := range allpeers {
   724  		ok, _ := newSeq.Filter.LookUpItem(peer.ID().KeyBytes())
   725  		if ok {
   726  			msgLog.WithField("id ", peer.id).Debug("filtered ,don't send")
   727  		} else {
   728  			newSeq.Filter.AddItem(peer.ID().KeyBytes())
   729  			peers = append(peers, peer)
   730  			msgLog.WithField("id ", peer.id).Debug("not filtered , send")
   731  		}
   732  	}
   733  	newSeq.Filter.Encode()
   734  	msg.Message = newSeq
   735  	msg.Data, _ = newSeq.MarshalMsg(nil)
   736  	for _, peer := range peers {
   737  		peer.AsyncSendMessage(msg)
   738  	}
   739  }
   740  
   741  */
   742  
   743  //multicastMessage
   744  func (h *Hub) multicastMessage(msg *message_archive.types) error {
   745  	peers := h.peers.GetRandomPeers(3)
   746  	// choose random peer and then send.
   747  	for _, peer := range peers {
   748  		peer.AsyncSendMessage(msg)
   749  	}
   750  	return nil
   751  }
   752  
   753  //multicastMessageToSource
   754  func (h *Hub) multicastMessageToSource(msg *message_archive.types) error {
   755  	if msg.SourceHash == nil {
   756  		msgLog.Warn("source msg Hash is nil , multicast to random")
   757  		return h.multicastMessage(msg)
   758  	}
   759  	ids := h.getMsgFromCache(message_archive.MessageTypeControl, *msg.SourceHash)
   760  	if len(ids) == 0 {
   761  		ids = h.getMsgFromCache(message_archive.MessageTypeNewTx, *msg.SourceHash)
   762  	}
   763  	//send to 2 peer , considering if one peer disconnect,
   764  	peers := h.peers.GetPeers(ids, 3)
   765  	if len(peers) == 0 {
   766  		msgLog.WithField("type ", msg.MessageType).WithField("peeers id ", ids).Warn(
   767  			"not found source peers, multicast to random")
   768  		return h.multicastMessage(msg)
   769  	}
   770  	// choose random peer and then send.
   771  	for _, peer := range peers {
   772  		if peer == nil {
   773  			continue
   774  		}
   775  		peer.AsyncSendMessage(msg)
   776  	}
   777  	return nil
   778  }
   779  
   780  //cacheMessge save msg to cache
   781  func (h *Hub) cacheMessage(m *message_archive.types) (exists bool) {
   782  	if m.Hash == nil {
   783  		return false
   784  	}
   785  	var peers []string
   786  	key := m.MsgKey()
   787  	if a, err := h.messageCache.GetIFPresent(key); err == nil {
   788  		// already there
   789  		exists = true
   790  		//var peers []string
   791  		peers = a.([]string)
   792  		msgLog.WithField("from ", m.SourceID).WithField("Hash", m.Hash).WithField("peers", peers).WithField(
   793  			"type", m.MessageType).Trace("we have a duplicate Message. Discard")
   794  		if len(peers) == 0 {
   795  			msgLog.Error("peers is nil")
   796  		} else if len(peers) >= DuplicateMsgPeerNum {
   797  			return exists
   798  		}
   799  	}
   800  	peers = append(peers, m.SourceID)
   801  	h.messageCache.Set(key, peers)
   802  	return exists
   803  }
   804  
   805  //getMsgFromCache
   806  func (h *Hub) getMsgFromCache(m message_archive.BinaryMessageType, hash types.Hash) []string {
   807  	key := message_archive.NewMsgKey(m, hash)
   808  	if a, err := h.messageCache.GetIFPresent(key); err == nil {
   809  		var peers []string
   810  		peers = a.([]string)
   811  		msgLog.WithField("peers", peers).Trace("get peers from cache")
   812  		return peers
   813  	}
   814  	return nil
   815  }
   816  
   817  func (h *Hub) receiveMessage(msg *message_archive.types) {
   818  	// route to specific callbacks according to the registry.
   819  	if msg.Version >= OG02 {
   820  		if v, ok := h.CallbackRegistryOG02[msg.MessageType]; ok {
   821  			log.WithField("from", msg.SourceID).WithField("type", msg.MessageType.String()).Trace("Received a Message")
   822  			v(msg)
   823  			return
   824  		}
   825  	}
   826  	if msg.MessageType == message_archive.MessageTypeGetMsg {
   827  		peer := h.peers.Peer(msg.SourceID)
   828  		if peer != nil {
   829  			msgLog.WithField("msg", msg.Message.String()).WithField("peer ", peer.String()).Trace("set path to true")
   830  			peer.SetOutPath(true)
   831  		}
   832  	}
   833  
   834  	if v, ok := h.CallbackRegistry[msg.MessageType]; ok {
   835  		msgLog.WithField("type", msg.MessageType).Debug("handle")
   836  		v(msg)
   837  	} else {
   838  		msgLog.WithField("from", msg.SourceID).WithField("type", msg.MessageType).Debug("Received an Unknown Message")
   839  	}
   840  }
   841  
   842  // NodeInfo retrieves some protocol metadata about the running host node.
   843  func (h *Hub) PeersInfo() []*PeerInfo {
   844  	peers := h.peers.Peers()
   845  	// Gather all the generic and sub-protocol specific infos
   846  	infos := make([]*PeerInfo, 0, len(peers))
   847  	for _, peer := range peers {
   848  		if peer != nil {
   849  			infos = append(infos, peer.Info())
   850  		}
   851  	}
   852  	return infos
   853  }
   854  
   855  // NodeInfo represents a short summary of the OG sub-protocol metadata
   856  // known about the host peer.
   857  type NodeStatus struct {
   858  	Network    uint64     `json:"network"`    // OG network ID (1=Frontier, 2=Morden, Ropsten=3, Rinkeby=4)
   859  	Difficulty *big.Int   `json:"difficulty"` // Total difficulty of the host's blockchain
   860  	Genesis    types.Hash `json:"genesis"`    // SHA3 Hash of the host's genesis block
   861  	Head       types.Hash `json:"head"`       // SHA3 Hash of the host's best owned block
   862  }
   863  
   864  // NodeInfo retrieves some protocol metadata about the running host node.
   865  func (h *Hub) NodeStatus() *NodeStatus {
   866  	statusData := h.StatusDataProvider.GetCurrentNodeStatus()
   867  	return &NodeStatus{
   868  		Network: statusData.NetworkId,
   869  		Genesis: statusData.GenesisBlock,
   870  		Head:    statusData.CurrentBlock,
   871  	}
   872  }