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.

687 lines
24 KiB

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