github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/netsync/consensusmgr/handle.go (about) 1 package consensusmgr 2 3 import ( 4 "encoding/hex" 5 "reflect" 6 7 "github.com/sirupsen/logrus" 8 9 "github.com/bytom/bytom/event" 10 "github.com/bytom/bytom/netsync/peers" 11 "github.com/bytom/bytom/p2p" 12 "github.com/bytom/bytom/p2p/security" 13 "github.com/bytom/bytom/protocol/bc" 14 "github.com/bytom/bytom/protocol/bc/types" 15 "github.com/bytom/bytom/protocol/casper" 16 ) 17 18 // Switch is the interface for p2p switch. 19 type Switch interface { 20 AddReactor(name string, reactor p2p.Reactor) p2p.Reactor 21 } 22 23 // Chain is the interface for Bytom core. 24 type Chain interface { 25 BestBlockHeight() uint64 26 GetHeaderByHash(*bc.Hash) (*types.BlockHeader, error) 27 ProcessBlock(*types.Block) (bool, error) 28 ProcessBlockVerification(*casper.ValidCasperSignMsg) error 29 } 30 31 type Peers interface { 32 AddPeer(peer peers.BasePeer) 33 BroadcastMsg(bm peers.BroadcastMsg) error 34 GetPeer(id string) *peers.Peer 35 MarkBlock(peerID string, hash *bc.Hash) 36 MarkBlockVerification(peerID string, signature []byte) 37 ProcessIllegal(peerID string, level byte, reason string) 38 RemovePeer(peerID string) 39 SetStatus(peerID string, height uint64, hash *bc.Hash) 40 } 41 42 type blockMsg struct { 43 block *types.Block 44 peerID string 45 } 46 47 // Manager is the consensus message network synchronization manager. 48 type Manager struct { 49 sw Switch 50 chain Chain 51 peers Peers 52 blockFetcher *blockFetcher 53 eventDispatcher *event.Dispatcher 54 55 quit chan struct{} 56 } 57 58 // NewManager create new manager. 59 func NewManager(sw Switch, chain Chain, peers Peers, dispatcher *event.Dispatcher) *Manager { 60 manager := &Manager{ 61 sw: sw, 62 chain: chain, 63 peers: peers, 64 blockFetcher: newBlockFetcher(chain, peers), 65 eventDispatcher: dispatcher, 66 quit: make(chan struct{}), 67 } 68 protocolReactor := NewConsensusReactor(manager) 69 manager.sw.AddReactor("CONSENSUS", protocolReactor) 70 return manager 71 } 72 73 func (m *Manager) addPeer(peer peers.BasePeer) { 74 m.peers.AddPeer(peer) 75 } 76 77 func (m *Manager) processMsg(peerID string, msgType byte, msg ConsensusMessage) { 78 peer := m.peers.GetPeer(peerID) 79 if peer == nil { 80 return 81 } 82 83 logrus.WithFields(logrus.Fields{"module": logModule, "peer": peer.Addr(), "type": reflect.TypeOf(msg), "message": msg.String()}).Debug("receive message from peer") 84 85 switch msg := msg.(type) { 86 case *BlockProposeMsg: 87 m.handleBlockProposeMsg(peerID, msg) 88 89 case *BlockVerificationMsg: 90 m.handleBlockVerificationMsg(peerID, msg) 91 92 default: 93 logrus.WithFields(logrus.Fields{"module": logModule, "peer": peerID, "message_type": reflect.TypeOf(msg)}).Error("unhandled message type") 94 } 95 } 96 97 func (m *Manager) handleBlockProposeMsg(peerID string, msg *BlockProposeMsg) { 98 block, err := msg.GetProposeBlock() 99 if err != nil { 100 logrus.WithFields(logrus.Fields{"module": logModule, "err": err}).Warning("failed on get propose block") 101 return 102 } 103 104 hash := block.Hash() 105 m.peers.MarkBlock(peerID, &hash) 106 m.blockFetcher.processNewBlock(&blockMsg{peerID: peerID, block: block}) 107 m.peers.SetStatus(peerID, block.Height, &hash) 108 } 109 110 func (m *Manager) handleBlockVerificationMsg(peerID string, msg *BlockVerificationMsg) { 111 m.peers.MarkBlockVerification(peerID, msg.Signature) 112 if err := m.chain.ProcessBlockVerification(&casper.ValidCasperSignMsg{ 113 SourceHash: msg.SourceHash, 114 TargetHash: msg.TargetHash, 115 Signature: msg.Signature, 116 PubKey: hex.EncodeToString(msg.PubKey), 117 }); err != nil { 118 m.peers.ProcessIllegal(peerID, security.LevelMsgIllegal, err.Error()) 119 } 120 } 121 122 func (m *Manager) blockProposeMsgBroadcastLoop() { 123 m.msgBroadcastLoop(event.NewProposedBlockEvent{}, func(data interface{}) (ConsensusMessage, error) { 124 ev := data.(event.NewProposedBlockEvent) 125 return NewBlockProposeMsg(&ev.Block) 126 }) 127 } 128 129 func (m *Manager) blockVerificationMsgBroadcastLoop() { 130 m.msgBroadcastLoop(casper.ValidCasperSignMsg{}, func(data interface{}) (ConsensusMessage, error) { 131 v := data.(casper.ValidCasperSignMsg) 132 pubKey, err := hex.DecodeString(v.PubKey) 133 if err != nil { 134 return nil, err 135 } 136 137 return NewBlockVerificationMsg(v.SourceHash, v.TargetHash, pubKey, v.Signature), nil 138 }) 139 } 140 141 func (m *Manager) msgBroadcastLoop(msgType interface{}, newMsg func(event interface{}) (ConsensusMessage, error)) { 142 subscribeType := reflect.TypeOf(msgType) 143 msgSub, err := m.eventDispatcher.Subscribe(msgType) 144 if err != nil { 145 logrus.WithFields(logrus.Fields{"module": logModule, "err": err}).Errorf("failed on subscribe %s", subscribeType) 146 return 147 } 148 defer msgSub.Unsubscribe() 149 for { 150 select { 151 case obj, ok := <-msgSub.Chan(): 152 if !ok { 153 logrus.WithFields(logrus.Fields{"module": logModule}).Warningf("%sSub channel closed", subscribeType) 154 return 155 } 156 157 if reflect.TypeOf(obj.Data) != subscribeType { 158 logrus.WithFields(logrus.Fields{"module": logModule}).Error("event type error") 159 continue 160 } 161 162 msg, err := newMsg(obj.Data) 163 if err != nil { 164 logrus.WithFields(logrus.Fields{"module": logModule, "err": err}).Errorf("failed on create %s message", subscribeType) 165 return 166 } 167 168 message := NewBroadcastMsg(msg, consensusChannel) 169 if err := m.peers.BroadcastMsg(message); err != nil { 170 logrus.WithFields(logrus.Fields{"module": logModule, "err": err}).Errorf("failed on broadcast %s message.", subscribeType) 171 continue 172 } 173 174 case <-m.quit: 175 return 176 } 177 } 178 } 179 180 func (m *Manager) removePeer(peerID string) { 181 m.peers.RemovePeer(peerID) 182 } 183 184 // Start consensus manager service. 185 func (m *Manager) Start() error { 186 go m.blockFetcher.blockProcessorLoop() 187 go m.blockProposeMsgBroadcastLoop() 188 go m.blockVerificationMsgBroadcastLoop() 189 return nil 190 } 191 192 // Stop consensus manager service. 193 func (m *Manager) Stop() { 194 close(m.quit) 195 }