-
Notifications
You must be signed in to change notification settings - Fork 0
/
bitcoind.go
141 lines (119 loc) · 3.31 KB
/
bitcoind.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
package bitbox
import (
"log"
"os/exec"
"github.com/angrypie/rndport"
"github.com/btcsuite/btcd/rpcclient"
)
type Bitcoind struct {
BitboxDefaults
}
func newBitcoind() *Bitcoind {
return &Bitcoind{}
}
//Start runs specified number of bitcoind nodes in regtest mode.
func (b *Bitcoind) Start(nodes int) (err error) {
return b.CreateNodes(nodes, startBitcoindNode)
}
//Balance returns avaliable balance of specified nodes wallet.
func (b *Bitcoind) Balance(node int) (balance float64, err error) {
return b.BitboxDefaults.AccountBalance(node, "*")
}
//Address generates new adderess of specified nodes wallet.
func (b *Bitcoind) Address(node int) (address string, err error) {
return b.BitboxDefaults.AccountAddress(node, "")
}
//InitMempool makes mempool usable by sending transaction and generating blocks.
func (b *Bitcoind) InitMempool() error {
return initBitboxMempool(b)
}
type bitcoindNode struct {
index int
datadir string
port string
rpcport string
client *rpcclient.Client
zmqaddress string
masterNodePort string
}
func (node *bitcoindNode) Client() *rpcclient.Client {
return node.client
}
func (node *bitcoindNode) Info() *State {
return &State{
NodePort: node.port,
RPCPort: node.rpcport,
ZmqAddress: node.zmqaddress,
}
}
func (node *bitcoindNode) Start() (err error) {
zmqPort, err := rndport.GetAddress()
if err != nil {
return err
}
zmqaddress := "127.0.0.1:" + zmqPort
node.zmqaddress = zmqaddress
opts := append([]string{}, "-regtest", "-daemon",
"-deprecatedrpc=estimatefee,generate",
"-deprecatedrpc=generate",
"-datadir="+node.datadir, "-port="+node.port,
"-rpcport="+node.rpcport, "-rpcuser=test", "-rpcpassword=test",
)
if node.index > 0 {
// First node will have empty masterNodeport but its' will not be executed
opts = append(opts, "-connect=127.0.0.1:"+node.masterNodePort)
} else {
opts = append(opts,
"-zmqpubhashtx=tcp://"+zmqaddress,
"-zmqpubhashblock=tcp://"+zmqaddress,
"-zmqpubrawblock=tcp://"+zmqaddress,
"-zmqpubrawtx=tcp://"+zmqaddress,
"-txindex=1",
)
}
err = exec.Command("bitcoind", opts...).Run()
if err != nil {
return
}
node.client, err = newRpcClient("127.0.0.1:" + node.rpcport)
if err != nil {
log.Println("ERR rpc client not connected to node ", node.index, err)
return
}
return waitUntilNodeStart(node)
}
func (node *bitcoindNode) Stop() (err error) {
node.client.Shutdown()
node.Command("stop")
exec.Command("rm", "-rf", node.datadir).Run()
return
}
func (node *bitcoindNode) Command(cmd ...string) error {
args := append([]string{}, "-rpcport="+node.rpcport, "-rpcuser=test", "-rpcpassword=test")
full := append(args, cmd...)
_, err := exec.Command("bitcoin-cli", full...).Output()
return err
}
func startBitcoindNode(index int, masterNodePort, strIndex string) (node Node, err error) {
datadir := "/tmp/bitbox_bitcoind_" + strIndex
port, _ := rndport.GetAddress()
rpcPort, _ := rndport.GetAddress()
node = &bitcoindNode{
index: index,
datadir: datadir,
port: port,
rpcport: rpcPort,
masterNodePort: masterNodePort,
}
//Create directory for node data
err = exec.Command("mkdir", datadir).Run()
if err != nil {
log.Println("ERR creating datadir", err)
return
}
err = node.Start()
if err != nil {
return
}
return
}