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.

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