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.

333 lines
8.7 KiB

Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
  1. package node
  2. import (
  3. "context"
  4. "sync"
  5. "time"
  6. "github.com/ethereum/go-ethereum/ethclient"
  7. "github.com/hermeznetwork/hermez-node/batchbuilder"
  8. "github.com/hermeznetwork/hermez-node/common"
  9. "github.com/hermeznetwork/hermez-node/config"
  10. "github.com/hermeznetwork/hermez-node/coordinator"
  11. dbUtils "github.com/hermeznetwork/hermez-node/db"
  12. "github.com/hermeznetwork/hermez-node/db/historydb"
  13. "github.com/hermeznetwork/hermez-node/db/l2db"
  14. "github.com/hermeznetwork/hermez-node/db/statedb"
  15. "github.com/hermeznetwork/hermez-node/eth"
  16. "github.com/hermeznetwork/hermez-node/log"
  17. "github.com/hermeznetwork/hermez-node/synchronizer"
  18. "github.com/hermeznetwork/hermez-node/test/debugapi"
  19. "github.com/hermeznetwork/hermez-node/txselector"
  20. "github.com/jmoiron/sqlx"
  21. )
  22. // Mode sets the working mode of the node (synchronizer or coordinator)
  23. type Mode string
  24. const (
  25. // ModeCoordinator defines the mode of the HermezNode as Coordinator, which
  26. // means that the node is set to forge (which also will be synchronizing with
  27. // the L1 blockchain state)
  28. ModeCoordinator Mode = "coordinator"
  29. // ModeSynchronizer defines the mode of the HermezNode as Synchronizer, which
  30. // means that the node is set to only synchronize with the L1 blockchain state
  31. // and will not forge
  32. ModeSynchronizer Mode = "synchronizer"
  33. )
  34. // Node is the Hermez Node
  35. type Node struct {
  36. debugAPI *debugapi.DebugAPI
  37. // Coordinator
  38. coord *coordinator.Coordinator
  39. coordCfg *config.Coordinator
  40. stopForge chan bool
  41. stopGetProofCallForge chan bool
  42. stopForgeCallConfirm chan bool
  43. stoppedForge chan bool
  44. stoppedGetProofCallForge chan bool
  45. stoppedForgeCallConfirm chan bool
  46. // Synchronizer
  47. sync *synchronizer.Synchronizer
  48. // General
  49. cfg *config.Node
  50. mode Mode
  51. sqlConn *sqlx.DB
  52. ctx context.Context
  53. wg sync.WaitGroup
  54. cancel context.CancelFunc
  55. }
  56. // NewNode creates a Node
  57. func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node, error) {
  58. // Stablish DB connection
  59. db, err := dbUtils.InitSQLDB(
  60. cfg.PostgreSQL.Port,
  61. cfg.PostgreSQL.Host,
  62. cfg.PostgreSQL.User,
  63. cfg.PostgreSQL.Password,
  64. cfg.PostgreSQL.Name,
  65. )
  66. if err != nil {
  67. return nil, err
  68. }
  69. historyDB := historydb.NewHistoryDB(db)
  70. stateDB, err := statedb.NewStateDB(cfg.StateDB.Path, statedb.TypeSynchronizer, 32)
  71. if err != nil {
  72. return nil, err
  73. }
  74. ethClient, err := ethclient.Dial(cfg.Web3.URL)
  75. if err != nil {
  76. return nil, err
  77. }
  78. client, err := eth.NewClient(ethClient, nil, nil, &eth.ClientConfig{
  79. Ethereum: eth.EthereumConfig{
  80. CallGasLimit: cfg.EthClient.CallGasLimit,
  81. DeployGasLimit: cfg.EthClient.DeployGasLimit,
  82. GasPriceDiv: cfg.EthClient.GasPriceDiv,
  83. ReceiptTimeout: cfg.EthClient.ReceiptTimeout.Duration,
  84. IntervalReceiptLoop: cfg.EthClient.IntervalReceiptLoop.Duration,
  85. },
  86. Rollup: eth.RollupConfig{
  87. Address: cfg.SmartContracts.Rollup,
  88. },
  89. Auction: eth.AuctionConfig{
  90. Address: cfg.SmartContracts.Auction,
  91. TokenHEZ: eth.TokenConfig{
  92. Address: cfg.SmartContracts.TokenHEZ,
  93. Name: cfg.SmartContracts.TokenHEZName,
  94. },
  95. },
  96. WDelayer: eth.WDelayerConfig{
  97. Address: cfg.SmartContracts.WDelayer,
  98. },
  99. })
  100. if err != nil {
  101. return nil, err
  102. }
  103. sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
  104. StartBlockNum: cfg.Synchronizer.StartBlockNum,
  105. InitialVariables: cfg.Synchronizer.InitialVariables,
  106. StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration,
  107. })
  108. if err != nil {
  109. return nil, err
  110. }
  111. var coord *coordinator.Coordinator
  112. if mode == ModeCoordinator {
  113. l2DB := l2db.NewL2DB(
  114. db,
  115. coordCfg.L2DB.SafetyPeriod,
  116. coordCfg.L2DB.MaxTxs,
  117. coordCfg.L2DB.TTL.Duration,
  118. )
  119. // TODO: Get (maxL1UserTxs, maxL1OperatorTxs, maxTxs) from the smart contract
  120. txSelector, err := txselector.NewTxSelector(coordCfg.TxSelector.Path, stateDB, l2DB, 10, 10, 10)
  121. if err != nil {
  122. return nil, err
  123. }
  124. // TODO: Get (configCircuits []ConfigCircuit, batchNum common.BatchNum, nLevels uint64) from smart contract
  125. nLevels := uint64(32) //nolint:gomnd
  126. batchBuilder, err := batchbuilder.NewBatchBuilder(coordCfg.BatchBuilder.Path, stateDB, nil, 0, nLevels)
  127. if err != nil {
  128. return nil, err
  129. }
  130. if err != nil {
  131. return nil, err
  132. }
  133. serverProofs := make([]coordinator.ServerProofInterface, len(coordCfg.ServerProofs))
  134. for i, serverProofCfg := range coordCfg.ServerProofs {
  135. serverProofs[i] = coordinator.NewServerProof(serverProofCfg.URL)
  136. }
  137. coord = coordinator.NewCoordinator(
  138. coordinator.Config{
  139. ForgerAddress: coordCfg.ForgerAddress,
  140. },
  141. historyDB,
  142. txSelector,
  143. batchBuilder,
  144. serverProofs,
  145. client,
  146. )
  147. }
  148. var debugAPI *debugapi.DebugAPI
  149. if cfg.Debug.APIAddress != "" {
  150. debugAPI = debugapi.NewDebugAPI(cfg.Debug.APIAddress, stateDB, sync)
  151. }
  152. ctx, cancel := context.WithCancel(context.Background())
  153. return &Node{
  154. debugAPI: debugAPI,
  155. coord: coord,
  156. coordCfg: coordCfg,
  157. sync: sync,
  158. cfg: cfg,
  159. mode: mode,
  160. sqlConn: db,
  161. ctx: ctx,
  162. cancel: cancel,
  163. }, nil
  164. }
  165. // StartCoordinator starts the coordinator
  166. func (n *Node) StartCoordinator() {
  167. log.Info("Starting Coordinator...")
  168. // TODO: Replace stopXXX by context
  169. // TODO: Replace stoppedXXX by waitgroup
  170. n.stopForge = make(chan bool)
  171. n.stopGetProofCallForge = make(chan bool)
  172. n.stopForgeCallConfirm = make(chan bool)
  173. n.stoppedForge = make(chan bool, 1)
  174. n.stoppedGetProofCallForge = make(chan bool, 1)
  175. n.stoppedForgeCallConfirm = make(chan bool, 1)
  176. queueSize := 1
  177. batchCh0 := make(chan *coordinator.BatchInfo, queueSize)
  178. batchCh1 := make(chan *coordinator.BatchInfo, queueSize)
  179. go func() {
  180. defer func() { n.stoppedForge <- true }()
  181. for {
  182. select {
  183. case <-n.stopForge:
  184. return
  185. default:
  186. if forge, err := n.coord.ForgeLoopFn(batchCh0, n.stopForge); err == coordinator.ErrStop {
  187. return
  188. } else if err != nil {
  189. log.Errorw("Coordinator.ForgeLoopFn", "error", err)
  190. } else if !forge {
  191. time.Sleep(n.coordCfg.ForgeLoopInterval.Duration)
  192. }
  193. }
  194. }
  195. }()
  196. go func() {
  197. defer func() { n.stoppedGetProofCallForge <- true }()
  198. for {
  199. select {
  200. case <-n.stopGetProofCallForge:
  201. return
  202. default:
  203. if err := n.coord.GetProofCallForgeLoopFn(
  204. batchCh0, batchCh1, n.stopGetProofCallForge); err == coordinator.ErrStop {
  205. return
  206. } else if err != nil {
  207. log.Errorw("Coordinator.GetProofCallForgeLoopFn", "error", err)
  208. }
  209. }
  210. }
  211. }()
  212. go func() {
  213. defer func() { n.stoppedForgeCallConfirm <- true }()
  214. for {
  215. select {
  216. case <-n.stopForgeCallConfirm:
  217. return
  218. default:
  219. if err := n.coord.ForgeCallConfirmLoopFn(
  220. batchCh1, n.stopForgeCallConfirm); err == coordinator.ErrStop {
  221. return
  222. } else if err != nil {
  223. log.Errorw("Coordinator.ForgeCallConfirmLoopFn", "error", err)
  224. }
  225. }
  226. }
  227. }()
  228. }
  229. // StopCoordinator stops the coordinator
  230. func (n *Node) StopCoordinator() {
  231. log.Info("Stopping Coordinator...")
  232. n.stopForge <- true
  233. n.stopGetProofCallForge <- true
  234. n.stopForgeCallConfirm <- true
  235. <-n.stoppedForge
  236. <-n.stoppedGetProofCallForge
  237. <-n.stoppedForgeCallConfirm
  238. }
  239. // StartSynchronizer starts the synchronizer
  240. func (n *Node) StartSynchronizer() {
  241. log.Info("Starting Synchronizer...")
  242. n.wg.Add(1)
  243. go func() {
  244. defer func() {
  245. log.Info("Synchronizer routine stopped")
  246. n.wg.Done()
  247. }()
  248. var lastBlock *common.Block
  249. d := time.Duration(0)
  250. for {
  251. select {
  252. case <-n.ctx.Done():
  253. log.Info("Synchronizer done")
  254. return
  255. case <-time.After(d):
  256. if blockData, discarded, err := n.sync.Sync2(n.ctx, lastBlock); err != nil {
  257. log.Errorw("Synchronizer.Sync", "error", err)
  258. lastBlock = nil
  259. d = n.cfg.Synchronizer.SyncLoopInterval.Duration
  260. } else if discarded != nil {
  261. log.Infow("Synchronizer.Sync reorg", "discarded", *discarded)
  262. lastBlock = nil
  263. d = time.Duration(0)
  264. } else if blockData != nil {
  265. lastBlock = &blockData.Block
  266. d = time.Duration(0)
  267. } else {
  268. d = n.cfg.Synchronizer.SyncLoopInterval.Duration
  269. }
  270. }
  271. }
  272. }()
  273. // TODO: Run price updater. This is required by the API and the TxSelector
  274. }
  275. // StartDebugAPI starts the DebugAPI
  276. func (n *Node) StartDebugAPI() {
  277. log.Info("Starting DebugAPI...")
  278. n.wg.Add(1)
  279. go func() {
  280. defer func() {
  281. log.Info("DebugAPI routine stopped")
  282. n.wg.Done()
  283. }()
  284. if err := n.debugAPI.Run(n.ctx); err != nil {
  285. log.Fatalw("DebugAPI.Run", "err", err)
  286. }
  287. }()
  288. }
  289. // Start the node
  290. func (n *Node) Start() {
  291. log.Infow("Starting node...", "mode", n.mode)
  292. if n.debugAPI != nil {
  293. n.StartDebugAPI()
  294. }
  295. if n.mode == ModeCoordinator {
  296. n.StartCoordinator()
  297. }
  298. n.StartSynchronizer()
  299. }
  300. // Stop the node
  301. func (n *Node) Stop() {
  302. log.Infow("Stopping node...")
  303. n.cancel()
  304. if n.mode == ModeCoordinator {
  305. n.StopCoordinator()
  306. }
  307. n.wg.Wait()
  308. }