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.

174 lines
5.5 KiB

Update coordinator, call all api update functions - Common: - Rename Block.EthBlockNum to Block.Num to avoid unneeded repetition - API: - Add UpdateNetworkInfoBlock to update just block information, to be used when the node is not yet synchronized - Node: - Call API.UpdateMetrics and UpdateRecommendedFee in a loop, with configurable time intervals - Synchronizer: - When mapping events by TxHash, use an array to support the possibility of multiple calls of the same function happening in the same transaction (for example, a smart contract in a single transaction could call withdraw with delay twice, which would generate 2 withdraw events, and 2 deposit events). - In Stats, keep entire LastBlock instead of just the blockNum - In Stats, add lastL1BatchBlock - Test Stats and SCVars - Coordinator: - Enable writing the BatchInfo in every step of the pipeline to disk (with JSON text files) for debugging purposes. - Move the Pipeline functionality from the Coordinator to its own struct (Pipeline) - Implement shouldL1lL2Batch - In TxManager, implement logic to perform several attempts when doing ethereum node RPC calls before considering the error. (Both for calls to forgeBatch and transaction receipt) - In TxManager, reorganize the flow and note the specific points in which actions are made when err != nil - HistoryDB: - Implement GetLastL1BatchBlockNum: returns the blockNum of the latest forged l1Batch, to help the coordinator decide when to forge an L1Batch. - EthereumClient and test.Client: - Update EthBlockByNumber to return the last block when the passed number is -1.
4 years ago
  1. package txselector
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "strconv"
  6. "testing"
  7. "time"
  8. ethCommon "github.com/ethereum/go-ethereum/common"
  9. "github.com/hermeznetwork/hermez-node/common"
  10. dbUtils "github.com/hermeznetwork/hermez-node/db"
  11. "github.com/hermeznetwork/hermez-node/db/historydb"
  12. "github.com/hermeznetwork/hermez-node/db/l2db"
  13. "github.com/hermeznetwork/hermez-node/db/statedb"
  14. "github.com/hermeznetwork/hermez-node/test"
  15. "github.com/hermeznetwork/hermez-node/test/til"
  16. "github.com/hermeznetwork/hermez-node/txprocessor"
  17. "github.com/jmoiron/sqlx"
  18. "github.com/stretchr/testify/assert"
  19. "github.com/stretchr/testify/require"
  20. )
  21. func initTest(t *testing.T, chainID uint16, testSet string) *TxSelector {
  22. pass := os.Getenv("POSTGRES_PASS")
  23. db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  24. require.NoError(t, err)
  25. l2DB := l2db.NewL2DB(db, 10, 100, 24*time.Hour)
  26. dir, err := ioutil.TempDir("", "tmpdb")
  27. require.NoError(t, err)
  28. defer assert.NoError(t, os.RemoveAll(dir))
  29. sdb, err := statedb.NewStateDB(dir, 128, statedb.TypeTxSelector, 0)
  30. require.NoError(t, err)
  31. txselDir, err := ioutil.TempDir("", "tmpTxSelDB")
  32. require.NoError(t, err)
  33. defer assert.NoError(t, os.RemoveAll(dir))
  34. coordAccount := &CoordAccount{ // TODO TMP
  35. Addr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  36. BJJ: common.EmptyBJJComp,
  37. AccountCreationAuth: nil,
  38. }
  39. txsel, err := NewTxSelector(coordAccount, txselDir, sdb, l2DB)
  40. require.NoError(t, err)
  41. return txsel
  42. }
  43. func addL2Txs(t *testing.T, txsel *TxSelector, poolL2Txs []common.PoolL2Tx) {
  44. for i := 0; i < len(poolL2Txs); i++ {
  45. err := txsel.l2db.AddTxTest(&poolL2Txs[i])
  46. require.NoError(t, err)
  47. }
  48. }
  49. func addTokens(t *testing.T, tokens []common.Token, db *sqlx.DB) {
  50. hdb := historydb.NewHistoryDB(db)
  51. test.WipeDB(hdb.DB())
  52. assert.NoError(t, hdb.AddBlock(&common.Block{
  53. Num: 1,
  54. }))
  55. assert.NoError(t, hdb.AddTokens(tokens))
  56. }
  57. func TestCoordIdxsDB(t *testing.T) {
  58. chainID := uint16(0)
  59. txsel := initTest(t, chainID, til.SetPool0)
  60. test.WipeDB(txsel.l2db.DB())
  61. coordIdxs := make(map[common.TokenID]common.Idx)
  62. coordIdxs[common.TokenID(0)] = common.Idx(256)
  63. coordIdxs[common.TokenID(1)] = common.Idx(257)
  64. coordIdxs[common.TokenID(2)] = common.Idx(258)
  65. err := txsel.AddCoordIdxs(coordIdxs)
  66. assert.NoError(t, err)
  67. r, err := txsel.GetCoordIdxs()
  68. assert.NoError(t, err)
  69. assert.Equal(t, coordIdxs, r)
  70. }
  71. func TestGetL2TxSelection(t *testing.T) {
  72. chainID := uint16(0)
  73. txsel := initTest(t, chainID, til.SetPool0)
  74. test.WipeDB(txsel.l2db.DB())
  75. tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
  76. // generate test transactions
  77. blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
  78. assert.NoError(t, err)
  79. // poolL2Txs, err := tc.GeneratePoolL2Txs(til.SetPool0)
  80. // assert.NoError(t, err)
  81. coordIdxs := make(map[common.TokenID]common.Idx)
  82. coordIdxs[common.TokenID(0)] = common.Idx(256)
  83. coordIdxs[common.TokenID(1)] = common.Idx(257)
  84. coordIdxs[common.TokenID(2)] = common.Idx(258)
  85. coordIdxs[common.TokenID(3)] = common.Idx(259)
  86. err = txsel.AddCoordIdxs(coordIdxs)
  87. assert.NoError(t, err)
  88. // add tokens to HistoryDB to avoid breaking FK constrains
  89. var tokens []common.Token
  90. for i := 0; i < int(tc.LastRegisteredTokenID); i++ {
  91. tokens = append(tokens, common.Token{
  92. TokenID: common.TokenID(i + 1),
  93. EthBlockNum: 1,
  94. EthAddr: ethCommon.BytesToAddress([]byte{byte(i + 1)}),
  95. Name: strconv.Itoa(i),
  96. Symbol: strconv.Itoa(i),
  97. Decimals: 18,
  98. })
  99. }
  100. addTokens(t, tokens, txsel.l2db.DB())
  101. tpc := txprocessor.Config{
  102. NLevels: 32,
  103. MaxFeeTx: 64,
  104. MaxTx: 512,
  105. MaxL1Tx: 64,
  106. ChainID: chainID,
  107. }
  108. selectionConfig := &SelectionConfig{
  109. MaxL1UserTxs: 32,
  110. MaxL1CoordinatorTxs: 32,
  111. TxProcessorConfig: tpc,
  112. }
  113. txselStateDB := txsel.localAccountsDB.StateDB
  114. tp := txprocessor.NewTxProcessor(txselStateDB, selectionConfig.TxProcessorConfig)
  115. // Process the 1st batch, which contains the L1CoordinatorTxs necessary
  116. // to create the Coordinator accounts to receive the fees
  117. _, err = tp.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
  118. require.NoError(t, err)
  119. // add the 1st batch of transactions to the TxSelector
  120. addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[0].L2Txs))
  121. _, _, l1CoordTxs, l2Txs, err := txsel.GetL2TxSelection(selectionConfig, 0)
  122. assert.NoError(t, err)
  123. assert.Equal(t, 0, len(l2Txs))
  124. assert.Equal(t, 0, len(l1CoordTxs))
  125. _, _, _, _, _, err = txsel.GetL1L2TxSelection(selectionConfig, 0, blocks[0].Rollup.L1UserTxs)
  126. assert.NoError(t, err)
  127. // TODO once L2DB is updated to return error in case that AddTxTest
  128. // fails, and the Til is updated, update this test, checking that the
  129. // selected PoolL2Tx are correctly sorted by Nonce
  130. // TODO once L2DB is updated to store the parameter AbsoluteFee (which
  131. // is used by TxSelector to sort L2Txs), uncomment this next lines of
  132. // test, and put the expected value for
  133. // l2Txs[len(l2Txs)-1].AbsoluteFee, which is the Tx which has the
  134. // Fee==192.
  135. /*
  136. // add the 3rd batch of transactions to the TxSelector
  137. addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs))
  138. _, l2Txs, err = txsel.GetL2TxSelection(coordIdxs, 0)
  139. assert.NoError(t, err)
  140. for _, tx := range l2Txs {
  141. fmt.Println(tx.FromIdx, tx.ToIdx, tx.AbsoluteFee)
  142. }
  143. require.Equal(t, 10, len(l2Txs))
  144. assert.Equal(t, float64(0), l2Txs[0].AbsoluteFee)
  145. fmt.Println(l2Txs[len(l2Txs)-1].Amount)
  146. assert.Equal(t, float64(4), l2Txs[len(l2Txs)-1].AbsoluteFee)
  147. */
  148. }