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.

429 lines
12 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
  1. package l2db
  2. import (
  3. "math/big"
  4. "os"
  5. "testing"
  6. "time"
  7. "github.com/hermeznetwork/hermez-node/common"
  8. dbUtils "github.com/hermeznetwork/hermez-node/db"
  9. "github.com/hermeznetwork/hermez-node/db/historydb"
  10. "github.com/hermeznetwork/hermez-node/log"
  11. "github.com/hermeznetwork/hermez-node/test"
  12. "github.com/jmoiron/sqlx"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. var l2DB *L2DB
  16. var tokens []common.Token
  17. var tokensUSD []historydb.TokenWithUSD
  18. func TestMain(m *testing.M) {
  19. // init DB
  20. pass := os.Getenv("POSTGRES_PASS")
  21. db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  22. if err != nil {
  23. panic(err)
  24. }
  25. l2DB = NewL2DB(db, 10, 100, 24*time.Hour)
  26. test.WipeDB(l2DB.DB())
  27. tokens, tokensUSD = prepareHistoryDB(db)
  28. // Run tests
  29. result := m.Run()
  30. // Close DB
  31. if err := db.Close(); err != nil {
  32. log.Error("Error closing the history DB:", err)
  33. }
  34. os.Exit(result)
  35. }
  36. func prepareHistoryDB(db *sqlx.DB) ([]common.Token, []historydb.TokenWithUSD) {
  37. historyDB := historydb.NewHistoryDB(db)
  38. const fromBlock int64 = 1
  39. const toBlock int64 = 5
  40. // Store blocks to historyDB
  41. blocks := test.GenBlocks(fromBlock, toBlock)
  42. if err := historyDB.AddBlocks(blocks); err != nil {
  43. panic(err)
  44. }
  45. // Store tokens to historyDB
  46. const nTokens = 5
  47. tokens, ethToken := test.GenTokens(nTokens, blocks)
  48. if err := historyDB.AddTokens(tokens); err != nil {
  49. panic(err)
  50. }
  51. tokens = append([]common.Token{ethToken}, tokens...)
  52. readTokens := []historydb.TokenWithUSD{}
  53. for i, token := range tokens {
  54. readToken := historydb.TokenWithUSD{
  55. TokenID: token.TokenID,
  56. EthBlockNum: token.EthBlockNum,
  57. EthAddr: token.EthAddr,
  58. Name: token.Name,
  59. Symbol: token.Symbol,
  60. Decimals: token.Decimals,
  61. }
  62. if i%2 != 0 {
  63. value := float64(i) * 5.4321
  64. if err := historyDB.UpdateTokenValue(token.Symbol, value); err != nil {
  65. panic(err)
  66. }
  67. now := time.Now().UTC()
  68. readToken.USDUpdate = &now
  69. readToken.USD = &value
  70. }
  71. readTokens = append(readTokens, readToken)
  72. }
  73. return tokens, readTokens
  74. }
  75. func TestAddTxTest(t *testing.T) {
  76. // Gen poolTxs
  77. const nInserts = 20
  78. test.WipeDB(l2DB.DB())
  79. txs := test.GenPoolTxs(nInserts, tokens)
  80. for _, tx := range txs {
  81. err := l2DB.AddTxTest(tx)
  82. assert.NoError(t, err)
  83. fetchedTx, err := l2DB.GetTx(tx.TxID)
  84. assert.NoError(t, err)
  85. // assertReadTx(t, commonToRead(tx, tokens), fetchedTx)
  86. assertTx(t, tx, fetchedTx)
  87. nameZone, offset := fetchedTx.Timestamp.Zone()
  88. assert.Equal(t, "UTC", nameZone)
  89. assert.Equal(t, 0, offset)
  90. }
  91. }
  92. func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
  93. // Check that timestamp has been set within the last 3 seconds
  94. assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix())
  95. assert.GreaterOrEqual(t, time.Now().UTC().Unix(), actual.Timestamp.Unix())
  96. expected.Timestamp = actual.Timestamp
  97. // Check absolute fee
  98. // find token
  99. token := historydb.TokenWithUSD{}
  100. for _, tkn := range tokensUSD {
  101. if expected.TokenID == tkn.TokenID {
  102. token = tkn
  103. break
  104. }
  105. }
  106. // If the token has value in USD setted
  107. if token.USDUpdate != nil {
  108. assert.Equal(t, token.USDUpdate.Unix(), actual.AbsoluteFeeUpdate.Unix())
  109. expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate
  110. // Set expected fee
  111. f := new(big.Float).SetInt(expected.Amount)
  112. amountF, _ := f.Float64()
  113. expected.AbsoluteFee = *token.USD * amountF * expected.Fee.Percentage()
  114. test.AssertUSD(t, &expected.AbsoluteFee, &actual.AbsoluteFee)
  115. }
  116. assert.Equal(t, expected, actual)
  117. }
  118. func BenchmarkAddTxTest(b *testing.B) {
  119. const nInserts = 20
  120. test.WipeDB(l2DB.DB())
  121. txs := test.GenPoolTxs(nInserts, tokens)
  122. now := time.Now()
  123. for _, tx := range txs {
  124. _ = l2DB.AddTxTest(tx)
  125. }
  126. elapsedTime := time.Since(now)
  127. log.Info("Time to insert 2048 txs:", elapsedTime)
  128. }
  129. func TestGetPending(t *testing.T) {
  130. const nInserts = 20
  131. test.WipeDB(l2DB.DB())
  132. txs := test.GenPoolTxs(nInserts, tokens)
  133. var pendingTxs []*common.PoolL2Tx
  134. for _, tx := range txs {
  135. err := l2DB.AddTxTest(tx)
  136. assert.NoError(t, err)
  137. if tx.State == common.PoolL2TxStatePending {
  138. pendingTxs = append(pendingTxs, tx)
  139. }
  140. }
  141. fetchedTxs, err := l2DB.GetPendingTxs()
  142. assert.NoError(t, err)
  143. assert.Equal(t, len(pendingTxs), len(fetchedTxs))
  144. for i := range fetchedTxs {
  145. assertTx(t, pendingTxs[i], &fetchedTxs[i])
  146. }
  147. }
  148. /*
  149. WARNING: this should be fixed once transaktio is ready
  150. func TestStartForging(t *testing.T) {
  151. // Generate txs
  152. const nInserts = 60
  153. const fakeBatchNum common.BatchNum = 33
  154. test.WipeDB(l2DB.DB())
  155. txs := test.GenPoolTxs(nInserts, tokens)
  156. var startForgingTxIDs []common.TxID
  157. randomizer := 0
  158. // Add txs to DB
  159. for _, tx := range txs {
  160. err := l2DB.AddTxTest(tx)
  161. assert.NoError(t, err)
  162. if tx.State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  163. randomizer++
  164. startForgingTxIDs = append(startForgingTxIDs, tx.TxID)
  165. }
  166. }
  167. // Start forging txs
  168. err := l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
  169. assert.NoError(t, err)
  170. // Fetch txs and check that they've been updated correctly
  171. for _, id := range startForgingTxIDs {
  172. fetchedTx, err := l2DB.GetTx(id)
  173. assert.NoError(t, err)
  174. assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
  175. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  176. }
  177. }
  178. */
  179. /*
  180. WARNING: this should be fixed once transaktio is ready
  181. func TestDoneForging(t *testing.T) {
  182. // Generate txs
  183. const nInserts = 60
  184. const fakeBatchNum common.BatchNum = 33
  185. test.WipeDB(l2DB.DB())
  186. txs := test.GenPoolTxs(nInserts, tokens)
  187. var doneForgingTxIDs []common.TxID
  188. randomizer := 0
  189. // Add txs to DB
  190. for _, tx := range txs {
  191. err := l2DB.AddTxTest(tx)
  192. assert.NoError(t, err)
  193. if tx.State == common.PoolL2TxStateForging && randomizer%2 == 0 {
  194. randomizer++
  195. doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID)
  196. }
  197. }
  198. // Start forging txs
  199. err := l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum)
  200. assert.NoError(t, err)
  201. // Fetch txs and check that they've been updated correctly
  202. for _, id := range doneForgingTxIDs {
  203. fetchedTx, err := l2DB.GetTx(id)
  204. assert.NoError(t, err)
  205. assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
  206. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  207. }
  208. }
  209. */
  210. /*
  211. WARNING: this should be fixed once transaktio is ready
  212. func TestInvalidate(t *testing.T) {
  213. // Generate txs
  214. const nInserts = 60
  215. const fakeBatchNum common.BatchNum = 33
  216. test.WipeDB(l2DB.DB())
  217. txs := test.GenPoolTxs(nInserts, tokens)
  218. var invalidTxIDs []common.TxID
  219. randomizer := 0
  220. // Add txs to DB
  221. for _, tx := range txs {
  222. err := l2DB.AddTxTest(tx)
  223. assert.NoError(t, err)
  224. if tx.State != common.PoolL2TxStateInvalid && randomizer%2 == 0 {
  225. randomizer++
  226. invalidTxIDs = append(invalidTxIDs, tx.TxID)
  227. }
  228. }
  229. // Start forging txs
  230. err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  231. assert.NoError(t, err)
  232. // Fetch txs and check that they've been updated correctly
  233. for _, id := range invalidTxIDs {
  234. fetchedTx, err := l2DB.GetTx(id)
  235. assert.NoError(t, err)
  236. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  237. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  238. }
  239. }
  240. */
  241. /*
  242. WARNING: this should be fixed once transaktio is ready
  243. func TestCheckNonces(t *testing.T) {
  244. // Generate txs
  245. const nInserts = 60
  246. const fakeBatchNum common.BatchNum = 33
  247. test.WipeDB(l2DB.DB())
  248. txs := test.GenPoolTxs(nInserts, tokens)
  249. var invalidTxIDs []common.TxID
  250. // Generate accounts
  251. const nAccoutns = 2
  252. const currentNonce = 2
  253. accs := []common.Account{}
  254. for i := 0; i < nAccoutns; i++ {
  255. accs = append(accs, common.Account{
  256. Idx: common.Idx(i),
  257. Nonce: currentNonce,
  258. })
  259. }
  260. // Add txs to DB
  261. for i := 0; i < len(txs); i++ {
  262. if txs[i].State != common.PoolL2TxStateInvalid {
  263. if i%2 == 0 { // Ensure transaction will be marked as invalid due to old nonce
  264. txs[i].Nonce = accs[i%len(accs)].Nonce
  265. txs[i].FromIdx = accs[i%len(accs)].Idx
  266. invalidTxIDs = append(invalidTxIDs, txs[i].TxID)
  267. } else { // Ensure transaction will NOT be marked as invalid due to old nonce
  268. txs[i].Nonce = currentNonce + 1
  269. }
  270. }
  271. err := l2DB.AddTxTest(txs[i])
  272. assert.NoError(t, err)
  273. }
  274. // Start forging txs
  275. err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  276. assert.NoError(t, err)
  277. // Fetch txs and check that they've been updated correctly
  278. for _, id := range invalidTxIDs {
  279. fetchedTx, err := l2DB.GetTx(id)
  280. assert.NoError(t, err)
  281. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  282. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  283. }
  284. }
  285. */
  286. func TestReorg(t *testing.T) {
  287. // Generate txs
  288. const nInserts = 20
  289. const lastValidBatch common.BatchNum = 20
  290. const reorgBatch common.BatchNum = lastValidBatch + 1
  291. test.WipeDB(l2DB.DB())
  292. txs := test.GenPoolTxs(nInserts, tokens)
  293. // Add txs to the DB
  294. reorgedTxIDs := []common.TxID{}
  295. nonReorgedTxIDs := []common.TxID{}
  296. for i := 0; i < len(txs); i++ {
  297. err := l2DB.AddTxTest(txs[i])
  298. assert.NoError(t, err)
  299. var batchNum common.BatchNum
  300. if txs[i].State == common.PoolL2TxStateForged || txs[i].State == common.PoolL2TxStateInvalid {
  301. reorgedTxIDs = append(reorgedTxIDs, txs[i].TxID)
  302. batchNum = reorgBatch
  303. } else {
  304. nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID)
  305. batchNum = lastValidBatch
  306. }
  307. _, err = l2DB.db.Exec(
  308. "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
  309. batchNum, txs[i].TxID,
  310. )
  311. assert.NoError(t, err)
  312. }
  313. err := l2DB.Reorg(lastValidBatch)
  314. assert.NoError(t, err)
  315. for _, id := range reorgedTxIDs {
  316. tx, err := l2DB.GetTxAPI(id)
  317. assert.NoError(t, err)
  318. assert.Nil(t, tx.BatchNum)
  319. assert.Equal(t, common.PoolL2TxStatePending, tx.State)
  320. }
  321. for _, id := range nonReorgedTxIDs {
  322. fetchedTx, err := l2DB.GetTxAPI(id)
  323. assert.NoError(t, err)
  324. assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
  325. }
  326. }
  327. func TestPurge(t *testing.T) {
  328. /*
  329. WARNING: this should be fixed once transaktio is ready
  330. // Generate txs
  331. nInserts := l2DB.maxTxs + 20
  332. test.WipeDB(l2DB.DB())
  333. txs := test.GenPoolTxs(int(nInserts), tokens)
  334. deletedIDs := []common.TxID{}
  335. keepedIDs := []common.TxID{}
  336. const toDeleteBatchNum common.BatchNum = 30
  337. safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
  338. // Add txs to the DB
  339. for i := 0; i < int(l2DB.maxTxs); i++ {
  340. var batchNum common.BatchNum
  341. if i%2 == 0 { // keep tx
  342. batchNum = safeBatchNum
  343. keepedIDs = append(keepedIDs, txs[i].TxID)
  344. } else { // delete after safety period
  345. batchNum = toDeleteBatchNum
  346. if i%3 == 0 {
  347. txs[i].State = common.PoolL2TxStateForged
  348. } else {
  349. txs[i].State = common.PoolL2TxStateInvalid
  350. }
  351. deletedIDs = append(deletedIDs, txs[i].TxID)
  352. }
  353. err := l2DB.AddTxTest(txs[i])
  354. assert.NoError(t, err)
  355. // Set batchNum
  356. _, err = l2DB.db.Exec(
  357. "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
  358. batchNum, txs[i].TxID,
  359. )
  360. assert.NoError(t, err)
  361. }
  362. for i := int(l2DB.maxTxs); i < len(txs); i++ {
  363. // Delete after TTL
  364. deletedIDs = append(deletedIDs, txs[i].TxID)
  365. err := l2DB.AddTxTest(txs[i])
  366. assert.NoError(t, err)
  367. // Set timestamp
  368. deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0)
  369. _, err = l2DB.db.Exec(
  370. "UPDATE tx_pool SET timestamp = $1 WHERE tx_id = $2;",
  371. deleteTimestamp, txs[i].TxID,
  372. )
  373. assert.NoError(t, err)
  374. }
  375. // Purge txs
  376. err := l2DB.Purge(safeBatchNum)
  377. assert.NoError(t, err)
  378. // Check results
  379. for _, id := range deletedIDs {
  380. tx, err := l2DB.GetTx(id)
  381. if err == nil {
  382. log.Debug(tx)
  383. }
  384. assert.Error(t, err)
  385. }
  386. for _, id := range keepedIDs {
  387. _, err := l2DB.GetTx(id)
  388. assert.NoError(t, err)
  389. }
  390. */
  391. }
  392. func TestAuth(t *testing.T) {
  393. test.WipeDB(l2DB.DB())
  394. const nAuths = 5
  395. // Generate authorizations
  396. auths := test.GenAuths(nAuths)
  397. for i := 0; i < len(auths); i++ {
  398. // Add to the DB
  399. err := l2DB.AddAccountCreationAuth(auths[i])
  400. assert.NoError(t, err)
  401. // Fetch from DB
  402. auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
  403. assert.NoError(t, err)
  404. // Check fetched vs generated
  405. assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
  406. assert.Equal(t, auths[i].BJJ, auth.BJJ)
  407. assert.Equal(t, auths[i].Signature, auth.Signature)
  408. assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
  409. nameZone, offset := auths[i].Timestamp.Zone()
  410. assert.Equal(t, "UTC", nameZone)
  411. assert.Equal(t, 0, offset)
  412. }
  413. }