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  }