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.

626 lines
22 KiB

  1. package statedb
  2. import (
  3. "encoding/binary"
  4. "encoding/hex"
  5. "io/ioutil"
  6. "math/big"
  7. "os"
  8. "testing"
  9. ethCommon "github.com/ethereum/go-ethereum/common"
  10. "github.com/hermeznetwork/hermez-node/common"
  11. "github.com/hermeznetwork/hermez-node/log"
  12. "github.com/hermeznetwork/hermez-node/test/til"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. )
  16. func checkBalance(t *testing.T, tc *til.Context, sdb *StateDB, username string, tokenid int, expected string) {
  17. idx := tc.Users[username].Accounts[common.TokenID(tokenid)].Idx
  18. acc, err := sdb.GetAccount(idx)
  19. require.Nil(t, err)
  20. assert.Equal(t, expected, acc.Balance.String())
  21. }
  22. func TestComputeEffectiveAmounts(t *testing.T) {
  23. dir, err := ioutil.TempDir("", "tmpdb")
  24. require.Nil(t, err)
  25. defer assert.Nil(t, os.RemoveAll(dir))
  26. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  27. assert.Nil(t, err)
  28. set := `
  29. Type: Blockchain
  30. AddToken(1)
  31. CreateAccountDeposit(0) A: 10
  32. CreateAccountDeposit(0) B: 10
  33. CreateAccountDeposit(1) C: 10
  34. > batchL1
  35. > batchL1
  36. > block
  37. `
  38. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  39. blocks, err := tc.GenerateBlocks(set)
  40. require.Nil(t, err)
  41. ptc := ProcessTxsConfig{
  42. NLevels: 32,
  43. MaxFeeTx: 64,
  44. MaxTx: 512,
  45. MaxL1Tx: 16,
  46. }
  47. _, err = sdb.ProcessTxs(ptc, nil, blocks[0].Rollup.L1UserTxs, nil, nil)
  48. require.Nil(t, err)
  49. tx := common.L1Tx{
  50. FromIdx: 256,
  51. ToIdx: 257,
  52. Amount: big.NewInt(10),
  53. DepositAmount: big.NewInt(0),
  54. FromEthAddr: tc.Users["A"].Addr,
  55. UserOrigin: true,
  56. }
  57. sdb.computeEffectiveAmounts(&tx)
  58. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  59. assert.Equal(t, big.NewInt(10), tx.EffectiveAmount)
  60. // expect error due not enough funds
  61. tx = common.L1Tx{
  62. FromIdx: 256,
  63. ToIdx: 257,
  64. Amount: big.NewInt(11),
  65. DepositAmount: big.NewInt(0),
  66. FromEthAddr: tc.Users["A"].Addr,
  67. UserOrigin: true,
  68. }
  69. sdb.computeEffectiveAmounts(&tx)
  70. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  71. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  72. // expect no-error as there are enough funds in a
  73. // CreateAccountDepositTransfer transction
  74. tx = common.L1Tx{
  75. FromIdx: 0,
  76. ToIdx: 257,
  77. Amount: big.NewInt(10),
  78. DepositAmount: big.NewInt(10),
  79. UserOrigin: true,
  80. }
  81. sdb.computeEffectiveAmounts(&tx)
  82. assert.Equal(t, big.NewInt(10), tx.EffectiveDepositAmount)
  83. assert.Equal(t, big.NewInt(10), tx.EffectiveAmount)
  84. // expect error due not enough funds in a CreateAccountDepositTransfer
  85. // transction
  86. tx = common.L1Tx{
  87. FromIdx: 0,
  88. ToIdx: 257,
  89. Amount: big.NewInt(11),
  90. DepositAmount: big.NewInt(10),
  91. UserOrigin: true,
  92. }
  93. sdb.computeEffectiveAmounts(&tx)
  94. assert.Equal(t, big.NewInt(10), tx.EffectiveDepositAmount)
  95. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  96. // expect error due not same TokenID
  97. tx = common.L1Tx{
  98. FromIdx: 256,
  99. ToIdx: 258,
  100. Amount: big.NewInt(5),
  101. DepositAmount: big.NewInt(0),
  102. FromEthAddr: tc.Users["A"].Addr,
  103. UserOrigin: true,
  104. }
  105. sdb.computeEffectiveAmounts(&tx)
  106. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  107. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  108. // expect error due not same EthAddr
  109. tx = common.L1Tx{
  110. FromIdx: 256,
  111. ToIdx: 257,
  112. Amount: big.NewInt(8),
  113. DepositAmount: big.NewInt(0),
  114. FromEthAddr: tc.Users["B"].Addr,
  115. UserOrigin: true,
  116. }
  117. sdb.computeEffectiveAmounts(&tx)
  118. assert.Equal(t, big.NewInt(0), tx.EffectiveDepositAmount)
  119. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  120. // expect on TxTypeDepositTransfer EffectiveAmount=0, but
  121. // EffectiveDepositAmount!=0, due not enough funds to make the transfer
  122. tx = common.L1Tx{
  123. FromIdx: 256,
  124. ToIdx: 257,
  125. Amount: big.NewInt(20),
  126. DepositAmount: big.NewInt(8),
  127. FromEthAddr: tc.Users["A"].Addr,
  128. UserOrigin: true,
  129. }
  130. sdb.computeEffectiveAmounts(&tx)
  131. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  132. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  133. // expect on TxTypeDepositTransfer EffectiveAmount=0, but
  134. // EffectiveDepositAmount!=0, due different EthAddr from FromIdx
  135. // address
  136. tx = common.L1Tx{
  137. FromIdx: 256,
  138. ToIdx: 257,
  139. Amount: big.NewInt(8),
  140. DepositAmount: big.NewInt(8),
  141. FromEthAddr: tc.Users["B"].Addr,
  142. UserOrigin: true,
  143. }
  144. sdb.computeEffectiveAmounts(&tx)
  145. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  146. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  147. }
  148. func TestProcessTxsBalances(t *testing.T) {
  149. dir, err := ioutil.TempDir("", "tmpdb")
  150. require.Nil(t, err)
  151. defer assert.Nil(t, os.RemoveAll(dir))
  152. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  153. assert.Nil(t, err)
  154. // generate test transactions from test.SetBlockchain0 code
  155. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  156. blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
  157. require.Nil(t, err)
  158. // Coordinator Idx where to send the fees
  159. coordIdxs := []common.Idx{256, 257}
  160. ptc := ProcessTxsConfig{
  161. NLevels: 32,
  162. MaxFeeTx: 64,
  163. MaxTx: 512,
  164. MaxL1Tx: 16,
  165. }
  166. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  167. _, err = sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  168. require.Nil(t, err)
  169. log.Debug("block:0 batch:1")
  170. l1UserTxs := []common.L1Tx{}
  171. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  172. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  173. require.Nil(t, err)
  174. log.Debug("block:0 batch:2")
  175. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
  176. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  177. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  178. require.Nil(t, err)
  179. checkBalance(t, tc, sdb, "A", 0, "500")
  180. log.Debug("block:0 batch:3")
  181. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
  182. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
  183. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
  184. require.Nil(t, err)
  185. checkBalance(t, tc, sdb, "A", 0, "500")
  186. checkBalance(t, tc, sdb, "A", 1, "500")
  187. log.Debug("block:0 batch:4")
  188. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
  189. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
  190. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
  191. require.Nil(t, err)
  192. checkBalance(t, tc, sdb, "A", 0, "500")
  193. checkBalance(t, tc, sdb, "A", 1, "500")
  194. log.Debug("block:0 batch:5")
  195. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
  196. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
  197. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
  198. require.Nil(t, err)
  199. checkBalance(t, tc, sdb, "A", 0, "600")
  200. checkBalance(t, tc, sdb, "A", 1, "500")
  201. checkBalance(t, tc, sdb, "B", 0, "400")
  202. log.Debug("block:0 batch:6")
  203. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
  204. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[6].L2Txs)
  205. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
  206. require.Nil(t, err)
  207. checkBalance(t, tc, sdb, "Coord", 0, "10")
  208. checkBalance(t, tc, sdb, "Coord", 1, "20")
  209. checkBalance(t, tc, sdb, "A", 0, "600")
  210. checkBalance(t, tc, sdb, "A", 1, "280")
  211. checkBalance(t, tc, sdb, "B", 0, "290")
  212. checkBalance(t, tc, sdb, "B", 1, "200")
  213. checkBalance(t, tc, sdb, "C", 0, "100")
  214. checkBalance(t, tc, sdb, "D", 0, "800")
  215. log.Debug("block:0 batch:7")
  216. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
  217. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[7].L2Txs)
  218. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
  219. require.Nil(t, err)
  220. checkBalance(t, tc, sdb, "Coord", 0, "35")
  221. checkBalance(t, tc, sdb, "Coord", 1, "30")
  222. checkBalance(t, tc, sdb, "A", 0, "430")
  223. checkBalance(t, tc, sdb, "A", 1, "280")
  224. checkBalance(t, tc, sdb, "B", 0, "390")
  225. checkBalance(t, tc, sdb, "B", 1, "90")
  226. checkBalance(t, tc, sdb, "C", 0, "45")
  227. checkBalance(t, tc, sdb, "C", 1, "100")
  228. checkBalance(t, tc, sdb, "D", 0, "800")
  229. log.Debug("block:1 batch:0")
  230. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
  231. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  232. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  233. require.Nil(t, err)
  234. checkBalance(t, tc, sdb, "Coord", 0, "75")
  235. checkBalance(t, tc, sdb, "Coord", 1, "30")
  236. checkBalance(t, tc, sdb, "A", 0, "730")
  237. checkBalance(t, tc, sdb, "A", 1, "280")
  238. checkBalance(t, tc, sdb, "B", 0, "380")
  239. checkBalance(t, tc, sdb, "B", 1, "90")
  240. checkBalance(t, tc, sdb, "C", 0, "845")
  241. checkBalance(t, tc, sdb, "C", 1, "100")
  242. checkBalance(t, tc, sdb, "D", 0, "470")
  243. log.Debug("block:1 batch:1")
  244. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
  245. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  246. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  247. require.Nil(t, err)
  248. // use Set of PoolL2 txs
  249. poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow1)
  250. assert.Nil(t, err)
  251. _, err = sdb.ProcessTxs(ptc, coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
  252. require.Nil(t, err)
  253. checkBalance(t, tc, sdb, "Coord", 0, "105")
  254. checkBalance(t, tc, sdb, "Coord", 1, "40")
  255. checkBalance(t, tc, sdb, "A", 0, "510")
  256. checkBalance(t, tc, sdb, "A", 1, "170")
  257. checkBalance(t, tc, sdb, "B", 0, "480")
  258. checkBalance(t, tc, sdb, "B", 1, "190")
  259. checkBalance(t, tc, sdb, "C", 0, "845")
  260. checkBalance(t, tc, sdb, "C", 1, "100")
  261. checkBalance(t, tc, sdb, "D", 0, "360")
  262. checkBalance(t, tc, sdb, "F", 0, "100")
  263. }
  264. func TestProcessTxsSynchronizer(t *testing.T) {
  265. dir, err := ioutil.TempDir("", "tmpdb")
  266. require.Nil(t, err)
  267. defer assert.Nil(t, os.RemoveAll(dir))
  268. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  269. assert.Nil(t, err)
  270. // generate test transactions from test.SetBlockchain0 code
  271. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  272. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  273. require.Nil(t, err)
  274. assert.Equal(t, 31, len(blocks[0].Rollup.L1UserTxs))
  275. assert.Equal(t, 4, len(blocks[0].Rollup.Batches[0].L1CoordinatorTxs))
  276. assert.Equal(t, 0, len(blocks[0].Rollup.Batches[1].L1CoordinatorTxs))
  277. assert.Equal(t, 22, len(blocks[0].Rollup.Batches[2].L2Txs))
  278. assert.Equal(t, 1, len(blocks[1].Rollup.Batches[0].L1CoordinatorTxs))
  279. assert.Equal(t, 62, len(blocks[1].Rollup.Batches[0].L2Txs))
  280. assert.Equal(t, 1, len(blocks[1].Rollup.Batches[1].L1CoordinatorTxs))
  281. assert.Equal(t, 8, len(blocks[1].Rollup.Batches[1].L2Txs))
  282. // Coordinator Idx where to send the fees
  283. coordIdxs := []common.Idx{256, 257, 258, 259}
  284. // Idx of user 'A'
  285. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  286. ptc := ProcessTxsConfig{
  287. NLevels: 32,
  288. MaxFeeTx: 64,
  289. MaxTx: 512,
  290. MaxL1Tx: 32,
  291. }
  292. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  293. // to create the Coordinator accounts to receive the fees
  294. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  295. ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  296. require.Nil(t, err)
  297. assert.Equal(t, 4, len(ptOut.CreatedAccounts))
  298. assert.Equal(t, 0, len(ptOut.CollectedFees))
  299. log.Debug("block:0 batch:1")
  300. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  301. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs,
  302. blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  303. require.Nil(t, err)
  304. assert.Equal(t, 0, len(ptOut.ExitInfos))
  305. assert.Equal(t, 31, len(ptOut.CreatedAccounts))
  306. assert.Equal(t, 4, len(ptOut.CollectedFees))
  307. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  308. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  309. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  310. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  311. acc, err := sdb.GetAccount(idxA1)
  312. require.Nil(t, err)
  313. assert.Equal(t, "50", acc.Balance.String())
  314. log.Debug("block:0 batch:2")
  315. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  316. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  317. require.Nil(t, err)
  318. assert.Equal(t, 0, len(ptOut.ExitInfos))
  319. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  320. assert.Equal(t, 4, len(ptOut.CollectedFees))
  321. assert.Equal(t, "2", ptOut.CollectedFees[common.TokenID(0)].String())
  322. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  323. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  324. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  325. acc, err = sdb.GetAccount(idxA1)
  326. require.Nil(t, err)
  327. assert.Equal(t, "35", acc.Balance.String())
  328. log.Debug("block:1 batch:0")
  329. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  330. // before processing expect l2Txs[0:2].Nonce==0
  331. assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
  332. assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
  333. assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
  334. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  335. require.Nil(t, err)
  336. // after processing expect l2Txs[0:2].Nonce!=0 and has expected value
  337. assert.Equal(t, common.Nonce(6), l2Txs[0].Nonce)
  338. assert.Equal(t, common.Nonce(7), l2Txs[1].Nonce)
  339. assert.Equal(t, common.Nonce(8), l2Txs[2].Nonce)
  340. assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
  341. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  342. assert.Equal(t, 4, len(ptOut.CollectedFees))
  343. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  344. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  345. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  346. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  347. acc, err = sdb.GetAccount(idxA1)
  348. require.Nil(t, err)
  349. assert.Equal(t, "57", acc.Balance.String())
  350. log.Debug("block:1 batch:1")
  351. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  352. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs,
  353. blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  354. require.Nil(t, err)
  355. assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
  356. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  357. assert.Equal(t, 4, len(ptOut.CollectedFees))
  358. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  359. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  360. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  361. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  362. acc, err = sdb.GetAccount(idxA1)
  363. assert.Nil(t, err)
  364. assert.Equal(t, "77", acc.Balance.String())
  365. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  366. acc, err = sdb.GetAccount(idxB0)
  367. require.Nil(t, err)
  368. assert.Equal(t, "51", acc.Balance.String())
  369. // get balance of Coordinator account for TokenID==0
  370. acc, err = sdb.GetAccount(common.Idx(256))
  371. require.Nil(t, err)
  372. assert.Equal(t, "2", acc.Balance.String())
  373. }
  374. func TestProcessTxsBatchBuilder(t *testing.T) {
  375. dir, err := ioutil.TempDir("", "tmpdb")
  376. require.Nil(t, err)
  377. defer assert.Nil(t, os.RemoveAll(dir))
  378. sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
  379. assert.Nil(t, err)
  380. // generate test transactions from test.SetBlockchain0 code
  381. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  382. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  383. require.Nil(t, err)
  384. // Coordinator Idx where to send the fees
  385. coordIdxs := []common.Idx{256, 257, 258, 259}
  386. // Idx of user 'A'
  387. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  388. ptc := ProcessTxsConfig{
  389. NLevels: 32,
  390. MaxFeeTx: 64,
  391. MaxTx: 512,
  392. MaxL1Tx: 32,
  393. }
  394. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  395. // to create the Coordinator accounts to receive the fees
  396. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  397. ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  398. require.Nil(t, err)
  399. // expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
  400. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  401. log.Debug("block:0 batch:1")
  402. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  403. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  404. require.Nil(t, err)
  405. assert.Equal(t, 0, len(ptOut.ExitInfos))
  406. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  407. acc, err := sdb.GetAccount(idxA1)
  408. require.Nil(t, err)
  409. assert.Equal(t, "50", acc.Balance.String())
  410. log.Debug("block:0 batch:2")
  411. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  412. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  413. require.Nil(t, err)
  414. assert.Equal(t, 0, len(ptOut.ExitInfos))
  415. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  416. acc, err = sdb.GetAccount(idxA1)
  417. require.Nil(t, err)
  418. assert.Equal(t, "35", acc.Balance.String())
  419. log.Debug("block:1 batch:0")
  420. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  421. _, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  422. require.Nil(t, err)
  423. acc, err = sdb.GetAccount(idxA1)
  424. require.Nil(t, err)
  425. assert.Equal(t, "57", acc.Balance.String())
  426. log.Debug("block:1 batch:1")
  427. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  428. _, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  429. require.Nil(t, err)
  430. acc, err = sdb.GetAccount(idxA1)
  431. assert.Nil(t, err)
  432. assert.Equal(t, "77", acc.Balance.String())
  433. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  434. acc, err = sdb.GetAccount(idxB0)
  435. require.Nil(t, err)
  436. assert.Equal(t, "51", acc.Balance.String())
  437. // get balance of Coordinator account for TokenID==0
  438. acc, err = sdb.GetAccount(common.Idx(256))
  439. require.Nil(t, err)
  440. assert.Equal(t, common.TokenID(0), acc.TokenID)
  441. assert.Equal(t, "2", acc.Balance.String())
  442. acc, err = sdb.GetAccount(common.Idx(257))
  443. require.Nil(t, err)
  444. assert.Equal(t, common.TokenID(1), acc.TokenID)
  445. assert.Equal(t, "2", acc.Balance.String())
  446. assert.Equal(t, "2720257526434001367979405991743527513807903085728407823609738212616896104498", sdb.mt.Root().BigInt().String())
  447. }
  448. func TestProcessTxsRootTestVectors(t *testing.T) {
  449. dir, err := ioutil.TempDir("", "tmpdb")
  450. require.Nil(t, err)
  451. defer assert.Nil(t, os.RemoveAll(dir))
  452. sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
  453. assert.Nil(t, err)
  454. // same values than in the js test
  455. bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
  456. assert.Nil(t, err)
  457. l1Txs := []common.L1Tx{
  458. {
  459. FromIdx: 0,
  460. DepositAmount: big.NewInt(16000000),
  461. Amount: big.NewInt(0),
  462. TokenID: 1,
  463. FromBJJ: bjj0,
  464. FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
  465. ToIdx: 0,
  466. Type: common.TxTypeCreateAccountDeposit,
  467. UserOrigin: true,
  468. },
  469. }
  470. l2Txs := []common.PoolL2Tx{
  471. {
  472. FromIdx: 256,
  473. ToIdx: 256,
  474. TokenID: 1,
  475. Amount: big.NewInt(1000),
  476. Nonce: 0,
  477. Fee: 126,
  478. Type: common.TxTypeTransfer,
  479. },
  480. }
  481. ptc := ProcessTxsConfig{
  482. NLevels: 32,
  483. MaxFeeTx: 8,
  484. MaxTx: 32,
  485. MaxL1Tx: 16,
  486. }
  487. _, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
  488. require.Nil(t, err)
  489. assert.Equal(t, "9827704113668630072730115158977131501210702363656902211840117643154933433410", sdb.mt.Root().BigInt().String())
  490. }
  491. func TestCreateAccountDepositMaxValue(t *testing.T) {
  492. dir, err := ioutil.TempDir("", "tmpdb")
  493. require.Nil(t, err)
  494. defer assert.Nil(t, os.RemoveAll(dir))
  495. nLevels := 16
  496. sdb, err := NewStateDB(dir, TypeBatchBuilder, nLevels)
  497. assert.Nil(t, err)
  498. users := generateJsUsers(t)
  499. daMaxHex, err := hex.DecodeString("FFFF")
  500. require.Nil(t, err)
  501. daMaxF16 := common.Float16(binary.BigEndian.Uint16(daMaxHex))
  502. daMaxBI := daMaxF16.BigInt()
  503. assert.Equal(t, "10235000000000000000000000000000000", daMaxBI.String())
  504. daMax1Hex, err := hex.DecodeString("FFFE")
  505. require.Nil(t, err)
  506. daMax1F16 := common.Float16(binary.BigEndian.Uint16(daMax1Hex))
  507. daMax1BI := daMax1F16.BigInt()
  508. assert.Equal(t, "10225000000000000000000000000000000", daMax1BI.String())
  509. l1Txs := []common.L1Tx{
  510. {
  511. FromIdx: 0,
  512. DepositAmount: daMaxBI,
  513. Amount: big.NewInt(0),
  514. TokenID: 1,
  515. FromBJJ: users[0].BJJ.Public(),
  516. FromEthAddr: users[0].Addr,
  517. ToIdx: 0,
  518. Type: common.TxTypeCreateAccountDeposit,
  519. UserOrigin: true,
  520. },
  521. {
  522. FromIdx: 0,
  523. DepositAmount: daMax1BI,
  524. Amount: big.NewInt(0),
  525. TokenID: 1,
  526. FromBJJ: users[1].BJJ.Public(),
  527. FromEthAddr: users[1].Addr,
  528. ToIdx: 0,
  529. Type: common.TxTypeCreateAccountDeposit,
  530. UserOrigin: true,
  531. },
  532. }
  533. ptc := ProcessTxsConfig{
  534. NLevels: uint32(nLevels),
  535. MaxTx: 3,
  536. MaxL1Tx: 2,
  537. MaxFeeTx: 2,
  538. }
  539. _, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, nil)
  540. require.Nil(t, err)
  541. // check balances
  542. acc, err := sdb.GetAccount(common.Idx(256))
  543. require.Nil(t, err)
  544. assert.Equal(t, daMaxBI, acc.Balance)
  545. acc, err = sdb.GetAccount(common.Idx(257))
  546. require.Nil(t, err)
  547. assert.Equal(t, daMax1BI, acc.Balance)
  548. }