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.

660 lines
23 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.NoError(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.NoError(t, err)
  25. defer assert.NoError(t, os.RemoveAll(dir))
  26. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  27. assert.NoError(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.NoError(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.NoError(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. // CreateAccountDepositTransfer for TokenID=1 when receiver does not
  148. // have an account for that TokenID, expect that the
  149. // EffectiveDepositAmount=DepositAmount, but EffectiveAmount==0
  150. tx = common.L1Tx{
  151. FromIdx: 0,
  152. ToIdx: 257,
  153. Amount: big.NewInt(8),
  154. DepositAmount: big.NewInt(8),
  155. FromEthAddr: tc.Users["A"].Addr,
  156. TokenID: 2,
  157. UserOrigin: true,
  158. Type: common.TxTypeCreateAccountDepositTransfer,
  159. }
  160. sdb.computeEffectiveAmounts(&tx)
  161. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  162. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  163. // DepositTransfer for TokenID=1 when receiver does not have an account
  164. // for that TokenID, expect that the
  165. // EffectiveDepositAmount=DepositAmount, but EffectiveAmount=0
  166. tx = common.L1Tx{
  167. FromIdx: 258,
  168. ToIdx: 256,
  169. Amount: big.NewInt(8),
  170. DepositAmount: big.NewInt(8),
  171. FromEthAddr: tc.Users["C"].Addr,
  172. TokenID: 1,
  173. UserOrigin: true,
  174. Type: common.TxTypeDepositTransfer,
  175. }
  176. sdb.computeEffectiveAmounts(&tx)
  177. assert.Equal(t, big.NewInt(8), tx.EffectiveDepositAmount)
  178. assert.Equal(t, big.NewInt(0), tx.EffectiveAmount)
  179. }
  180. func TestProcessTxsBalances(t *testing.T) {
  181. dir, err := ioutil.TempDir("", "tmpdb")
  182. require.NoError(t, err)
  183. defer assert.NoError(t, os.RemoveAll(dir))
  184. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  185. assert.NoError(t, err)
  186. // generate test transactions from test.SetBlockchain0 code
  187. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  188. blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
  189. require.NoError(t, err)
  190. // Coordinator Idx where to send the fees
  191. coordIdxs := []common.Idx{256, 257}
  192. ptc := ProcessTxsConfig{
  193. NLevels: 32,
  194. MaxFeeTx: 64,
  195. MaxTx: 512,
  196. MaxL1Tx: 16,
  197. }
  198. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  199. _, err = sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  200. require.NoError(t, err)
  201. log.Debug("block:0 batch:1")
  202. l1UserTxs := []common.L1Tx{}
  203. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  204. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  205. require.NoError(t, err)
  206. log.Debug("block:0 batch:2")
  207. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
  208. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  209. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  210. require.NoError(t, err)
  211. checkBalance(t, tc, sdb, "A", 0, "500")
  212. log.Debug("block:0 batch:3")
  213. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
  214. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
  215. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
  216. require.NoError(t, err)
  217. checkBalance(t, tc, sdb, "A", 0, "500")
  218. checkBalance(t, tc, sdb, "A", 1, "500")
  219. log.Debug("block:0 batch:4")
  220. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
  221. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
  222. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
  223. require.NoError(t, err)
  224. checkBalance(t, tc, sdb, "A", 0, "500")
  225. checkBalance(t, tc, sdb, "A", 1, "500")
  226. log.Debug("block:0 batch:5")
  227. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
  228. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
  229. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
  230. require.NoError(t, err)
  231. checkBalance(t, tc, sdb, "A", 0, "600")
  232. checkBalance(t, tc, sdb, "A", 1, "500")
  233. checkBalance(t, tc, sdb, "B", 0, "400")
  234. log.Debug("block:0 batch:6")
  235. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
  236. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[6].L2Txs)
  237. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
  238. require.NoError(t, err)
  239. checkBalance(t, tc, sdb, "Coord", 0, "10")
  240. checkBalance(t, tc, sdb, "Coord", 1, "20")
  241. checkBalance(t, tc, sdb, "A", 0, "600")
  242. checkBalance(t, tc, sdb, "A", 1, "280")
  243. checkBalance(t, tc, sdb, "B", 0, "290")
  244. checkBalance(t, tc, sdb, "B", 1, "200")
  245. checkBalance(t, tc, sdb, "C", 0, "100")
  246. checkBalance(t, tc, sdb, "D", 0, "800")
  247. log.Debug("block:0 batch:7")
  248. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
  249. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[7].L2Txs)
  250. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
  251. require.NoError(t, err)
  252. checkBalance(t, tc, sdb, "Coord", 0, "35")
  253. checkBalance(t, tc, sdb, "Coord", 1, "30")
  254. checkBalance(t, tc, sdb, "A", 0, "430")
  255. checkBalance(t, tc, sdb, "A", 1, "280")
  256. checkBalance(t, tc, sdb, "B", 0, "390")
  257. checkBalance(t, tc, sdb, "B", 1, "90")
  258. checkBalance(t, tc, sdb, "C", 0, "45")
  259. checkBalance(t, tc, sdb, "C", 1, "100")
  260. checkBalance(t, tc, sdb, "D", 0, "800")
  261. log.Debug("block:1 batch:0")
  262. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
  263. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  264. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  265. require.NoError(t, err)
  266. checkBalance(t, tc, sdb, "Coord", 0, "75")
  267. checkBalance(t, tc, sdb, "Coord", 1, "30")
  268. checkBalance(t, tc, sdb, "A", 0, "730")
  269. checkBalance(t, tc, sdb, "A", 1, "280")
  270. checkBalance(t, tc, sdb, "B", 0, "380")
  271. checkBalance(t, tc, sdb, "B", 1, "90")
  272. checkBalance(t, tc, sdb, "C", 0, "845")
  273. checkBalance(t, tc, sdb, "C", 1, "100")
  274. checkBalance(t, tc, sdb, "D", 0, "470")
  275. log.Debug("block:1 batch:1")
  276. l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
  277. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  278. _, err = sdb.ProcessTxs(ptc, coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  279. require.NoError(t, err)
  280. // use Set of PoolL2 txs
  281. poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPoolL2MinimumFlow1)
  282. assert.NoError(t, err)
  283. _, err = sdb.ProcessTxs(ptc, coordIdxs, []common.L1Tx{}, []common.L1Tx{}, poolL2Txs)
  284. require.NoError(t, err)
  285. checkBalance(t, tc, sdb, "Coord", 0, "105")
  286. checkBalance(t, tc, sdb, "Coord", 1, "40")
  287. checkBalance(t, tc, sdb, "A", 0, "510")
  288. checkBalance(t, tc, sdb, "A", 1, "170")
  289. checkBalance(t, tc, sdb, "B", 0, "480")
  290. checkBalance(t, tc, sdb, "B", 1, "190")
  291. checkBalance(t, tc, sdb, "C", 0, "845")
  292. checkBalance(t, tc, sdb, "C", 1, "100")
  293. checkBalance(t, tc, sdb, "D", 0, "360")
  294. checkBalance(t, tc, sdb, "F", 0, "100")
  295. }
  296. func TestProcessTxsSynchronizer(t *testing.T) {
  297. dir, err := ioutil.TempDir("", "tmpdb")
  298. require.NoError(t, err)
  299. defer assert.NoError(t, os.RemoveAll(dir))
  300. sdb, err := NewStateDB(dir, TypeSynchronizer, 32)
  301. assert.NoError(t, err)
  302. // generate test transactions from test.SetBlockchain0 code
  303. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  304. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  305. require.NoError(t, err)
  306. assert.Equal(t, 31, len(blocks[0].Rollup.L1UserTxs))
  307. assert.Equal(t, 4, len(blocks[0].Rollup.Batches[0].L1CoordinatorTxs))
  308. assert.Equal(t, 0, len(blocks[0].Rollup.Batches[1].L1CoordinatorTxs))
  309. assert.Equal(t, 22, len(blocks[0].Rollup.Batches[2].L2Txs))
  310. assert.Equal(t, 1, len(blocks[1].Rollup.Batches[0].L1CoordinatorTxs))
  311. assert.Equal(t, 62, len(blocks[1].Rollup.Batches[0].L2Txs))
  312. assert.Equal(t, 1, len(blocks[1].Rollup.Batches[1].L1CoordinatorTxs))
  313. assert.Equal(t, 8, len(blocks[1].Rollup.Batches[1].L2Txs))
  314. // Coordinator Idx where to send the fees
  315. coordIdxs := []common.Idx{256, 257, 258, 259}
  316. // Idx of user 'A'
  317. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  318. ptc := ProcessTxsConfig{
  319. NLevels: 32,
  320. MaxFeeTx: 64,
  321. MaxTx: 512,
  322. MaxL1Tx: 32,
  323. }
  324. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  325. // to create the Coordinator accounts to receive the fees
  326. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  327. ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  328. require.NoError(t, err)
  329. assert.Equal(t, 4, len(ptOut.CreatedAccounts))
  330. assert.Equal(t, 0, len(ptOut.CollectedFees))
  331. log.Debug("block:0 batch:1")
  332. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  333. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs,
  334. blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  335. require.NoError(t, err)
  336. assert.Equal(t, 0, len(ptOut.ExitInfos))
  337. assert.Equal(t, 31, len(ptOut.CreatedAccounts))
  338. assert.Equal(t, 4, len(ptOut.CollectedFees))
  339. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  340. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  341. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  342. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  343. acc, err := sdb.GetAccount(idxA1)
  344. require.NoError(t, err)
  345. assert.Equal(t, "50", acc.Balance.String())
  346. log.Debug("block:0 batch:2")
  347. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  348. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  349. require.NoError(t, err)
  350. assert.Equal(t, 0, len(ptOut.ExitInfos))
  351. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  352. assert.Equal(t, 4, len(ptOut.CollectedFees))
  353. assert.Equal(t, "2", ptOut.CollectedFees[common.TokenID(0)].String())
  354. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  355. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  356. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  357. acc, err = sdb.GetAccount(idxA1)
  358. require.NoError(t, err)
  359. assert.Equal(t, "35", acc.Balance.String())
  360. log.Debug("block:1 batch:0")
  361. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  362. // before processing expect l2Txs[0:2].Nonce==0
  363. assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
  364. assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
  365. assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
  366. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  367. require.NoError(t, err)
  368. // after processing expect l2Txs[0:2].Nonce!=0 and has expected value
  369. assert.Equal(t, common.Nonce(6), l2Txs[0].Nonce)
  370. assert.Equal(t, common.Nonce(7), l2Txs[1].Nonce)
  371. assert.Equal(t, common.Nonce(8), l2Txs[2].Nonce)
  372. assert.Equal(t, 4, len(ptOut.ExitInfos)) // the 'ForceExit(1)' is not computed yet, as the batch is without L1UserTxs
  373. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  374. assert.Equal(t, 4, len(ptOut.CollectedFees))
  375. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  376. assert.Equal(t, "1", ptOut.CollectedFees[common.TokenID(1)].String())
  377. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  378. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  379. acc, err = sdb.GetAccount(idxA1)
  380. require.NoError(t, err)
  381. assert.Equal(t, "57", acc.Balance.String())
  382. log.Debug("block:1 batch:1")
  383. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  384. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs,
  385. blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  386. require.NoError(t, err)
  387. assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
  388. assert.Equal(t, 1, len(ptOut.CreatedAccounts))
  389. assert.Equal(t, 4, len(ptOut.CollectedFees))
  390. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(0)].String())
  391. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(1)].String())
  392. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(2)].String())
  393. assert.Equal(t, "0", ptOut.CollectedFees[common.TokenID(3)].String())
  394. acc, err = sdb.GetAccount(idxA1)
  395. assert.NoError(t, err)
  396. assert.Equal(t, "77", acc.Balance.String())
  397. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  398. acc, err = sdb.GetAccount(idxB0)
  399. require.NoError(t, err)
  400. assert.Equal(t, "51", acc.Balance.String())
  401. // get balance of Coordinator account for TokenID==0
  402. acc, err = sdb.GetAccount(common.Idx(256))
  403. require.NoError(t, err)
  404. assert.Equal(t, "2", acc.Balance.String())
  405. }
  406. func TestProcessTxsBatchBuilder(t *testing.T) {
  407. dir, err := ioutil.TempDir("", "tmpdb")
  408. require.NoError(t, err)
  409. defer assert.NoError(t, os.RemoveAll(dir))
  410. sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
  411. assert.NoError(t, err)
  412. // generate test transactions from test.SetBlockchain0 code
  413. tc := til.NewContext(common.RollupConstMaxL1UserTx)
  414. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  415. require.NoError(t, err)
  416. // Coordinator Idx where to send the fees
  417. coordIdxs := []common.Idx{256, 257, 258, 259}
  418. // Idx of user 'A'
  419. idxA1 := tc.Users["A"].Accounts[common.TokenID(1)].Idx
  420. ptc := ProcessTxsConfig{
  421. NLevels: 32,
  422. MaxFeeTx: 64,
  423. MaxTx: 512,
  424. MaxL1Tx: 32,
  425. }
  426. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  427. // to create the Coordinator accounts to receive the fees
  428. log.Debug("block:0 batch:0, only L1CoordinatorTxs")
  429. ptOut, err := sdb.ProcessTxs(ptc, nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  430. require.NoError(t, err)
  431. // expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
  432. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  433. log.Debug("block:0 batch:1")
  434. l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
  435. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  436. require.NoError(t, err)
  437. assert.Equal(t, 0, len(ptOut.ExitInfos))
  438. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  439. acc, err := sdb.GetAccount(idxA1)
  440. require.NoError(t, err)
  441. assert.Equal(t, "50", acc.Balance.String())
  442. log.Debug("block:0 batch:2")
  443. l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
  444. ptOut, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
  445. require.NoError(t, err)
  446. assert.Equal(t, 0, len(ptOut.ExitInfos))
  447. assert.Equal(t, 0, len(ptOut.CreatedAccounts))
  448. acc, err = sdb.GetAccount(idxA1)
  449. require.NoError(t, err)
  450. assert.Equal(t, "35", acc.Balance.String())
  451. log.Debug("block:1 batch:0")
  452. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
  453. _, err = sdb.ProcessTxs(ptc, coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
  454. require.NoError(t, err)
  455. acc, err = sdb.GetAccount(idxA1)
  456. require.NoError(t, err)
  457. assert.Equal(t, "57", acc.Balance.String())
  458. log.Debug("block:1 batch:1")
  459. l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
  460. _, err = sdb.ProcessTxs(ptc, coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
  461. require.NoError(t, err)
  462. acc, err = sdb.GetAccount(idxA1)
  463. assert.NoError(t, err)
  464. assert.Equal(t, "77", acc.Balance.String())
  465. idxB0 := tc.Users["C"].Accounts[common.TokenID(0)].Idx
  466. acc, err = sdb.GetAccount(idxB0)
  467. require.NoError(t, err)
  468. assert.Equal(t, "51", acc.Balance.String())
  469. // get balance of Coordinator account for TokenID==0
  470. acc, err = sdb.GetAccount(common.Idx(256))
  471. require.NoError(t, err)
  472. assert.Equal(t, common.TokenID(0), acc.TokenID)
  473. assert.Equal(t, "2", acc.Balance.String())
  474. acc, err = sdb.GetAccount(common.Idx(257))
  475. require.NoError(t, err)
  476. assert.Equal(t, common.TokenID(1), acc.TokenID)
  477. assert.Equal(t, "2", acc.Balance.String())
  478. assert.Equal(t, "2720257526434001367979405991743527513807903085728407823609738212616896104498", sdb.mt.Root().BigInt().String())
  479. }
  480. func TestProcessTxsRootTestVectors(t *testing.T) {
  481. dir, err := ioutil.TempDir("", "tmpdb")
  482. require.NoError(t, err)
  483. defer assert.NoError(t, os.RemoveAll(dir))
  484. sdb, err := NewStateDB(dir, TypeBatchBuilder, 32)
  485. assert.NoError(t, err)
  486. // same values than in the js test
  487. bjj0, err := common.BJJFromStringWithChecksum("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7")
  488. assert.NoError(t, err)
  489. l1Txs := []common.L1Tx{
  490. {
  491. FromIdx: 0,
  492. DepositAmount: big.NewInt(16000000),
  493. Amount: big.NewInt(0),
  494. TokenID: 1,
  495. FromBJJ: bjj0,
  496. FromEthAddr: ethCommon.HexToAddress("0x7e5f4552091a69125d5dfcb7b8c2659029395bdf"),
  497. ToIdx: 0,
  498. Type: common.TxTypeCreateAccountDeposit,
  499. UserOrigin: true,
  500. },
  501. }
  502. l2Txs := []common.PoolL2Tx{
  503. {
  504. FromIdx: 256,
  505. ToIdx: 256,
  506. TokenID: 1,
  507. Amount: big.NewInt(1000),
  508. Nonce: 0,
  509. Fee: 126,
  510. Type: common.TxTypeTransfer,
  511. },
  512. }
  513. ptc := ProcessTxsConfig{
  514. NLevels: 32,
  515. MaxFeeTx: 8,
  516. MaxTx: 32,
  517. MaxL1Tx: 16,
  518. }
  519. _, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, l2Txs)
  520. require.NoError(t, err)
  521. assert.Equal(t, "9827704113668630072730115158977131501210702363656902211840117643154933433410", sdb.mt.Root().BigInt().String())
  522. }
  523. func TestCreateAccountDepositMaxValue(t *testing.T) {
  524. dir, err := ioutil.TempDir("", "tmpdb")
  525. require.NoError(t, err)
  526. defer assert.NoError(t, os.RemoveAll(dir))
  527. nLevels := 16
  528. sdb, err := NewStateDB(dir, TypeBatchBuilder, nLevels)
  529. assert.NoError(t, err)
  530. users := generateJsUsers(t)
  531. daMaxHex, err := hex.DecodeString("FFFF")
  532. require.NoError(t, err)
  533. daMaxF16 := common.Float16(binary.BigEndian.Uint16(daMaxHex))
  534. daMaxBI := daMaxF16.BigInt()
  535. assert.Equal(t, "10235000000000000000000000000000000", daMaxBI.String())
  536. daMax1Hex, err := hex.DecodeString("FFFE")
  537. require.NoError(t, err)
  538. daMax1F16 := common.Float16(binary.BigEndian.Uint16(daMax1Hex))
  539. daMax1BI := daMax1F16.BigInt()
  540. assert.Equal(t, "10225000000000000000000000000000000", daMax1BI.String())
  541. l1Txs := []common.L1Tx{
  542. {
  543. FromIdx: 0,
  544. DepositAmount: daMaxBI,
  545. Amount: big.NewInt(0),
  546. TokenID: 1,
  547. FromBJJ: users[0].BJJ.Public().Compress(),
  548. FromEthAddr: users[0].Addr,
  549. ToIdx: 0,
  550. Type: common.TxTypeCreateAccountDeposit,
  551. UserOrigin: true,
  552. },
  553. {
  554. FromIdx: 0,
  555. DepositAmount: daMax1BI,
  556. Amount: big.NewInt(0),
  557. TokenID: 1,
  558. FromBJJ: users[1].BJJ.Public().Compress(),
  559. FromEthAddr: users[1].Addr,
  560. ToIdx: 0,
  561. Type: common.TxTypeCreateAccountDeposit,
  562. UserOrigin: true,
  563. },
  564. }
  565. ptc := ProcessTxsConfig{
  566. NLevels: uint32(nLevels),
  567. MaxTx: 3,
  568. MaxL1Tx: 2,
  569. MaxFeeTx: 2,
  570. }
  571. _, err = sdb.ProcessTxs(ptc, nil, l1Txs, nil, nil)
  572. require.NoError(t, err)
  573. // check balances
  574. acc, err := sdb.GetAccount(common.Idx(256))
  575. require.NoError(t, err)
  576. assert.Equal(t, daMaxBI, acc.Balance)
  577. acc, err = sdb.GetAccount(common.Idx(257))
  578. require.NoError(t, err)
  579. assert.Equal(t, daMax1BI, acc.Balance)
  580. }