-
Notifications
You must be signed in to change notification settings - Fork 244
/
devnode.go
149 lines (133 loc) · 3.87 KB
/
devnode.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package devtests
import (
"crypto/ecdsa"
"io/ioutil"
"math/big"
"os"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/params"
statusrpc "github.com/status-im/status-go/rpc"
"github.com/stretchr/testify/suite"
)
// NewDevNode returns node with clieque engine and prefunded accounts.
func NewDevNode(faucet common.Address) (*node.Node, error) {
cfg := node.DefaultConfig
ipc, err := ioutil.TempFile("", "devnode-ipc-")
if err != nil {
return nil, err
}
cfg.IPCPath = ipc.Name()
cfg.HTTPModules = []string{"eth"}
cfg.DataDir = ""
cfg.P2P.MaxPeers = 0
cfg.P2P.ListenAddr = ":0"
cfg.P2P.NoDiscovery = true
cfg.P2P.DiscoveryV5 = false
stack, err := node.New(&cfg)
if err != nil {
return nil, err
}
ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
// ensure that etherbase is added to an account manager
etherbase, err := crypto.GenerateKey()
if err != nil {
return nil, err
}
acc, err := ks.ImportECDSA(etherbase, "")
if err != nil {
return nil, err
}
err = ks.Unlock(acc, "")
if err != nil {
return nil, err
}
ethcfg := eth.DefaultConfig
ethcfg.NetworkId = 1337
// 0 - mine only if transaction pending
ethcfg.Genesis = core.DeveloperGenesisBlock(0, faucet)
extra := make([]byte, 32) // extraVanity
extra = append(extra, acc.Address[:]...)
extra = append(extra, make([]byte, 65)...) // extraSeal
ethcfg.Genesis.ExtraData = extra
ethcfg.MinerGasPrice = big.NewInt(1)
ethcfg.Etherbase = acc.Address
return stack, stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
return eth.New(ctx, ðcfg)
})
}
// StartWithMiner starts node with eth service and a miner.
func StartWithMiner(stack *node.Node) error {
err := stack.Start()
if err != nil {
return err
}
var ethereum *eth.Ethereum
err = stack.Service(ðereum)
if err != nil {
return err
}
ethereum.TxPool().SetGasPrice(big.NewInt(1))
return ethereum.StartMining(0)
}
// DevNodeSuite provides convenient wrapper for starting node with clique backend for mining.
type DevNodeSuite struct {
suite.Suite
Remote *rpc.Client
Eth *ethclient.Client
Local *statusrpc.Client
DevAccount *ecdsa.PrivateKey
DevAccountAddress common.Address
dir string
backend *api.StatusBackend
miner *node.Node
}
// SetupTest creates clique node and status node with an rpc connection to a clique node.
func (s *DevNodeSuite) SetupTest() {
account, err := crypto.GenerateKey()
s.Require().NoError(err)
s.DevAccount = account
s.DevAccountAddress = crypto.PubkeyToAddress(account.PublicKey)
s.miner, err = NewDevNode(s.DevAccountAddress)
s.Require().NoError(err)
s.Require().NoError(StartWithMiner(s.miner))
s.dir, err = ioutil.TempDir("", "devtests-")
s.Require().NoError(err)
config, err := params.NewNodeConfig(
s.dir,
1337,
)
s.Require().NoError(err)
config.WhisperConfig.Enabled = false
config.LightEthConfig.Enabled = false
config.UpstreamConfig.Enabled = true
config.UpstreamConfig.URL = s.miner.IPCEndpoint()
s.backend = api.NewStatusBackend()
s.Require().NoError(s.backend.StartNode(config))
s.Remote, err = s.miner.Attach()
s.Require().NoError(err)
s.Eth = ethclient.NewClient(s.Remote)
s.Local = s.backend.StatusNode().RPCClient()
}
// TearDownTest stops status node and clique node.
func (s *DevNodeSuite) TearDownTest() {
if s.miner != nil {
s.Require().NoError(s.miner.Stop())
s.miner = nil
}
if s.backend != nil {
s.Require().NoError(s.backend.StopNode())
s.backend = nil
}
if len(s.dir) != 0 {
os.RemoveAll(s.dir)
s.dir = ""
}
}