github.com/annchain/OG@v0.0.9/consensus/annsensus/adapter_bft.go (about) 1 package annsensus 2 3 import ( 4 "bytes" 5 "errors" 6 "github.com/annchain/OG/consensus/bft" 7 ogcrypto2 "github.com/annchain/OG/deprecated/ogcrypto" 8 "github.com/annchain/OG/og/account" 9 "github.com/sirupsen/logrus" 10 ) 11 12 type ProxyBftPeerCommunicator struct { 13 bftMessageAdapter BftMessageAdapter // either TrustfulBftAdapter or PlainBftAdapter 14 annsensusOutgoing AnnsensusPeerCommunicatorOutgoing 15 pipe chan *bft.BftMessageEvent 16 } 17 18 func NewProxyBftPeerCommunicator( 19 bftMessageAdapter BftMessageAdapter, 20 annsensusOutgoing AnnsensusPeerCommunicatorOutgoing) *ProxyBftPeerCommunicator { 21 return &ProxyBftPeerCommunicator{ 22 bftMessageAdapter: bftMessageAdapter, 23 annsensusOutgoing: annsensusOutgoing, 24 pipe: make(chan *bft.BftMessageEvent), 25 } 26 } 27 28 func (p *ProxyBftPeerCommunicator) Broadcast(msg bft.BftMessage, peers []bft.BftPeer) { 29 annsensusMessage, err := p.bftMessageAdapter.AdaptBftMessage(msg) 30 if err != nil { 31 panic("adapt should never fail") 32 } 33 // adapt the interface so that the request can be handled by annsensus 34 annsensusPeers := make([]AnnsensusPeer, len(peers)) 35 for i, peer := range peers { 36 adaptedValue, err := p.bftMessageAdapter.AdaptBftPeer(peer) 37 if err != nil { 38 panic("adapt should never fail") 39 } 40 annsensusPeers[i] = adaptedValue 41 } 42 43 p.annsensusOutgoing.Broadcast(annsensusMessage, annsensusPeers) 44 } 45 46 func (p *ProxyBftPeerCommunicator) Unicast(msg bft.BftMessage, peer bft.BftPeer) { 47 // adapt the interface so that the request can be handled by annsensus 48 annsensusMessage, err := p.bftMessageAdapter.AdaptBftMessage(msg) 49 if err != nil { 50 panic("adapt should never fail") 51 } 52 annsensusPeer, err := p.bftMessageAdapter.AdaptBftPeer(peer) 53 if err != nil { 54 panic("adapt should never fail") 55 } 56 p.annsensusOutgoing.Unicast(annsensusMessage, annsensusPeer) 57 } 58 59 func (p *ProxyBftPeerCommunicator) GetPipeOut() chan *bft.BftMessageEvent { 60 // the channel to be consumed by the downstream. 61 return p.pipe 62 } 63 64 func (p *ProxyBftPeerCommunicator) GetPipeIn() chan *bft.BftMessageEvent { 65 // the channel to be fed by other peers 66 return p.pipe 67 } 68 69 func (p *ProxyBftPeerCommunicator) Run() { 70 // nothing to do 71 return 72 } 73 74 type BftMessageUnmarshaller struct { 75 } 76 77 func (b *BftMessageUnmarshaller) Unmarshal(messageType bft.BftMessageType, message []byte) (outMsg bft.BftMessage, err error) { 78 switch messageType { 79 case bft.BftMessageTypeProposal: 80 m := &bft.BftMessageProposal{ 81 Value: &bft.StringProposal{}, 82 } 83 _, err = m.UnmarshalMsg(message) 84 outMsg = m 85 case bft.BftMessageTypePreVote: 86 m := &bft.BftMessagePreVote{} 87 _, err = m.UnmarshalMsg(message) 88 outMsg = m 89 case bft.BftMessageTypePreCommit: 90 m := &bft.BftMessagePreCommit{} 91 _, err = m.UnmarshalMsg(message) 92 outMsg = m 93 default: 94 err = errors.New("message type of Bft not supported") 95 } 96 return 97 } 98 99 // TrustfulBftAdapter signs and validate messages using pubkey/privkey given by DKG/BLS 100 type TrustfulBftAdapter struct { 101 signatureProvider account.SignatureProvider 102 termHolder HistoricalTermsHolder 103 bftMessageUnmarshaller *BftMessageUnmarshaller 104 } 105 106 func (r *TrustfulBftAdapter) AdaptAnnsensusPeer(annPeer AnnsensusPeer) (bft.BftPeer, error) { 107 return bft.BftPeer{ 108 Id: annPeer.Id, 109 PublicKey: annPeer.PublicKey, 110 Address: annPeer.Address, 111 PublicKeyBytes: annPeer.PublicKeyBytes, 112 }, nil 113 } 114 115 func (r *TrustfulBftAdapter) AdaptBftPeer(bftPeer bft.BftPeer) (AnnsensusPeer, error) { 116 return AnnsensusPeer{ 117 Id: bftPeer.Id, 118 PublicKey: bftPeer.PublicKey, 119 Address: bftPeer.Address, 120 PublicKeyBytes: bftPeer.PublicKeyBytes, 121 }, nil 122 } 123 124 func (r *TrustfulBftAdapter) AdaptBftMessage(outgoingMsg bft.BftMessage) (msg AnnsensusMessage, err error) { 125 signed := r.Sign(outgoingMsg) 126 msg = &signed 127 return 128 } 129 130 func NewTrustfulBftAdapter( 131 signatureProvider account.SignatureProvider, 132 termHolder HistoricalTermsHolder) *TrustfulBftAdapter { 133 return &TrustfulBftAdapter{signatureProvider: signatureProvider, termHolder: termHolder} 134 } 135 136 func (r *TrustfulBftAdapter) Sign(rawMessage bft.BftMessage) AnnsensusMessageBftSigned { 137 publicKey, signature := r.signatureProvider.Sign(rawMessage.SignatureTargets()) 138 signedMessage := AnnsensusMessageBftSigned{ 139 InnerMessageType: uint16(rawMessage.GetType()), 140 InnerMessage: rawMessage.SignatureTargets(), 141 Signature: signature, 142 PublicKey: publicKey, 143 } 144 //SessionId: partner.CurrentTerm(), 145 //PublicKey: account.PublicKey.KeyBytes, 146 return signedMessage 147 } 148 149 // Multicast must be anonymous since it is actually among all partners, not all nodes. 150 //func (r *TrustfulBftAdapter) Multicast(msg bft.BftMessage, peers []bft.BftPeer) { 151 // signed := r.Sign(msg) 152 // for _, peer := range peers { 153 // r.p2pSender.AnonymousSendMessage(message.BinaryMessageType(msg.Type), &signed, &peer.PublicKey) 154 // } 155 //} 156 // 157 //// Unicast must be anonymous 158 //func (r *TrustfulBftAdapter) Unicast(msg bft.BftMessage, peer bft.BftPeer) { 159 // signed := r.Sign(msg) 160 // r.p2pSender.AnonymousSendMessage(message.BinaryMessageType(msg.Type), &signed, &peer.PublicKey) 161 //} 162 163 func (b *TrustfulBftAdapter) VerifyParnterIdentity(signedMsg *AnnsensusMessageBftSigned) error { 164 term, ok := b.termHolder.GetTermById(signedMsg.TermId) 165 if !ok { 166 // this term is unknown. 167 return errors.New("term not found") 168 } 169 170 // use public key to find sourcePartner 171 for _, peer := range term.contextProvider.GetTerm().Senators { 172 if bytes.Equal(peer.PublicKey.KeyBytes, signedMsg.PublicKey) { 173 return nil 174 } 175 } 176 return errors.New("public key not found in current term") 177 } 178 179 func (b *TrustfulBftAdapter) VerifyMessageSignature(outMsg bft.BftMessage, publicKey []byte, signature []byte) error { 180 ok := ogcrypto2.VerifySignature(publicKey, outMsg.SignatureTargets(), signature) 181 if !ok { 182 return errors.New("signature invalid") 183 } 184 return nil 185 } 186 187 func (b *TrustfulBftAdapter) AdaptAnnsensusMessage(incomingMsg AnnsensusMessage) (msg bft.BftMessage, err error) { // Only allows SignedOgPartnerMessage 188 if incomingMsg.GetType() != AnnsensusMessageTypeBftSigned { 189 err = errors.New("TrustfulBftAdapter received a message of an unsupported type") 190 return 191 } 192 193 signedMsg, ok := incomingMsg.(*AnnsensusMessageBftSigned) 194 if !ok { 195 err = errors.New("TrustfulBftAdapter received a message of type AnnsensusMessageBftSigned but it is not.") 196 return 197 } 198 199 // check inner type 200 bftMessage, err := b.bftMessageUnmarshaller.Unmarshal(bft.BftMessageType(signedMsg.InnerMessageType), signedMsg.InnerMessage) 201 if err != nil { 202 return 203 } 204 205 err = b.VerifyParnterIdentity(signedMsg) 206 if err != nil { 207 logrus.WithField("term", signedMsg.TermId).WithError(err).Warn("bft message partner identity is not valid or unknown") 208 err = errors.New("bft message partner identity is not valid or unknown") 209 return 210 } 211 212 err = b.VerifyMessageSignature(bftMessage, signedMsg.PublicKey, signedMsg.Signature) 213 if err != nil { 214 logrus.WithError(err).Warn("bft message signature is not valid") 215 err = errors.New("bft message signature is not valid") 216 return 217 } 218 219 return bftMessage, nil 220 } 221 222 // PlainBftAdapter will not wrap the message using MessageTypeAnnsensusSigned 223 type PlainBftAdapter struct { 224 BftMessageUnmarshaller *BftMessageUnmarshaller 225 } 226 227 func (p PlainBftAdapter) AdaptAnnsensusPeer(annPeer AnnsensusPeer) (bft.BftPeer, error) { 228 return bft.BftPeer{ 229 Id: annPeer.Id, 230 PublicKey: annPeer.PublicKey, 231 Address: annPeer.Address, 232 PublicKeyBytes: annPeer.PublicKeyBytes, 233 }, nil 234 } 235 236 func (p PlainBftAdapter) AdaptBftPeer(bftPeer bft.BftPeer) (AnnsensusPeer, error) { 237 return AnnsensusPeer{ 238 Id: bftPeer.Id, 239 PublicKey: bftPeer.PublicKey, 240 Address: bftPeer.Address, 241 PublicKeyBytes: bftPeer.PublicKeyBytes, 242 }, nil 243 } 244 245 func (p PlainBftAdapter) AdaptAnnsensusMessage(incomingMsg AnnsensusMessage) (msg bft.BftMessage, err error) { 246 if incomingMsg.GetType() != AnnsensusMessageTypeBftPlain { 247 err = errors.New("PlainBftAdapter received a message of an unsupported type") 248 return 249 } 250 iMsg := incomingMsg.(*AnnsensusMessageBftPlain) 251 innerMessageType := bft.BftMessageType(iMsg.InnerMessageType) 252 253 switch innerMessageType { 254 case bft.BftMessageTypeProposal: 255 fallthrough 256 case bft.BftMessageTypePreVote: 257 fallthrough 258 case bft.BftMessageTypePreCommit: 259 msg, err = p.BftMessageUnmarshaller.Unmarshal(innerMessageType, iMsg.InnerMessage) 260 default: 261 err = errors.New("PlainBftAdapter received a message of an unsupported inner type") 262 } 263 return 264 265 } 266 267 func (p PlainBftAdapter) AdaptBftMessage(outgoingMsg bft.BftMessage) (adaptedMessage AnnsensusMessage, err error) { 268 var msgBytes []byte 269 switch outgoingMsg.GetType() { 270 case bft.BftMessageTypeProposal: 271 omsg := outgoingMsg.(*bft.BftMessageProposal) 272 msgBytes, err = omsg.MarshalMsg(nil) 273 if err != nil { 274 return 275 } 276 adaptedMessage = &AnnsensusMessageBftPlain{ 277 InnerMessageType: uint16(omsg.GetType()), 278 InnerMessage: msgBytes, 279 } 280 case bft.BftMessageTypePreVote: 281 omsg := outgoingMsg.(*bft.BftMessagePreVote) 282 msgBytes, err = omsg.MarshalMsg(nil) 283 if err != nil { 284 return 285 } 286 adaptedMessage = &AnnsensusMessageBftPlain{ 287 InnerMessageType: uint16(omsg.GetType()), 288 InnerMessage: msgBytes, 289 } 290 case bft.BftMessageTypePreCommit: 291 omsg := outgoingMsg.(*bft.BftMessagePreCommit) 292 msgBytes, err = omsg.MarshalMsg(nil) 293 if err != nil { 294 return 295 } 296 adaptedMessage = &AnnsensusMessageBftPlain{ 297 InnerMessageType: uint16(omsg.GetType()), 298 InnerMessage: msgBytes, 299 } 300 default: 301 err = errors.New("PlainBftAdapter received a message of an unsupported type") 302 } 303 return 304 }