@@ -55,9 +55,13 @@ type GossipChannel interface {
55
55
// IsMemberInChan checks whether the given member is eligible to be in the channel
56
56
IsMemberInChan (member discovery.NetworkMember ) bool
57
57
58
- // UpdateStateInfo updates this channel's StateInfo message
59
- // that is periodically published
60
- UpdateStateInfo (msg * proto.SignedGossipMessage )
58
+ // UpdateLedgerHeight updates the ledger height the peer
59
+ // publishes to other peers in the channel
60
+ UpdateLedgerHeight (height uint64 )
61
+
62
+ // UpdateChaincodes updates the chaincodes the peer publishes
63
+ // to other peers in the channel
64
+ UpdateChaincodes (chaincode []* proto.Chaincode )
61
65
62
66
// IsOrgInChannel returns whether the given organization is in the channel
63
67
IsOrgInChannel (membersOrg api.OrgIdentityType ) bool
@@ -86,6 +90,8 @@ type GossipChannel interface {
86
90
// Adapter enables the gossipChannel
87
91
// to communicate with gossipServiceImpl.
88
92
type Adapter interface {
93
+ Sign (msg * proto.GossipMessage ) (* proto.SignedGossipMessage , error )
94
+
89
95
// GetConf returns the configuration that this GossipChannel will posses
90
96
GetConf () Config
91
97
@@ -140,6 +146,7 @@ type gossipChannel struct {
140
146
stateInfoRequestScheduler * time.Ticker
141
147
memFilter * membershipFilter
142
148
ledgerHeight uint64
149
+ incTime uint64
143
150
leftChannel int32
144
151
}
145
152
@@ -166,6 +173,7 @@ func (mf *membershipFilter) GetMembership() []discovery.NetworkMember {
166
173
func NewGossipChannel (pkiID common.PKIidType , org api.OrgIdentityType , mcs api.MessageCryptoService ,
167
174
chainID common.ChainID , adapter Adapter , joinMsg api.JoinChannelMessage ) GossipChannel {
168
175
gc := & gossipChannel {
176
+ incTime : uint64 (time .Now ().UnixNano ()),
169
177
selfOrg : org ,
170
178
pkiID : pkiID ,
171
179
mcs : mcs ,
@@ -281,7 +289,18 @@ func (gc *gossipChannel) periodicalInvocation(fn func(), c <-chan time.Time) {
281
289
282
290
// LeaveChannel makes the peer leave the channel
283
291
func (gc * gossipChannel ) LeaveChannel () {
292
+ gc .Lock ()
293
+ defer gc .Unlock ()
294
+
284
295
atomic .StoreInt32 (& gc .leftChannel , 1 )
296
+
297
+ var chaincodes []* proto.Chaincode
298
+ var height uint64
299
+ if prevMsg := gc .stateInfoMsg ; prevMsg != nil {
300
+ chaincodes = prevMsg .GetStateInfo ().Properties .Chaincodes
301
+ height = prevMsg .GetStateInfo ().Properties .LedgerHeight
302
+ }
303
+ gc .updateProperties (height , chaincodes , true )
285
304
}
286
305
287
306
func (gc * gossipChannel ) hasLeftChannel () bool {
@@ -307,7 +326,6 @@ func (gc *gossipChannel) GetPeers() []discovery.NetworkMember {
307
326
if props != nil && props .LeftChannel {
308
327
continue
309
328
}
310
- member .Metadata = stateInf .GetStateInfo ().Metadata
311
329
member .Properties = stateInf .GetStateInfo ().Properties
312
330
members = append (members , member )
313
331
}
@@ -772,22 +790,75 @@ func (gc *gossipChannel) createStateInfoRequest() (*proto.SignedGossipMessage, e
772
790
}).NoopSign ()
773
791
}
774
792
775
- // UpdateStateInfo updates this channel's StateInfo message
776
- // that is periodically published
777
- func (gc * gossipChannel ) UpdateStateInfo (msg * proto.SignedGossipMessage ) {
778
- if ! msg .IsStateInfoMsg () {
779
- return
793
+ // UpdateLedgerHeight updates the ledger height the peer
794
+ // publishes to other peers in the channel
795
+ func (gc * gossipChannel ) UpdateLedgerHeight (height uint64 ) {
796
+ gc .Lock ()
797
+ defer gc .Unlock ()
798
+
799
+ var chaincodes []* proto.Chaincode
800
+ var leftChannel bool
801
+ if prevMsg := gc .stateInfoMsg ; prevMsg != nil {
802
+ leftChannel = prevMsg .GetStateInfo ().Properties .LeftChannel
803
+ chaincodes = prevMsg .GetStateInfo ().Properties .Chaincodes
780
804
}
805
+ gc .updateProperties (height , chaincodes , leftChannel )
806
+ }
781
807
808
+ // UpdateChaincodes updates the chaincodes the peer publishes
809
+ // to other peers in the channel
810
+ func (gc * gossipChannel ) UpdateChaincodes (chaincodes []* proto.Chaincode ) {
782
811
gc .Lock ()
783
812
defer gc .Unlock ()
784
813
814
+ var ledgerHeight uint64 = 1
815
+ var leftChannel bool
816
+ if prevMsg := gc .stateInfoMsg ; prevMsg != nil {
817
+ ledgerHeight = prevMsg .GetStateInfo ().Properties .LedgerHeight
818
+ leftChannel = prevMsg .GetStateInfo ().Properties .LeftChannel
819
+ }
820
+ gc .updateProperties (ledgerHeight , chaincodes , leftChannel )
821
+ }
822
+
823
+ // UpdateStateInfo updates this channel's StateInfo message
824
+ // that is periodically published
825
+ func (gc * gossipChannel ) updateStateInfo (msg * proto.SignedGossipMessage ) {
785
826
gc .stateInfoMsgStore .Add (msg )
786
827
gc .ledgerHeight = msg .GetStateInfo ().Properties .LedgerHeight
787
828
gc .stateInfoMsg = msg
788
829
atomic .StoreInt32 (& gc .shouldGossipStateInfo , int32 (1 ))
789
830
}
790
831
832
+ func (gc * gossipChannel ) updateProperties (ledgerHeight uint64 , chaincodes []* proto.Chaincode , leftChannel bool ) {
833
+ stateInfMsg := & proto.StateInfo {
834
+ Channel_MAC : GenerateMAC (gc .pkiID , gc .chainID ),
835
+ PkiId : gc .pkiID ,
836
+ Timestamp : & proto.PeerTime {
837
+ IncNum : gc .incTime ,
838
+ SeqNum : uint64 (time .Now ().UnixNano ()),
839
+ },
840
+ Properties : & proto.Properties {
841
+ LeftChannel : leftChannel ,
842
+ LedgerHeight : ledgerHeight ,
843
+ Chaincodes : chaincodes ,
844
+ },
845
+ }
846
+ m := & proto.GossipMessage {
847
+ Nonce : 0 ,
848
+ Tag : proto .GossipMessage_CHAN_OR_ORG ,
849
+ Content : & proto.GossipMessage_StateInfo {
850
+ StateInfo : stateInfMsg ,
851
+ },
852
+ }
853
+
854
+ msg , err := gc .Sign (m )
855
+ if err != nil {
856
+ gc .logger .Error ("Failed signing message:" , err )
857
+ return
858
+ }
859
+ gc .updateStateInfo (msg )
860
+ }
861
+
791
862
func newStateInfoCache (sweepInterval time.Duration , hasExpired func (interface {}) bool , verifyFunc membershipPredicate ) * stateInfoCache {
792
863
membershipStore := util .NewMembershipStore ()
793
864
pol := proto .NewGossipMessageComparator (0 )
0 commit comments