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  }