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.

379 lines
15 KiB

  1. package statedb
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "testing"
  8. "github.com/hermeznetwork/hermez-node/common"
  9. "github.com/hermeznetwork/hermez-node/eth"
  10. "github.com/hermeznetwork/hermez-node/log"
  11. "github.com/hermeznetwork/hermez-node/test/til"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. )
  15. func checkBalance(t *testing.T, tc *til.Context, sdb *StateDB, username string, tokenid int, expected string) {
  16. idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
  17. acc, err := sdb.GetAccount(idx)
  18. require.Nil(t, err)
  19. assert.Equal(t, expected, acc.Balance.String())
  20. }
  21. func TestProcessTxsBalances(t *testing.T) {
  22. dir, err := ioutil.TempDir("", "tmpdb")
  23. require.Nil(t, err)
  24. defer assert.Nil(t, os.RemoveAll(dir))
  25. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  26. assert.Nil(t, err)
  27. // generate test transactions from test.SetBlockchain0 code
  28. tc := til.NewContext(eth.RollupConstMaxL1UserTx)
  29. blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
  30. require.Nil(t, err)
  31. // Coordinator Idx where to send the fees
  32. coordIdxs := []common.Idx{256, 257}
  33. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  34. _, err = sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
  35. require.Nil(t, err)
  36. log.Debug("block:0 batch:1")
  37. l1UserTxs := []common.L1Tx{}
  38. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
  39. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
  40. require.Nil(t, err)
  41. log.Debug("block:0 batch:2")
  42. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[2].Batch.ForgeL1TxsNum])
  43. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
  44. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
  45. require.Nil(t, err)
  46. checkBalance(t, tc, sdb, "A", 0, "500")
  47. log.Debug("block:0 batch:3")
  48. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[3].Batch.ForgeL1TxsNum])
  49. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[3].L2Txs)
  50. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[3].L1CoordinatorTxs, l2Txs)
  51. require.Nil(t, err)
  52. checkBalance(t, tc, sdb, "A", 0, "500")
  53. checkBalance(t, tc, sdb, "A", 1, "500")
  54. log.Debug("block:0 batch:4")
  55. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[4].Batch.ForgeL1TxsNum])
  56. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[4].L2Txs)
  57. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[4].L1CoordinatorTxs, l2Txs)
  58. require.Nil(t, err)
  59. checkBalance(t, tc, sdb, "A", 0, "500")
  60. checkBalance(t, tc, sdb, "A", 1, "500")
  61. log.Debug("block:0 batch:5")
  62. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[5].Batch.ForgeL1TxsNum])
  63. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[5].L2Txs)
  64. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[5].L1CoordinatorTxs, l2Txs)
  65. require.Nil(t, err)
  66. checkBalance(t, tc, sdb, "A", 0, "600")
  67. checkBalance(t, tc, sdb, "A", 1, "500")
  68. checkBalance(t, tc, sdb, "B", 0, "400")
  69. log.Debug("block:0 batch:6")
  70. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[6].Batch.ForgeL1TxsNum])
  71. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[6].L2Txs)
  72. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[6].L1CoordinatorTxs, l2Txs)
  73. require.Nil(t, err)
  74. checkBalance(t, tc, sdb, "Coord", 0, "10")
  75. checkBalance(t, tc, sdb, "Coord", 1, "20")
  76. checkBalance(t, tc, sdb, "A", 0, "600")
  77. checkBalance(t, tc, sdb, "A", 1, "280")
  78. checkBalance(t, tc, sdb, "B", 0, "290")
  79. checkBalance(t, tc, sdb, "B", 1, "200")
  80. checkBalance(t, tc, sdb, "C", 0, "100")
  81. checkBalance(t, tc, sdb, "D", 0, "800")
  82. log.Debug("block:0 batch:7")
  83. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[7].Batch.ForgeL1TxsNum])
  84. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[7].L2Txs)
  85. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[7].L1CoordinatorTxs, l2Txs)
  86. require.Nil(t, err)
  87. checkBalance(t, tc, sdb, "Coord", 0, "35")
  88. checkBalance(t, tc, sdb, "Coord", 1, "30")
  89. checkBalance(t, tc, sdb, "A", 0, "430")
  90. checkBalance(t, tc, sdb, "A", 1, "280")
  91. checkBalance(t, tc, sdb, "B", 0, "390")
  92. checkBalance(t, tc, sdb, "B", 1, "90")
  93. checkBalance(t, tc, sdb, "C", 0, "45")
  94. checkBalance(t, tc, sdb, "C", 1, "100")
  95. checkBalance(t, tc, sdb, "D", 0, "800")
  96. log.Debug("block:1 batch:0")
  97. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Batches[0].Batch.ForgeL1TxsNum])
  98. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
  99. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
  100. require.Nil(t, err)
  101. checkBalance(t, tc, sdb, "Coord", 0, "75")
  102. checkBalance(t, tc, sdb, "Coord", 1, "30")
  103. checkBalance(t, tc, sdb, "A", 0, "730")
  104. checkBalance(t, tc, sdb, "A", 1, "280")
  105. checkBalance(t, tc, sdb, "B", 0, "380")
  106. checkBalance(t, tc, sdb, "B", 1, "90")
  107. checkBalance(t, tc, sdb, "C", 0, "845")
  108. checkBalance(t, tc, sdb, "C", 1, "100")
  109. checkBalance(t, tc, sdb, "D", 0, "470")
  110. log.Debug("block:1 batch:1")
  111. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Batches[1].Batch.ForgeL1TxsNum])
  112. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
  113. _, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
  114. require.Nil(t, err)
  115. // use Set of PoolL2 txs
  116. poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow0)
  117. assert.Nil(t, err)
  118. _, err = sdb.ProcessTxs(coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
  119. require.Nil(t, err)
  120. checkBalance(t, tc, sdb, "Coord", 0, "105")
  121. checkBalance(t, tc, sdb, "Coord", 1, "40")
  122. checkBalance(t, tc, sdb, "A", 0, "510")
  123. checkBalance(t, tc, sdb, "A", 1, "170")
  124. checkBalance(t, tc, sdb, "B", 0, "480")
  125. checkBalance(t, tc, sdb, "B", 1, "190")
  126. checkBalance(t, tc, sdb, "C", 0, "845")
  127. checkBalance(t, tc, sdb, "C", 1, "100")
  128. checkBalance(t, tc, sdb, "D", 0, "360")
  129. checkBalance(t, tc, sdb, "F", 0, "100")
  130. }
  131. func TestProcessTxsSynchronizer(t *testing.T) {
  132. dir, err := ioutil.TempDir("", "tmpdb")
  133. require.Nil(t, err)
  134. defer assert.Nil(t, os.RemoveAll(dir))
  135. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  136. assert.Nil(t, err)
  137. // generate test transactions from test.SetBlockchain0 code
  138. tc := til.NewContext(eth.RollupConstMaxL1UserTx)
  139. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  140. require.Nil(t, err)
  141. assert.Equal(t, 31, len(blocks[0].L1UserTxs))
  142. assert.Equal(t, 4, len(blocks[0].Batches[0].L1CoordinatorTxs))
  143. assert.Equal(t, 0, len(blocks[0].Batches[1].L1CoordinatorTxs))
  144. assert.Equal(t, 22, len(blocks[0].Batches[2].L2Txs))
  145. assert.Equal(t, 1, len(blocks[1].Batches[0].L1CoordinatorTxs))
  146. assert.Equal(t, 62, len(blocks[1].Batches[0].L2Txs))
  147. assert.Equal(t, 1, len(blocks[1].Batches[1].L1CoordinatorTxs))
  148. assert.Equal(t, 8, len(blocks[1].Batches[1].L2Txs))
  149. // Coordinator Idx where to send the fees
  150. coordIdxs := []common.Idx{256, 257, 258, 259}
  151. // Idx of user 'A'
  152. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  153. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  154. // to create the Coordinator accounts to receive the fees
  155. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  156. ptOut, err := sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
  157. require.Nil(t, err)
  158. assert.Equal(t, 4, len(ptOut.CreatedAccounts))
  159. assert.Equal(t, 0, len(ptOut.CollectedFees))
  160. log.Debug("block:0 batch:1")
  161. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
  162. ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[0].L1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
  163. require.Nil(t, err)
  164. assert.Equal(t, 0, len(ptOut.ExitInfos))
  165. assert.Equal(t, 31, len(ptOut.CreatedAccounts))
  166. assert.Equal(t, 4, len(ptOut.CollectedFees))
  167. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  168. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  169. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  170. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  171. acc, err := sdb.GetAccount(idxA1)
  172. require.Nil(t, err)
  173. assert.Equal(t, "50", acc.Balance.String())
  174. log.Debug("block:0 batch:2")
  175. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
  176. ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
  177. require.Nil(t, err)
  178. assert.Equal(t, 0, len(ptOut.ExitInfos))
  179. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  180. assert.Equal(t, 4, len(ptOut.CollectedFees))
  181. assert.Equal(t, "2", ptOut.CollectedFees[common.TokenID(0)].String())
  182. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  183. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  184. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  185. acc, err = sdb.GetAccount(idxA1)
  186. require.Nil(t, err)
  187. assert.Equal(t, "35", acc.Balance.String())
  188. log.Debug("block:1 batch:0")
  189. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
  190. // before processing expect l2Txs[0:2].Nonce==0
  191. assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
  192. assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
  193. assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
  194. ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
  195. require.Nil(t, err)
  196. // after processing expect l2Txs[0:2].Nonce!=0 and has expected value
  197. assert.Equal(t, common.Nonce(6), l2Txs[0].Nonce)
  198. assert.Equal(t, common.Nonce(7), l2Txs[1].Nonce)
  199. assert.Equal(t, common.Nonce(8), l2Txs[2].Nonce)
  200. assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
  201. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  202. assert.Equal(t, 4, len(ptOut.CollectedFees))
  203. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  204. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  205. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  206. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  207. acc, err = sdb.GetAccount(idxA1)
  208. require.Nil(t, err)
  209. assert.Equal(t, "57", acc.Balance.String())
  210. log.Debug("block:1 batch:1")
  211. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
  212. ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[1].L1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
  213. require.Nil(t, err)
  214. assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
  215. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  216. assert.Equal(t, 4, len(ptOut.CollectedFees))
  217. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  218. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  219. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  220. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  221. acc, err = sdb.GetAccount(idxA1)
  222. assert.Nil(t, err)
  223. assert.Equal(t, "77", acc.Balance.String())
  224. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  225. acc, err = sdb.GetAccount(idxB0)
  226. require.Nil(t, err)
  227. assert.Equal(t, "51", acc.Balance.String())
  228. // get balance of Coordinator account for TokenID==0
  229. acc, err = sdb.GetAccount(common.Idx(256))
  230. require.Nil(t, err)
  231. assert.Equal(t, "2", acc.Balance.String())
  232. }
  233. func TestProcessTxsBatchBuilder(t *testing.T) {
  234. dir, err := ioutil.TempDir("", "tmpdb")
  235. require.Nil(t, err)
  236. defer assert.Nil(t, os.RemoveAll(dir))
  237. sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
  238. assert.Nil(t, err)
  239. // generate test transactions from test.SetBlockchain0 code
  240. tc := til.NewContext(eth.RollupConstMaxL1UserTx)
  241. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  242. require.Nil(t, err)
  243. // Coordinator Idx where to send the fees
  244. coordIdxs := []common.Idx{256, 257, 258, 259}
  245. // Idx of user 'A'
  246. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  247. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  248. // to create the Coordinator accounts to receive the fees
  249. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  250. ptOut, err := sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
  251. require.Nil(t, err)
  252. // expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
  253. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  254. log.Debug("block:0 batch:1")
  255. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
  256. ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[0].L1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
  257. require.Nil(t, err)
  258. assert.Equal(t, 0, len(ptOut.ExitInfos))
  259. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  260. acc, err := sdb.GetAccount(idxA1)
  261. require.Nil(t, err)
  262. assert.Equal(t, "50", acc.Balance.String())
  263. log.Debug("block:0 batch:2")
  264. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
  265. ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
  266. require.Nil(t, err)
  267. assert.Equal(t, 0, len(ptOut.ExitInfos))
  268. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  269. acc, err = sdb.GetAccount(idxA1)
  270. require.Nil(t, err)
  271. assert.Equal(t, "35", acc.Balance.String())
  272. log.Debug("block:1 batch:0")
  273. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
  274. _, err = sdb.ProcessTxs(coordIdxs, nil, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
  275. require.Nil(t, err)
  276. acc, err = sdb.GetAccount(idxA1)
  277. require.Nil(t, err)
  278. assert.Equal(t, "57", acc.Balance.String())
  279. log.Debug("block:1 batch:1")
  280. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
  281. _, err = sdb.ProcessTxs(coordIdxs, blocks[1].L1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
  282. require.Nil(t, err)
  283. acc, err = sdb.GetAccount(idxA1)
  284. assert.Nil(t, err)
  285. assert.Equal(t, "77", acc.Balance.String())
  286. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  287. acc, err = sdb.GetAccount(idxB0)
  288. require.Nil(t, err)
  289. assert.Equal(t, "51", acc.Balance.String())
  290. // get balance of Coordinator account for TokenID==0
  291. acc, err = sdb.GetAccount(common.Idx(256))
  292. require.Nil(t, err)
  293. assert.Equal(t, common.TokenID(0), acc.TokenID)
  294. assert.Equal(t, "2", acc.Balance.String())
  295. acc, err = sdb.GetAccount(common.Idx(257))
  296. require.Nil(t, err)
  297. assert.Equal(t, common.TokenID(1), acc.TokenID)
  298. assert.Equal(t, "2", acc.Balance.String())
  299. }
  300. func TestZKInputsGeneration(t *testing.T) {
  301. dir, err := ioutil.TempDir("", "tmpdb")
  302. require.Nil(t, err)
  303. defer assert.Nil(t, os.RemoveAll(dir))
  304. sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
  305. assert.Nil(t, err)
  306. // generate test transactions from test.SetBlockchain0 code
  307. tc := til.NewContext(eth.RollupConstMaxL1UserTx)
  308. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  309. require.Nil(t, err)
  310. // Coordinator Idx where to send the fees
  311. coordIdxs := []common.Idx{256, 257, 258, 259}
  312. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  313. _, err = sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
  314. require.Nil(t, err)
  315. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
  316. ptOut, err := sdb.ProcessTxs(coordIdxs, blocks[0].L1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
  317. require.Nil(t, err)
  318. s, err := json.Marshal(ptOut.ZKInputs)
  319. require.Nil(t, err)
  320. debug := false
  321. if debug {
  322. fmt.Println(string(s))
  323. }
  324. }