@@ -23,6 +23,7 @@ import (
23
23
24
24
"github.com/hyperledger/fabric/gossip/api"
25
25
"github.com/hyperledger/fabric/gossip/comm"
26
+ "github.com/hyperledger/fabric/gossip/common"
26
27
"github.com/hyperledger/fabric/gossip/discovery"
27
28
"github.com/hyperledger/fabric/gossip/gossip/algo"
28
29
"github.com/hyperledger/fabric/gossip/gossip/pull"
@@ -41,6 +42,12 @@ func init() {
41
42
algo .SetResponseWaitTime (shortenedWaitTime )
42
43
}
43
44
45
+ var (
46
+ cs = & naiveCryptoService {
47
+ revokedPkiIDS : make (map [string ]struct {}),
48
+ }
49
+ )
50
+
44
51
type pullerMock struct {
45
52
mock.Mock
46
53
pull.Mediator
@@ -90,78 +97,135 @@ func TestCertStoreBadSignature(t *testing.T) {
90
97
badSignature := func (nonce uint64 ) proto.ReceivedMessage {
91
98
return createUpdateMessage (nonce , createBadlySignedUpdateMessage ())
92
99
}
93
-
94
- testCertificateUpdate (t , badSignature , false )
100
+ pm , cs , _ := createObjects (badSignature , nil )
101
+ defer pm .Stop ()
102
+ testCertificateUpdate (t , false , cs )
95
103
}
96
104
97
105
func TestCertStoreMismatchedIdentity (t * testing.T ) {
98
106
mismatchedIdentity := func (nonce uint64 ) proto.ReceivedMessage {
99
107
return createUpdateMessage (nonce , createMismatchedUpdateMessage ())
100
108
}
101
109
102
- testCertificateUpdate (t , mismatchedIdentity , false )
110
+ pm , cs , _ := createObjects (mismatchedIdentity , nil )
111
+ defer pm .Stop ()
112
+ testCertificateUpdate (t , false , cs )
103
113
}
104
114
105
115
func TestCertStoreShouldSucceed (t * testing.T ) {
106
116
totallyFineIdentity := func (nonce uint64 ) proto.ReceivedMessage {
107
117
return createUpdateMessage (nonce , createValidUpdateMessage ())
108
118
}
109
119
110
- testCertificateUpdate (t , totallyFineIdentity , true )
120
+ pm , cs , _ := createObjects (totallyFineIdentity , nil )
121
+ defer pm .Stop ()
122
+ testCertificateUpdate (t , true , cs )
111
123
}
112
124
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
+ }()
132
131
133
- },
132
+ identityExpirationCheckInterval = time .Second
133
+
134
+ totallyFineIdentity := func (nonce uint64 ) proto.ReceivedMessage {
135
+ return createUpdateMessage (nonce , createValidUpdateMessage ())
134
136
}
135
- pullMediator := pull .NewPullMediator (config , adapter )
136
- certStore := newCertStore (& pullerMock {
137
- Mediator : pullMediator ,
138
- }, identity .NewIdentityMapper (& naiveCryptoService {}), api .PeerIdentityType ("SELF" ), & naiveCryptoService {})
139
137
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 )
141
151
142
- wg := sync.WaitGroup {}
143
- wg .Add (1 )
144
152
sentHello := false
145
- sentDataReq := false
146
153
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 ) {
148
156
msg := arg .Get (0 ).(* proto.SignedGossipMessage )
149
157
l .Lock ()
150
158
defer l .Unlock ()
151
159
152
160
if hello := msg .GetHello (); hello != nil && ! sentHello {
153
161
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 ()})
155
173
}
156
174
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 {}{}
161
218
}
162
219
})
163
- wg .Wait ()
164
220
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 ) {
165
229
hello := & sentMsg {
166
230
msg : (& proto.GossipMessage {
167
231
Channel : []byte ("" ),
@@ -302,3 +366,61 @@ func createDigest(nonce uint64) proto.ReceivedMessage {
302
366
}
303
367
return & sentMsg {msg : digest .NoopSign ()}
304
368
}
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