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.

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