arnaucube
arnaucube/slowlorisdbPublic Self-hosted repository
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}