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.

423 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. }
  88. }
  89. func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
  90. // Check that timestamp has been set within the last 3 seconds
  91. assert.Less(t, time.Now().UTC().Unix()-3, actual.Timestamp.Unix())
  92. assert.GreaterOrEqual(t, time.Now().UTC().Unix(), actual.Timestamp.Unix())
  93. expected.Timestamp = actual.Timestamp
  94. // Check absolute fee
  95. // find token
  96. token := historydb.TokenWithUSD{}
  97. for _, tkn := range tokensUSD {
  98. if expected.TokenID == tkn.TokenID {
  99. token = tkn
  100. break
  101. }
  102. }
  103. // If the token has value in USD setted
  104. if token.USDUpdate != nil {
  105. assert.Equal(t, token.USDUpdate.Unix(), actual.AbsoluteFeeUpdate.Unix())
  106. expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate
  107. // Set expected fee
  108. f := new(big.Float).SetInt(expected.Amount)
  109. amountF, _ := f.Float64()
  110. expected.AbsoluteFee = *token.USD * amountF * expected.Fee.Percentage()
  111. test.AssertUSD(t, &expected.AbsoluteFee, &actual.AbsoluteFee)
  112. }
  113. assert.Equal(t, expected, actual)
  114. }
  115. func BenchmarkAddTxTest(b *testing.B) {
  116. const nInserts = 20
  117. test.WipeDB(l2DB.DB())
  118. txs := test.GenPoolTxs(nInserts, tokens)
  119. now := time.Now()
  120. for _, tx := range txs {
  121. _ = l2DB.AddTxTest(tx)
  122. }
  123. elapsedTime := time.Since(now)
  124. log.Info("Time to insert 2048 txs:", elapsedTime)
  125. }
  126. func TestGetPending(t *testing.T) {
  127. const nInserts = 20
  128. test.WipeDB(l2DB.DB())
  129. txs := test.GenPoolTxs(nInserts, tokens)
  130. var pendingTxs []*common.PoolL2Tx
  131. for _, tx := range txs {
  132. err := l2DB.AddTxTest(tx)
  133. assert.NoError(t, err)
  134. if tx.State == common.PoolL2TxStatePending {
  135. pendingTxs = append(pendingTxs, tx)
  136. }
  137. }
  138. fetchedTxs, err := l2DB.GetPendingTxs()
  139. assert.NoError(t, err)
  140. assert.Equal(t, len(pendingTxs), len(fetchedTxs))
  141. for i := range fetchedTxs {
  142. assertTx(t, pendingTxs[i], &fetchedTxs[i])
  143. }
  144. }
  145. /*
  146. WARNING: this should be fixed once transaktio is ready
  147. func TestStartForging(t *testing.T) {
  148. // Generate txs
  149. const nInserts = 60
  150. const fakeBatchNum common.BatchNum = 33
  151. test.WipeDB(l2DB.DB())
  152. txs := test.GenPoolTxs(nInserts, tokens)
  153. var startForgingTxIDs []common.TxID
  154. randomizer := 0
  155. // Add txs to DB
  156. for _, tx := range txs {
  157. err := l2DB.AddTxTest(tx)
  158. assert.NoError(t, err)
  159. if tx.State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  160. randomizer++
  161. startForgingTxIDs = append(startForgingTxIDs, tx.TxID)
  162. }
  163. }
  164. // Start forging txs
  165. err := l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
  166. assert.NoError(t, err)
  167. // Fetch txs and check that they've been updated correctly
  168. for _, id := range startForgingTxIDs {
  169. fetchedTx, err := l2DB.GetTx(id)
  170. assert.NoError(t, err)
  171. assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
  172. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  173. }
  174. }
  175. */
  176. /*
  177. WARNING: this should be fixed once transaktio is ready
  178. func TestDoneForging(t *testing.T) {
  179. // Generate txs
  180. const nInserts = 60
  181. const fakeBatchNum common.BatchNum = 33
  182. test.WipeDB(l2DB.DB())
  183. txs := test.GenPoolTxs(nInserts, tokens)
  184. var doneForgingTxIDs []common.TxID
  185. randomizer := 0
  186. // Add txs to DB
  187. for _, tx := range txs {
  188. err := l2DB.AddTxTest(tx)
  189. assert.NoError(t, err)
  190. if tx.State == common.PoolL2TxStateForging && randomizer%2 == 0 {
  191. randomizer++
  192. doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID)
  193. }
  194. }
  195. // Start forging txs
  196. err := l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum)
  197. assert.NoError(t, err)
  198. // Fetch txs and check that they've been updated correctly
  199. for _, id := range doneForgingTxIDs {
  200. fetchedTx, err := l2DB.GetTx(id)
  201. assert.NoError(t, err)
  202. assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
  203. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  204. }
  205. }
  206. */
  207. /*
  208. WARNING: this should be fixed once transaktio is ready
  209. func TestInvalidate(t *testing.T) {
  210. // Generate txs
  211. const nInserts = 60
  212. const fakeBatchNum common.BatchNum = 33
  213. test.WipeDB(l2DB.DB())
  214. txs := test.GenPoolTxs(nInserts, tokens)
  215. var invalidTxIDs []common.TxID
  216. randomizer := 0
  217. // Add txs to DB
  218. for _, tx := range txs {
  219. err := l2DB.AddTxTest(tx)
  220. assert.NoError(t, err)
  221. if tx.State != common.PoolL2TxStateInvalid && randomizer%2 == 0 {
  222. randomizer++
  223. invalidTxIDs = append(invalidTxIDs, tx.TxID)
  224. }
  225. }
  226. // Start forging txs
  227. err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  228. assert.NoError(t, err)
  229. // Fetch txs and check that they've been updated correctly
  230. for _, id := range invalidTxIDs {
  231. fetchedTx, err := l2DB.GetTx(id)
  232. assert.NoError(t, err)
  233. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  234. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  235. }
  236. }
  237. */
  238. /*
  239. WARNING: this should be fixed once transaktio is ready
  240. func TestCheckNonces(t *testing.T) {
  241. // Generate txs
  242. const nInserts = 60
  243. const fakeBatchNum common.BatchNum = 33
  244. test.WipeDB(l2DB.DB())
  245. txs := test.GenPoolTxs(nInserts, tokens)
  246. var invalidTxIDs []common.TxID
  247. // Generate accounts
  248. const nAccoutns = 2
  249. const currentNonce = 2
  250. accs := []common.Account{}
  251. for i := 0; i < nAccoutns; i++ {
  252. accs = append(accs, common.Account{
  253. Idx: common.Idx(i),
  254. Nonce: currentNonce,
  255. })
  256. }
  257. // Add txs to DB
  258. for i := 0; i < len(txs); i++ {
  259. if txs[i].State != common.PoolL2TxStateInvalid {
  260. if i%2 == 0 { // Ensure transaction will be marked as invalid due to old nonce
  261. txs[i].Nonce = accs[i%len(accs)].Nonce
  262. txs[i].FromIdx = accs[i%len(accs)].Idx
  263. invalidTxIDs = append(invalidTxIDs, txs[i].TxID)
  264. } else { // Ensure transaction will NOT be marked as invalid due to old nonce
  265. txs[i].Nonce = currentNonce + 1
  266. }
  267. }
  268. err := l2DB.AddTxTest(txs[i])
  269. assert.NoError(t, err)
  270. }
  271. // Start forging txs
  272. err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  273. assert.NoError(t, err)
  274. // Fetch txs and check that they've been updated correctly
  275. for _, id := range invalidTxIDs {
  276. fetchedTx, err := l2DB.GetTx(id)
  277. assert.NoError(t, err)
  278. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  279. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  280. }
  281. }
  282. */
  283. func TestReorg(t *testing.T) {
  284. // Generate txs
  285. const nInserts = 20
  286. const lastValidBatch common.BatchNum = 20
  287. const reorgBatch common.BatchNum = lastValidBatch + 1
  288. test.WipeDB(l2DB.DB())
  289. txs := test.GenPoolTxs(nInserts, tokens)
  290. // Add txs to the DB
  291. reorgedTxIDs := []common.TxID{}
  292. nonReorgedTxIDs := []common.TxID{}
  293. for i := 0; i < len(txs); i++ {
  294. err := l2DB.AddTxTest(txs[i])
  295. assert.NoError(t, err)
  296. var batchNum common.BatchNum
  297. if txs[i].State == common.PoolL2TxStateForged || txs[i].State == common.PoolL2TxStateInvalid {
  298. reorgedTxIDs = append(reorgedTxIDs, txs[i].TxID)
  299. batchNum = reorgBatch
  300. } else {
  301. nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID)
  302. batchNum = lastValidBatch
  303. }
  304. _, err = l2DB.db.Exec(
  305. "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
  306. batchNum, txs[i].TxID,
  307. )
  308. assert.NoError(t, err)
  309. }
  310. err := l2DB.Reorg(lastValidBatch)
  311. assert.NoError(t, err)
  312. for _, id := range reorgedTxIDs {
  313. tx, err := l2DB.GetTxAPI(id)
  314. assert.NoError(t, err)
  315. assert.Nil(t, tx.BatchNum)
  316. assert.Equal(t, common.PoolL2TxStatePending, tx.State)
  317. }
  318. for _, id := range nonReorgedTxIDs {
  319. fetchedTx, err := l2DB.GetTxAPI(id)
  320. assert.NoError(t, err)
  321. assert.Equal(t, lastValidBatch, *fetchedTx.BatchNum)
  322. }
  323. }
  324. func TestPurge(t *testing.T) {
  325. /*
  326. WARNING: this should be fixed once transaktio is ready
  327. // Generate txs
  328. nInserts := l2DB.maxTxs + 20
  329. test.WipeDB(l2DB.DB())
  330. txs := test.GenPoolTxs(int(nInserts), tokens)
  331. deletedIDs := []common.TxID{}
  332. keepedIDs := []common.TxID{}
  333. const toDeleteBatchNum common.BatchNum = 30
  334. safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
  335. // Add txs to the DB
  336. for i := 0; i < int(l2DB.maxTxs); i++ {
  337. var batchNum common.BatchNum
  338. if i%2 == 0 { // keep tx
  339. batchNum = safeBatchNum
  340. keepedIDs = append(keepedIDs, txs[i].TxID)
  341. } else { // delete after safety period
  342. batchNum = toDeleteBatchNum
  343. if i%3 == 0 {
  344. txs[i].State = common.PoolL2TxStateForged
  345. } else {
  346. txs[i].State = common.PoolL2TxStateInvalid
  347. }
  348. deletedIDs = append(deletedIDs, txs[i].TxID)
  349. }
  350. err := l2DB.AddTxTest(txs[i])
  351. assert.NoError(t, err)
  352. // Set batchNum
  353. _, err = l2DB.db.Exec(
  354. "UPDATE tx_pool SET batch_num = $1 WHERE tx_id = $2;",
  355. batchNum, txs[i].TxID,
  356. )
  357. assert.NoError(t, err)
  358. }
  359. for i := int(l2DB.maxTxs); i < len(txs); i++ {
  360. // Delete after TTL
  361. deletedIDs = append(deletedIDs, txs[i].TxID)
  362. err := l2DB.AddTxTest(txs[i])
  363. assert.NoError(t, err)
  364. // Set timestamp
  365. deleteTimestamp := time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0)
  366. _, err = l2DB.db.Exec(
  367. "UPDATE tx_pool SET timestamp = $1 WHERE tx_id = $2;",
  368. deleteTimestamp, txs[i].TxID,
  369. )
  370. assert.NoError(t, err)
  371. }
  372. // Purge txs
  373. err := l2DB.Purge(safeBatchNum)
  374. assert.NoError(t, err)
  375. // Check results
  376. for _, id := range deletedIDs {
  377. tx, err := l2DB.GetTx(id)
  378. if err == nil {
  379. log.Debug(tx)
  380. }
  381. assert.Error(t, err)
  382. }
  383. for _, id := range keepedIDs {
  384. _, err := l2DB.GetTx(id)
  385. assert.NoError(t, err)
  386. }
  387. */
  388. }
  389. func TestAuth(t *testing.T) {
  390. test.WipeDB(l2DB.DB())
  391. const nAuths = 5
  392. // Generate authorizations
  393. auths := test.GenAuths(nAuths)
  394. for i := 0; i < len(auths); i++ {
  395. // Add to the DB
  396. err := l2DB.AddAccountCreationAuth(auths[i])
  397. assert.NoError(t, err)
  398. // Fetch from DB
  399. auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr)
  400. assert.NoError(t, err)
  401. // Check fetched vs generated
  402. assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
  403. assert.Equal(t, auths[i].BJJ, auth.BJJ)
  404. assert.Equal(t, auths[i].Signature, auth.Signature)
  405. assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
  406. }
  407. }