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.

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