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