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.

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