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.

665 lines
23 KiB

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