You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
7.8 KiB

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