-
Notifications
You must be signed in to change notification settings - Fork 212
/
test_network.go
127 lines (109 loc) · 3.65 KB
/
test_network.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package node
import (
"context"
"errors"
"path/filepath"
"strconv"
"testing"
"time"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/config"
"github.com/spacemeshos/go-spacemesh/log"
)
// NewTestNetwork creates a network of fully connected nodes.
func NewTestNetwork(t *testing.T, conf config.Config, l log.Log, size int) []*TestApp {
// We need to set this global state
types.SetLayersPerEpoch(conf.LayersPerEpoch)
types.SetNetworkHRP(conf.NetworkHRP) // set to generate coinbase
// To save an epoch of startup time, we bootstrap (meaning we manually set
// it) the beacon for epoch 2 so that in epoch 3 hare can start.
bootstrapEpoch := (types.GetEffectiveGenesis() + 1).GetEpoch()
bootstrapBeacon := types.Beacon{}
genesis := conf.Genesis.GenesisID()
copy(bootstrapBeacon[:], genesis[:])
// This context is used to call Start on a node and canceling it will
// shutdown the node. (Hence no timeout has been set).
ctx, cancel := context.WithCancel(context.Background())
g, grpContext := errgroup.WithContext(ctx)
var apps []*TestApp
for i := 0; i < size; i++ {
// Copy config, services don't modify their config, so we just need to
// be careful here when we modify any pointer values in the config.
c := conf
dir := t.TempDir()
c.DataDirParent = dir
c.SMESHING.Opts.DataDir = dir
c.SMESHING.CoinbaseAccount = types.GenerateAddress([]byte(strconv.Itoa(i))).String()
c.FileLock = filepath.Join(c.DataDirParent, "LOCK")
app := NewApp(t, &c, l)
instanceIndex := i
g.Go(func() error {
err := app.Start(grpContext)
if err != nil && !errors.Is(err, context.Canceled) {
t.Logf("failed to start instance %d: %v", instanceIndex, err)
}
return err
})
<-app.Started()
err := app.beaconProtocol.UpdateBeacon(bootstrapEpoch, bootstrapBeacon)
require.NoError(t, err, "failed to bootstrap beacon for node %q", i)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
conn, err := grpc.DialContext(ctx, app.grpcPublicServer.BoundAddress,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithBlock(),
)
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, conn.Close()) })
apps = append(apps, &TestApp{app, conn})
}
// Note that we must call cleanup after all calls to t.TempDir since calls
// to cleanup are executed in LIFO fashion (similar to defer) and t.TempDir
// internally calls Cleanup to delete the dir. By calling Cleanup here
// we ensure that the apps have been shut-down before attempting to delete
// the temp dirs.
t.Cleanup(func() {
cancel()
// Wait for nodes to shutdown
g.Wait()
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
for _, a := range apps {
a.Cleanup(ctx)
a.eg.Wait()
}
})
// Connect all nodes to each other
for i := 0; i < size; i++ {
for j := i + 1; j < size; j++ {
err := apps[i].Host().Connect(context.Background(), peer.AddrInfo{
ID: apps[j].Host().ID(),
Addrs: apps[j].Host().Addrs(),
})
require.NoError(t, err)
}
}
return apps
}
func NewApp(t *testing.T, conf *config.Config, l log.Log) *App {
app := New(
WithConfig(conf),
WithLog(l),
)
err := app.Initialize()
require.NoError(t, err)
/* Create or load miner identity */
app.edSgn, err = app.LoadOrCreateEdSigner()
require.NoError(t, err, "could not retrieve identity")
return app
}
type TestApp struct {
*App
Conn *grpc.ClientConn
}