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.

297 lines
7.8 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
  1. package node
  2. import (
  3. "context"
  4. "time"
  5. "github.com/ethereum/go-ethereum/ethclient"
  6. "github.com/hermeznetwork/hermez-node/batchbuilder"
  7. "github.com/hermeznetwork/hermez-node/common"
  8. "github.com/hermeznetwork/hermez-node/config"
  9. "github.com/hermeznetwork/hermez-node/coordinator"
  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/eth"
  15. "github.com/hermeznetwork/hermez-node/log"
  16. "github.com/hermeznetwork/hermez-node/synchronizer"
  17. "github.com/hermeznetwork/hermez-node/txselector"
  18. "github.com/jmoiron/sqlx"
  19. )
  20. // Mode sets the working mode of the node (synchronizer or coordinator)
  21. type Mode string
  22. const (
  23. // ModeCoordinator defines the mode of the HermezNode as Coordinator, which
  24. // means that the node is set to forge (which also will be synchronizing with
  25. // the L1 blockchain state)
  26. ModeCoordinator Mode = "coordinator"
  27. // ModeSynchronizer defines the mode of the HermezNode as Synchronizer, which
  28. // means that the node is set to only synchronize with the L1 blockchain state
  29. // and will not forge
  30. ModeSynchronizer Mode = "synchronizer"
  31. )
  32. // Node is the Hermez Node
  33. type Node struct {
  34. // Coordinator
  35. coord *coordinator.Coordinator
  36. coordCfg *config.Coordinator
  37. stopForge chan bool
  38. stopGetProofCallForge chan bool
  39. stopForgeCallConfirm chan bool
  40. stoppedForge chan bool
  41. stoppedGetProofCallForge chan bool
  42. stoppedForgeCallConfirm chan bool
  43. // Synchronizer
  44. sync *synchronizer.Synchronizer
  45. stoppedSync chan bool
  46. // General
  47. cfg *config.Node
  48. mode Mode
  49. sqlConn *sqlx.DB
  50. ctx context.Context
  51. cancel context.CancelFunc
  52. }
  53. // NewNode creates a Node
  54. func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node, error) {
  55. // Stablish DB connection
  56. db, err := dbUtils.InitSQLDB(
  57. cfg.PostgreSQL.Port,
  58. cfg.PostgreSQL.Host,
  59. cfg.PostgreSQL.User,
  60. cfg.PostgreSQL.Password,
  61. cfg.PostgreSQL.Name,
  62. )
  63. if err != nil {
  64. return nil, err
  65. }
  66. historyDB := historydb.NewHistoryDB(db)
  67. stateDB, err := statedb.NewStateDB(cfg.StateDB.Path, statedb.TypeSynchronizer, 32)
  68. if err != nil {
  69. return nil, err
  70. }
  71. ethClient, err := ethclient.Dial(cfg.Web3.URL)
  72. if err != nil {
  73. return nil, err
  74. }
  75. client, err := eth.NewClient(ethClient, nil, nil, &eth.ClientConfig{
  76. Ethereum: eth.EthereumConfig{
  77. CallGasLimit: cfg.EthClient.CallGasLimit,
  78. DeployGasLimit: cfg.EthClient.DeployGasLimit,
  79. GasPriceDiv: cfg.EthClient.GasPriceDiv,
  80. ReceiptTimeout: cfg.EthClient.ReceiptTimeout.Duration,
  81. IntervalReceiptLoop: cfg.EthClient.IntervalReceiptLoop.Duration,
  82. },
  83. Rollup: eth.RollupConfig{
  84. Address: cfg.SmartContracts.Rollup,
  85. },
  86. Auction: eth.AuctionConfig{
  87. Address: cfg.SmartContracts.Auction,
  88. TokenHEZAddress: cfg.SmartContracts.TokenHEZ,
  89. },
  90. })
  91. if err != nil {
  92. return nil, err
  93. }
  94. sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB)
  95. if err != nil {
  96. return nil, err
  97. }
  98. var coord *coordinator.Coordinator
  99. if mode == ModeCoordinator {
  100. l2DB := l2db.NewL2DB(
  101. db,
  102. coordCfg.L2DB.SafetyPeriod,
  103. coordCfg.L2DB.MaxTxs,
  104. coordCfg.L2DB.TTL.Duration,
  105. )
  106. // TODO: Get (maxL1UserTxs, maxL1OperatorTxs, maxTxs) from the smart contract
  107. txSelector, err := txselector.NewTxSelector(coordCfg.TxSelector.Path, stateDB, l2DB, 10, 10, 10)
  108. if err != nil {
  109. return nil, err
  110. }
  111. // TODO: Get (configCircuits []ConfigCircuit, batchNum common.BatchNum, nLevels uint64) from smart contract
  112. nLevels := uint64(32) //nolint:gomnd
  113. batchBuilder, err := batchbuilder.NewBatchBuilder(coordCfg.BatchBuilder.Path, stateDB, nil, 0, nLevels)
  114. if err != nil {
  115. return nil, err
  116. }
  117. if err != nil {
  118. return nil, err
  119. }
  120. serverProofs := make([]coordinator.ServerProofInterface, len(coordCfg.ServerProofs))
  121. for i, serverProofCfg := range coordCfg.ServerProofs {
  122. serverProofs[i] = coordinator.NewServerProof(serverProofCfg.URL)
  123. }
  124. coord = coordinator.NewCoordinator(
  125. coordinator.Config{
  126. ForgerAddress: coordCfg.ForgerAddress,
  127. },
  128. historyDB,
  129. txSelector,
  130. batchBuilder,
  131. serverProofs,
  132. client,
  133. )
  134. }
  135. ctx, cancel := context.WithCancel(context.Background())
  136. return &Node{
  137. coord: coord,
  138. coordCfg: coordCfg,
  139. sync: sync,
  140. cfg: cfg,
  141. mode: mode,
  142. sqlConn: db,
  143. ctx: ctx,
  144. cancel: cancel,
  145. }, nil
  146. }
  147. // StartCoordinator starts the coordinator
  148. func (n *Node) StartCoordinator() {
  149. log.Info("Starting Coordinator...")
  150. n.stopForge = make(chan bool)
  151. n.stopGetProofCallForge = make(chan bool)
  152. n.stopForgeCallConfirm = make(chan bool)
  153. n.stoppedForge = make(chan bool)
  154. n.stoppedGetProofCallForge = make(chan bool)
  155. n.stoppedForgeCallConfirm = make(chan bool)
  156. queueSize := 1
  157. batchCh0 := make(chan *coordinator.BatchInfo, queueSize)
  158. batchCh1 := make(chan *coordinator.BatchInfo, queueSize)
  159. go func() {
  160. defer func() { n.stoppedForge <- true }()
  161. for {
  162. select {
  163. case <-n.stopForge:
  164. return
  165. default:
  166. if forge, err := n.coord.ForgeLoopFn(batchCh0, n.stopForge); err == coordinator.ErrStop {
  167. return
  168. } else if err != nil {
  169. log.Errorw("Coordinator.ForgeLoopFn", "error", err)
  170. } else if !forge {
  171. time.Sleep(n.coordCfg.ForgeLoopInterval.Duration)
  172. }
  173. }
  174. }
  175. }()
  176. go func() {
  177. defer func() { n.stoppedGetProofCallForge <- true }()
  178. for {
  179. select {
  180. case <-n.stopGetProofCallForge:
  181. return
  182. default:
  183. if err := n.coord.GetProofCallForgeLoopFn(
  184. batchCh0, batchCh1, n.stopGetProofCallForge); err == coordinator.ErrStop {
  185. return
  186. } else if err != nil {
  187. log.Errorw("Coordinator.GetProofCallForgeLoopFn", "error", err)
  188. }
  189. }
  190. }
  191. }()
  192. go func() {
  193. defer func() { n.stoppedForgeCallConfirm <- true }()
  194. for {
  195. select {
  196. case <-n.stopForgeCallConfirm:
  197. return
  198. default:
  199. if err := n.coord.ForgeCallConfirmLoopFn(
  200. batchCh1, n.stopForgeCallConfirm); err == coordinator.ErrStop {
  201. return
  202. } else if err != nil {
  203. log.Errorw("Coordinator.ForgeCallConfirmLoopFn", "error", err)
  204. }
  205. }
  206. }
  207. }()
  208. }
  209. // StopCoordinator stops the coordinator
  210. func (n *Node) StopCoordinator() {
  211. log.Info("Stopping Coordinator...")
  212. n.stopForge <- true
  213. n.stopGetProofCallForge <- true
  214. n.stopForgeCallConfirm <- true
  215. <-n.stoppedForge
  216. <-n.stoppedGetProofCallForge
  217. <-n.stoppedForgeCallConfirm
  218. }
  219. // StartSynchronizer starts the synchronizer
  220. func (n *Node) StartSynchronizer() {
  221. log.Info("Starting Synchronizer...")
  222. n.stoppedSync = make(chan bool)
  223. go func() {
  224. defer func() { n.stoppedSync <- true }()
  225. var lastBlock *common.Block
  226. d := time.Duration(0)
  227. for {
  228. select {
  229. case <-n.ctx.Done():
  230. log.Info("Coordinator stopped")
  231. return
  232. case <-time.After(d):
  233. if blockData, discarded, err := n.sync.Sync2(n.ctx, lastBlock); err != nil {
  234. log.Errorw("Synchronizer.Sync", "error", err)
  235. lastBlock = nil
  236. d = n.cfg.Synchronizer.SyncLoopInterval.Duration
  237. } else if discarded != nil {
  238. log.Infow("Synchronizer.Sync reorg", "discarded", *discarded)
  239. lastBlock = nil
  240. d = time.Duration(0)
  241. } else if blockData != nil {
  242. lastBlock = &blockData.Block
  243. d = time.Duration(0)
  244. } else {
  245. d = n.cfg.Synchronizer.SyncLoopInterval.Duration
  246. }
  247. }
  248. }
  249. }()
  250. // TODO: Run price updater. This is required by the API and the TxSelector
  251. }
  252. // WaitStopSynchronizer waits for the synchronizer to stop
  253. func (n *Node) WaitStopSynchronizer() {
  254. log.Info("Waiting for Synchronizer to stop...")
  255. <-n.stoppedSync
  256. }
  257. // Start the node
  258. func (n *Node) Start() {
  259. log.Infow("Starting node...", "mode", n.mode)
  260. if n.mode == ModeCoordinator {
  261. n.StartCoordinator()
  262. }
  263. n.StartSynchronizer()
  264. }
  265. // Stop the node
  266. func (n *Node) Stop() {
  267. log.Infow("Stopping node...")
  268. n.cancel()
  269. if n.mode == ModeCoordinator {
  270. n.StopCoordinator()
  271. }
  272. n.WaitStopSynchronizer()
  273. }