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.

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