github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/protos/gossip/extensions.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package gossip 18 19 import ( 20 "bytes" 21 "errors" 22 "fmt" 23 24 "github.com/golang/protobuf/proto" 25 "github.com/hyperledger/fabric/gossip/api" 26 "github.com/hyperledger/fabric/gossip/common" 27 ) 28 29 // NewGossipMessageComparator creates a MessageReplacingPolicy given a maximum number of blocks to hold 30 func NewGossipMessageComparator(dataBlockStorageSize int) common.MessageReplacingPolicy { 31 return (&msgComparator{dataBlockStorageSize: dataBlockStorageSize}).getMsgReplacingPolicy() 32 } 33 34 type msgComparator struct { 35 dataBlockStorageSize int 36 } 37 38 func (mc *msgComparator) getMsgReplacingPolicy() common.MessageReplacingPolicy { 39 return func(this interface{}, that interface{}) common.InvalidationResult { 40 return mc.invalidationPolicy(this, that) 41 } 42 } 43 44 func (mc *msgComparator) invalidationPolicy(this interface{}, that interface{}) common.InvalidationResult { 45 thisMsg := this.(*SignedGossipMessage) 46 thatMsg := that.(*SignedGossipMessage) 47 48 if thisMsg.IsAliveMsg() && thatMsg.IsAliveMsg() { 49 return aliveInvalidationPolicy(thisMsg.GetAliveMsg(), thatMsg.GetAliveMsg()) 50 } 51 52 if thisMsg.IsDataMsg() && thatMsg.IsDataMsg() { 53 return mc.dataInvalidationPolicy(thisMsg.GetDataMsg(), thatMsg.GetDataMsg()) 54 } 55 56 if thisMsg.IsStateInfoMsg() && thatMsg.IsStateInfoMsg() { 57 return mc.stateInvalidationPolicy(thisMsg.GetStateInfo(), thatMsg.GetStateInfo()) 58 } 59 60 if thisMsg.IsIdentityMsg() && thatMsg.IsIdentityMsg() { 61 return mc.identityInvalidationPolicy(thisMsg.GetPeerIdentity(), thatMsg.GetPeerIdentity()) 62 } 63 64 if thisMsg.IsLeadershipMsg() && thatMsg.IsLeadershipMsg() { 65 return leaderInvalidationPolicy(thisMsg.GetLeadershipMsg(), thatMsg.GetLeadershipMsg()) 66 } 67 68 return common.MessageNoAction 69 } 70 71 func (mc *msgComparator) stateInvalidationPolicy(thisStateMsg *StateInfo, thatStateMsg *StateInfo) common.InvalidationResult { 72 if !bytes.Equal(thisStateMsg.PkiId, thatStateMsg.PkiId) { 73 return common.MessageNoAction 74 } 75 return compareTimestamps(thisStateMsg.Timestamp, thatStateMsg.Timestamp) 76 } 77 78 func (mc *msgComparator) identityInvalidationPolicy(thisIdentityMsg *PeerIdentity, thatIdentityMsg *PeerIdentity) common.InvalidationResult { 79 if bytes.Equal(thisIdentityMsg.PkiId, thatIdentityMsg.PkiId) { 80 return common.MessageInvalidated 81 } 82 83 return common.MessageNoAction 84 } 85 86 func (mc *msgComparator) dataInvalidationPolicy(thisDataMsg *DataMessage, thatDataMsg *DataMessage) common.InvalidationResult { 87 if thisDataMsg.Payload.SeqNum == thatDataMsg.Payload.SeqNum { 88 return common.MessageInvalidated 89 } 90 91 diff := abs(thisDataMsg.Payload.SeqNum, thatDataMsg.Payload.SeqNum) 92 if diff <= uint64(mc.dataBlockStorageSize) { 93 return common.MessageNoAction 94 } 95 96 if thisDataMsg.Payload.SeqNum > thatDataMsg.Payload.SeqNum { 97 return common.MessageInvalidates 98 } 99 return common.MessageInvalidated 100 } 101 102 func aliveInvalidationPolicy(thisMsg *AliveMessage, thatMsg *AliveMessage) common.InvalidationResult { 103 if !bytes.Equal(thisMsg.Membership.PkiId, thatMsg.Membership.PkiId) { 104 return common.MessageNoAction 105 } 106 107 return compareTimestamps(thisMsg.Timestamp, thatMsg.Timestamp) 108 } 109 110 func leaderInvalidationPolicy(thisMsg *LeadershipMessage, thatMsg *LeadershipMessage) common.InvalidationResult { 111 if !bytes.Equal(thisMsg.PkiId, thatMsg.PkiId) { 112 return common.MessageNoAction 113 } 114 115 return compareTimestamps(thisMsg.Timestamp, thatMsg.Timestamp) 116 } 117 118 func compareTimestamps(thisTS *PeerTime, thatTS *PeerTime) common.InvalidationResult { 119 if thisTS.IncNum == thatTS.IncNum { 120 if thisTS.SeqNum > thatTS.SeqNum { 121 return common.MessageInvalidates 122 } 123 124 return common.MessageInvalidated 125 } 126 if thisTS.IncNum < thatTS.IncNum { 127 return common.MessageInvalidated 128 } 129 return common.MessageInvalidates 130 } 131 132 // IsAliveMsg returns whether this GossipMessage is an AliveMessage 133 func (m *GossipMessage) IsAliveMsg() bool { 134 return m.GetAliveMsg() != nil 135 } 136 137 // IsDataMsg returns whether this GossipMessage is a data message 138 func (m *GossipMessage) IsDataMsg() bool { 139 return m.GetDataMsg() != nil 140 } 141 142 // IsStateInfoPullRequestMsg returns whether this GossipMessage is a stateInfoPullRequest 143 func (m *GossipMessage) IsStateInfoPullRequestMsg() bool { 144 return m.GetStateInfoPullReq() != nil 145 } 146 147 // IsStateInfoSnapshot returns whether this GossipMessage is a stateInfo snapshot 148 func (m *GossipMessage) IsStateInfoSnapshot() bool { 149 return m.GetStateSnapshot() != nil 150 } 151 152 // IsStateInfoMsg returns whether this GossipMessage is a stateInfo message 153 func (m *GossipMessage) IsStateInfoMsg() bool { 154 return m.GetStateInfo() != nil 155 } 156 157 // IsPullMsg returns whether this GossipMessage is a message that belongs 158 // to the pull mechanism 159 func (m *GossipMessage) IsPullMsg() bool { 160 return m.GetDataReq() != nil || m.GetDataUpdate() != nil || 161 m.GetHello() != nil || m.GetDataDig() != nil 162 } 163 164 // IsRemoteStateMessage returns whether this GossipMessage is related to state synchronization 165 func (m *GossipMessage) IsRemoteStateMessage() bool { 166 return m.GetStateRequest() != nil || m.GetStateResponse() != nil 167 } 168 169 // GetPullMsgType returns the phase of the pull mechanism this GossipMessage belongs to 170 // for example: Hello, Digest, etc. 171 // If this isn't a pull message, PullMsgType_UNDEFINED is returned. 172 func (m *GossipMessage) GetPullMsgType() PullMsgType { 173 if helloMsg := m.GetHello(); helloMsg != nil { 174 return helloMsg.MsgType 175 } 176 177 if digMsg := m.GetDataDig(); digMsg != nil { 178 return digMsg.MsgType 179 } 180 181 if reqMsg := m.GetDataReq(); reqMsg != nil { 182 return reqMsg.MsgType 183 } 184 185 if resMsg := m.GetDataUpdate(); resMsg != nil { 186 return resMsg.MsgType 187 } 188 189 return PullMsgType_UNDEFINED 190 } 191 192 // IsChannelRestricted returns whether this GossipMessage should be routed 193 // only in its channel 194 func (m *GossipMessage) IsChannelRestricted() bool { 195 return m.Tag == GossipMessage_CHAN_AND_ORG || m.Tag == GossipMessage_CHAN_ONLY || m.Tag == GossipMessage_CHAN_OR_ORG 196 } 197 198 // IsOrgRestricted returns whether this GossipMessage should be routed only 199 // inside the organization 200 func (m *GossipMessage) IsOrgRestricted() bool { 201 return m.Tag == GossipMessage_CHAN_AND_ORG || m.Tag == GossipMessage_ORG_ONLY 202 } 203 204 // IsIdentityMsg returns whether this GossipMessage is an identity message 205 func (m *GossipMessage) IsIdentityMsg() bool { 206 return m.GetPeerIdentity() != nil 207 } 208 209 // IsDataReq returns whether this GossipMessage is a data request message 210 func (m *GossipMessage) IsDataReq() bool { 211 return m.GetDataReq() != nil 212 } 213 214 // IsDataUpdate returns whether this GossipMessage is a data update message 215 func (m *GossipMessage) IsDataUpdate() bool { 216 return m.GetDataUpdate() != nil 217 } 218 219 // IsHelloMsg returns whether this GossipMessage is a hello message 220 func (m *GossipMessage) IsHelloMsg() bool { 221 return m.GetHello() != nil 222 } 223 224 // IsDigestMsg returns whether this GossipMessage is a digest message 225 func (m *GossipMessage) IsDigestMsg() bool { 226 return m.GetDataDig() != nil 227 } 228 229 // IsLeadershipMsg returns whether this GossipMessage is a leadership (leader election) message 230 func (m *GossipMessage) IsLeadershipMsg() bool { 231 return m.GetLeadershipMsg() != nil 232 } 233 234 // MsgConsumer invokes code given a SignedGossipMessage 235 type MsgConsumer func(message *SignedGossipMessage) 236 237 // IdentifierExtractor extracts from a SignedGossipMessage an identifier 238 type IdentifierExtractor func(*SignedGossipMessage) string 239 240 // IsTagLegal checks the GossipMessage tags and inner type 241 // and returns an error if the tag doesn't match the type. 242 func (m *GossipMessage) IsTagLegal() error { 243 if m.Tag == GossipMessage_UNDEFINED { 244 return fmt.Errorf("Undefined tag") 245 } 246 if m.IsDataMsg() { 247 if m.Tag != GossipMessage_CHAN_AND_ORG { 248 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_CHAN_AND_ORG)]) 249 } 250 return nil 251 } 252 253 if m.IsAliveMsg() || m.GetMemReq() != nil || m.GetMemRes() != nil { 254 if m.Tag != GossipMessage_EMPTY { 255 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_EMPTY)]) 256 } 257 return nil 258 } 259 260 if m.IsIdentityMsg() { 261 if m.Tag != GossipMessage_ORG_ONLY { 262 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_ORG_ONLY)]) 263 } 264 return nil 265 } 266 267 if m.IsPullMsg() { 268 switch m.GetPullMsgType() { 269 case PullMsgType_BLOCK_MSG: 270 if m.Tag != GossipMessage_CHAN_AND_ORG { 271 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_CHAN_AND_ORG)]) 272 } 273 return nil 274 case PullMsgType_IDENTITY_MSG: 275 if m.Tag != GossipMessage_EMPTY { 276 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_EMPTY)]) 277 } 278 return nil 279 default: 280 return fmt.Errorf("Invalid PullMsgType: %s", PullMsgType_name[int32(m.GetPullMsgType())]) 281 } 282 } 283 284 if m.IsStateInfoMsg() || m.IsStateInfoPullRequestMsg() || m.IsStateInfoSnapshot() || m.IsRemoteStateMessage() { 285 if m.Tag != GossipMessage_CHAN_OR_ORG { 286 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_CHAN_OR_ORG)]) 287 } 288 return nil 289 } 290 291 if m.IsLeadershipMsg() { 292 if m.Tag != GossipMessage_CHAN_AND_ORG { 293 return fmt.Errorf("Tag should be %s", GossipMessage_Tag_name[int32(GossipMessage_CHAN_AND_ORG)]) 294 } 295 return nil 296 } 297 298 return fmt.Errorf("Unknown message type: %v", m) 299 } 300 301 // Verifier receives a peer identity, a signature and a message 302 // and returns nil if the signature on the message could be verified 303 // using the given identity. 304 type Verifier func(peerIdentity []byte, signature, message []byte) error 305 306 // Signer signs a message, and returns (signature, nil) 307 // on success, and nil and an error on failure. 308 type Signer func(msg []byte) ([]byte, error) 309 310 // ReceivedMessage is a GossipMessage wrapper that 311 // enables the user to send a message to the origin from which 312 // the ReceivedMessage was sent from. 313 // It also allows to know the identity of the sender, 314 // to obtain the raw bytes the GossipMessage was un-marshaled from, 315 // and the signature over these raw bytes. 316 type ReceivedMessage interface { 317 318 // Respond sends a GossipMessage to the origin from which this ReceivedMessage was sent from 319 Respond(msg *GossipMessage) 320 321 // GetGossipMessage returns the underlying GossipMessage 322 GetGossipMessage() *SignedGossipMessage 323 324 // GetSourceMessage Returns the Envelope the ReceivedMessage was 325 // constructed with 326 GetSourceEnvelope() *Envelope 327 328 // GetConnectionInfo returns information about the remote peer 329 // that sent the message 330 GetConnectionInfo() *ConnectionInfo 331 } 332 333 // ConnectionInfo represents information about 334 // the remote peer that sent a certain ReceivedMessage 335 type ConnectionInfo struct { 336 ID common.PKIidType 337 Auth *AuthInfo 338 Identity api.PeerIdentityType 339 Endpoint string 340 } 341 342 // String returns a string representation of this ConnectionInfo 343 func (c *ConnectionInfo) String() string { 344 return fmt.Sprintf("%s %v", c.Endpoint, c.ID) 345 } 346 347 // IsAuthenticated returns whether the connection to the remote peer 348 // was authenticated when the handshake took place 349 func (c *ConnectionInfo) IsAuthenticated() bool { 350 return c.Auth != nil 351 } 352 353 // AuthInfo represents the authentication 354 // data that was provided by the remote peer 355 // at the connection time 356 type AuthInfo struct { 357 SignedData []byte 358 Signature []byte 359 } 360 361 // Sign signs a GossipMessage with given Signer. 362 // Returns an Envelope on success, 363 // panics on failure. 364 func (m *SignedGossipMessage) Sign(signer Signer) (*Envelope, error) { 365 // If we have a secretEnvelope, don't override it. 366 // Back it up, and restore it later 367 var secretEnvelope *SecretEnvelope 368 if m.Envelope != nil { 369 secretEnvelope = m.Envelope.SecretEnvelope 370 } 371 m.Envelope = nil 372 payload, err := proto.Marshal(m.GossipMessage) 373 if err != nil { 374 return nil, err 375 } 376 sig, err := signer(payload) 377 if err != nil { 378 return nil, err 379 } 380 381 e := &Envelope{ 382 Payload: payload, 383 Signature: sig, 384 SecretEnvelope: secretEnvelope, 385 } 386 m.Envelope = e 387 return e, nil 388 } 389 390 // NoopSign creates a SignedGossipMessage with a nil signature 391 func (m *GossipMessage) NoopSign() (*SignedGossipMessage, error) { 392 signer := func(msg []byte) ([]byte, error) { 393 return nil, nil 394 } 395 sMsg := &SignedGossipMessage{ 396 GossipMessage: m, 397 } 398 _, err := sMsg.Sign(signer) 399 return sMsg, err 400 } 401 402 // Verify verifies a signed GossipMessage with a given Verifier. 403 // Returns nil on success, error on failure. 404 func (m *SignedGossipMessage) Verify(peerIdentity []byte, verify Verifier) error { 405 if m.Envelope == nil { 406 return errors.New("Missing envelope") 407 } 408 if len(m.Envelope.Payload) == 0 { 409 return errors.New("Empty payload") 410 } 411 if len(m.Envelope.Signature) == 0 { 412 return errors.New("Empty signature") 413 } 414 payloadSigVerificationErr := verify(peerIdentity, m.Envelope.Signature, m.Envelope.Payload) 415 if payloadSigVerificationErr != nil { 416 return payloadSigVerificationErr 417 } 418 if m.Envelope.SecretEnvelope != nil { 419 payload := m.Envelope.SecretEnvelope.Payload 420 sig := m.Envelope.SecretEnvelope.Signature 421 if len(payload) == 0 { 422 return errors.New("Empty payload") 423 } 424 if len(sig) == 0 { 425 return errors.New("Empty signature") 426 } 427 return verify(peerIdentity, sig, payload) 428 } 429 return nil 430 } 431 432 // IsSigned returns whether the message 433 // has a signature in the envelope. 434 func (m *SignedGossipMessage) IsSigned() bool { 435 return m.Envelope != nil && m.Envelope.Payload != nil && m.Envelope.Signature != nil 436 } 437 438 // ToGossipMessage un-marshals a given envelope and creates a 439 // SignedGossipMessage out of it. 440 // Returns an error if un-marshaling fails. 441 func (e *Envelope) ToGossipMessage() (*SignedGossipMessage, error) { 442 msg := &GossipMessage{} 443 err := proto.Unmarshal(e.Payload, msg) 444 if err != nil { 445 return nil, fmt.Errorf("Failed unmarshaling GossipMessage from envelope: %v", err) 446 } 447 return &SignedGossipMessage{ 448 GossipMessage: msg, 449 Envelope: e, 450 }, nil 451 } 452 453 // SignSecret signs the secret payload and creates 454 // a secret envelope out of it. 455 func (e *Envelope) SignSecret(signer Signer, secret *Secret) error { 456 payload, err := proto.Marshal(secret) 457 if err != nil { 458 return err 459 } 460 sig, err := signer(payload) 461 if err != nil { 462 return err 463 } 464 e.SecretEnvelope = &SecretEnvelope{ 465 Payload: payload, 466 Signature: sig, 467 } 468 return nil 469 } 470 471 // InternalEndpoint returns the internal endpoint 472 // in the secret envelope, or an empty string 473 // if a failure occurs. 474 func (s *SecretEnvelope) InternalEndpoint() string { 475 secret := &Secret{} 476 if err := proto.Unmarshal(s.Payload, secret); err != nil { 477 return "" 478 } 479 return secret.GetInternalEndpoint() 480 } 481 482 // SignedGossipMessage contains a GossipMessage 483 // and the Envelope from which it came from 484 type SignedGossipMessage struct { 485 *Envelope 486 *GossipMessage 487 } 488 489 func (p *Payload) toString() string { 490 return fmt.Sprintf("Block message: {Data: %d bytes, seq: %d}", len(p.Data), p.SeqNum) 491 } 492 493 func (du *DataUpdate) toString() string { 494 mType := PullMsgType_name[int32(du.MsgType)] 495 return fmt.Sprintf("Type: %s, items: %d, nonce: %d", mType, len(du.Data), du.Nonce) 496 } 497 498 func (mr *MembershipResponse) toString() string { 499 return fmt.Sprintf("MembershipResponse with Alive: %d, Dead: %d", len(mr.Alive), len(mr.Dead)) 500 } 501 502 func (sis *StateInfoSnapshot) toString() string { 503 return fmt.Sprintf("StateInfoSnapshot with %d items", len(sis.Elements)) 504 } 505 506 // String returns a string representation 507 // of a SignedGossipMessage 508 func (m *SignedGossipMessage) String() string { 509 env := "No envelope" 510 if m.Envelope != nil { 511 var secretEnv string 512 if m.SecretEnvelope != nil { 513 pl := len(m.SecretEnvelope.Payload) 514 sl := len(m.SecretEnvelope.Signature) 515 secretEnv = fmt.Sprintf(" Secret payload: %d bytes, Secret Signature: %d bytes", pl, sl) 516 } 517 env = fmt.Sprintf("%d bytes, Signature: %d bytes%s", len(m.Envelope.Payload), len(m.Envelope.Signature), secretEnv) 518 } 519 gMsg := "No gossipMessage" 520 if m.GossipMessage != nil { 521 var isSimpleMsg bool 522 if m.GetStateResponse() != nil { 523 gMsg = fmt.Sprintf("StateResponse with %d items", len(m.GetStateResponse().Payloads)) 524 } else if m.IsDataMsg() && m.GetDataMsg().Payload != nil { 525 gMsg = m.GetDataMsg().Payload.toString() 526 } else if m.IsDataUpdate() { 527 update := m.GetDataUpdate() 528 gMsg = fmt.Sprintf("DataUpdate: %s", update.toString()) 529 } else if m.GetMemRes() != nil { 530 gMsg = m.GetMemRes().toString() 531 } else if m.IsStateInfoSnapshot() { 532 gMsg = m.GetStateSnapshot().toString() 533 } else { 534 gMsg = m.GossipMessage.String() 535 isSimpleMsg = true 536 } 537 if !isSimpleMsg { 538 desc := fmt.Sprintf("Channel: %s, nonce: %d, tag: %s", string(m.Channel), m.Nonce, GossipMessage_Tag_name[int32(m.Tag)]) 539 gMsg = fmt.Sprintf("%s %s", desc, gMsg) 540 } 541 } 542 return fmt.Sprintf("GossipMessage: %v, Envelope: %s", gMsg, env) 543 } 544 545 // Abs returns abs(a-b) 546 func abs(a, b uint64) uint64 { 547 if a > b { 548 return a - b 549 } 550 return b - a 551 }