@@ -24,6 +24,8 @@ import (
24
24
"testing"
25
25
"time"
26
26
27
+ "errors"
28
+
27
29
pb "github.com/golang/protobuf/proto"
28
30
"github.com/hyperledger/fabric/common/configtx/test"
29
31
"github.com/hyperledger/fabric/common/util"
49
51
50
52
var orgID = []byte ("ORG1" )
51
53
54
+ type peerIdentityAcceptor func (identity api.PeerIdentityType ) error
55
+
56
+ var noopPeerIdentityAcceptor = func (identity api.PeerIdentityType ) error {
57
+ return nil
58
+ }
59
+
52
60
type joinChanMsg struct {
53
61
}
54
62
@@ -78,30 +86,33 @@ func (*orgCryptoService) Verify(joinChanMsg api.JoinChannelMessage) error {
78
86
return nil
79
87
}
80
88
81
- type naiveCryptoService struct {
89
+ type cryptoServiceMock struct {
90
+ acceptor peerIdentityAcceptor
82
91
}
83
92
84
93
// GetPKIidOfCert returns the PKI-ID of a peer's identity
85
- func (* naiveCryptoService ) GetPKIidOfCert (peerIdentity api.PeerIdentityType ) common.PKIidType {
94
+ func (* cryptoServiceMock ) GetPKIidOfCert (peerIdentity api.PeerIdentityType ) common.PKIidType {
86
95
return common .PKIidType (peerIdentity )
87
96
}
88
97
89
98
// VerifyBlock returns nil if the block is properly signed,
90
99
// else returns error
91
- func (* naiveCryptoService ) VerifyBlock (chainID common.ChainID , signedBlock api.SignedBlock ) error {
100
+ func (* cryptoServiceMock ) VerifyBlock (chainID common.ChainID , signedBlock api.SignedBlock ) error {
92
101
return nil
93
102
}
94
103
95
104
// Sign signs msg with this peer's signing key and outputs
96
105
// the signature if no error occurred.
97
- func (* naiveCryptoService ) Sign (msg []byte ) ([]byte , error ) {
98
- return msg , nil
106
+ func (* cryptoServiceMock ) Sign (msg []byte ) ([]byte , error ) {
107
+ clone := make ([]byte , len (msg ))
108
+ copy (clone , msg )
109
+ return clone , nil
99
110
}
100
111
101
112
// Verify checks that signature is a valid signature of message under a peer's verification key.
102
113
// If the verification succeeded, Verify returns nil meaning no error occurred.
103
114
// If peerCert is nil, then the signature is verified against this peer's verification key.
104
- func (* naiveCryptoService ) Verify (peerIdentity api.PeerIdentityType , signature , message []byte ) error {
115
+ func (* cryptoServiceMock ) Verify (peerIdentity api.PeerIdentityType , signature , message []byte ) error {
105
116
equal := bytes .Equal (signature , message )
106
117
if ! equal {
107
118
return fmt .Errorf ("Wrong signature:%v, %v" , signature , message )
@@ -113,11 +124,11 @@ func (*naiveCryptoService) Verify(peerIdentity api.PeerIdentityType, signature,
113
124
// under a peer's verification key, but also in the context of a specific channel.
114
125
// If the verification succeeded, Verify returns nil meaning no error occurred.
115
126
// If peerIdentity is nil, then the signature is verified against this peer's verification key.
116
- func (* naiveCryptoService ) VerifyByChannel (chainID common.ChainID , peerIdentity api.PeerIdentityType , signature , message []byte ) error {
117
- return nil
127
+ func (cs * cryptoServiceMock ) VerifyByChannel (chainID common.ChainID , peerIdentity api.PeerIdentityType , signature , message []byte ) error {
128
+ return cs . acceptor ( peerIdentity )
118
129
}
119
130
120
- func (* naiveCryptoService ) ValidateIdentity (peerIdentity api.PeerIdentityType ) error {
131
+ func (* cryptoServiceMock ) ValidateIdentity (peerIdentity api.PeerIdentityType ) error {
121
132
return nil
122
133
}
123
134
@@ -132,9 +143,10 @@ func bootPeers(ids ...int) []string {
132
143
// Simple presentation of peer which includes only
133
144
// communication module, gossip and state transfer
134
145
type peerNode struct {
135
- g gossip.Gossip
136
- s GossipStateProvider
137
-
146
+ port int
147
+ g gossip.Gossip
148
+ s GossipStateProvider
149
+ cs * cryptoServiceMock
138
150
commit committer.Committer
139
151
}
140
152
@@ -145,13 +157,13 @@ func (node *peerNode) shutdown() {
145
157
}
146
158
147
159
// Default configuration to be used for gossip and communication modules
148
- func newGossipConfig (id int , maxMsgCount int , boot ... int ) * gossip.Config {
160
+ func newGossipConfig (id int , boot ... int ) * gossip.Config {
149
161
port := id + portPrefix
150
162
return & gossip.Config {
151
163
BindPort : port ,
152
164
BootstrapPeers : bootPeers (boot ... ),
153
165
ID : fmt .Sprintf ("p%d" , id ),
154
- MaxBlockCountToStore : maxMsgCount ,
166
+ MaxBlockCountToStore : 0 ,
155
167
MaxPropagationBurstLatency : time .Duration (10 ) * time .Millisecond ,
156
168
MaxPropagationBurstSize : 10 ,
157
169
PropagateIterations : 1 ,
@@ -166,11 +178,10 @@ func newGossipConfig(id int, maxMsgCount int, boot ...int) *gossip.Config {
166
178
}
167
179
168
180
// Create gossip instance
169
- func newGossipInstance (config * gossip.Config ) gossip.Gossip {
170
- cryptoService := & naiveCryptoService {}
171
- idMapper := identity .NewIdentityMapper (cryptoService )
181
+ func newGossipInstance (config * gossip.Config , mcs api.MessageCryptoService ) gossip.Gossip {
182
+ idMapper := identity .NewIdentityMapper (mcs )
172
183
173
- return gossip .NewGossipServiceWithServer (config , & orgCryptoService {}, cryptoService , idMapper , []byte (config .InternalEndpoint ))
184
+ return gossip .NewGossipServiceWithServer (config , & orgCryptoService {}, mcs , idMapper , []byte (config .InternalEndpoint ))
174
185
}
175
186
176
187
// Create new instance of KVLedger to be used for testing
@@ -182,24 +193,117 @@ func newCommitter(id int) committer.Committer {
182
193
}
183
194
184
195
// Constructing pseudo peer node, simulating only gossip and state transfer part
185
- func newPeerNode (config * gossip.Config , committer committer.Committer ) * peerNode {
186
-
196
+ func newPeerNode (config * gossip.Config , committer committer.Committer , acceptor peerIdentityAcceptor ) * peerNode {
197
+ cs := & cryptoServiceMock { acceptor : acceptor }
187
198
// Gossip component based on configuration provided and communication module
188
- gossip := newGossipInstance (config )
199
+ gossip := newGossipInstance (config , & cryptoServiceMock { acceptor : noopPeerIdentityAcceptor } )
189
200
190
201
logger .Debug ("Joinning channel" , util .GetTestChainID ())
191
202
gossip .JoinChan (& joinChanMsg {}, common .ChainID (util .GetTestChainID ()))
192
203
193
204
// Initialize pseudo peer simulator, which has only three
194
205
// basic parts
195
- return & peerNode {
196
- g : gossip ,
197
- s : NewGossipStateProvider (util .GetTestChainID (), gossip , committer ),
198
206
207
+ return & peerNode {
208
+ port : config .BindPort ,
209
+ g : gossip ,
210
+ s : NewGossipStateProvider (util .GetTestChainID (), gossip , committer , cs ),
199
211
commit : committer ,
212
+ cs : cs ,
200
213
}
201
214
}
202
215
216
+ func TestAccessControl (t * testing.T ) {
217
+ viper .Set ("peer.fileSystemPath" , "/tmp/tests/ledger/node" )
218
+ ledgermgmt .InitializeTestEnv ()
219
+ defer ledgermgmt .CleanupTestEnv ()
220
+
221
+ bootstrapSetSize := 5
222
+ bootstrapSet := make ([]* peerNode , 0 )
223
+
224
+ authorizedPeers := map [string ]struct {}{
225
+ "localhost:5610" : {},
226
+ "localhost:5615" : {},
227
+ "localhost:5618" : {},
228
+ "localhost:5621" : {},
229
+ }
230
+
231
+ blockPullPolicy := func (identity api.PeerIdentityType ) error {
232
+ if _ , isAuthorized := authorizedPeers [string (identity )]; isAuthorized {
233
+ return nil
234
+ }
235
+ return errors .New ("Not authorized" )
236
+ }
237
+
238
+ for i := 0 ; i < bootstrapSetSize ; i ++ {
239
+ committer := newCommitter (i )
240
+ bootstrapSet = append (bootstrapSet , newPeerNode (newGossipConfig (i ), committer , blockPullPolicy ))
241
+ }
242
+
243
+ defer func () {
244
+ for _ , p := range bootstrapSet {
245
+ p .shutdown ()
246
+ }
247
+ }()
248
+
249
+ msgCount := 5
250
+
251
+ for i := 1 ; i <= msgCount ; i ++ {
252
+ rawblock := pcomm .NewBlock (uint64 (i ), []byte {})
253
+ if bytes , err := pb .Marshal (rawblock ); err == nil {
254
+ payload := & proto.Payload {uint64 (i ), "" , bytes }
255
+ bootstrapSet [0 ].s .AddPayload (payload )
256
+ } else {
257
+ t .Fail ()
258
+ }
259
+ }
260
+
261
+ standardPeerSetSize := 10
262
+ peersSet := make ([]* peerNode , 0 )
263
+
264
+ for i := 0 ; i < standardPeerSetSize ; i ++ {
265
+ committer := newCommitter (bootstrapSetSize + i )
266
+ peersSet = append (peersSet , newPeerNode (newGossipConfig (bootstrapSetSize + i , 0 , 1 , 2 , 3 , 4 ), committer , blockPullPolicy ))
267
+ }
268
+
269
+ defer func () {
270
+ for _ , p := range peersSet {
271
+ p .shutdown ()
272
+ }
273
+ }()
274
+
275
+ waitUntilTrueOrTimeout (t , func () bool {
276
+ for _ , p := range peersSet {
277
+ if len (p .g .PeersOfChannel (common .ChainID (util .GetTestChainID ()))) != bootstrapSetSize + standardPeerSetSize - 1 {
278
+ logger .Debug ("Peer discovery has not finished yet" )
279
+ return false
280
+ }
281
+ }
282
+ logger .Debug ("All peer discovered each other!!!" )
283
+ return true
284
+ }, 30 * time .Second )
285
+
286
+ logger .Debug ("Waiting for all blocks to arrive." )
287
+ waitUntilTrueOrTimeout (t , func () bool {
288
+ logger .Debug ("Trying to see all authorized peers get all blocks, and all non-authorized didn't" )
289
+ for _ , p := range peersSet {
290
+ height , err := p .commit .LedgerHeight ()
291
+ id := fmt .Sprintf ("localhost:%d" , p .port )
292
+ if _ , isAuthorized := authorizedPeers [id ]; isAuthorized {
293
+ if height != uint64 (msgCount + 1 ) || err != nil {
294
+ return false
295
+ }
296
+ } else {
297
+ if err == nil && height > 1 {
298
+ assert .Fail (t , "Peer" , id , "got message but isn't authorized! Height:" , height )
299
+ }
300
+ }
301
+ }
302
+ logger .Debug ("All peers have same ledger height!!!" )
303
+ return true
304
+ }, 60 * time .Second )
305
+ }
306
+
203
307
/*// Simple scenario to start first booting node, gossip a message
204
308
// then start second node and verify second node also receives it
205
309
func TestNewGossipStateProvider_GossipingOneMessage(t *testing.T) {
@@ -289,7 +393,7 @@ func TestNewGossipStateProvider_SendingManyMessages(t *testing.T) {
289
393
290
394
for i := 0 ; i < bootstrapSetSize ; i ++ {
291
395
committer := newCommitter (i )
292
- bootstrapSet = append (bootstrapSet , newPeerNode (newGossipConfig (i , 100 ), committer ))
396
+ bootstrapSet = append (bootstrapSet , newPeerNode (newGossipConfig (i ), committer , noopPeerIdentityAcceptor ))
293
397
}
294
398
295
399
defer func () {
@@ -315,7 +419,7 @@ func TestNewGossipStateProvider_SendingManyMessages(t *testing.T) {
315
419
316
420
for i := 0 ; i < standartPeersSize ; i ++ {
317
421
committer := newCommitter (bootstrapSetSize + i )
318
- peersSet = append (peersSet , newPeerNode (newGossipConfig (bootstrapSetSize + i , 100 , 0 , 1 , 2 , 3 , 4 ), committer ))
422
+ peersSet = append (peersSet , newPeerNode (newGossipConfig (bootstrapSetSize + i , 0 , 1 , 2 , 3 , 4 ), committer , noopPeerIdentityAcceptor ))
319
423
}
320
424
321
425
defer func () {
@@ -354,14 +458,18 @@ func TestGossipStateProvider_TestStateMessages(t *testing.T) {
354
458
ledgermgmt .InitializeTestEnv ()
355
459
defer ledgermgmt .CleanupTestEnv ()
356
460
357
- bootPeer := newPeerNode (newGossipConfig (0 , 100 ), newCommitter (0 ))
461
+ bootPeer := newPeerNode (newGossipConfig (0 ), newCommitter (0 ), noopPeerIdentityAcceptor )
358
462
defer bootPeer .shutdown ()
359
463
360
- peer := newPeerNode (newGossipConfig (1 , 100 , 0 ), newCommitter (1 ))
464
+ peer := newPeerNode (newGossipConfig (1 , 0 ), newCommitter (1 ), noopPeerIdentityAcceptor )
361
465
defer peer .shutdown ()
362
466
363
- _ , bootCh := bootPeer .g .Accept (remoteStateMsgFilter , true )
364
- _ , peerCh := peer .g .Accept (remoteStateMsgFilter , true )
467
+ naiveStateMsgPredicate := func (message interface {}) bool {
468
+ return message .(proto.ReceivedMessage ).GetGossipMessage ().IsRemoteStateMessage ()
469
+ }
470
+
471
+ _ , bootCh := bootPeer .g .Accept (naiveStateMsgPredicate , true )
472
+ _ , peerCh := peer .g .Accept (naiveStateMsgPredicate , true )
365
473
366
474
wg := sync.WaitGroup {}
367
475
wg .Add (2 )
0 commit comments