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.

700 lines
20 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package l2db
  2. import (
  3. "math"
  4. "math/big"
  5. "os"
  6. "testing"
  7. "time"
  8. ethCommon "github.com/ethereum/go-ethereum/common"
  9. "github.com/hermeznetwork/hermez-node/common"
  10. dbUtils "github.com/hermeznetwork/hermez-node/db"
  11. "github.com/hermeznetwork/hermez-node/db/historydb"
  12. "github.com/hermeznetwork/hermez-node/log"
  13. "github.com/hermeznetwork/hermez-node/test"
  14. "github.com/hermeznetwork/hermez-node/test/til"
  15. "github.com/hermeznetwork/tracerr"
  16. "github.com/iden3/go-iden3-crypto/babyjub"
  17. "github.com/stretchr/testify/assert"
  18. "github.com/stretchr/testify/require"
  19. )
  20. var l2DB *L2DB
  21. var historyDB *historydb.HistoryDB
  22. var tc *til.Context
  23. var tokens map[common.TokenID]historydb.TokenWithUSD
  24. var tokensValue map[common.TokenID]float64
  25. var accs map[common.Idx]common.Account
  26. func TestMain(m *testing.M) {
  27. // init DB
  28. pass := os.Getenv("POSTGRES_PASS")
  29. db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  30. if err != nil {
  31. panic(err)
  32. }
  33. l2DB = NewL2DB(db, 10, 1000, 24*time.Hour)
  34. test.WipeDB(l2DB.DB())
  35. historyDB = historydb.NewHistoryDB(db)
  36. // Run tests
  37. result := m.Run()
  38. // Close DB
  39. if err := db.Close(); err != nil {
  40. log.Error("Error closing the history DB:", err)
  41. }
  42. os.Exit(result)
  43. }
  44. func prepareHistoryDB(historyDB *historydb.HistoryDB) error {
  45. // Reset DB
  46. test.WipeDB(l2DB.DB())
  47. // Generate pool txs using til
  48. setBlockchain := `
  49. Type: Blockchain
  50. AddToken(1)
  51. AddToken(2)
  52. CreateAccountDeposit(1) A: 2000
  53. CreateAccountDeposit(2) A: 2000
  54. CreateAccountDeposit(1) B: 1000
  55. CreateAccountDeposit(2) B: 1000
  56. > batchL1
  57. > batchL1
  58. > block
  59. > block
  60. `
  61. tc = til.NewContext(uint16(0), common.RollupConstMaxL1UserTx)
  62. tilCfgExtra := til.ConfigExtra{
  63. BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
  64. CoordUser: "A",
  65. }
  66. blocks, err := tc.GenerateBlocks(setBlockchain)
  67. if err != nil {
  68. return tracerr.Wrap(err)
  69. }
  70. err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
  71. if err != nil {
  72. return tracerr.Wrap(err)
  73. }
  74. tokens = make(map[common.TokenID]historydb.TokenWithUSD)
  75. tokensValue = make(map[common.TokenID]float64)
  76. accs = make(map[common.Idx]common.Account)
  77. value := 5 * 5.389329
  78. now := time.Now().UTC()
  79. // Add all blocks except for the last one
  80. for i := range blocks[:len(blocks)-1] {
  81. err = historyDB.AddBlockSCData(&blocks[i])
  82. if err != nil {
  83. return tracerr.Wrap(err)
  84. }
  85. for _, batch := range blocks[i].Rollup.Batches {
  86. for _, account := range batch.CreatedAccounts {
  87. accs[account.Idx] = account
  88. }
  89. }
  90. for _, token := range blocks[i].Rollup.AddedTokens {
  91. readToken := historydb.TokenWithUSD{
  92. TokenID: token.TokenID,
  93. EthBlockNum: token.EthBlockNum,
  94. EthAddr: token.EthAddr,
  95. Name: token.Name,
  96. Symbol: token.Symbol,
  97. Decimals: token.Decimals,
  98. }
  99. tokensValue[token.TokenID] = value / math.Pow(10, float64(token.Decimals))
  100. readToken.USDUpdate = &now
  101. readToken.USD = &value
  102. tokens[token.TokenID] = readToken
  103. }
  104. // Set value to the tokens (tokens have no symbol)
  105. tokenSymbol := ""
  106. err := historyDB.UpdateTokenValue(tokenSymbol, value)
  107. if err != nil {
  108. return tracerr.Wrap(err)
  109. }
  110. }
  111. return nil
  112. }
  113. func generatePoolL2Txs() ([]common.PoolL2Tx, error) {
  114. setPool := `
  115. Type: PoolL2
  116. PoolTransfer(1) A-B: 6 (4)
  117. PoolTransfer(2) A-B: 3 (1)
  118. PoolTransfer(1) B-A: 5 (2)
  119. PoolTransfer(2) B-A: 10 (3)
  120. PoolTransfer(1) A-B: 7 (2)
  121. PoolTransfer(2) A-B: 2 (1)
  122. PoolTransfer(1) B-A: 8 (2)
  123. PoolTransfer(2) B-A: 1 (1)
  124. PoolTransfer(1) A-B: 3 (1)
  125. PoolTransferToEthAddr(2) B-A: 5 (2)
  126. PoolTransferToBJJ(2) B-A: 5 (2)
  127. PoolExit(1) A: 5 (2)
  128. PoolExit(2) B: 3 (1)
  129. `
  130. poolL2Txs, err := tc.GeneratePoolL2Txs(setPool)
  131. if err != nil {
  132. return nil, tracerr.Wrap(err)
  133. }
  134. return poolL2Txs, nil
  135. }
  136. func TestAddTxTest(t *testing.T) {
  137. err := prepareHistoryDB(historyDB)
  138. if err != nil {
  139. log.Error("Error prepare historyDB", err)
  140. }
  141. poolL2Txs, err := generatePoolL2Txs()
  142. assert.NoError(t, err)
  143. for i := range poolL2Txs {
  144. err := l2DB.AddTxTest(&poolL2Txs[i])
  145. assert.NoError(t, err)
  146. fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID)
  147. assert.NoError(t, err)
  148. assertTx(t, &poolL2Txs[i], fetchedTx)
  149. nameZone, offset := fetchedTx.Timestamp.Zone()
  150. assert.Equal(t, "UTC", nameZone)
  151. assert.Equal(t, 0, offset)
  152. }
  153. }
  154. func TestUpdateTxsInfo(t *testing.T) {
  155. err := prepareHistoryDB(historyDB)
  156. if err != nil {
  157. log.Error("Error prepare historyDB", err)
  158. }
  159. poolL2Txs, err := generatePoolL2Txs()
  160. assert.NoError(t, err)
  161. for i := range poolL2Txs {
  162. err := l2DB.AddTxTest(&poolL2Txs[i])
  163. require.NoError(t, err)
  164. // once added, change the Info parameter
  165. poolL2Txs[i].Info = "test"
  166. }
  167. // update the txs
  168. err = l2DB.UpdateTxsInfo(poolL2Txs)
  169. require.NoError(t, err)
  170. for i := range poolL2Txs {
  171. fetchedTx, err := l2DB.GetTx(poolL2Txs[i].TxID)
  172. assert.NoError(t, err)
  173. assert.Equal(t, "test", fetchedTx.Info)
  174. }
  175. }
  176. func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
  177. // Check that timestamp has been set within the last 3 seconds
  178. assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix())
  179. assert.GreaterOrEqual(t, time.Now().UTC().Unix(), actual.Timestamp.Unix())
  180. expected.Timestamp = actual.Timestamp
  181. // Check absolute fee
  182. // find token
  183. token := tokens[expected.TokenID]
  184. // If the token has value in USD setted
  185. if token.USDUpdate != nil {
  186. assert.Less(t, token.USDUpdate.Unix()-3, actual.AbsoluteFeeUpdate.Unix())
  187. expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate
  188. // Set expected fee
  189. f := new(big.Float).SetInt(expected.Amount)
  190. amountF, _ := f.Float64()
  191. expected.AbsoluteFee = *token.USD * amountF * expected.Fee.Percentage()
  192. test.AssertUSD(t, &expected.AbsoluteFee, &actual.AbsoluteFee)
  193. }
  194. assert.Equal(t, expected, actual)
  195. }
  196. // NO UPDATE: benchmarks will be done after impl is finished
  197. // func BenchmarkAddTxTest(b *testing.B) {
  198. // const nInserts = 20
  199. // test.WipeDB(l2DB.DB())
  200. // txs := test.GenPoolTxs(nInserts, tokens)
  201. // now := time.Now()
  202. // for _, tx := range txs {
  203. // _ = l2DB.AddTxTest(tx)
  204. // }
  205. // elapsedTime := time.Since(now)
  206. // log.Info("Time to insert 2048 txs:", elapsedTime)
  207. // }
  208. func TestGetPending(t *testing.T) {
  209. err := prepareHistoryDB(historyDB)
  210. if err != nil {
  211. log.Error("Error prepare historyDB", err)
  212. }
  213. poolL2Txs, err := generatePoolL2Txs()
  214. assert.NoError(t, err)
  215. var pendingTxs []*common.PoolL2Tx
  216. for i := range poolL2Txs {
  217. err := l2DB.AddTxTest(&poolL2Txs[i])
  218. assert.NoError(t, err)
  219. pendingTxs = append(pendingTxs, &poolL2Txs[i])
  220. }
  221. fetchedTxs, err := l2DB.GetPendingTxs()
  222. assert.NoError(t, err)
  223. assert.Equal(t, len(pendingTxs), len(fetchedTxs))
  224. for i := range fetchedTxs {
  225. assertTx(t, pendingTxs[i], &fetchedTxs[i])
  226. }
  227. }
  228. func TestStartForging(t *testing.T) {
  229. // Generate txs
  230. var fakeBatchNum common.BatchNum = 33
  231. err := prepareHistoryDB(historyDB)
  232. if err != nil {
  233. log.Error("Error prepare historyDB", err)
  234. }
  235. poolL2Txs, err := generatePoolL2Txs()
  236. assert.NoError(t, err)
  237. var startForgingTxIDs []common.TxID
  238. randomizer := 0
  239. // Add txs to DB
  240. for i := range poolL2Txs {
  241. err := l2DB.AddTxTest(&poolL2Txs[i])
  242. assert.NoError(t, err)
  243. if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  244. startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
  245. }
  246. randomizer++
  247. }
  248. // Start forging txs
  249. err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
  250. assert.NoError(t, err)
  251. // Fetch txs and check that they've been updated correctly
  252. for _, id := range startForgingTxIDs {
  253. fetchedTx, err := l2DB.GetTxAPI(id)
  254. assert.NoError(t, err)
  255. assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
  256. assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
  257. }
  258. }
  259. func TestDoneForging(t *testing.T) {
  260. // Generate txs
  261. var fakeBatchNum common.BatchNum = 33
  262. err := prepareHistoryDB(historyDB)
  263. if err != nil {
  264. log.Error("Error prepare historyDB", err)
  265. }
  266. poolL2Txs, err := generatePoolL2Txs()
  267. assert.NoError(t, err)
  268. var startForgingTxIDs []common.TxID
  269. randomizer := 0
  270. // Add txs to DB
  271. for i := range poolL2Txs {
  272. err := l2DB.AddTxTest(&poolL2Txs[i])
  273. assert.NoError(t, err)
  274. if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  275. startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
  276. }
  277. randomizer++
  278. }
  279. // Start forging txs
  280. err = l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
  281. assert.NoError(t, err)
  282. var doneForgingTxIDs []common.TxID
  283. randomizer = 0
  284. for _, txID := range startForgingTxIDs {
  285. if randomizer%2 == 0 {
  286. doneForgingTxIDs = append(doneForgingTxIDs, txID)
  287. }
  288. randomizer++
  289. }
  290. // Done forging txs
  291. err = l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum)
  292. assert.NoError(t, err)
  293. // Fetch txs and check that they've been updated correctly
  294. for _, id := range doneForgingTxIDs {
  295. fetchedTx, err := l2DB.GetTxAPI(id)
  296. assert.NoError(t, err)
  297. assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
  298. assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
  299. }
  300. }
  301. func TestInvalidate(t *testing.T) {
  302. // Generate txs
  303. var fakeBatchNum common.BatchNum = 33
  304. err := prepareHistoryDB(historyDB)
  305. if err != nil {
  306. log.Error("Error prepare historyDB", err)
  307. }
  308. poolL2Txs, err := generatePoolL2Txs()
  309. assert.NoError(t, err)
  310. var invalidTxIDs []common.TxID
  311. randomizer := 0
  312. // Add txs to DB
  313. for i := range poolL2Txs {
  314. err := l2DB.AddTxTest(&poolL2Txs[i])
  315. assert.NoError(t, err)
  316. if poolL2Txs[i].State != common.PoolL2TxStateInvalid && randomizer%2 == 0 {
  317. randomizer++
  318. invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
  319. }
  320. }
  321. // Invalidate txs
  322. err = l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  323. assert.NoError(t, err)
  324. // Fetch txs and check that they've been updated correctly
  325. for _, id := range invalidTxIDs {
  326. fetchedTx, err := l2DB.GetTxAPI(id)
  327. assert.NoError(t, err)
  328. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  329. assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
  330. }
  331. }
  332. func TestInvalidateOldNonces(t *testing.T) {
  333. // Generate txs
  334. var fakeBatchNum common.BatchNum = 33
  335. err := prepareHistoryDB(historyDB)
  336. if err != nil {
  337. log.Error("Error prepare historyDB", err)
  338. }
  339. poolL2Txs, err := generatePoolL2Txs()
  340. assert.NoError(t, err)
  341. // Update Accounts currentNonce
  342. var updateAccounts []common.IdxNonce
  343. var currentNonce = common.Nonce(1)
  344. for i := range accs {
  345. updateAccounts = append(updateAccounts, common.IdxNonce{
  346. Idx: accs[i].Idx,
  347. Nonce: common.Nonce(currentNonce),
  348. })
  349. }
  350. // Add txs to DB
  351. var invalidTxIDs []common.TxID
  352. for i := range poolL2Txs {
  353. if poolL2Txs[i].Nonce < currentNonce {
  354. invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
  355. }
  356. err := l2DB.AddTxTest(&poolL2Txs[i])
  357. assert.NoError(t, err)
  358. }
  359. // sanity check
  360. require.Greater(t, len(invalidTxIDs), 0)
  361. err = l2DB.InvalidateOldNonces(updateAccounts, fakeBatchNum)
  362. assert.NoError(t, err)
  363. // Fetch txs and check that they've been updated correctly
  364. for _, id := range invalidTxIDs {
  365. fetchedTx, err := l2DB.GetTxAPI(id)
  366. require.NoError(t, err)
  367. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  368. assert.Equal(t, &fakeBatchNum, fetchedTx.BatchNum)
  369. }
  370. }
  371. // TestReorg: first part of the test with reorg
  372. // With invalidated transactions BEFORE reorgBatch
  373. // And forged transactions in reorgBatch
  374. func TestReorg(t *testing.T) {
  375. // Generate txs
  376. const lastValidBatch common.BatchNum = 20
  377. const reorgBatch common.BatchNum = lastValidBatch + 1
  378. err := prepareHistoryDB(historyDB)
  379. if err != nil {
  380. log.Error("Error prepare historyDB", err)
  381. }
  382. poolL2Txs, err := generatePoolL2Txs()
  383. assert.NoError(t, err)
  384. reorgedTxIDs := []common.TxID{}
  385. nonReorgedTxIDs := []common.TxID{}
  386. var startForgingTxIDs []common.TxID
  387. var invalidTxIDs []common.TxID
  388. var allTxRandomize []common.TxID
  389. randomizer := 0
  390. // Add txs to DB
  391. for i := range poolL2Txs {
  392. err := l2DB.AddTxTest(&poolL2Txs[i])
  393. assert.NoError(t, err)
  394. if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  395. startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
  396. allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
  397. } else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 {
  398. invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
  399. allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
  400. }
  401. randomizer++
  402. }
  403. // Start forging txs
  404. err = l2DB.StartForging(startForgingTxIDs, lastValidBatch)
  405. assert.NoError(t, err)
  406. var doneForgingTxIDs []common.TxID
  407. randomizer = 0
  408. for _, txID := range allTxRandomize {
  409. invalidTx := false
  410. for i := range invalidTxIDs {
  411. if invalidTxIDs[i] == txID {
  412. invalidTx = true
  413. nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
  414. }
  415. }
  416. if !invalidTx {
  417. if randomizer%2 == 0 {
  418. doneForgingTxIDs = append(doneForgingTxIDs, txID)
  419. reorgedTxIDs = append(reorgedTxIDs, txID)
  420. } else {
  421. nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
  422. }
  423. randomizer++
  424. }
  425. }
  426. // Invalidate txs BEFORE reorgBatch --> nonReorg
  427. err = l2DB.InvalidateTxs(invalidTxIDs, lastValidBatch)
  428. assert.NoError(t, err)
  429. // Done forging txs in reorgBatch --> Reorg
  430. err = l2DB.DoneForging(doneForgingTxIDs, reorgBatch)
  431. assert.NoError(t, err)
  432. err = l2DB.Reorg(lastValidBatch)
  433. assert.NoError(t, err)
  434. for _, id := range reorgedTxIDs {
  435. tx, err := l2DB.GetTxAPI(id)
  436. assert.NoError(t, err)
  437. assert.Nil(t, tx.BatchNum)
  438. assert.Equal(t, common.PoolL2TxStatePending, tx.State)
  439. }
  440. for _, id := range nonReorgedTxIDs {
  441. fetchedTx, err := l2DB.GetTxAPI(id)
  442. assert.NoError(t, err)
  443. assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
  444. }
  445. }
  446. // TestReorg: second part of test with reorg
  447. // With invalidated transactions in reorgBatch
  448. // And forged transactions BEFORE reorgBatch
  449. func TestReorg2(t *testing.T) {
  450. // Generate txs
  451. const lastValidBatch common.BatchNum = 20
  452. const reorgBatch common.BatchNum = lastValidBatch + 1
  453. err := prepareHistoryDB(historyDB)
  454. if err != nil {
  455. log.Error("Error prepare historyDB", err)
  456. }
  457. poolL2Txs, err := generatePoolL2Txs()
  458. assert.NoError(t, err)
  459. reorgedTxIDs := []common.TxID{}
  460. nonReorgedTxIDs := []common.TxID{}
  461. var startForgingTxIDs []common.TxID
  462. var invalidTxIDs []common.TxID
  463. var allTxRandomize []common.TxID
  464. randomizer := 0
  465. // Add txs to DB
  466. for i := range poolL2Txs {
  467. err := l2DB.AddTxTest(&poolL2Txs[i])
  468. assert.NoError(t, err)
  469. if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  470. startForgingTxIDs = append(startForgingTxIDs, poolL2Txs[i].TxID)
  471. allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
  472. } else if poolL2Txs[i].State == common.PoolL2TxStatePending && randomizer%3 == 0 {
  473. invalidTxIDs = append(invalidTxIDs, poolL2Txs[i].TxID)
  474. allTxRandomize = append(allTxRandomize, poolL2Txs[i].TxID)
  475. }
  476. randomizer++
  477. }
  478. // Start forging txs
  479. err = l2DB.StartForging(startForgingTxIDs, lastValidBatch)
  480. assert.NoError(t, err)
  481. var doneForgingTxIDs []common.TxID
  482. randomizer = 0
  483. for _, txID := range allTxRandomize {
  484. invalidTx := false
  485. for i := range invalidTxIDs {
  486. if invalidTxIDs[i] == txID {
  487. invalidTx = true
  488. reorgedTxIDs = append(reorgedTxIDs, txID)
  489. }
  490. }
  491. if !invalidTx {
  492. if randomizer%2 == 0 {
  493. doneForgingTxIDs = append(doneForgingTxIDs, txID)
  494. }
  495. nonReorgedTxIDs = append(nonReorgedTxIDs, txID)
  496. randomizer++
  497. }
  498. }
  499. // Done forging txs BEFORE reorgBatch --> nonReorg
  500. err = l2DB.DoneForging(doneForgingTxIDs, lastValidBatch)
  501. assert.NoError(t, err)
  502. // Invalidate txs in reorgBatch --> Reorg
  503. err = l2DB.InvalidateTxs(invalidTxIDs, reorgBatch)
  504. assert.NoError(t, err)
  505. err = l2DB.Reorg(lastValidBatch)
  506. assert.NoError(t, err)
  507. for _, id := range reorgedTxIDs {
  508. tx, err := l2DB.GetTxAPI(id)
  509. assert.NoError(t, err)
  510. assert.Nil(t, tx.BatchNum)
  511. assert.Equal(t, common.PoolL2TxStatePending, tx.State)
  512. }
  513. for _, id := range nonReorgedTxIDs {
  514. fetchedTx, err := l2DB.GetTxAPI(id)
  515. assert.NoError(t, err)
  516. assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
  517. }
  518. }
  519. func TestPurge(t *testing.T) {
  520. // Generate txs
  521. err := prepareHistoryDB(historyDB)
  522. if err != nil {
  523. log.Error("Error prepare historyDB", err)
  524. }
  525. // generatePoolL2Txs
  526. generateTx := int(l2DB.maxTxs/8 + 1)
  527. var poolL2Tx []common.PoolL2Tx
  528. for i := 0; i < generateTx; i++ {
  529. poolL2TxAux, err := generatePoolL2Txs()
  530. assert.NoError(t, err)
  531. poolL2Tx = append(poolL2Tx, poolL2TxAux...)
  532. }
  533. afterTTLIDs := []common.TxID{}
  534. keepedIDs := []common.TxID{}
  535. var deletedIDs []common.TxID
  536. var invalidTxIDs []common.TxID
  537. var doneForgingTxIDs []common.TxID
  538. const toDeleteBatchNum common.BatchNum = 30
  539. safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
  540. // Add txs to the DB
  541. for i := 0; i < len(poolL2Tx); i++ {
  542. tx := poolL2Tx[i]
  543. if i%2 == 0 { // keep tx
  544. keepedIDs = append(keepedIDs, tx.TxID)
  545. } else { // delete after safety period
  546. if i%3 == 0 {
  547. doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID)
  548. } else if i%5 == 0 {
  549. invalidTxIDs = append(invalidTxIDs, tx.TxID)
  550. } else {
  551. afterTTLIDs = append(afterTTLIDs, tx.TxID)
  552. }
  553. deletedIDs = append(deletedIDs, poolL2Tx[i].TxID)
  554. }
  555. err := l2DB.AddTxTest(&tx)
  556. assert.NoError(t, err)
  557. }
  558. // Set batchNum keeped txs
  559. for i := range keepedIDs {
  560. _, err = l2DB.db.Exec(
  561. "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
  562. safeBatchNum, keepedIDs[i],
  563. )
  564. assert.NoError(t, err)
  565. }
  566. // Start forging txs and set batchNum
  567. err = l2DB.StartForging(doneForgingTxIDs, toDeleteBatchNum)
  568. assert.NoError(t, err)
  569. // Done forging txs and set batchNum
  570. err = l2DB.DoneForging(doneForgingTxIDs, toDeleteBatchNum)
  571. assert.NoError(t, err)
  572. // Invalidate txs and set batchNum
  573. err = l2DB.InvalidateTxs(invalidTxIDs, toDeleteBatchNum)
  574. assert.NoError(t, err)
  575. // Update timestamp of afterTTL txs
  576. deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0)
  577. for _, id := range afterTTLIDs {
  578. // Set timestamp
  579. _, err = l2DB.db.Exec(
  580. "UPDATE tx_pool SET timestamp = $1, state = $2 WHERE tx_id = $3;",
  581. deleteTimestamp, common.PoolL2TxStatePending, id,
  582. )
  583. assert.NoError(t, err)
  584. }
  585. // Purge txs
  586. err = l2DB.Purge(safeBatchNum)
  587. assert.NoError(t, err)
  588. // Check results
  589. for _, id := range deletedIDs {
  590. _, err := l2DB.GetTx(id)
  591. assert.Error(t, err)
  592. }
  593. for _, id := range keepedIDs {
  594. _, err := l2DB.GetTx(id)
  595. assert.NoError(t, err)
  596. }
  597. }
  598. func TestAuth(t *testing.T) {
  599. test.WipeDB(l2DB.DB())
  600. const nAuths = 5
  601. chainID := uint16(0)
  602. hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6")
  603. // Generate authorizations
  604. auths := test.GenAuths(nAuths, chainID, hermezContractAddr)
  605. for i := 0; i < len(auths); i++ {
  606. // Add to the DB
  607. err := l2DB.AddAccountCreationAuth(auths[i])
  608. assert.NoError(t, err)
  609. // Fetch from DB
  610. auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
  611. assert.NoError(t, err)
  612. // Check fetched vs generated
  613. assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
  614. assert.Equal(t, auths[i].BJJ, auth.BJJ)
  615. assert.Equal(t, auths[i].Signature, auth.Signature)
  616. assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
  617. nameZone, offset := auths[i].Timestamp.Zone()
  618. assert.Equal(t, "UTC", nameZone)
  619. assert.Equal(t, 0, offset)
  620. }
  621. }
  622. func TestAddGet(t *testing.T) {
  623. err := prepareHistoryDB(historyDB)
  624. if err != nil {
  625. log.Error("Error prepare historyDB", err)
  626. }
  627. poolL2Txs, err := generatePoolL2Txs()
  628. assert.NoError(t, err)
  629. // We will work with only 3 txs
  630. require.GreaterOrEqual(t, len(poolL2Txs), 3)
  631. txs := poolL2Txs[:3]
  632. // NOTE: By changing the tx fields, the signature will no longer be
  633. // valid, but we are not checking the signautre here so it's OK.
  634. // 0. Has ToIdx >= 256 && ToEthAddr == 0 && ToBJJ == 0
  635. require.GreaterOrEqual(t, int(txs[0].ToIdx), 256)
  636. txs[0].ToEthAddr = ethCommon.Address{}
  637. txs[0].ToBJJ = babyjub.PublicKeyComp{}
  638. // 1. Has ToIdx >= 256 && ToEthAddr != 0 && ToBJJ != 0
  639. require.GreaterOrEqual(t, int(txs[1].ToIdx), 256)
  640. require.NotEqual(t, txs[1].ToEthAddr, ethCommon.Address{})
  641. require.NotEqual(t, txs[1].ToBJJ, babyjub.PublicKeyComp{})
  642. // 2. Has ToIdx == 0 && ToEthAddr != 0 && ToBJJ != 0
  643. txs[2].ToIdx = 0
  644. require.NotEqual(t, txs[2].ToEthAddr, ethCommon.Address{})
  645. require.NotEqual(t, txs[2].ToBJJ, babyjub.PublicKeyComp{})
  646. for i := 0; i < len(txs); i++ {
  647. require.NoError(t, txs[i].SetID())
  648. require.NoError(t, l2DB.AddTxTest(&txs[i]))
  649. }
  650. // Verify that the inserts haven't altered any field (specially
  651. // ToEthAddr and ToBJJ)
  652. for i := 0; i < len(txs); i++ {
  653. dbTx, err := l2DB.GetTx(txs[i].TxID)
  654. require.NoError(t, err)
  655. // Ignore Timestamp, AbsoluteFee, AbsoluteFeeUpdate
  656. txs[i].Timestamp = dbTx.Timestamp
  657. txs[i].AbsoluteFee = dbTx.AbsoluteFee
  658. txs[i].AbsoluteFeeUpdate = dbTx.AbsoluteFeeUpdate
  659. assert.Equal(t, txs[i], *dbTx)
  660. }
  661. }