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.

355 lines
10 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
  1. package l2db
  2. import (
  3. "os"
  4. "testing"
  5. "time"
  6. "github.com/hermeznetwork/hermez-node/common"
  7. dbUtils "github.com/hermeznetwork/hermez-node/db"
  8. "github.com/hermeznetwork/hermez-node/db/historydb"
  9. "github.com/hermeznetwork/hermez-node/log"
  10. "github.com/hermeznetwork/hermez-node/test"
  11. "github.com/jmoiron/sqlx"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. var l2DB *L2DB
  15. var tokens []common.Token
  16. func TestMain(m *testing.M) {
  17. // init DB
  18. pass := os.Getenv("POSTGRES_PASS")
  19. db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  20. if err != nil {
  21. panic(err)
  22. }
  23. l2DB = NewL2DB(db, 10, 100, 24*time.Hour)
  24. tokens, err = prepareHistoryDB(db)
  25. if err != nil {
  26. panic(err)
  27. }
  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, error) {
  37. historyDB := historydb.NewHistoryDB(db)
  38. const fromBlock int64 = 1
  39. const toBlock int64 = 5
  40. // Clean historyDB
  41. if err := historyDB.Reorg(-1); err != nil {
  42. panic(err)
  43. }
  44. // Store blocks to historyDB
  45. blocks := test.GenBlocks(fromBlock, toBlock)
  46. if err := historyDB.AddBlocks(blocks); err != nil {
  47. panic(err)
  48. }
  49. // Store tokens to historyDB
  50. const nTokens = 5
  51. tokens := test.GenTokens(nTokens, blocks)
  52. return tokens, historyDB.AddTokens(tokens)
  53. }
  54. func TestAddTxTest(t *testing.T) {
  55. // Gen poolTxs
  56. const nInserts = 20
  57. test.CleanL2DB(l2DB.DB())
  58. txs := test.GenPoolTxs(nInserts, tokens)
  59. for _, tx := range txs {
  60. err := l2DB.AddTxTest(tx)
  61. assert.NoError(t, err)
  62. fetchedTx, err := l2DB.GetTx(tx.TxID)
  63. assert.NoError(t, err)
  64. assertTx(t, tx, fetchedTx)
  65. }
  66. }
  67. func assertTx(t *testing.T, expected, actual *common.PoolL2Tx) {
  68. assert.Equal(t, expected.Timestamp.Unix(), actual.Timestamp.Unix())
  69. expected.Timestamp = actual.Timestamp
  70. if expected.AbsoluteFeeUpdate != nil {
  71. assert.Equal(t, expected.AbsoluteFeeUpdate.Unix(), actual.AbsoluteFeeUpdate.Unix())
  72. expected.AbsoluteFeeUpdate = actual.AbsoluteFeeUpdate
  73. } else {
  74. assert.Equal(t, expected.AbsoluteFeeUpdate, actual.AbsoluteFeeUpdate)
  75. }
  76. test.AssertUSD(t, expected.AbsoluteFee, actual.AbsoluteFee)
  77. assert.Equal(t, expected, actual)
  78. }
  79. func BenchmarkAddTxTest(b *testing.B) {
  80. const nInserts = 20
  81. test.CleanL2DB(l2DB.DB())
  82. txs := test.GenPoolTxs(nInserts, tokens)
  83. now := time.Now()
  84. for _, tx := range txs {
  85. _ = l2DB.AddTxTest(tx)
  86. }
  87. elapsedTime := time.Since(now)
  88. log.Info("Time to insert 2048 txs:", elapsedTime)
  89. }
  90. func TestGetPending(t *testing.T) {
  91. const nInserts = 20
  92. test.CleanL2DB(l2DB.DB())
  93. txs := test.GenPoolTxs(nInserts, tokens)
  94. var pendingTxs []*common.PoolL2Tx
  95. for _, tx := range txs {
  96. err := l2DB.AddTxTest(tx)
  97. assert.NoError(t, err)
  98. if tx.State == common.PoolL2TxStatePending && tx.AbsoluteFee != nil {
  99. pendingTxs = append(pendingTxs, tx)
  100. }
  101. }
  102. fetchedTxs, err := l2DB.GetPendingTxs()
  103. assert.NoError(t, err)
  104. assert.Equal(t, len(pendingTxs), len(fetchedTxs))
  105. for i := range fetchedTxs {
  106. assertTx(t, pendingTxs[i], &fetchedTxs[i])
  107. }
  108. }
  109. func TestStartForging(t *testing.T) {
  110. // Generate txs
  111. const nInserts = 60
  112. const fakeBatchNum common.BatchNum = 33
  113. test.CleanL2DB(l2DB.DB())
  114. txs := test.GenPoolTxs(nInserts, tokens)
  115. var startForgingTxIDs []common.TxID
  116. randomizer := 0
  117. // Add txs to DB
  118. for _, tx := range txs {
  119. err := l2DB.AddTxTest(tx)
  120. assert.NoError(t, err)
  121. if tx.State == common.PoolL2TxStatePending && randomizer%2 == 0 {
  122. randomizer++
  123. startForgingTxIDs = append(startForgingTxIDs, tx.TxID)
  124. }
  125. }
  126. // Start forging txs
  127. err := l2DB.StartForging(startForgingTxIDs, fakeBatchNum)
  128. assert.NoError(t, err)
  129. // Fetch txs and check that they've been updated correctly
  130. for _, id := range startForgingTxIDs {
  131. fetchedTx, err := l2DB.GetTx(id)
  132. assert.NoError(t, err)
  133. assert.Equal(t, common.PoolL2TxStateForging, fetchedTx.State)
  134. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  135. }
  136. }
  137. func TestDoneForging(t *testing.T) {
  138. // Generate txs
  139. const nInserts = 60
  140. const fakeBatchNum common.BatchNum = 33
  141. test.CleanL2DB(l2DB.DB())
  142. txs := test.GenPoolTxs(nInserts, tokens)
  143. var doneForgingTxIDs []common.TxID
  144. randomizer := 0
  145. // Add txs to DB
  146. for _, tx := range txs {
  147. err := l2DB.AddTxTest(tx)
  148. assert.NoError(t, err)
  149. if tx.State == common.PoolL2TxStateForging && randomizer%2 == 0 {
  150. randomizer++
  151. doneForgingTxIDs = append(doneForgingTxIDs, tx.TxID)
  152. }
  153. }
  154. // Start forging txs
  155. err := l2DB.DoneForging(doneForgingTxIDs, fakeBatchNum)
  156. assert.NoError(t, err)
  157. // Fetch txs and check that they've been updated correctly
  158. for _, id := range doneForgingTxIDs {
  159. fetchedTx, err := l2DB.GetTx(id)
  160. assert.NoError(t, err)
  161. assert.Equal(t, common.PoolL2TxStateForged, fetchedTx.State)
  162. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  163. }
  164. }
  165. func TestInvalidate(t *testing.T) {
  166. // Generate txs
  167. const nInserts = 60
  168. const fakeBatchNum common.BatchNum = 33
  169. test.CleanL2DB(l2DB.DB())
  170. txs := test.GenPoolTxs(nInserts, tokens)
  171. var invalidTxIDs []common.TxID
  172. randomizer := 0
  173. // Add txs to DB
  174. for _, tx := range txs {
  175. err := l2DB.AddTxTest(tx)
  176. assert.NoError(t, err)
  177. if tx.State != common.PoolL2TxStateInvalid && randomizer%2 == 0 {
  178. randomizer++
  179. invalidTxIDs = append(invalidTxIDs, tx.TxID)
  180. }
  181. }
  182. // Start forging txs
  183. err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  184. assert.NoError(t, err)
  185. // Fetch txs and check that they've been updated correctly
  186. for _, id := range invalidTxIDs {
  187. fetchedTx, err := l2DB.GetTx(id)
  188. assert.NoError(t, err)
  189. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  190. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  191. }
  192. }
  193. func TestCheckNonces(t *testing.T) {
  194. // Generate txs
  195. const nInserts = 60
  196. const fakeBatchNum common.BatchNum = 33
  197. test.CleanL2DB(l2DB.DB())
  198. txs := test.GenPoolTxs(nInserts, tokens)
  199. var invalidTxIDs []common.TxID
  200. // Generate accounts
  201. const nAccoutns = 2
  202. const currentNonce = 2
  203. accs := []common.Account{}
  204. for i := 0; i < nAccoutns; i++ {
  205. accs = append(accs, common.Account{
  206. Idx: common.Idx(i),
  207. Nonce: currentNonce,
  208. })
  209. }
  210. // Add txs to DB
  211. for i := 0; i < len(txs); i++ {
  212. if txs[i].State != common.PoolL2TxStateInvalid {
  213. if i%2 == 0 { // Ensure transaction will be marked as invalid due to old nonce
  214. txs[i].Nonce = accs[i%len(accs)].Nonce
  215. txs[i].FromIdx = accs[i%len(accs)].Idx
  216. invalidTxIDs = append(invalidTxIDs, txs[i].TxID)
  217. } else { // Ensure transaction will NOT be marked as invalid due to old nonce
  218. txs[i].Nonce = currentNonce + 1
  219. }
  220. }
  221. err := l2DB.AddTxTest(txs[i])
  222. assert.NoError(t, err)
  223. }
  224. // Start forging txs
  225. err := l2DB.InvalidateTxs(invalidTxIDs, fakeBatchNum)
  226. assert.NoError(t, err)
  227. // Fetch txs and check that they've been updated correctly
  228. for _, id := range invalidTxIDs {
  229. fetchedTx, err := l2DB.GetTx(id)
  230. assert.NoError(t, err)
  231. assert.Equal(t, common.PoolL2TxStateInvalid, fetchedTx.State)
  232. assert.Equal(t, fakeBatchNum, *fetchedTx.BatchNum)
  233. }
  234. }
  235. func TestReorg(t *testing.T) {
  236. // Generate txs
  237. const nInserts = 20
  238. const lastValidBatch common.BatchNum = 20
  239. const reorgBatch common.BatchNum = lastValidBatch + 1
  240. test.CleanL2DB(l2DB.DB())
  241. txs := test.GenPoolTxs(nInserts, tokens)
  242. // Add txs to the DB
  243. reorgedTxIDs := []common.TxID{}
  244. nonReorgedTxIDs := []common.TxID{}
  245. for i := 0; i < len(txs); i++ {
  246. txs[i].BatchNum = new(common.BatchNum)
  247. if txs[i].State == common.PoolL2TxStateForged || txs[i].State == common.PoolL2TxStateInvalid {
  248. *txs[i].BatchNum = reorgBatch
  249. reorgedTxIDs = append(reorgedTxIDs, txs[i].TxID)
  250. } else {
  251. *txs[i].BatchNum = lastValidBatch
  252. nonReorgedTxIDs = append(nonReorgedTxIDs, txs[i].TxID)
  253. }
  254. err := l2DB.AddTxTest(txs[i])
  255. assert.NoError(t, err)
  256. }
  257. err := l2DB.Reorg(lastValidBatch)
  258. assert.NoError(t, err)
  259. for _, id := range reorgedTxIDs {
  260. tx, err := l2DB.GetTx(id)
  261. assert.NoError(t, err)
  262. assert.Nil(t, tx.BatchNum)
  263. assert.Equal(t, common.PoolL2TxStatePending, tx.State)
  264. }
  265. for _, id := range nonReorgedTxIDs {
  266. tx, err := l2DB.GetTx(id)
  267. assert.NoError(t, err)
  268. assert.Equal(t, lastValidBatch, *tx.BatchNum)
  269. }
  270. }
  271. func TestPurge(t *testing.T) {
  272. // Generate txs
  273. nInserts := l2DB.maxTxs + 20
  274. test.CleanL2DB(l2DB.DB())
  275. txs := test.GenPoolTxs(int(nInserts), tokens)
  276. deletedIDs := []common.TxID{}
  277. keepedIDs := []common.TxID{}
  278. const toDeleteBatchNum common.BatchNum = 30
  279. safeBatchNum := toDeleteBatchNum + l2DB.safetyPeriod + 1
  280. // Add txs to the DB
  281. for i := 0; i < int(l2DB.maxTxs); i++ {
  282. txs[i].BatchNum = new(common.BatchNum)
  283. if i%1 == 0 { // keep tx
  284. *txs[i].BatchNum = safeBatchNum
  285. keepedIDs = append(keepedIDs, txs[i].TxID)
  286. } else if i%2 == 0 { // delete after safety period
  287. *txs[i].BatchNum = toDeleteBatchNum
  288. if i%3 == 0 {
  289. txs[i].State = common.PoolL2TxStateForged
  290. } else {
  291. txs[i].State = common.PoolL2TxStateInvalid
  292. }
  293. deletedIDs = append(deletedIDs, txs[i].TxID)
  294. }
  295. err := l2DB.AddTxTest(txs[i])
  296. assert.NoError(t, err)
  297. }
  298. for i := int(l2DB.maxTxs); i < len(txs); i++ {
  299. // Delete after TTL
  300. txs[i].Timestamp = time.Unix(time.Now().UTC().Unix()-int64(l2DB.ttl.Seconds()+float64(4*time.Second)), 0)
  301. deletedIDs = append(deletedIDs, txs[i].TxID)
  302. err := l2DB.AddTxTest(txs[i])
  303. assert.NoError(t, err)
  304. }
  305. // Purge txs
  306. err := l2DB.Purge(safeBatchNum - 1)
  307. assert.NoError(t, err)
  308. // Check results
  309. for _, id := range deletedIDs {
  310. tx, err := l2DB.GetTx(id)
  311. if err == nil {
  312. log.Debug(tx)
  313. }
  314. assert.Error(t, err)
  315. }
  316. for _, id := range keepedIDs {
  317. _, err := l2DB.GetTx(id)
  318. assert.NoError(t, err)
  319. }
  320. }
  321. func TestAuth(t *testing.T) {
  322. test.CleanL2DB(l2DB.DB())
  323. const nAuths = 5
  324. // Generate authorizations
  325. auths := test.GenAuths(nAuths)
  326. for i := 0; i < len(auths); i++ {
  327. // Add to the DB
  328. err := l2DB.AddAccountCreationAuth(auths[i])
  329. assert.NoError(t, err)
  330. // Fetch from DB
  331. auth, err := l2DB.GetAccountCreationAuth(&auths[i].EthAddr)
  332. assert.NoError(t, err)
  333. // Check fetched vs generated
  334. assert.Equal(t, auths[i].EthAddr, auth.EthAddr)
  335. assert.Equal(t, auths[i].BJJ, auth.BJJ)
  336. assert.Equal(t, auths[i].Signature, auth.Signature)
  337. assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix())
  338. }
  339. }