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