code.vegaprotocol.io/vega@v0.79.0/core/blockchain/abci/tm_node.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package abci
    17  
    18  import (
    19  	"fmt"
    20  
    21  	"code.vegaprotocol.io/vega/core/blockchain"
    22  	"code.vegaprotocol.io/vega/logging"
    23  
    24  	"github.com/cometbft/cometbft/abci/types"
    25  	"github.com/cometbft/cometbft/config"
    26  	bftconfig "github.com/cometbft/cometbft/config"
    27  	"github.com/cometbft/cometbft/libs/service"
    28  	nm "github.com/cometbft/cometbft/node"
    29  	"github.com/cometbft/cometbft/p2p"
    30  	"github.com/cometbft/cometbft/privval"
    31  	"github.com/cometbft/cometbft/proxy"
    32  	tmtypes "github.com/cometbft/cometbft/types"
    33  	"github.com/spf13/viper"
    34  )
    35  
    36  type TmNode struct {
    37  	conf        blockchain.Config
    38  	node        service.Service
    39  	MempoolSize int64
    40  }
    41  
    42  const namedLogger = "tendermint"
    43  
    44  func NewTmNode(
    45  	conf blockchain.Config,
    46  	log *logging.Logger,
    47  	homeDir string,
    48  	app types.Application,
    49  	genesisDoc *tmtypes.GenesisDoc,
    50  ) (*TmNode, error) {
    51  	log = log.Named(namedLogger)
    52  	log.SetLevel(conf.Tendermint.Level.Get())
    53  
    54  	config, err := loadConfig(homeDir)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	viper.SetConfigFile(fmt.Sprintf("%s/%s", homeDir, "config/config.toml"))
    60  	if err := viper.ReadInConfig(); err != nil {
    61  		return nil, fmt.Errorf("reading tendermint config: %v", err)
    62  	}
    63  	if err := viper.Unmarshal(config); err != nil {
    64  		return nil, fmt.Errorf("decoding tendermint config: %v", err)
    65  	}
    66  
    67  	overwriteConfig(config)
    68  
    69  	if err := config.ValidateBasic(); err != nil {
    70  		return nil, fmt.Errorf("invalid tendermint configuration data: %v", err)
    71  	}
    72  
    73  	if genesisDoc == nil {
    74  		genesisDoc, err = tmtypes.GenesisDocFromFile(config.GenesisFile())
    75  		if err != nil {
    76  			return nil, fmt.Errorf("loading tendermint genesis document: %v", err)
    77  		}
    78  	}
    79  
    80  	genesisDocProvider := func() (*tmtypes.GenesisDoc, error) {
    81  		return genesisDoc, nil
    82  	}
    83  
    84  	// read private validator
    85  	pv := privval.LoadFilePV(
    86  		config.PrivValidatorKeyFile(),
    87  		config.PrivValidatorStateFile(),
    88  	)
    89  
    90  	// read node key
    91  	nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile())
    92  	if err != nil {
    93  		return nil, fmt.Errorf("failed to load node's key: %w", err)
    94  	}
    95  
    96  	// create logger
    97  	logger := &TmLogger{log.ToSugared()}
    98  
    99  	// create node
   100  	node, err := nm.NewNode(
   101  		config,
   102  		pv,
   103  		nodeKey,
   104  		proxy.NewLocalClientCreator(app),
   105  		genesisDocProvider,
   106  		bftconfig.DefaultDBProvider,
   107  		nm.DefaultMetricsProvider(config.Instrumentation),
   108  		logger)
   109  	if err != nil {
   110  		return nil, fmt.Errorf("failed to create new Tendermint node: %w", err)
   111  	}
   112  
   113  	// acc := abciclient.NewLocalCreator(app)
   114  	// node, err := nm.New(config, logger, acc, genesisDoc)
   115  	// if err != nil {
   116  	// 	return nil, fmt.Errorf("creating tendermint node: %v", err)
   117  	// }
   118  
   119  	return &TmNode{conf, node, config.Mempool.MaxTxsBytes}, nil
   120  }
   121  
   122  func (*TmNode) ReloadConf(cfg blockchain.Config) {
   123  }
   124  
   125  func (t *TmNode) GetClient() (*LocalClient, error) {
   126  	return newLocalClient(t.node)
   127  }
   128  
   129  func (t *TmNode) Start() error {
   130  	return t.node.Start()
   131  }
   132  
   133  func (t *TmNode) Stop() error {
   134  	if t.node != nil && t.node.IsRunning() {
   135  		if err := t.node.Stop(); err != nil {
   136  			return err
   137  		}
   138  	}
   139  	<-t.node.Quit()
   140  	return nil
   141  }
   142  
   143  func loadConfig(homeDir string) (*config.Config, error) {
   144  	conf := config.DefaultConfig()
   145  	if err := viper.Unmarshal(conf); err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	conf.SetRoot(homeDir)
   150  	if err := conf.ValidateBasic(); err != nil {
   151  		return nil, fmt.Errorf("error in config file: %w", err)
   152  	}
   153  
   154  	return conf, nil
   155  }
   156  
   157  // we want to force validators to skip timeout on commit so they don't wait after consensus has been reached.
   158  func overwriteConfig(config *config.Config) {
   159  	config.Consensus.TimeoutCommit = 0
   160  	config.Consensus.CreateEmptyBlocks = true
   161  	// ensure rechecking tx is enabled
   162  	config.Mempool.Recheck = true
   163  	// enforce compatibility
   164  	config.P2P.MaxPacketMsgPayloadSize = 16384
   165  }