slowlorisdb/node/node_test.go
node/node_test.goRaw
1package node
2
3import (
4 "crypto/ecdsa"
5 "encoding/hex"
6 "fmt"
7 "io/ioutil"
8 "testing"
9
10 "github.com/arnaucube/slowlorisdb/core"
11 "github.com/arnaucube/slowlorisdb/db"
12 "github.com/stretchr/testify/assert"
13)
14
15func newTestPoABlockchain() (*ecdsa.PrivateKey, *core.Blockchain, error) {
16 dir, err := ioutil.TempDir("", "db")
17 if err != nil {
18 return nil, nil, err
19 }
20 db, err := db.New(dir)
21 if err != nil {
22 return nil, nil, err
23 }
24
25 privK, err := core.NewKey()
26 if err != nil {
27 return nil, nil, err
28 }
29
30 var authNodes []*ecdsa.PublicKey
31 authNodes = append(authNodes, &privK.PublicKey)
32
33 bc := core.NewPoABlockchain(db, authNodes)
34 return privK, bc, nil
35}
36
37func TestNode(t *testing.T) {
38 dir, err := ioutil.TempDir("", "db")
39 assert.Nil(t, err)
40 db, err := db.New(dir)
41 assert.Nil(t, err)
42
43 privK, err := core.NewKey()
44 assert.Nil(t, err)
45
46 dif := uint64(1)
47 bc := core.NewBlockchain(db, dif)
48 node, err := NewNode(privK, bc, true)
49 assert.Nil(t, err)
50
51 assert.Equal(t, node.Addr, core.AddressFromPrivK(node.PrivK))
52}
53
54func TestNodeSignature(t *testing.T) {
55 dir, err := ioutil.TempDir("", "db")
56 assert.Nil(t, err)
57 db, err := db.New(dir)
58 assert.Nil(t, err)
59
60 privK, err := core.NewKey()
61 assert.Nil(t, err)
62
63 dif := uint64(1)
64 bc := core.NewBlockchain(db, dif)
65 node, err := NewNode(privK, bc, true)
66 assert.Nil(t, err)
67
68 m := []byte("test")
69 sig, err := node.Sign(m)
70 assert.Nil(t, err)
71 pubK := node.PrivK.PublicKey
72 assert.True(t, core.VerifySignature(&pubK, m, *sig))
73}
74
75func TestBlockFromPendingTxs(t *testing.T) {
76 privK, bc, err := newTestPoABlockchain()
77 assert.Nil(t, err)
78
79 node, err := NewNode(privK, bc, true)
80 assert.Nil(t, err)
81
82 privK0, err := core.NewKey()
83 assert.Nil(t, err)
84 pubK0 := privK0.PublicKey
85 privK1, err := core.NewKey()
86 assert.Nil(t, err)
87 pubK1 := privK1.PublicKey
88 tx := core.NewTx(&pubK0, &pubK1, []core.Input{}, []core.Output{})
89 node.AddToPendingTxs(*tx)
90 block, err := node.BlockFromPendingTxs()
91 assert.Nil(t, err)
92 assert.True(t, core.CheckBlockPoW(block, node.Bc.Difficulty))
93 assert.True(t, node.Bc.VerifyBlock(block))
94}
95
96func TestBlockFromPendingTxsIteration(t *testing.T) {
97 privK, bc, err := newTestPoABlockchain()
98 assert.Nil(t, err)
99
100 node, err := NewNode(privK, bc, true)
101 assert.Nil(t, err)
102
103 privK0, err := core.NewKey()
104 assert.Nil(t, err)
105 pubK0 := privK0.PublicKey
106 privK1, err := core.NewKey()
107 assert.Nil(t, err)
108 pubK1 := privK1.PublicKey
109
110 for i := 0; i < 10; i++ {
111 tx := core.NewTx(&pubK0, &pubK1, []core.Input{}, []core.Output{})
112 node.AddToPendingTxs(*tx)
113 }
114 block, err := node.BlockFromPendingTxs()
115 assert.Nil(t, err)
116 assert.True(t, core.CheckBlockPoW(block, node.Bc.Difficulty))
117 assert.True(t, node.Bc.VerifyBlock(block))
118}
119
120func TestFromGenesisToTenBlocks(t *testing.T) {
121 privK, bc, err := newTestPoABlockchain()
122 assert.Nil(t, err)
123
124 node, err := NewNode(privK, bc, true)
125 assert.Nil(t, err)
126
127 // create the genesis block
128 // genesisBlock sends 100 to pubK
129 genesisBlock, err := node.CreateGenesis(&privK.PublicKey, uint64(100))
130 assert.Nil(t, err)
131 assert.NotEqual(t, genesisBlock.Signature, core.Signature{})
132 assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
133 assert.True(t, node.Bc.VerifyBlock(genesisBlock))
134
135 // add the genesis block into the blockchain
136 err = node.Bc.AddBlock(genesisBlock)
137 assert.Nil(t, err)
138 assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
139 assert.Equal(t, genesisBlock.Hash, node.Bc.LastBlock.Hash)
140
141 // add a tx sending coins to the pubK0
142 privK0, err := core.NewKey()
143 assert.Nil(t, err)
144 pubK0 := privK0.PublicKey
145
146 var ins []core.Input
147 in := core.Input{
148 TxId: genesisBlock.Txs[0].TxId,
149 Vout: 0,
150 Value: 100,
151 }
152 ins = append(ins, in)
153 var outs []core.Output
154 out0 := core.Output{
155 Value: 10,
156 }
157 out1 := core.Output{
158 Value: 90,
159 }
160 outs = append(outs, out0)
161 outs = append(outs, out1)
162 tx := core.NewTx(&privK.PublicKey, &pubK0, ins, outs)
163
164 // verify tx
165 txVerified := core.CheckTx(tx)
166 assert.True(t, txVerified)
167
168 // then create a new block with the tx and add it to the blockchain
169 var txs []core.Tx
170 txs = append(txs, *tx)
171 block, err := node.NewBlock(txs)
172 assert.Nil(t, err)
173 err = node.Bc.AddBlock(block)
174 assert.Nil(t, err)
175
176 balance, err := node.Bc.GetBalance(&pubK0)
177 assert.Nil(t, err)
178 fmt.Println(hex.EncodeToString(core.PackPubK(&pubK0)[:10]))
179 fmt.Println("balance in pubK0", balance)
180 assert.Equal(t, balance, uint64(100))
181
182 // add another tx sending coins to the pubK1
183 privK1, err := core.NewKey()
184 assert.Nil(t, err)
185 pubK1 := privK1.PublicKey
186
187 ins = []core.Input{}
188 in = core.Input{
189 TxId: block.Txs[0].TxId,
190 Vout: 0,
191 Value: 10,
192 }
193 ins = append(ins, in)
194 outs = []core.Output{}
195 out0 = core.Output{
196 Value: 10,
197 }
198 outs = append(outs, out0)
199 tx = core.NewTx(&pubK0, &pubK1, ins, outs)
200
201 // verify tx
202 txVerified = core.CheckTx(tx)
203 assert.True(t, txVerified)
204
205 // then create a new block with the tx and add it to the blockchain
206 txs = []core.Tx{}
207 txs = append(txs, *tx)
208 block, err = node.NewBlock(txs)
209 assert.Nil(t, err)
210 err = node.Bc.AddBlock(block)
211 assert.Nil(t, err)
212
213 balance, err = node.Bc.GetBalance(&pubK0)
214 assert.Nil(t, err)
215 fmt.Println(hex.EncodeToString(core.PackPubK(&pubK0)[:10]))
216 fmt.Println("balance in pubK0", balance)
217 assert.Equal(t, balance, uint64(90))
218}
219
220func TestMultipleNodesAddingBlocks(t *testing.T) {
221 dirA, err := ioutil.TempDir("", "dbA")
222 assert.Nil(t, err)
223 dbA, err := db.New(dirA)
224 assert.Nil(t, err)
225 dirB, err := ioutil.TempDir("", "dbB")
226 assert.Nil(t, err)
227 dbB, err := db.New(dirB)
228 assert.Nil(t, err)
229
230 // node A
231 privKA, err := core.NewKey()
232 assert.Nil(t, err)
233
234 // node B
235 privKB, err := core.NewKey()
236 assert.Nil(t, err)
237
238 var authNodes []*ecdsa.PublicKey
239 authNodes = append(authNodes, &privKA.PublicKey)
240 authNodes = append(authNodes, &privKB.PublicKey)
241 bcA := core.NewPoABlockchain(dbA, authNodes)
242 bcB := core.NewPoABlockchain(dbB, authNodes)
243
244 nodeA, err := NewNode(privKA, bcA, true)
245 assert.Nil(t, err)
246 nodeB, err := NewNode(privKB, bcB, true)
247 assert.Nil(t, err)
248
249 // create genesisBlock that sends 100 to pubK of nodeA
250 genesisBlock, err := nodeA.CreateGenesis(&privKA.PublicKey, uint64(100))
251 assert.Nil(t, err)
252 assert.NotEqual(t, genesisBlock.Signature, core.Signature{})
253 assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
254 assert.True(t, nodeA.Bc.VerifyBlock(genesisBlock))
255 // add the genesis block into the blockchain
256 assert.Equal(t, nodeA.Bc.LastBlock.Hash, nodeB.Bc.LastBlock.Hash)
257 err = nodeA.Bc.AddBlock(genesisBlock)
258 assert.Nil(t, err)
259 assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
260 assert.Equal(t, genesisBlock.Hash, nodeA.Bc.LastBlock.Hash)
261 err = nodeB.Bc.AddBlock(genesisBlock)
262 assert.Nil(t, err)
263 assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
264 assert.Equal(t, genesisBlock.Hash, nodeB.Bc.LastBlock.Hash)
265 assert.Equal(t, nodeA.Bc.LastBlock.Hash, nodeB.Bc.LastBlock.Hash)
266
267 // add a tx sending coins to the pubKB (of nodeB)
268 var ins []core.Input
269 in := core.Input{
270 TxId: genesisBlock.Txs[0].TxId,
271 Vout: 0,
272 Value: 100,
273 }
274 ins = append(ins, in)
275 var outs []core.Output
276 out0 := core.Output{
277 Value: 10,
278 }
279 out1 := core.Output{
280 Value: 90,
281 }
282 outs = append(outs, out0)
283 outs = append(outs, out1)
284 tx := core.NewTx(&privKA.PublicKey, &privKB.PublicKey, ins, outs)
285 // verify tx
286 assert.True(t, core.CheckTx(tx))
287 // create a new block with the tx and add it to the blockchain
288 var txs []core.Tx
289 txs = append(txs, *tx)
290 block, err := nodeA.NewBlock(txs)
291 assert.Nil(t, err)
292
293 // nodeA adds the block
294 err = nodeA.Bc.AddBlock(block)
295 assert.Nil(t, err)
296 // nodeB adds the block
297 err = nodeB.Bc.AddBlock(block)
298 assert.Nil(t, err)
299
300 balanceA, err := nodeA.Bc.GetBalance(&privKA.PublicKey)
301 assert.Nil(t, err)
302 balanceB, err := nodeB.Bc.GetBalance(&privKB.PublicKey)
303 assert.Nil(t, err)
304 fmt.Println(hex.EncodeToString(core.PackPubK(&privKA.PublicKey)[:10]))
305 // check that the coins are moved from nodeA to nodeB
306 assert.Equal(t, balanceA, uint64(0))
307 assert.Equal(t, balanceB, uint64(100))
308}