@@ -23,6 +23,7 @@ import (
2323
2424 "github.com/hyperledger/fabric/gossip/api"
2525 "github.com/hyperledger/fabric/gossip/comm"
26+ "github.com/hyperledger/fabric/gossip/common"
2627 "github.com/hyperledger/fabric/gossip/discovery"
2728 "github.com/hyperledger/fabric/gossip/gossip/algo"
2829 "github.com/hyperledger/fabric/gossip/gossip/pull"
@@ -41,6 +42,12 @@ func init() {
4142 algo .SetResponseWaitTime (shortenedWaitTime )
4243}
4344
45+ var (
46+ cs = & naiveCryptoService {
47+ revokedPkiIDS : make (map [string ]struct {}),
48+ }
49+ )
50+
4451type pullerMock struct {
4552 mock.Mock
4653 pull.Mediator
@@ -90,78 +97,135 @@ func TestCertStoreBadSignature(t *testing.T) {
9097 badSignature := func (nonce uint64 ) proto.ReceivedMessage {
9198 return createUpdateMessage (nonce , createBadlySignedUpdateMessage ())
9299 }
93-
94- testCertificateUpdate (t , badSignature , false )
100+ pm , cs , _ := createObjects (badSignature , nil )
101+ defer pm .Stop ()
102+ testCertificateUpdate (t , false , cs )
95103}
96104
97105func TestCertStoreMismatchedIdentity (t * testing.T ) {
98106 mismatchedIdentity := func (nonce uint64 ) proto.ReceivedMessage {
99107 return createUpdateMessage (nonce , createMismatchedUpdateMessage ())
100108 }
101109
102- testCertificateUpdate (t , mismatchedIdentity , false )
110+ pm , cs , _ := createObjects (mismatchedIdentity , nil )
111+ defer pm .Stop ()
112+ testCertificateUpdate (t , false , cs )
103113}
104114
105115func TestCertStoreShouldSucceed (t * testing.T ) {
106116 totallyFineIdentity := func (nonce uint64 ) proto.ReceivedMessage {
107117 return createUpdateMessage (nonce , createValidUpdateMessage ())
108118 }
109119
110- testCertificateUpdate (t , totallyFineIdentity , true )
120+ pm , cs , _ := createObjects (totallyFineIdentity , nil )
121+ defer pm .Stop ()
122+ testCertificateUpdate (t , true , cs )
111123}
112124
113- func testCertificateUpdate (t * testing.T , updateFactory func (uint64 ) proto.ReceivedMessage , shouldSucceed bool ) {
114- config := pull.Config {
115- MsgType : proto .PullMsgType_IDENTITY_MSG ,
116- PeerCountToSelect : 1 ,
117- PullInterval : time .Millisecond * 500 ,
118- Tag : proto .GossipMessage_EMPTY ,
119- Channel : nil ,
120- ID : "id1" ,
121- }
122- sender := & senderMock {}
123- memberSvc := & membershipSvcMock {}
124- memberSvc .On ("GetMembership" ).Return ([]discovery.NetworkMember {{PKIid : []byte ("bla bla" ), Endpoint : "localhost:5611" }})
125- adapter := pull.PullAdapter {
126- Sndr : sender ,
127- MemSvc : memberSvc ,
128- IdExtractor : func (msg * proto.SignedGossipMessage ) string {
129- return string (msg .GetPeerIdentity ().PkiId )
130- },
131- MsgCons : func (msg * proto.SignedGossipMessage ) {
125+ func TestCertExpiration (t * testing.T ) {
126+ identityExpCheckInterval := identityExpirationCheckInterval
127+ defer func () {
128+ identityExpirationCheckInterval = identityExpCheckInterval
129+ cs .revokedPkiIDS = map [string ]struct {}{}
130+ }()
132131
133- },
132+ identityExpirationCheckInterval = time .Second
133+
134+ totallyFineIdentity := func (nonce uint64 ) proto.ReceivedMessage {
135+ return createUpdateMessage (nonce , createValidUpdateMessage ())
134136 }
135- pullMediator := pull .NewPullMediator (config , adapter )
136- certStore := newCertStore (& pullerMock {
137- Mediator : pullMediator ,
138- }, identity .NewIdentityMapper (& naiveCryptoService {}), api .PeerIdentityType ("SELF" ), & naiveCryptoService {})
139137
140- defer pullMediator .Stop ()
138+ askedForIdentity := make (chan struct {}, 1 )
139+
140+ pm , cStore , sender := createObjects (totallyFineIdentity , func (message * proto.SignedGossipMessage ) {
141+ askedForIdentity <- struct {}{}
142+ })
143+ defer pm .Stop ()
144+ testCertificateUpdate (t , true , cStore )
145+ // Should have asked for an identity for the first time
146+ assert .Len (t , askedForIdentity , 1 )
147+ // Drain channel
148+ <- askedForIdentity
149+ // Now it's 0
150+ assert .Len (t , askedForIdentity , 0 )
141151
142- wg := sync.WaitGroup {}
143- wg .Add (1 )
144152 sentHello := false
145- sentDataReq := false
146153 l := sync.Mutex {}
147- sender .On ("Send" , mock .Anything , mock .Anything ).Run (func (arg mock.Arguments ) {
154+ senderMock := mock.Mock {}
155+ senderMock .On ("Send" , mock .Anything , mock .Anything ).Run (func (arg mock.Arguments ) {
148156 msg := arg .Get (0 ).(* proto.SignedGossipMessage )
149157 l .Lock ()
150158 defer l .Unlock ()
151159
152160 if hello := msg .GetHello (); hello != nil && ! sentHello {
153161 sentHello = true
154- go certStore .handleMessage (createDigest (hello .Nonce ))
162+ dig := & proto.GossipMessage {
163+ Tag : proto .GossipMessage_EMPTY ,
164+ Content : & proto.GossipMessage_DataDig {
165+ DataDig : & proto.DataDigest {
166+ Nonce : hello .Nonce ,
167+ MsgType : proto .PullMsgType_IDENTITY_MSG ,
168+ Digests : []string {"B" },
169+ },
170+ },
171+ }
172+ go cStore .handleMessage (& sentMsg {msg : dig .NoopSign ()})
155173 }
156174
157- if dataReq := msg .GetDataReq (); dataReq != nil && ! sentDataReq {
158- sentDataReq = true
159- certStore .handleMessage (updateFactory (dataReq .Nonce ))
160- wg .Done ()
175+ if dataReq := msg .GetDataReq (); dataReq != nil {
176+ askedForIdentity <- struct {}{}
177+ }
178+ })
179+ sender .Mock = senderMock
180+ testCertificateUpdate (t , true , cStore )
181+ // Shouldn't have asked, because already got identity
182+ select {
183+ case <- time .After (time .Second * 3 ):
184+ case <- askedForIdentity :
185+ assert .Fail (t , "Shouldn't have asked for an identity, becase we already have it" )
186+ }
187+ assert .Len (t , askedForIdentity , 0 )
188+ // Revoke the identity
189+ cs .revoke (common .PKIidType ("B" ))
190+ cStore .listRevokedPeers (func (id api.PeerIdentityType ) bool {
191+ return string (id ) == "B"
192+ })
193+ sentHello = false
194+ l = sync.Mutex {}
195+ senderMock = mock.Mock {}
196+ senderMock .On ("Send" , mock .Anything , mock .Anything ).Run (func (arg mock.Arguments ) {
197+ msg := arg .Get (0 ).(* proto.SignedGossipMessage )
198+ l .Lock ()
199+ defer l .Unlock ()
200+
201+ if hello := msg .GetHello (); hello != nil && ! sentHello {
202+ sentHello = true
203+ dig := & proto.GossipMessage {
204+ Tag : proto .GossipMessage_EMPTY ,
205+ Content : & proto.GossipMessage_DataDig {
206+ DataDig : & proto.DataDigest {
207+ Nonce : hello .Nonce ,
208+ MsgType : proto .PullMsgType_IDENTITY_MSG ,
209+ Digests : []string {"B" },
210+ },
211+ },
212+ }
213+ go cStore .handleMessage (& sentMsg {msg : dig .NoopSign ()})
214+ }
215+
216+ if dataReq := msg .GetDataReq (); dataReq != nil {
217+ askedForIdentity <- struct {}{}
161218 }
162219 })
163- wg .Wait ()
164220
221+ select {
222+ case <- time .After (time .Second * 5 ):
223+ assert .Fail (t , "Didn't ask for identity, but should have. Looks like identity hasn't expired" )
224+ case <- askedForIdentity :
225+ }
226+ }
227+
228+ func testCertificateUpdate (t * testing.T , shouldSucceed bool , certStore * certStore ) {
165229 hello := & sentMsg {
166230 msg : (& proto.GossipMessage {
167231 Channel : []byte ("" ),
@@ -302,3 +366,61 @@ func createDigest(nonce uint64) proto.ReceivedMessage {
302366 }
303367 return & sentMsg {msg : digest .NoopSign ()}
304368}
369+
370+ func createObjects (updateFactory func (uint64 ) proto.ReceivedMessage , msgCons proto.MsgConsumer ) (pull.Mediator , * certStore , * senderMock ) {
371+ if msgCons == nil {
372+ msgCons = func (_ * proto.SignedGossipMessage ) {}
373+ }
374+ config := pull.Config {
375+ MsgType : proto .PullMsgType_IDENTITY_MSG ,
376+ PeerCountToSelect : 1 ,
377+ PullInterval : time .Millisecond * 500 ,
378+ Tag : proto .GossipMessage_EMPTY ,
379+ Channel : nil ,
380+ ID : "id1" ,
381+ }
382+ sender := & senderMock {}
383+ memberSvc := & membershipSvcMock {}
384+ memberSvc .On ("GetMembership" ).Return ([]discovery.NetworkMember {{PKIid : []byte ("bla bla" ), Endpoint : "localhost:5611" }})
385+
386+ var certStore * certStore
387+ adapter := pull.PullAdapter {
388+ Sndr : sender ,
389+ MsgCons : func (msg * proto.SignedGossipMessage ) {
390+ certStore .idMapper .Put (msg .GetPeerIdentity ().PkiId , msg .GetPeerIdentity ().Cert )
391+ msgCons (msg )
392+ },
393+ IdExtractor : func (msg * proto.SignedGossipMessage ) string {
394+ return string (msg .GetPeerIdentity ().PkiId )
395+ },
396+ MemSvc : memberSvc ,
397+ }
398+ pullMediator := pull .NewPullMediator (config , adapter )
399+ certStore = newCertStore (& pullerMock {
400+ Mediator : pullMediator ,
401+ }, identity .NewIdentityMapper (cs ), api .PeerIdentityType ("SELF" ), cs )
402+
403+ wg := sync.WaitGroup {}
404+ wg .Add (1 )
405+ sentHello := false
406+ sentDataReq := false
407+ l := sync.Mutex {}
408+ sender .On ("Send" , mock .Anything , mock .Anything ).Run (func (arg mock.Arguments ) {
409+ msg := arg .Get (0 ).(* proto.SignedGossipMessage )
410+ l .Lock ()
411+ defer l .Unlock ()
412+
413+ if hello := msg .GetHello (); hello != nil && ! sentHello {
414+ sentHello = true
415+ go certStore .handleMessage (createDigest (hello .Nonce ))
416+ }
417+
418+ if dataReq := msg .GetDataReq (); dataReq != nil && ! sentDataReq {
419+ sentDataReq = true
420+ certStore .handleMessage (updateFactory (dataReq .Nonce ))
421+ wg .Done ()
422+ }
423+ })
424+ wg .Wait ()
425+ return pullMediator , certStore , sender
426+ }
0 commit comments