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.

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