@@ -18,13 +18,22 @@ package swap
18
18
19
19
import (
20
20
"context"
21
+ "fmt"
22
+ "io/ioutil"
23
+ "os"
24
+ "path/filepath"
25
+ "reflect"
26
+ "runtime"
21
27
"testing"
22
28
"time"
23
29
24
30
"github.com/ethereum/go-ethereum/common"
25
31
"github.com/ethereum/go-ethereum/log"
32
+ "github.com/ethereum/go-ethereum/node"
26
33
"github.com/ethereum/go-ethereum/p2p"
27
34
"github.com/ethereum/go-ethereum/p2p/enode"
35
+ "github.com/ethereum/go-ethereum/rpc"
36
+ contract "github.com/ethersphere/swarm/contracts/swap"
28
37
"github.com/ethersphere/swarm/p2p/protocols"
29
38
p2ptest "github.com/ethersphere/swarm/p2p/testing"
30
39
)
@@ -296,3 +305,166 @@ func TestTriggerDisconnectThreshold(t *testing.T) {
296
305
t .Fatalf ("Expected still no cheque, but there are %d" , lenCheques )
297
306
}
298
307
}
308
+
309
+ // TestSwapRPC tests some basic things over RPC
310
+ // We want this so that we can check the API works
311
+ func TestSwapRPC (t * testing.T ) {
312
+
313
+ if runtime .GOOS == "windows" {
314
+ t .Skip ()
315
+ }
316
+
317
+ var (
318
+ ipcPath = ".swap.ipc"
319
+ err error
320
+ )
321
+
322
+ swap , clean := newTestSwap (t , ownerKey )
323
+ defer clean ()
324
+
325
+ // need to have a dummy contract or the call will fail at `GetParams` due to `NewAPI`
326
+ swap .contract , err = contract .InstanceAt (common.Address {}, swap .backend )
327
+ if err != nil {
328
+ t .Fatal (err )
329
+ }
330
+
331
+ // start a service stack
332
+ stack := createAndStartSvcNode (swap , ipcPath , t )
333
+ defer func () {
334
+ go stack .Stop ()
335
+ }()
336
+
337
+ // use unique IPC path on windows
338
+ ipcPath = filepath .Join (stack .DataDir (), ipcPath )
339
+
340
+ // connect to the servicenode RPCs
341
+ rpcclient , err := rpc .Dial (ipcPath )
342
+ if err != nil {
343
+ t .Fatal (err )
344
+ }
345
+ defer os .RemoveAll (stack .DataDir ())
346
+
347
+ // create dummy peers so that we can artificially set balances and query
348
+ dummyPeer1 := newDummyPeer ()
349
+ dummyPeer2 := newDummyPeer ()
350
+ id1 := dummyPeer1 .ID ()
351
+ id2 := dummyPeer2 .ID ()
352
+
353
+ // set some fake balances
354
+ fakeBalance1 := int64 (234 )
355
+ fakeBalance2 := int64 (- 100 )
356
+
357
+ // query a first time, should give error
358
+ var balance int64
359
+ err = rpcclient .Call (& balance , "swap_balance" , id1 )
360
+ // at this point no balance should be there: no peer at address in map...
361
+ if err == nil {
362
+ t .Fatal ("Expected error but no error received" )
363
+ }
364
+ log .Debug ("servicenode balance" , "balance" , balance )
365
+
366
+ // ...thus balance should be zero
367
+ if balance != 0 {
368
+ t .Fatalf ("Expected balance to be 0 but it is %d" , balance )
369
+ }
370
+
371
+ // now artificially assign some balances
372
+ swap .balances [id1 ] = fakeBalance1
373
+ swap .balances [id2 ] = fakeBalance2
374
+
375
+ // query them, values should coincide
376
+ err = rpcclient .Call (& balance , "swap_balance" , id1 )
377
+ if err != nil {
378
+ t .Fatal (err )
379
+ }
380
+ log .Debug ("balance1" , "balance1" , balance )
381
+ if balance != fakeBalance1 {
382
+ t .Fatalf ("Expected balance %d to be equal to fake balance %d, but it is not" , balance , fakeBalance1 )
383
+ }
384
+
385
+ err = rpcclient .Call (& balance , "swap_balance" , id2 )
386
+ if err != nil {
387
+ t .Fatal (err )
388
+ }
389
+ log .Debug ("balance2" , "balance2" , balance )
390
+ if balance != fakeBalance2 {
391
+ t .Fatalf ("Expected balance %d to be equal to fake balance %d, but it is not" , balance , fakeBalance2 )
392
+ }
393
+
394
+ // now call all balances
395
+ allBalances := make (map [enode.ID ]int64 )
396
+ err = rpcclient .Call (& allBalances , "swap_balances" )
397
+ if err != nil {
398
+ t .Fatal (err )
399
+ }
400
+ log .Debug ("received balances" , "allBalances" , allBalances )
401
+
402
+ var sum int64
403
+ for _ , v := range allBalances {
404
+ sum += v
405
+ }
406
+
407
+ fakeSum := fakeBalance1 + fakeBalance2
408
+ if sum != fakeSum {
409
+ t .Fatalf ("Expected total balance to be %d, but it %d" , fakeSum , sum )
410
+ }
411
+
412
+ if ! reflect .DeepEqual (allBalances , swap .balances ) {
413
+ t .Fatal ("Balances are not deep equal" )
414
+ }
415
+ }
416
+
417
+ // createAndStartSvcNode setup a p2p service and start it
418
+ func createAndStartSvcNode (swap * Swap , ipcPath string , t * testing.T ) * node.Node {
419
+ stack , err := newServiceNode (ipcPath , 0 , 0 )
420
+ if err != nil {
421
+ t .Fatal ("Create servicenode #1 fail" , "err" , err )
422
+ }
423
+
424
+ swapsvc := func (ctx * node.ServiceContext ) (node.Service , error ) {
425
+ return swap , nil
426
+ }
427
+
428
+ err = stack .Register (swapsvc )
429
+ if err != nil {
430
+ t .Fatal ("Register service in servicenode #1 fail" , "err" , err )
431
+ }
432
+
433
+ // start the nodes
434
+ err = stack .Start ()
435
+ if err != nil {
436
+ t .Fatal ("servicenode #1 start failed" , "err" , err )
437
+ }
438
+
439
+ return stack
440
+ }
441
+
442
+ // newServiceNode creates a p2p.Service node stub
443
+ func newServiceNode (ipcPath string , httpport int , wsport int , modules ... string ) (* node.Node , error ) {
444
+ var err error
445
+ cfg := & node .DefaultConfig
446
+ cfg .P2P .EnableMsgEvents = true
447
+ cfg .P2P .NoDiscovery = true
448
+ cfg .IPCPath = ipcPath
449
+ cfg .DataDir , err = ioutil .TempDir ("" , "test-Service-node" )
450
+ if err != nil {
451
+ return nil , err
452
+ }
453
+ if httpport > 0 {
454
+ cfg .HTTPHost = node .DefaultHTTPHost
455
+ cfg .HTTPPort = httpport
456
+ }
457
+ if wsport > 0 {
458
+ cfg .WSHost = node .DefaultWSHost
459
+ cfg .WSPort = wsport
460
+ cfg .WSOrigins = []string {"*" }
461
+ for i := 0 ; i < len (modules ); i ++ {
462
+ cfg .WSModules = append (cfg .WSModules , modules [i ])
463
+ }
464
+ }
465
+ stack , err := node .New (cfg )
466
+ if err != nil {
467
+ return nil , fmt .Errorf ("ServiceNode create fail: %v" , err )
468
+ }
469
+ return stack , nil
470
+ }
0 commit comments