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  }