From 68c4e1716e790bfc9a7dfb1a6bbdf20345e1135a Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 5 Dec 2022 17:59:54 -0500 Subject: [PATCH 01/18] create cli flag for light mode --- config/config.go | 3 +++ config/defaults.go | 1 + 2 files changed, 4 insertions(+) diff --git a/config/config.go b/config/config.go index 8d1e43aac8..bc8f44c191 100644 --- a/config/config.go +++ b/config/config.go @@ -19,6 +19,7 @@ const ( flagDAStartHeight = "rollmint.da_start_height" flagNamespaceID = "rollmint.namespace_id" flagFraudProofs = "rollmint.experimental_insecure_fraud_proofs" + flagLight = "rollmint.light" ) // NodeConfig stores rollmint node configuration. @@ -33,6 +34,7 @@ type NodeConfig struct { BlockManagerConfig `mapstructure:",squash"` DALayer string `mapstructure:"da_layer"` DAConfig string `mapstructure:"da_config"` + Light bool `mapstructure:"light"` } // BlockManagerConfig consists of all parameters required by BlockManagerConfig @@ -80,4 +82,5 @@ func AddFlags(cmd *cobra.Command) { cmd.Flags().Uint64(flagDAStartHeight, def.DAStartHeight, "starting DA block height (for syncing)") cmd.Flags().BytesHex(flagNamespaceID, def.NamespaceID[:], "namespace identifies (8 bytes in hex)") cmd.Flags().Bool(flagFraudProofs, def.FraudProofs, "enable fraud proofs (experimental & insecure)") + cmd.Flags().Bool(flagLight, def.Light, "run as a light client") } diff --git a/config/defaults.go b/config/defaults.go index 6a12576498..9738ea770c 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -26,4 +26,5 @@ var DefaultNodeConfig = NodeConfig{ }, DALayer: "mock", DAConfig: "", + Light: false, } From 55b1c44793a64a5217c6f674d706455624d3ee76 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Tue, 6 Dec 2022 11:39:26 -0500 Subject: [PATCH 02/18] node interface --- node/node.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/node/node.go b/node/node.go index 52f434042d..87d76c94ec 100644 --- a/node/node.go +++ b/node/node.go @@ -46,9 +46,21 @@ const ( genesisChunkSize = 16 * 1024 * 1024 // 16 MiB ) +type Node interface { + AppClient() abciclient.Client + EventBus() *tmtypes.EventBus + GetLogger() log.Logger + SetLogger() + OnReset() error + OnStop() + OnStart() error + GetGenesisChunks() ([]string, error) + GetGenesis() *tmtypes.GenesisDoc +} + // Node represents a client node in rollmint network. // It connects all the components and orchestrates their work. -type Node struct { +type FullNode struct { service.BaseService eventBus *tmtypes.EventBus appClient abciclient.Client From d25e4477fa9e892084891c1df3a44a359116b10e Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Tue, 6 Dec 2022 18:58:13 -0500 Subject: [PATCH 03/18] changed some occurences of Node to FullNode --- node/node.go | 131 +++++++++++++++++++++++++++++++++++++------ rpc/client/client.go | 4 +- rpc/server.go | 2 +- 3 files changed, 117 insertions(+), 20 deletions(-) diff --git a/node/node.go b/node/node.go index 87d76c94ec..4c0c6b88b7 100644 --- a/node/node.go +++ b/node/node.go @@ -90,7 +90,90 @@ type FullNode struct { ctx context.Context } -// NewNode creates new rollmint node. +func newFullNode( + ctx context.Context, + conf config.NodeConfig, + p2pKey crypto.PrivKey, + signingKey crypto.PrivKey, + appClient abciclient.Client, + genesis *tmtypes.GenesisDoc, + logger log.Logger, +) (*FullNode, error) { + eventBus := tmtypes.NewEventBus() + eventBus.SetLogger(logger.With("module", "events")) + if err := eventBus.Start(); err != nil { + return nil, err + } + + client, err := p2p.NewClient(conf.P2P, p2pKey, genesis.ChainID, logger.With("module", "p2p")) + if err != nil { + return nil, err + } + + var baseKV store.KVStore + if conf.RootDir == "" && conf.DBPath == "" { // this is used for testing + logger.Info("WARNING: working in in-memory mode") + baseKV = store.NewDefaultInMemoryKVStore() + } else { + baseKV = store.NewDefaultKVStore(conf.RootDir, conf.DBPath, "rollmint") + } + mainKV := store.NewPrefixKV(baseKV, mainPrefix) + dalcKV := store.NewPrefixKV(baseKV, dalcPrefix) + indexerKV := store.NewPrefixKV(baseKV, indexerPrefix) + + s := store.New(mainKV) + + dalc := registry.GetClient(conf.DALayer) + if dalc == nil { + return nil, fmt.Errorf("couldn't get data availability client named '%s'", conf.DALayer) + } + err = dalc.Init(conf.NamespaceID, []byte(conf.DAConfig), dalcKV, logger.With("module", "da_client")) + if err != nil { + return nil, fmt.Errorf("data availability layer client initialization error: %w", err) + } + + indexerService, txIndexer, blockIndexer, err := createAndStartIndexerService(conf, indexerKV, eventBus, logger) + if err != nil { + return nil, err + } + + mp := mempoolv1.NewTxMempool(logger, llcfg.DefaultMempoolConfig(), appClient, 0) + mpIDs := newMempoolIDs() + + blockManager, err := block.NewManager(signingKey, conf.BlockManagerConfig, genesis, s, mp, appClient, dalc, eventBus, logger.With("module", "BlockManager")) + if err != nil { + return nil, fmt.Errorf("BlockManager initialization error: %w", err) + } + + node := &FullNode{ + appClient: appClient, + eventBus: eventBus, + genesis: genesis, + conf: conf, + P2P: client, + blockManager: blockManager, + dalc: dalc, + Mempool: mp, + mempoolIDs: mpIDs, + incomingTxCh: make(chan *p2p.GossipMessage), + Store: s, + TxIndexer: txIndexer, + IndexerService: indexerService, + BlockIndexer: blockIndexer, + ctx: ctx, + } + + node.BaseService = *service.NewBaseService(logger, "Node", node) + + node.P2P.SetTxValidator(node.newTxValidator()) + node.P2P.SetHeaderValidator(node.newHeaderValidator()) + node.P2P.SetCommitValidator(node.newCommitValidator()) + node.P2P.SetFraudProofValidator(node.newFraudProofValidator()) + + return node, nil + +} + func NewNode( ctx context.Context, conf config.NodeConfig, @@ -99,6 +182,20 @@ func NewNode( appClient abciclient.Client, genesis *tmtypes.GenesisDoc, logger log.Logger, +) (*FullNode, error) { + n, err := newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) + return n, err +} + +// NewNode creates new rollmint node. +/*func NewNode( + ctx context.Context, + conf config.NodeConfig, + p2pKey crypto.PrivKey, + signingKey crypto.PrivKey, + appClient abciclient.Client, + genesis *tmtypes.GenesisDoc, + logger log.Logger, ) (*Node, error) { eventBus := tmtypes.NewEventBus() eventBus.SetLogger(logger.With("module", "events")) @@ -172,11 +269,11 @@ func NewNode( node.P2P.SetFraudProofValidator(node.newFraudProofValidator()) return node, nil -} +}*/ // initGenesisChunks creates a chunked format of the genesis document to make it easier to // iterate through larger genesis structures. -func (n *Node) initGenesisChunks() error { +func (n *FullNode) initGenesisChunks() error { if n.genChunks != nil { return nil } @@ -203,7 +300,7 @@ func (n *Node) initGenesisChunks() error { return nil } -func (n *Node) headerPublishLoop(ctx context.Context) { +func (n *FullNode) headerPublishLoop(ctx context.Context) { for { select { case signedHeader := <-n.blockManager.HeaderOutCh: @@ -222,7 +319,7 @@ func (n *Node) headerPublishLoop(ctx context.Context) { } // OnStart is a part of Service interface. -func (n *Node) OnStart() error { +func (n *FullNode) OnStart() error { n.Logger.Info("starting P2P client") err := n.P2P.Start(n.ctx) if err != nil { @@ -244,12 +341,12 @@ func (n *Node) OnStart() error { } // GetGenesis returns entire genesis doc. -func (n *Node) GetGenesis() *tmtypes.GenesisDoc { +func (n *FullNode) GetGenesis() *tmtypes.GenesisDoc { return n.genesis } // GetGenesisChunks returns chunked version of genesis. -func (n *Node) GetGenesisChunks() ([]string, error) { +func (n *FullNode) GetGenesisChunks() ([]string, error) { err := n.initGenesisChunks() if err != nil { return nil, err @@ -258,40 +355,40 @@ func (n *Node) GetGenesisChunks() ([]string, error) { } // OnStop is a part of Service interface. -func (n *Node) OnStop() { +func (n *FullNode) OnStop() { err := n.dalc.Stop() err = multierr.Append(err, n.P2P.Close()) n.Logger.Error("errors while stopping node:", "errors", err) } // OnReset is a part of Service interface. -func (n *Node) OnReset() error { +func (n *FullNode) OnReset() error { panic("OnReset - not implemented!") } // SetLogger sets the logger used by node. -func (n *Node) SetLogger(logger log.Logger) { +func (n *FullNode) SetLogger(logger log.Logger) { n.Logger = logger } // GetLogger returns logger. -func (n *Node) GetLogger() log.Logger { +func (n *FullNode) GetLogger() log.Logger { return n.Logger } // EventBus gives access to Node's event bus. -func (n *Node) EventBus() *tmtypes.EventBus { +func (n *FullNode) EventBus() *tmtypes.EventBus { return n.eventBus } // AppClient returns ABCI proxy connections to communicate with application. -func (n *Node) AppClient() abciclient.Client { +func (n *FullNode) AppClient() abciclient.Client { return n.appClient } // newTxValidator creates a pubsub validator that uses the node's mempool to check the // transaction. If the transaction is valid, then it is added to the mempool -func (n *Node) newTxValidator() p2p.GossipValidator { +func (n *FullNode) newTxValidator() p2p.GossipValidator { return func(m *p2p.GossipMessage) bool { n.Logger.Debug("transaction received", "bytes", len(m.Data)) checkTxResCh := make(chan *abci.Response, 1) @@ -321,7 +418,7 @@ func (n *Node) newTxValidator() p2p.GossipValidator { // newHeaderValidator returns a pubsub validator that runs basic checks and forwards // the deserialized header for further processing -func (n *Node) newHeaderValidator() p2p.GossipValidator { +func (n *FullNode) newHeaderValidator() p2p.GossipValidator { return func(headerMsg *p2p.GossipMessage) bool { n.Logger.Debug("header received", "from", headerMsg.From, "bytes", len(headerMsg.Data)) var header types.SignedHeader @@ -342,7 +439,7 @@ func (n *Node) newHeaderValidator() p2p.GossipValidator { // newCommitValidator returns a pubsub validator that runs basic checks and forwards // the deserialized commit for further processing -func (n *Node) newCommitValidator() p2p.GossipValidator { +func (n *FullNode) newCommitValidator() p2p.GossipValidator { return func(commitMsg *p2p.GossipMessage) bool { n.Logger.Debug("commit received", "from", commitMsg.From, "bytes", len(commitMsg.Data)) var commit types.Commit @@ -364,7 +461,7 @@ func (n *Node) newCommitValidator() p2p.GossipValidator { // newFraudProofValidator returns a pubsub validator that validates a fraud proof and forwards // it to be verified -func (n *Node) newFraudProofValidator() p2p.GossipValidator { +func (n *FullNode) newFraudProofValidator() p2p.GossipValidator { return func(fraudProofMsg *p2p.GossipMessage) bool { n.Logger.Debug("fraud proof received", "from", fraudProofMsg.From, "bytes", len(fraudProofMsg.Data)) var fraudProof types.FraudProof diff --git a/rpc/client/client.go b/rpc/client/client.go index c51c127c72..9c712d5374 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -50,11 +50,11 @@ type Client struct { *types.EventBus config *config.RPCConfig - node *node.Node + node *node.FullNode } // NewClient returns Client working with given node. -func NewClient(node *node.Node) *Client { +func NewClient(node *node.FullNode) *Client { return &Client{ EventBus: node.EventBus(), config: config.DefaultRPCConfig(), diff --git a/rpc/server.go b/rpc/server.go index 3aa1b78381..503b8935c7 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -31,7 +31,7 @@ type Server struct { } // NewServer creates new instance of Server with given configuration. -func NewServer(node *node.Node, config *config.RPCConfig, logger log.Logger) *Server { +func NewServer(node *node.FullNode, config *config.RPCConfig, logger log.Logger) *Server { srv := &Server{ config: config, client: client.NewClient(node), From 160764a6e681d32884ef7d42b6a0bb15568ccf5b Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Wed, 7 Dec 2022 16:59:48 -0500 Subject: [PATCH 04/18] moved full node to its own file --- node/full_node.go | 138 ++++++++++++++++++++++++++++++ node/node.go | 210 +--------------------------------------------- 2 files changed, 141 insertions(+), 207 deletions(-) create mode 100644 node/full_node.go diff --git a/node/full_node.go b/node/full_node.go new file mode 100644 index 0000000000..3a24bf8a01 --- /dev/null +++ b/node/full_node.go @@ -0,0 +1,138 @@ +package node +import ( + "context" + "fmt" + + "github.com/libp2p/go-libp2p/core/crypto" + + abciclient "github.com/tendermint/tendermint/abci/client" + llcfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/service" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/celestiaorg/rollmint/block" + "github.com/celestiaorg/rollmint/config" + "github.com/celestiaorg/rollmint/da" + "github.com/celestiaorg/rollmint/da/registry" + "github.com/celestiaorg/rollmint/mempool" + mempoolv1 "github.com/celestiaorg/rollmint/mempool/v1" + "github.com/celestiaorg/rollmint/p2p" + "github.com/celestiaorg/rollmint/state/indexer" + "github.com/celestiaorg/rollmint/state/txindex" + "github.com/celestiaorg/rollmint/store" +) + +type FullNode struct { + service.BaseService + eventBus *tmtypes.EventBus + appClient abciclient.Client + + genesis *tmtypes.GenesisDoc + // cache of chunked genesis data. + genChunks []string + + conf config.NodeConfig + P2P *p2p.Client + + // TODO(tzdybal): consider extracting "mempool reactor" + Mempool mempool.Mempool + mempoolIDs *mempoolIDs + incomingTxCh chan *p2p.GossipMessage + + Store store.Store + blockManager *block.Manager + dalc da.DataAvailabilityLayerClient + + TxIndexer txindex.TxIndexer + BlockIndexer indexer.BlockIndexer + IndexerService *txindex.IndexerService + + // keep context here only because of API compatibility + // - it's used in `OnStart` (defined in service.Service interface) + ctx context.Context +} + +func newFullNode( + ctx context.Context, + conf config.NodeConfig, + p2pKey crypto.PrivKey, + signingKey crypto.PrivKey, + appClient abciclient.Client, + genesis *tmtypes.GenesisDoc, + logger log.Logger, +) (*FullNode, error) { + eventBus := tmtypes.NewEventBus() + eventBus.SetLogger(logger.With("module", "events")) + if err := eventBus.Start(); err != nil { + return nil, err + } + + client, err := p2p.NewClient(conf.P2P, p2pKey, genesis.ChainID, logger.With("module", "p2p")) + if err != nil { + return nil, err + } + + var baseKV store.KVStore + if conf.RootDir == "" && conf.DBPath == "" { // this is used for testing + logger.Info("WARNING: working in in-memory mode") + baseKV = store.NewDefaultInMemoryKVStore() + } else { + baseKV = store.NewDefaultKVStore(conf.RootDir, conf.DBPath, "rollmint") + } + mainKV := store.NewPrefixKV(baseKV, mainPrefix) + dalcKV := store.NewPrefixKV(baseKV, dalcPrefix) + indexerKV := store.NewPrefixKV(baseKV, indexerPrefix) + + s := store.New(mainKV) + + dalc := registry.GetClient(conf.DALayer) + if dalc == nil { + return nil, fmt.Errorf("couldn't get data availability client named '%s'", conf.DALayer) + } + err = dalc.Init(conf.NamespaceID, []byte(conf.DAConfig), dalcKV, logger.With("module", "da_client")) + if err != nil { + return nil, fmt.Errorf("data availability layer client initialization error: %w", err) + } + + indexerService, txIndexer, blockIndexer, err := createAndStartIndexerService(conf, indexerKV, eventBus, logger) + if err != nil { + return nil, err + } + + mp := mempoolv1.NewTxMempool(logger, llcfg.DefaultMempoolConfig(), appClient, 0) + mpIDs := newMempoolIDs() + + blockManager, err := block.NewManager(signingKey, conf.BlockManagerConfig, genesis, s, mp, appClient, dalc, eventBus, logger.With("module", "BlockManager")) + if err != nil { + return nil, fmt.Errorf("BlockManager initialization error: %w", err) + } + + node := &FullNode{ + appClient: appClient, + eventBus: eventBus, + genesis: genesis, + conf: conf, + P2P: client, + blockManager: blockManager, + dalc: dalc, + Mempool: mp, + mempoolIDs: mpIDs, + incomingTxCh: make(chan *p2p.GossipMessage), + Store: s, + TxIndexer: txIndexer, + IndexerService: indexerService, + BlockIndexer: blockIndexer, + ctx: ctx, + } + + node.BaseService = *service.NewBaseService(logger, "Node", node) + + node.P2P.SetTxValidator(node.newTxValidator()) + node.P2P.SetHeaderValidator(node.newHeaderValidator()) + node.P2P.SetCommitValidator(node.newCommitValidator()) + node.P2P.SetFraudProofValidator(node.newFraudProofValidator()) + + return node, nil + +} diff --git a/node/node.go b/node/node.go index 4c0c6b88b7..a6519ae57b 100644 --- a/node/node.go +++ b/node/node.go @@ -2,7 +2,7 @@ package node import ( "context" - "encoding/base64" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -12,18 +12,12 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" abci "github.com/tendermint/tendermint/abci/types" - llcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/libs/service" corep2p "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" - "github.com/celestiaorg/rollmint/block" "github.com/celestiaorg/rollmint/config" - "github.com/celestiaorg/rollmint/da" - "github.com/celestiaorg/rollmint/da/registry" "github.com/celestiaorg/rollmint/mempool" - mempoolv1 "github.com/celestiaorg/rollmint/mempool/v1" "github.com/celestiaorg/rollmint/p2p" "github.com/celestiaorg/rollmint/state/indexer" blockidxkv "github.com/celestiaorg/rollmint/state/indexer/block/kv" @@ -46,6 +40,8 @@ const ( genesisChunkSize = 16 * 1024 * 1024 // 16 MiB ) +// Node represents a client node in rollmint network. +// It connects all the components and orchestrates their work. type Node interface { AppClient() abciclient.Client EventBus() *tmtypes.EventBus @@ -58,122 +54,6 @@ type Node interface { GetGenesis() *tmtypes.GenesisDoc } -// Node represents a client node in rollmint network. -// It connects all the components and orchestrates their work. -type FullNode struct { - service.BaseService - eventBus *tmtypes.EventBus - appClient abciclient.Client - - genesis *tmtypes.GenesisDoc - // cache of chunked genesis data. - genChunks []string - - conf config.NodeConfig - P2P *p2p.Client - - // TODO(tzdybal): consider extracting "mempool reactor" - Mempool mempool.Mempool - mempoolIDs *mempoolIDs - incomingTxCh chan *p2p.GossipMessage - - Store store.Store - blockManager *block.Manager - dalc da.DataAvailabilityLayerClient - - TxIndexer txindex.TxIndexer - BlockIndexer indexer.BlockIndexer - IndexerService *txindex.IndexerService - - // keep context here only because of API compatibility - // - it's used in `OnStart` (defined in service.Service interface) - ctx context.Context -} - -func newFullNode( - ctx context.Context, - conf config.NodeConfig, - p2pKey crypto.PrivKey, - signingKey crypto.PrivKey, - appClient abciclient.Client, - genesis *tmtypes.GenesisDoc, - logger log.Logger, -) (*FullNode, error) { - eventBus := tmtypes.NewEventBus() - eventBus.SetLogger(logger.With("module", "events")) - if err := eventBus.Start(); err != nil { - return nil, err - } - - client, err := p2p.NewClient(conf.P2P, p2pKey, genesis.ChainID, logger.With("module", "p2p")) - if err != nil { - return nil, err - } - - var baseKV store.KVStore - if conf.RootDir == "" && conf.DBPath == "" { // this is used for testing - logger.Info("WARNING: working in in-memory mode") - baseKV = store.NewDefaultInMemoryKVStore() - } else { - baseKV = store.NewDefaultKVStore(conf.RootDir, conf.DBPath, "rollmint") - } - mainKV := store.NewPrefixKV(baseKV, mainPrefix) - dalcKV := store.NewPrefixKV(baseKV, dalcPrefix) - indexerKV := store.NewPrefixKV(baseKV, indexerPrefix) - - s := store.New(mainKV) - - dalc := registry.GetClient(conf.DALayer) - if dalc == nil { - return nil, fmt.Errorf("couldn't get data availability client named '%s'", conf.DALayer) - } - err = dalc.Init(conf.NamespaceID, []byte(conf.DAConfig), dalcKV, logger.With("module", "da_client")) - if err != nil { - return nil, fmt.Errorf("data availability layer client initialization error: %w", err) - } - - indexerService, txIndexer, blockIndexer, err := createAndStartIndexerService(conf, indexerKV, eventBus, logger) - if err != nil { - return nil, err - } - - mp := mempoolv1.NewTxMempool(logger, llcfg.DefaultMempoolConfig(), appClient, 0) - mpIDs := newMempoolIDs() - - blockManager, err := block.NewManager(signingKey, conf.BlockManagerConfig, genesis, s, mp, appClient, dalc, eventBus, logger.With("module", "BlockManager")) - if err != nil { - return nil, fmt.Errorf("BlockManager initialization error: %w", err) - } - - node := &FullNode{ - appClient: appClient, - eventBus: eventBus, - genesis: genesis, - conf: conf, - P2P: client, - blockManager: blockManager, - dalc: dalc, - Mempool: mp, - mempoolIDs: mpIDs, - incomingTxCh: make(chan *p2p.GossipMessage), - Store: s, - TxIndexer: txIndexer, - IndexerService: indexerService, - BlockIndexer: blockIndexer, - ctx: ctx, - } - - node.BaseService = *service.NewBaseService(logger, "Node", node) - - node.P2P.SetTxValidator(node.newTxValidator()) - node.P2P.SetHeaderValidator(node.newHeaderValidator()) - node.P2P.SetCommitValidator(node.newCommitValidator()) - node.P2P.SetFraudProofValidator(node.newFraudProofValidator()) - - return node, nil - -} - func NewNode( ctx context.Context, conf config.NodeConfig, @@ -187,90 +67,6 @@ func NewNode( return n, err } -// NewNode creates new rollmint node. -/*func NewNode( - ctx context.Context, - conf config.NodeConfig, - p2pKey crypto.PrivKey, - signingKey crypto.PrivKey, - appClient abciclient.Client, - genesis *tmtypes.GenesisDoc, - logger log.Logger, -) (*Node, error) { - eventBus := tmtypes.NewEventBus() - eventBus.SetLogger(logger.With("module", "events")) - if err := eventBus.Start(); err != nil { - return nil, err - } - - client, err := p2p.NewClient(conf.P2P, p2pKey, genesis.ChainID, logger.With("module", "p2p")) - if err != nil { - return nil, err - } - - var baseKV store.KVStore - if conf.RootDir == "" && conf.DBPath == "" { // this is used for testing - logger.Info("WARNING: working in in-memory mode") - baseKV = store.NewDefaultInMemoryKVStore() - } else { - baseKV = store.NewDefaultKVStore(conf.RootDir, conf.DBPath, "rollmint") - } - mainKV := store.NewPrefixKV(baseKV, mainPrefix) - dalcKV := store.NewPrefixKV(baseKV, dalcPrefix) - indexerKV := store.NewPrefixKV(baseKV, indexerPrefix) - - s := store.New(mainKV) - - dalc := registry.GetClient(conf.DALayer) - if dalc == nil { - return nil, fmt.Errorf("couldn't get data availability client named '%s'", conf.DALayer) - } - err = dalc.Init(conf.NamespaceID, []byte(conf.DAConfig), dalcKV, logger.With("module", "da_client")) - if err != nil { - return nil, fmt.Errorf("data availability layer client initialization error: %w", err) - } - - indexerService, txIndexer, blockIndexer, err := createAndStartIndexerService(conf, indexerKV, eventBus, logger) - if err != nil { - return nil, err - } - - mp := mempoolv1.NewTxMempool(logger, llcfg.DefaultMempoolConfig(), appClient, 0) - mpIDs := newMempoolIDs() - - blockManager, err := block.NewManager(signingKey, conf.BlockManagerConfig, genesis, s, mp, appClient, dalc, eventBus, logger.With("module", "BlockManager")) - if err != nil { - return nil, fmt.Errorf("BlockManager initialization error: %w", err) - } - - node := &Node{ - appClient: appClient, - eventBus: eventBus, - genesis: genesis, - conf: conf, - P2P: client, - blockManager: blockManager, - dalc: dalc, - Mempool: mp, - mempoolIDs: mpIDs, - incomingTxCh: make(chan *p2p.GossipMessage), - Store: s, - TxIndexer: txIndexer, - IndexerService: indexerService, - BlockIndexer: blockIndexer, - ctx: ctx, - } - - node.BaseService = *service.NewBaseService(logger, "Node", node) - - node.P2P.SetTxValidator(node.newTxValidator()) - node.P2P.SetHeaderValidator(node.newHeaderValidator()) - node.P2P.SetCommitValidator(node.newCommitValidator()) - node.P2P.SetFraudProofValidator(node.newFraudProofValidator()) - - return node, nil -}*/ - // initGenesisChunks creates a chunked format of the genesis document to make it easier to // iterate through larger genesis structures. func (n *FullNode) initGenesisChunks() error { From 76459fb02accbc081c83d1813d93e9408174b079 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Wed, 7 Dec 2022 17:33:21 -0500 Subject: [PATCH 05/18] light_node stub --- node/light_node.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 node/light_node.go diff --git a/node/light_node.go b/node/light_node.go new file mode 100644 index 0000000000..ba5e56c4ed --- /dev/null +++ b/node/light_node.go @@ -0,0 +1,37 @@ +package node + +import ( + abciclient "github.com/tendermint/tendermint/abci/client" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/libs/log" +) + +type LightNode struct {} + +func (n *LightNode) AppClient() abciclient.Client { + panic("Todo") +} +func (n *LightNode) EventBus() *tmtypes.EventBus { + panic("Todo") +} +func (n *LightNode) GetLogger() log.Logger { + panic("Todo") +} +func (n *LightNode) SetLogger() { + panic("Todo") +} +func (n *LightNode) OnReset() error { + panic("Todo") +} +func (n *LightNode) OnStop() { + panic("Todo") +} +func (n *LightNode) OnStart() error { + panic("Todo") +} +func (n *LightNode) GetGenesisChunks() ([]string, error) { + panic("Todo") +} +func (n *LightNode) GetGenesis() *tmtypes.GenesisDoc { + panic("Todo") +} From cf0cd7e25859874c863e56c3dc65c1ef2dc32bcb Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Wed, 7 Dec 2022 17:41:07 -0500 Subject: [PATCH 06/18] moved full_node functions to full_node file --- node/full_node.go | 213 ++++++++++++++++++++++++++++++++++++++++- node/node.go | 237 +++------------------------------------------- 2 files changed, 223 insertions(+), 227 deletions(-) diff --git a/node/full_node.go b/node/full_node.go index 3a24bf8a01..7512059329 100644 --- a/node/full_node.go +++ b/node/full_node.go @@ -2,8 +2,9 @@ package node import ( "context" "fmt" - + "errors" "github.com/libp2p/go-libp2p/core/crypto" + "github.com/celestiaorg/rollmint/types" abciclient "github.com/tendermint/tendermint/abci/client" llcfg "github.com/tendermint/tendermint/config" @@ -21,6 +22,11 @@ import ( "github.com/celestiaorg/rollmint/state/indexer" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/store" + "encoding/json" + "encoding/base64" + "go.uber.org/multierr" + abci "github.com/tendermint/tendermint/abci/types" + corep2p "github.com/tendermint/tendermint/p2p" ) type FullNode struct { @@ -136,3 +142,208 @@ func newFullNode( return node, nil } + +// initGenesisChunks creates a chunked format of the genesis document to make it easier to +// iterate through larger genesis structures. +func (n *FullNode) initGenesisChunks() error { + if n.genChunks != nil { + return nil + } + + if n.genesis == nil { + return nil + } + + data, err := json.Marshal(n.genesis) + if err != nil { + return err + } + + for i := 0; i < len(data); i += genesisChunkSize { + end := i + genesisChunkSize + + if end > len(data) { + end = len(data) + } + + n.genChunks = append(n.genChunks, base64.StdEncoding.EncodeToString(data[i:end])) + } + + return nil +} + +// OnStart is a part of Service interface. +func (n *FullNode) OnStart() error { + n.Logger.Info("starting P2P client") + err := n.P2P.Start(n.ctx) + if err != nil { + return fmt.Errorf("error while starting P2P client: %w", err) + } + err = n.dalc.Start() + if err != nil { + return fmt.Errorf("error while starting data availability layer client: %w", err) + } + if n.conf.Aggregator { + n.Logger.Info("working in aggregator mode", "block time", n.conf.BlockTime) + go n.blockManager.AggregationLoop(n.ctx) + go n.headerPublishLoop(n.ctx) + } + go n.blockManager.RetrieveLoop(n.ctx) + go n.blockManager.SyncLoop(n.ctx) + + return nil +} + +// GetGenesis returns entire genesis doc. +func (n *FullNode) GetGenesis() *tmtypes.GenesisDoc { + return n.genesis +} + +// GetGenesisChunks returns chunked version of genesis. +func (n *FullNode) GetGenesisChunks() ([]string, error) { + err := n.initGenesisChunks() + if err != nil { + return nil, err + } + return n.genChunks, err +} + +// OnStop is a part of Service interface. +func (n *FullNode) OnStop() { + err := n.dalc.Stop() + err = multierr.Append(err, n.P2P.Close()) + n.Logger.Error("errors while stopping node:", "errors", err) +} + +// OnReset is a part of Service interface. +func (n *FullNode) OnReset() error { + panic("OnReset - not implemented!") +} + +// SetLogger sets the logger used by node. +func (n *FullNode) SetLogger(logger log.Logger) { + n.Logger = logger +} + +// GetLogger returns logger. +func (n *FullNode) GetLogger() log.Logger { + return n.Logger +} + +// EventBus gives access to Node's event bus. +func (n *FullNode) EventBus() *tmtypes.EventBus { + return n.eventBus +} + +// AppClient returns ABCI proxy connections to communicate with application. +func (n *FullNode) AppClient() abciclient.Client { + return n.appClient +} + +// newTxValidator creates a pubsub validator that uses the node's mempool to check the +// transaction. If the transaction is valid, then it is added to the mempool +func (n *FullNode) newTxValidator() p2p.GossipValidator { + return func(m *p2p.GossipMessage) bool { + n.Logger.Debug("transaction received", "bytes", len(m.Data)) + checkTxResCh := make(chan *abci.Response, 1) + err := n.Mempool.CheckTx(m.Data, func(resp *abci.Response) { + checkTxResCh <- resp + }, mempool.TxInfo{ + SenderID: n.mempoolIDs.GetForPeer(m.From), + SenderP2PID: corep2p.ID(m.From), + }) + switch { + case errors.Is(err, mempool.ErrTxInCache): + return true + case errors.Is(err, mempool.ErrMempoolIsFull{}): + return true + case errors.Is(err, mempool.ErrTxTooLarge{}): + return false + case errors.Is(err, mempool.ErrPreCheck{}): + return false + default: + } + res := <-checkTxResCh + checkTxResp := res.GetCheckTx() + + return checkTxResp.Code == abci.CodeTypeOK + } +} + +// newHeaderValidator returns a pubsub validator that runs basic checks and forwards +// the deserialized header for further processing +func (n *FullNode) newHeaderValidator() p2p.GossipValidator { + return func(headerMsg *p2p.GossipMessage) bool { + n.Logger.Debug("header received", "from", headerMsg.From, "bytes", len(headerMsg.Data)) + var header types.SignedHeader + err := header.UnmarshalBinary(headerMsg.Data) + if err != nil { + n.Logger.Error("failed to deserialize header", "error", err) + return false + } + err = header.ValidateBasic() + if err != nil { + n.Logger.Error("failed to validate header", "error", err) + return false + } + n.blockManager.HeaderInCh <- &header + return true + } +} + +// newCommitValidator returns a pubsub validator that runs basic checks and forwards +// the deserialized commit for further processing +func (n *FullNode) newCommitValidator() p2p.GossipValidator { + return func(commitMsg *p2p.GossipMessage) bool { + n.Logger.Debug("commit received", "from", commitMsg.From, "bytes", len(commitMsg.Data)) + var commit types.Commit + err := commit.UnmarshalBinary(commitMsg.Data) + if err != nil { + n.Logger.Error("failed to deserialize commit", "error", err) + return false + } + err = commit.ValidateBasic() + if err != nil { + n.Logger.Error("failed to validate commit", "error", err) + return false + } + n.Logger.Debug("commit received", "height", commit.Height) + n.blockManager.CommitInCh <- &commit + return true + } +} + +// newFraudProofValidator returns a pubsub validator that validates a fraud proof and forwards +// it to be verified +func (n *FullNode) newFraudProofValidator() p2p.GossipValidator { + return func(fraudProofMsg *p2p.GossipMessage) bool { + n.Logger.Debug("fraud proof received", "from", fraudProofMsg.From, "bytes", len(fraudProofMsg.Data)) + var fraudProof types.FraudProof + err := fraudProof.UnmarshalBinary(fraudProofMsg.Data) + if err != nil { + n.Logger.Error("failed to deserialize fraud proof", "error", err) + return false + } + // TODO(manav): Add validation checks for fraud proof here + n.blockManager.FraudProofCh <- &fraudProof + return true + } +} + +func (n *FullNode) headerPublishLoop(ctx context.Context) { + for { + select { + case signedHeader := <-n.blockManager.HeaderOutCh: + headerBytes, err := signedHeader.MarshalBinary() + if err != nil { + n.Logger.Error("failed to serialize signed block header", "error", err) + } + err = n.P2P.GossipSignedHeader(ctx, headerBytes) + if err != nil { + n.Logger.Error("failed to gossip signed block header", "error", err) + } + case <-ctx.Done(): + return + } + } +} diff --git a/node/node.go b/node/node.go index a6519ae57b..0f093aa364 100644 --- a/node/node.go +++ b/node/node.go @@ -2,29 +2,19 @@ package node import ( "context" - "encoding/base64" - "encoding/json" - "errors" - "fmt" "github.com/libp2p/go-libp2p/core/crypto" - "go.uber.org/multierr" abciclient "github.com/tendermint/tendermint/abci/client" - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" - corep2p "github.com/tendermint/tendermint/p2p" tmtypes "github.com/tendermint/tendermint/types" "github.com/celestiaorg/rollmint/config" - "github.com/celestiaorg/rollmint/mempool" - "github.com/celestiaorg/rollmint/p2p" "github.com/celestiaorg/rollmint/state/indexer" blockidxkv "github.com/celestiaorg/rollmint/state/indexer/block/kv" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/state/txindex/kv" "github.com/celestiaorg/rollmint/store" - "github.com/celestiaorg/rollmint/types" ) // prefixes used in KV store to separate main node data from DALC data @@ -43,15 +33,15 @@ const ( // Node represents a client node in rollmint network. // It connects all the components and orchestrates their work. type Node interface { - AppClient() abciclient.Client - EventBus() *tmtypes.EventBus - GetLogger() log.Logger - SetLogger() - OnReset() error - OnStop() - OnStart() error - GetGenesisChunks() ([]string, error) - GetGenesis() *tmtypes.GenesisDoc + AppClient() abciclient.Client + EventBus() *tmtypes.EventBus + GetLogger() log.Logger + SetLogger() + OnReset() error + OnStop() + OnStart() error + GetGenesisChunks() ([]string, error) + GetGenesis() *tmtypes.GenesisDoc } func NewNode( @@ -63,213 +53,8 @@ func NewNode( genesis *tmtypes.GenesisDoc, logger log.Logger, ) (*FullNode, error) { - n, err := newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) - return n, err -} - -// initGenesisChunks creates a chunked format of the genesis document to make it easier to -// iterate through larger genesis structures. -func (n *FullNode) initGenesisChunks() error { - if n.genChunks != nil { - return nil - } - - if n.genesis == nil { - return nil - } - - data, err := json.Marshal(n.genesis) - if err != nil { - return err - } - - for i := 0; i < len(data); i += genesisChunkSize { - end := i + genesisChunkSize - - if end > len(data) { - end = len(data) - } - - n.genChunks = append(n.genChunks, base64.StdEncoding.EncodeToString(data[i:end])) - } - - return nil -} - -func (n *FullNode) headerPublishLoop(ctx context.Context) { - for { - select { - case signedHeader := <-n.blockManager.HeaderOutCh: - headerBytes, err := signedHeader.MarshalBinary() - if err != nil { - n.Logger.Error("failed to serialize signed block header", "error", err) - } - err = n.P2P.GossipSignedHeader(ctx, headerBytes) - if err != nil { - n.Logger.Error("failed to gossip signed block header", "error", err) - } - case <-ctx.Done(): - return - } - } -} - -// OnStart is a part of Service interface. -func (n *FullNode) OnStart() error { - n.Logger.Info("starting P2P client") - err := n.P2P.Start(n.ctx) - if err != nil { - return fmt.Errorf("error while starting P2P client: %w", err) - } - err = n.dalc.Start() - if err != nil { - return fmt.Errorf("error while starting data availability layer client: %w", err) - } - if n.conf.Aggregator { - n.Logger.Info("working in aggregator mode", "block time", n.conf.BlockTime) - go n.blockManager.AggregationLoop(n.ctx) - go n.headerPublishLoop(n.ctx) - } - go n.blockManager.RetrieveLoop(n.ctx) - go n.blockManager.SyncLoop(n.ctx) - - return nil -} - -// GetGenesis returns entire genesis doc. -func (n *FullNode) GetGenesis() *tmtypes.GenesisDoc { - return n.genesis -} - -// GetGenesisChunks returns chunked version of genesis. -func (n *FullNode) GetGenesisChunks() ([]string, error) { - err := n.initGenesisChunks() - if err != nil { - return nil, err - } - return n.genChunks, err -} - -// OnStop is a part of Service interface. -func (n *FullNode) OnStop() { - err := n.dalc.Stop() - err = multierr.Append(err, n.P2P.Close()) - n.Logger.Error("errors while stopping node:", "errors", err) -} - -// OnReset is a part of Service interface. -func (n *FullNode) OnReset() error { - panic("OnReset - not implemented!") -} - -// SetLogger sets the logger used by node. -func (n *FullNode) SetLogger(logger log.Logger) { - n.Logger = logger -} - -// GetLogger returns logger. -func (n *FullNode) GetLogger() log.Logger { - return n.Logger -} - -// EventBus gives access to Node's event bus. -func (n *FullNode) EventBus() *tmtypes.EventBus { - return n.eventBus -} - -// AppClient returns ABCI proxy connections to communicate with application. -func (n *FullNode) AppClient() abciclient.Client { - return n.appClient -} - -// newTxValidator creates a pubsub validator that uses the node's mempool to check the -// transaction. If the transaction is valid, then it is added to the mempool -func (n *FullNode) newTxValidator() p2p.GossipValidator { - return func(m *p2p.GossipMessage) bool { - n.Logger.Debug("transaction received", "bytes", len(m.Data)) - checkTxResCh := make(chan *abci.Response, 1) - err := n.Mempool.CheckTx(m.Data, func(resp *abci.Response) { - checkTxResCh <- resp - }, mempool.TxInfo{ - SenderID: n.mempoolIDs.GetForPeer(m.From), - SenderP2PID: corep2p.ID(m.From), - }) - switch { - case errors.Is(err, mempool.ErrTxInCache): - return true - case errors.Is(err, mempool.ErrMempoolIsFull{}): - return true - case errors.Is(err, mempool.ErrTxTooLarge{}): - return false - case errors.Is(err, mempool.ErrPreCheck{}): - return false - default: - } - res := <-checkTxResCh - checkTxResp := res.GetCheckTx() - - return checkTxResp.Code == abci.CodeTypeOK - } -} - -// newHeaderValidator returns a pubsub validator that runs basic checks and forwards -// the deserialized header for further processing -func (n *FullNode) newHeaderValidator() p2p.GossipValidator { - return func(headerMsg *p2p.GossipMessage) bool { - n.Logger.Debug("header received", "from", headerMsg.From, "bytes", len(headerMsg.Data)) - var header types.SignedHeader - err := header.UnmarshalBinary(headerMsg.Data) - if err != nil { - n.Logger.Error("failed to deserialize header", "error", err) - return false - } - err = header.ValidateBasic() - if err != nil { - n.Logger.Error("failed to validate header", "error", err) - return false - } - n.blockManager.HeaderInCh <- &header - return true - } -} - -// newCommitValidator returns a pubsub validator that runs basic checks and forwards -// the deserialized commit for further processing -func (n *FullNode) newCommitValidator() p2p.GossipValidator { - return func(commitMsg *p2p.GossipMessage) bool { - n.Logger.Debug("commit received", "from", commitMsg.From, "bytes", len(commitMsg.Data)) - var commit types.Commit - err := commit.UnmarshalBinary(commitMsg.Data) - if err != nil { - n.Logger.Error("failed to deserialize commit", "error", err) - return false - } - err = commit.ValidateBasic() - if err != nil { - n.Logger.Error("failed to validate commit", "error", err) - return false - } - n.Logger.Debug("commit received", "height", commit.Height) - n.blockManager.CommitInCh <- &commit - return true - } -} - -// newFraudProofValidator returns a pubsub validator that validates a fraud proof and forwards -// it to be verified -func (n *FullNode) newFraudProofValidator() p2p.GossipValidator { - return func(fraudProofMsg *p2p.GossipMessage) bool { - n.Logger.Debug("fraud proof received", "from", fraudProofMsg.From, "bytes", len(fraudProofMsg.Data)) - var fraudProof types.FraudProof - err := fraudProof.UnmarshalBinary(fraudProofMsg.Data) - if err != nil { - n.Logger.Error("failed to deserialize fraud proof", "error", err) - return false - } - // TODO(manav): Add validation checks for fraud proof here - n.blockManager.FraudProofCh <- &fraudProof - return true - } + n, err := newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) + return n, err } func createAndStartIndexerService( From 9ca94ddf44cec938989f51a388788caa07785d78 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Thu, 15 Dec 2022 16:07:51 -0500 Subject: [PATCH 07/18] tried to add methods to interface, will do accessors --- node/node.go | 7 +++++++ rpc/client/client.go | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/node/node.go b/node/node.go index 0f093aa364..9c7b382616 100644 --- a/node/node.go +++ b/node/node.go @@ -15,6 +15,7 @@ import ( "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/state/txindex/kv" "github.com/celestiaorg/rollmint/store" + "github.com/celestiaorg/rollmint/p2p" ) // prefixes used in KV store to separate main node data from DALC data @@ -42,6 +43,12 @@ type Node interface { OnStart() error GetGenesisChunks() ([]string, error) GetGenesis() *tmtypes.GenesisDoc + + P2P *p2p.Client + Mempool mempool.Mempool + Store store.Store + TxIndexer txindex.TxIndexer + BlockIndexer indexer.BlockIndexer } func NewNode( diff --git a/rpc/client/client.go b/rpc/client/client.go index 9c712d5374..c51c127c72 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -50,11 +50,11 @@ type Client struct { *types.EventBus config *config.RPCConfig - node *node.FullNode + node *node.Node } // NewClient returns Client working with given node. -func NewClient(node *node.FullNode) *Client { +func NewClient(node *node.Node) *Client { return &Client{ EventBus: node.EventBus(), config: config.DefaultRPCConfig(), From a0e104f1bd2a46e1012a984671e8595fa575d548 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Fri, 16 Dec 2022 17:40:09 -0500 Subject: [PATCH 08/18] made client use Node accessors --- node/full_node.go | 16 +++++++ node/node.go | 13 +++--- rpc/client/client.go | 99 +++++++++++++++++++++++++++----------------- 3 files changed, 84 insertions(+), 44 deletions(-) diff --git a/node/full_node.go b/node/full_node.go index 7512059329..d8874228d2 100644 --- a/node/full_node.go +++ b/node/full_node.go @@ -347,3 +347,19 @@ func (n *FullNode) headerPublishLoop(ctx context.Context) { } } } + +func (n *FullNode) GetP2P() (*p2p.Client) { + return n.P2P +} +func (n *FullNode) GetMempool() (mempool.Mempool) { + return n.Mempool +} +func (n *FullNode) GetStore() (store.Store) { + return n.Store +} +func (n *FullNode) GetTxIndexer() (txindex.TxIndexer) { + return n.TxIndexer +} +func (n *FullNode) GetBlockIndexer() (indexer.BlockIndexer) { + return n.BlockIndexer +} diff --git a/node/node.go b/node/node.go index 9c7b382616..37f076db80 100644 --- a/node/node.go +++ b/node/node.go @@ -16,6 +16,7 @@ import ( "github.com/celestiaorg/rollmint/state/txindex/kv" "github.com/celestiaorg/rollmint/store" "github.com/celestiaorg/rollmint/p2p" + "github.com/celestiaorg/rollmint/mempool" ) // prefixes used in KV store to separate main node data from DALC data @@ -37,18 +38,18 @@ type Node interface { AppClient() abciclient.Client EventBus() *tmtypes.EventBus GetLogger() log.Logger - SetLogger() + SetLogger(log.Logger) OnReset() error OnStop() OnStart() error GetGenesisChunks() ([]string, error) GetGenesis() *tmtypes.GenesisDoc - P2P *p2p.Client - Mempool mempool.Mempool - Store store.Store - TxIndexer txindex.TxIndexer - BlockIndexer indexer.BlockIndexer + GetP2P() *p2p.Client + GetMempool() mempool.Mempool + GetStore() store.Store + GetTxIndexer() txindex.TxIndexer + GetBlockIndexer() indexer.BlockIndexer } func NewNode( diff --git a/rpc/client/client.go b/rpc/client/client.go index c51c127c72..7429b98da1 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -50,11 +50,11 @@ type Client struct { *types.EventBus config *config.RPCConfig - node *node.Node + node node.Node } // NewClient returns Client working with given node. -func NewClient(node *node.Node) *Client { +func NewClient(node node.Node) *Client { return &Client{ EventBus: node.EventBus(), config: config.DefaultRPCConfig(), @@ -123,7 +123,8 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re // add to mempool and wait for CheckTx result checkTxResCh := make(chan *abci.Response, 1) - err = c.node.Mempool.CheckTx(tx, func(res *abci.Response) { + mp := c.node.GetMempool() + err = mp.CheckTx(tx, func(res *abci.Response) { checkTxResCh <- res }, mempool.TxInfo{}) if err != nil { @@ -141,7 +142,8 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re } // broadcast tx - err = c.node.P2P.GossipTx(ctx, tx) + p2p := c.node.GetP2P() + err = p2p.GossipTx(ctx, tx) if err != nil { return nil, fmt.Errorf("tx added to local mempool but failure to broadcast: %w", err) } @@ -185,12 +187,14 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re // CheckTx nor DeliverTx results. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async func (c *Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - err := c.node.Mempool.CheckTx(tx, nil, mempool.TxInfo{}) + mp := c.node.GetMempool() + err := mp.CheckTx(tx, nil, mempool.TxInfo{}) if err != nil { return nil, err } // gossipTx optimistically - err = c.node.P2P.GossipTx(ctx, tx) + p2p := c.node.GetP2P() + err = p2p.GossipTx(ctx, tx) if err != nil { return nil, fmt.Errorf("tx added to local mempool but failed to gossip: %w", err) } @@ -202,7 +206,8 @@ func (c *Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.Res // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync func (c *Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { resCh := make(chan *abci.Response, 1) - err := c.node.Mempool.CheckTx(tx, func(res *abci.Response) { + mp := c.node.GetMempool() + err := mp.CheckTx(tx, func(res *abci.Response) { resCh <- res }, mempool.TxInfo{}) if err != nil { @@ -214,14 +219,15 @@ func (c *Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.Resu // gossip the transaction if it's in the mempool. // Note: we have to do this here because, unlike the tendermint mempool reactor, there // is no routine that gossips transactions after they enter the pool + p2p := c.node.GetP2P() if r.Code == abci.CodeTypeOK { - err = c.node.P2P.GossipTx(ctx, tx) + err = p2p.GossipTx(ctx, tx) if err != nil { // the transaction must be removed from the mempool if it cannot be gossiped. // if this does not occur, then the user will not be able to try again using // this node, as the CheckTx call above will return an error indicating that // the tx is already in the mempool - _ = c.node.Mempool.RemoveTxByKey(tx.Key()) + _ = mp.RemoveTxByKey(tx.Key()) return nil, fmt.Errorf("failed to gossip tx: %w", err) } } @@ -307,10 +313,11 @@ func (c *Client) GenesisChunked(context context.Context, id uint) (*ctypes.Resul func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { const limit int64 = 20 + store := c.node.GetStore() // Currently blocks are not pruned and are synced linearly so the base height is 0 minHeight, maxHeight, err := filterMinMax( 0, - int64(c.node.Store.Height()), + int64(store.Height()), minHeight, maxHeight, limit) @@ -321,7 +328,7 @@ func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) blocks := make([]*types.BlockMeta, 0, maxHeight-minHeight+1) for height := maxHeight; height >= minHeight; height-- { - block, err := c.node.Store.LoadBlock(uint64(height)) + block, err := store.LoadBlock(uint64(height)) if err != nil { return nil, err } @@ -335,7 +342,7 @@ func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) } return &ctypes.ResultBlockchainInfo{ - LastHeight: int64(c.node.Store.Height()), + LastHeight: int64(store.Height()), BlockMetas: blocks, }, nil @@ -343,13 +350,14 @@ func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) // NetInfo returns basic information about client P2P connections. func (c *Client) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) { + p2p := c.node.GetP2P() res := ctypes.ResultNetInfo{ Listening: true, } - for _, ma := range c.node.P2P.Addrs() { + for _, ma := range p2p.Addrs() { res.Listeners = append(res.Listeners, ma.String()) } - peers := c.node.P2P.Peers() + peers := p2p.Peers() res.NPeers = len(peers) for _, peer := range peers { res.Peers = append(res.Peers, ctypes.Peer{ @@ -412,7 +420,8 @@ func (c *Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) { // If height is nil, it returns information about last known block. func (c *Client) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) { heightValue := c.normalizeHeight(height) - block, err := c.node.Store.LoadBlock(heightValue) + store := c.node.GetStore() + block, err := store.LoadBlock(heightValue) if err != nil { return nil, err } @@ -438,7 +447,8 @@ func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBl var h [32]byte copy(h[:], hash) - block, err := c.node.Store.LoadBlockByHash(h) + store := c.node.GetStore() + block, err := store.LoadBlockByHash(h) if err != nil { return nil, err } @@ -461,13 +471,14 @@ func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBl // BlockResults returns information about transactions, events and updates of validator set and consensus params. func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) { + store := c.node.GetStore() var h uint64 if height == nil { - h = c.node.Store.Height() + h = store.Height() } else { h = uint64(*height) } - resp, err := c.node.Store.LoadBlockResponses(h) + resp, err := store.LoadBlockResponses(h) if err != nil { return nil, err } @@ -484,12 +495,13 @@ func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.Resul // Commit returns signed header (aka commit) at given height. func (c *Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) { + store := c.node.GetStore() heightValue := c.normalizeHeight(height) - com, err := c.node.Store.LoadCommit(heightValue) + com, err := store.LoadCommit(heightValue) if err != nil { return nil, err } - b, err := c.node.Store.LoadBlock(heightValue) + b, err := store.LoadBlock(heightValue) if err != nil { return nil, err } @@ -505,7 +517,8 @@ func (c *Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommi // Validators returns paginated list of validators at given height. func (c *Client) Validators(ctx context.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*ctypes.ResultValidators, error) { height := c.normalizeHeight(heightPtr) - validators, err := c.node.Store.LoadValidators(height) + store := c.node.GetStore() + validators, err := store.LoadValidators(height) if err != nil { return nil, fmt.Errorf("failed to load validators for height %d: %w", height, err) } @@ -529,7 +542,8 @@ func (c *Client) Validators(ctx context.Context, heightPtr *int64, pagePtr, perP // Tx returns detailed information about transaction identified by its hash. func (c *Client) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) { - res, err := c.node.TxIndexer.Get(hash) + ti := c.node.GetTxIndexer() + res, err := ti.Get(hash) if err != nil { return nil, err } @@ -542,8 +556,9 @@ func (c *Client) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.Resul index := res.Index var proof types.TxProof + store := c.node.GetStore() if prove { - block, _ := c.node.Store.LoadBlock(uint64(height)) + block, _ := store.LoadBlock(uint64(height)) blockProof := block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines proof = types.TxProof{ RootHash: blockProof.RootHash, @@ -569,7 +584,8 @@ func (c *Client) TxSearch(ctx context.Context, query string, prove bool, pagePtr return nil, err } - results, err := c.node.TxIndexer.Search(ctx, q) + ti := c.node.GetTxIndexer() + results, err := ti.Search(ctx, q) if err != nil { return nil, err } @@ -637,7 +653,8 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i return nil, err } - results, err := c.node.BlockIndexer.Search(ctx, q) + bi := c.node.GetBlockIndexer() + results, err := bi.Search(ctx, q) if err != nil { return nil, err } @@ -671,8 +688,9 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i // Fetch the blocks blocks := make([]*ctypes.ResultBlock, 0, pageSize) + store := c.node.GetStore() for i := skipCount; i < skipCount+pageSize; i++ { - b, err := c.node.Store.LoadBlock(uint64(results[i])) + b, err := store.LoadBlock(uint64(results[i])) if err != nil { return nil, err } @@ -693,23 +711,24 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i // Status returns detailed information about current status of the node. func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { - latest, err := c.node.Store.LoadBlock(c.node.Store.Height()) + store := c.node.GetStore() + latest, err := store.LoadBlock(store.Height()) if err != nil { return nil, fmt.Errorf("failed to find latest block: %w", err) } - initial, err := c.node.Store.LoadBlock(uint64(c.node.GetGenesis().InitialHeight)) + initial, err := store.LoadBlock(uint64(c.node.GetGenesis().InitialHeight)) if err != nil { return nil, fmt.Errorf("failed to find earliest block: %w", err) } - validators, err := c.node.Store.LoadValidators(latest.Header.Height) + validators, err := store.LoadValidators(latest.Header.Height) if err != nil { return nil, fmt.Errorf("failed to fetch the validator info at latest block: %w", err) } _, validator := validators.GetByAddress(latest.Header.ProposerAddress) - state, err := c.node.Store.LoadState() + state, err := store.LoadState() if err != nil { return nil, fmt.Errorf("failed to load the last saved state: %w", err) } @@ -718,7 +737,8 @@ func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { state.Version.Consensus.Block, state.Version.Consensus.App, ) - id, addr, network := c.node.P2P.Info() + p2p := c.node.GetP2P() + id, addr, network := p2p.Info() txIndexerStatus := "on" result := &ctypes.ResultStatus{ @@ -763,10 +783,11 @@ func (c *Client) BroadcastEvidence(ctx context.Context, evidence types.Evidence) // NumUnconfirmedTxs returns information about transactions in mempool. func (c *Client) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) { + mp := c.node.GetMempool() return &ctypes.ResultUnconfirmedTxs{ - Count: c.node.Mempool.Size(), - Total: c.node.Mempool.Size(), - TotalBytes: c.node.Mempool.SizeBytes(), + Count: mp.Size(), + Total: mp.Size(), + TotalBytes: mp.SizeBytes(), }, nil } @@ -776,11 +797,12 @@ func (c *Client) UnconfirmedTxs(ctx context.Context, limitPtr *int) (*ctypes.Res // reuse per_page validator limit := validatePerPage(limitPtr) - txs := c.node.Mempool.ReapMaxTxs(limit) + mp := c.node.GetMempool() + txs := mp.ReapMaxTxs(limit) return &ctypes.ResultUnconfirmedTxs{ Count: len(txs), - Total: c.node.Mempool.Size(), - TotalBytes: c.node.Mempool.SizeBytes(), + Total: mp.Size(), + TotalBytes: mp.SizeBytes(), Txs: txs}, nil } @@ -849,8 +871,9 @@ func (c *Client) appClient() abcicli.Client { func (c *Client) normalizeHeight(height *int64) uint64 { var heightValue uint64 + store := c.node.GetStore() if height == nil { - heightValue = c.node.Store.Height() + heightValue = store.Height() } else { heightValue = uint64(*height) } From c07217c8ff883eaf10cbb86f6f6f2b0f2edada2b Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 19 Dec 2022 22:07:37 -0500 Subject: [PATCH 09/18] cli option for light mode --- node/full_node.go | 33 +++++++++++++++------------- node/light_node.go | 55 ++++++++++++++++++++++++++++++++++++---------- node/node.go | 19 ++++++++++------ 3 files changed, 73 insertions(+), 34 deletions(-) diff --git a/node/full_node.go b/node/full_node.go index d8874228d2..a646d36695 100644 --- a/node/full_node.go +++ b/node/full_node.go @@ -1,10 +1,12 @@ package node + import ( "context" - "fmt" "errors" - "github.com/libp2p/go-libp2p/core/crypto" + "fmt" + "github.com/celestiaorg/rollmint/types" + "github.com/libp2p/go-libp2p/core/crypto" abciclient "github.com/tendermint/tendermint/abci/client" llcfg "github.com/tendermint/tendermint/config" @@ -12,6 +14,9 @@ import ( "github.com/tendermint/tendermint/libs/service" tmtypes "github.com/tendermint/tendermint/types" + "encoding/base64" + "encoding/json" + "github.com/celestiaorg/rollmint/block" "github.com/celestiaorg/rollmint/config" "github.com/celestiaorg/rollmint/da" @@ -22,11 +27,9 @@ import ( "github.com/celestiaorg/rollmint/state/indexer" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/store" - "encoding/json" - "encoding/base64" - "go.uber.org/multierr" abci "github.com/tendermint/tendermint/abci/types" corep2p "github.com/tendermint/tendermint/p2p" + "go.uber.org/multierr" ) type FullNode struct { @@ -348,18 +351,18 @@ func (n *FullNode) headerPublishLoop(ctx context.Context) { } } -func (n *FullNode) GetP2P() (*p2p.Client) { - return n.P2P +func (n *FullNode) GetP2P() *p2p.Client { + return n.P2P } -func (n *FullNode) GetMempool() (mempool.Mempool) { - return n.Mempool +func (n *FullNode) GetMempool() mempool.Mempool { + return n.Mempool } -func (n *FullNode) GetStore() (store.Store) { - return n.Store +func (n *FullNode) GetStore() store.Store { + return n.Store } -func (n *FullNode) GetTxIndexer() (txindex.TxIndexer) { - return n.TxIndexer +func (n *FullNode) GetTxIndexer() txindex.TxIndexer { + return n.TxIndexer } -func (n *FullNode) GetBlockIndexer() (indexer.BlockIndexer) { - return n.BlockIndexer +func (n *FullNode) GetBlockIndexer() indexer.BlockIndexer { + return n.BlockIndexer } diff --git a/node/light_node.go b/node/light_node.go index ba5e56c4ed..ba8eb868ea 100644 --- a/node/light_node.go +++ b/node/light_node.go @@ -1,37 +1,68 @@ package node import ( + "context" + + "github.com/libp2p/go-libp2p/core/crypto" + abciclient "github.com/tendermint/tendermint/abci/client" - tmtypes "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/celestiaorg/rollmint/config" + "github.com/celestiaorg/rollmint/mempool" + "github.com/celestiaorg/rollmint/p2p" + "github.com/celestiaorg/rollmint/state/indexer" + "github.com/celestiaorg/rollmint/state/txindex" + "github.com/celestiaorg/rollmint/store" ) -type LightNode struct {} +func newLightNode( + ctx context.Context, + conf config.NodeConfig, + p2pKey crypto.PrivKey, + signingKey crypto.PrivKey, + appClient abciclient.Client, + genesis *tmtypes.GenesisDoc, + logger log.Logger, +) (*LightNode, error) { + panic("Todo") +} + +type LightNode struct{} func (n *LightNode) AppClient() abciclient.Client { - panic("Todo") + panic("Todo") } func (n *LightNode) EventBus() *tmtypes.EventBus { - panic("Todo") + panic("Todo") } func (n *LightNode) GetLogger() log.Logger { - panic("Todo") + panic("Todo") } -func (n *LightNode) SetLogger() { - panic("Todo") +func (n *LightNode) SetLogger(log.Logger) { + panic("Todo") } func (n *LightNode) OnReset() error { - panic("Todo") + panic("Todo") } func (n *LightNode) OnStop() { - panic("Todo") + panic("Todo") } func (n *LightNode) OnStart() error { - panic("Todo") + panic("Todo") } func (n *LightNode) GetGenesisChunks() ([]string, error) { - panic("Todo") + panic("Todo") } func (n *LightNode) GetGenesis() *tmtypes.GenesisDoc { - panic("Todo") + panic("Todo") +} + +func (n *LightNode) GetP2P() *p2p.Client { + panic("Todo") } +func (n *LightNode) GetMempool() mempool.Mempool { panic("Todo") } +func (n *LightNode) GetStore() store.Store { panic("Todo") } +func (n *LightNode) GetTxIndexer() txindex.TxIndexer { panic("Todo") } +func (n *LightNode) GetBlockIndexer() indexer.BlockIndexer { panic("Todo") } diff --git a/node/node.go b/node/node.go index 37f076db80..e0eafea110 100644 --- a/node/node.go +++ b/node/node.go @@ -10,13 +10,13 @@ import ( tmtypes "github.com/tendermint/tendermint/types" "github.com/celestiaorg/rollmint/config" + "github.com/celestiaorg/rollmint/mempool" + "github.com/celestiaorg/rollmint/p2p" "github.com/celestiaorg/rollmint/state/indexer" blockidxkv "github.com/celestiaorg/rollmint/state/indexer/block/kv" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/state/txindex/kv" "github.com/celestiaorg/rollmint/store" - "github.com/celestiaorg/rollmint/p2p" - "github.com/celestiaorg/rollmint/mempool" ) // prefixes used in KV store to separate main node data from DALC data @@ -45,8 +45,8 @@ type Node interface { GetGenesisChunks() ([]string, error) GetGenesis() *tmtypes.GenesisDoc - GetP2P() *p2p.Client - GetMempool() mempool.Mempool + GetP2P() *p2p.Client + GetMempool() mempool.Mempool GetStore() store.Store GetTxIndexer() txindex.TxIndexer GetBlockIndexer() indexer.BlockIndexer @@ -60,9 +60,14 @@ func NewNode( appClient abciclient.Client, genesis *tmtypes.GenesisDoc, logger log.Logger, -) (*FullNode, error) { - n, err := newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) - return n, err +) (Node, error) { + if conf.Light { + n, err := newLightNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) + return n, err + } else { + n, err := newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) + return n, err + } } func createAndStartIndexerService( From c86761126bf62f943a514556d88819e54910a45f Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Fri, 23 Dec 2022 10:57:26 -0500 Subject: [PATCH 10/18] changed Node to FullNode in tests --- node/integration_test.go | 15 ++++++++------- node/node_test.go | 4 ++-- rpc/client/client_test.go | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/node/integration_test.go b/node/integration_test.go index 34fa583047..1a70428213 100644 --- a/node/integration_test.go +++ b/node/integration_test.go @@ -52,7 +52,7 @@ func TestAggregatorMode(t *testing.T) { BlockTime: 1 * time.Second, NamespaceID: rmtypes.NamespaceID{1, 2, 3, 4, 5, 6, 7, 8}, } - node, err := NewNode(context.Background(), config.NodeConfig{DALayer: "mock", Aggregator: true, BlockManagerConfig: blockManagerConfig}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) + node, err := newFullNode(context.Background(), config.NodeConfig{DALayer: "mock", Aggregator: true, BlockManagerConfig: blockManagerConfig}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) require.NoError(err) require.NotNil(node) @@ -191,7 +191,7 @@ func TestFraudProofTrigger(t *testing.T) { } // Creates a starts the given number of client nodes along with an aggregator node. Uses the given flag to decide whether to have the aggregator produce malicious blocks. -func createAndStartNodes(clientNodes int, isMalicious bool, t *testing.T) ([]*Node, []*mocks.Application) { +func createAndStartNodes(clientNodes int, isMalicious bool, t *testing.T) ([]*FullNode, []*mocks.Application) { var wg sync.WaitGroup aggCtx, aggCancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background()) @@ -209,7 +209,7 @@ func createAndStartNodes(clientNodes int, isMalicious bool, t *testing.T) ([]*No // Starts the given nodes using the given wait group to synchronize them // and wait for them to gossip transactions -func startNodes(nodes []*Node, wg *sync.WaitGroup, t *testing.T) { +func startNodes(nodes []*FullNode, wg *sync.WaitGroup, t *testing.T) { numNodes := len(nodes) wg.Add((numNodes) * (numNodes - 1)) for _, n := range nodes { @@ -238,7 +238,7 @@ func startNodes(nodes []*Node, wg *sync.WaitGroup, t *testing.T) { } // Creates the given number of nodes the given nodes using the given wait group to synchornize them -func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, wg *sync.WaitGroup, t *testing.T) ([]*Node, []*mocks.Application) { +func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, wg *sync.WaitGroup, t *testing.T) ([]*FullNode, []*mocks.Application) { t.Helper() if aggCtx == nil { @@ -254,7 +254,7 @@ func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, wg *syn keys[i], _, _ = crypto.GenerateEd25519Key(rand.Reader) } - nodes := make([]*Node, num) + nodes := make([]*FullNode, num) apps := make([]*mocks.Application, num) dalc := &mockda.DataAvailabilityLayerClient{} _ = dalc.Init([8]byte{}, nil, store.NewDefaultInMemoryKVStore(), log.TestingLogger()) @@ -267,7 +267,7 @@ func createNodes(aggCtx, ctx context.Context, num int, isMalicious bool, wg *syn return nodes, apps } -func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, dalc da.DataAvailabilityLayerClient, keys []crypto.PrivKey, wg *sync.WaitGroup, t *testing.T) (*Node, *mocks.Application) { +func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, dalc da.DataAvailabilityLayerClient, keys []crypto.PrivKey, wg *sync.WaitGroup, t *testing.T) (*FullNode, *mocks.Application) { t.Helper() require := require.New(t) // nodes will listen on consecutive ports on local interface @@ -317,13 +317,14 @@ func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, d } signingKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) - node, err := NewNode( + node, err := newFullNode( ctx, config.NodeConfig{ P2P: p2pConfig, DALayer: "mock", Aggregator: aggregator, BlockManagerConfig: bmConfig, + Light: false, }, keys[n], signingKey, diff --git a/node/node_test.go b/node/node_test.go index d6877945f6..8121225579 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -31,7 +31,7 @@ func TestStartup(t *testing.T) { app.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) key, _, _ := crypto.GenerateEd25519Key(rand.Reader) signingKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) - node, err := NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) + node, err := newFullNode(context.Background(), config.NodeConfig{DALayer: "mock"}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) require.NoError(err) require.NotNil(node) @@ -57,7 +57,7 @@ func TestMempoolDirectly(t *testing.T) { signingKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) anotherKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) - node, err := NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) + node, err := newFullNode(context.Background(), config.NodeConfig{DALayer: "mock"}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) require.NoError(err) require.NotNil(node) diff --git a/rpc/client/client_test.go b/rpc/client/client_test.go index 5667e4d417..45a8b2a808 100644 --- a/rpc/client/client_test.go +++ b/rpc/client/client_test.go @@ -91,6 +91,7 @@ func TestGenesisChunked(t *testing.T) { mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) privKey, _, _ := crypto.GenerateEd25519Key(cryptorand.Reader) signingKey, _, _ := crypto.GenerateEd25519Key(cryptorand.Reader) + //n, _ := node.NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, privKey, signingKey, abcicli.NewLocalClient(nil, mockApp), genDoc, log.TestingLogger()) n, _ := node.NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, privKey, signingKey, abcicli.NewLocalClient(nil, mockApp), genDoc, log.TestingLogger()) rpc := NewClient(n) From 9d5992e71197007cc044d3477151269c23533b59 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Fri, 23 Dec 2022 22:13:51 -0500 Subject: [PATCH 11/18] fixed tests --- node/light_node.go | 5 ++++- node/node.go | 2 ++ rpc/client/client_test.go | 45 +++++++++++++++++++-------------------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/node/light_node.go b/node/light_node.go index ba8eb868ea..de24eb0805 100644 --- a/node/light_node.go +++ b/node/light_node.go @@ -15,6 +15,7 @@ import ( "github.com/celestiaorg/rollmint/state/indexer" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/store" + "github.com/tendermint/tendermint/libs/service" ) func newLightNode( @@ -29,7 +30,9 @@ func newLightNode( panic("Todo") } -type LightNode struct{} +type LightNode struct { + service.BaseService +} func (n *LightNode) AppClient() abciclient.Client { panic("Todo") diff --git a/node/node.go b/node/node.go index e0eafea110..2f78fa540e 100644 --- a/node/node.go +++ b/node/node.go @@ -50,6 +50,8 @@ type Node interface { GetStore() store.Store GetTxIndexer() txindex.TxIndexer GetBlockIndexer() indexer.BlockIndexer + Start() error + Stop() error } func NewNode( diff --git a/rpc/client/client_test.go b/rpc/client/client_test.go index 45a8b2a808..e41f34901a 100644 --- a/rpc/client/client_test.go +++ b/rpc/client/client_test.go @@ -3,7 +3,6 @@ package client import ( "context" crand "crypto/rand" - cryptorand "crypto/rand" "fmt" "math/rand" "testing" @@ -89,8 +88,8 @@ func TestGenesisChunked(t *testing.T) { mockApp := &mocks.Application{} mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) - privKey, _, _ := crypto.GenerateEd25519Key(cryptorand.Reader) - signingKey, _, _ := crypto.GenerateEd25519Key(cryptorand.Reader) + privKey, _, _ := crypto.GenerateEd25519Key(crand.Reader) + signingKey, _, _ := crypto.GenerateEd25519Key(crand.Reader) //n, _ := node.NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, privKey, signingKey, abcicli.NewLocalClient(nil, mockApp), genDoc, log.TestingLogger()) n, _ := node.NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, privKey, signingKey, abcicli.NewLocalClient(nil, mockApp), genDoc, log.TestingLogger()) @@ -248,8 +247,8 @@ func TestGetBlock(t *testing.T) { require.NoError(err) block := getRandomBlock(1, 10) - err = rpc.node.Store.SaveBlock(block, &types.Commit{}) - rpc.node.Store.SetHeight(block.Header.Height) + err = rpc.node.GetStore().SaveBlock(block, &types.Commit{}) + rpc.node.GetStore().SetHeight(block.Header.Height) require.NoError(err) blockResp, err := rpc.Block(context.Background(), nil) @@ -275,8 +274,8 @@ func TestGetCommit(t *testing.T) { require.NoError(err) for _, b := range blocks { - err = rpc.node.Store.SaveBlock(b, &types.Commit{Height: b.Header.Height}) - rpc.node.Store.SetHeight(b.Header.Height) + err = rpc.node.GetStore().SaveBlock(b, &types.Commit{Height: b.Header.Height}) + rpc.node.GetStore().SetHeight(b.Header.Height) require.NoError(err) } t.Run("Fetch all commits", func(t *testing.T) { @@ -310,7 +309,7 @@ func TestBlockSearch(t *testing.T) { heights := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for _, h := range heights { block := getRandomBlock(uint64(h), 5) - err := rpc.node.Store.SaveBlock(block, &types.Commit{ + err := rpc.node.GetStore().SaveBlock(block, &types.Commit{ Height: uint64(h), HeaderHash: block.Header.Hash(), }) @@ -374,7 +373,7 @@ func TestGetBlockByHash(t *testing.T) { require.NoError(err) block := getRandomBlock(1, 10) - err = rpc.node.Store.SaveBlock(block, &types.Commit{}) + err = rpc.node.GetStore().SaveBlock(block, &types.Commit{}) require.NoError(err) abciBlock, err := abciconv.ToABCIBlock(block) require.NoError(err) @@ -564,11 +563,11 @@ func TestBlockchainInfo(t *testing.T) { heights := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for _, h := range heights { block := getRandomBlock(uint64(h), 5) - err := rpc.node.Store.SaveBlock(block, &types.Commit{ + err := rpc.node.GetStore().SaveBlock(block, &types.Commit{ Height: uint64(h), HeaderHash: block.Header.Hash(), }) - rpc.node.Store.SetHeight(block.Header.Height) + rpc.node.GetStore().SetHeight(block.Header.Height) require.NoError(err) } @@ -767,7 +766,7 @@ func getRandomBytes(n int) []byte { } func getBlockMeta(rpc *Client, n int64) *tmtypes.BlockMeta { - b, err := rpc.node.Store.LoadBlock(uint64(n)) + b, err := rpc.node.GetStore().LoadBlock(uint64(n)) if err != nil { return nil } @@ -801,7 +800,7 @@ func indexBlocks(t *testing.T, rpc *Client, heights []int64) { t.Helper() for _, h := range heights { - require.NoError(t, rpc.node.BlockIndexer.Index(tmtypes.EventDataNewBlockHeader{ + require.NoError(t, rpc.node.GetBlockIndexer().Index(tmtypes.EventDataNewBlockHeader{ Header: tmtypes.Header{Height: h}, ResultBeginBlock: abci.ResponseBeginBlock{ Events: []abci.Event{ @@ -898,13 +897,13 @@ func TestMempool2Nodes(t *testing.T) { assert.Error(err) assert.Nil(resp) - txAvailable := node2.Mempool.TxsAvailable() + txAvailable := node2.GetMempool().TxsAvailable() select { case <-txAvailable: case <-ctx.Done(): } - assert.Equal(node2.Mempool.SizeBytes(), int64(len("good"))) + assert.Equal(node2.GetMempool().SizeBytes(), int64(len("good"))) } func TestStatus(t *testing.T) { @@ -960,24 +959,24 @@ func TestStatus(t *testing.T) { require.NotNil(node) validatorSet := tmtypes.NewValidatorSet(validators) - err = node.Store.SaveValidators(1, validatorSet) + err = node.GetStore().SaveValidators(1, validatorSet) require.NoError(err) - err = node.Store.SaveValidators(2, validatorSet) + err = node.GetStore().SaveValidators(2, validatorSet) require.NoError(err) - err = node.Store.UpdateState(types.State{LastValidators: validatorSet, NextValidators: validatorSet, Validators: validatorSet}) + err = node.GetStore().UpdateState(types.State{LastValidators: validatorSet, NextValidators: validatorSet, Validators: validatorSet}) assert.NoError(err) rpc := NewClient(node) assert.NotNil(rpc) earliestBlock := getRandomBlockWithProposer(1, 1, validators[0].Address.Bytes()) - err = rpc.node.Store.SaveBlock(earliestBlock, &types.Commit{Height: earliestBlock.Header.Height}) - rpc.node.Store.SetHeight(earliestBlock.Header.Height) + err = rpc.node.GetStore().SaveBlock(earliestBlock, &types.Commit{Height: earliestBlock.Header.Height}) + rpc.node.GetStore().SetHeight(earliestBlock.Header.Height) require.NoError(err) latestBlock := getRandomBlockWithProposer(2, 1, validators[1].Address.Bytes()) - err = rpc.node.Store.SaveBlock(latestBlock, &types.Commit{Height: latestBlock.Header.Height}) - rpc.node.Store.SetHeight(latestBlock.Header.Height) + err = rpc.node.GetStore().SaveBlock(latestBlock, &types.Commit{Height: latestBlock.Header.Height}) + rpc.node.GetStore().SetHeight(latestBlock.Header.Height) require.NoError(err) err = node.Start() @@ -995,7 +994,7 @@ func TestStatus(t *testing.T) { // specific validation assert.Equal(tconfig.DefaultBaseConfig().Moniker, resp.NodeInfo.Moniker) - state, err := rpc.node.Store.LoadState() + state, err := rpc.node.GetStore().LoadState() assert.NoError(err) defaultProtocolVersion := p2p.NewProtocolVersion( version.P2PProtocol, From cfa3c2c94f526ce1aac41c53262ce4c6d02e3eed Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Fri, 23 Dec 2022 22:19:28 -0500 Subject: [PATCH 12/18] cleaned up commentr --- rpc/client/client_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/rpc/client/client_test.go b/rpc/client/client_test.go index e41f34901a..dfa4ea7a08 100644 --- a/rpc/client/client_test.go +++ b/rpc/client/client_test.go @@ -90,7 +90,6 @@ func TestGenesisChunked(t *testing.T) { mockApp.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) privKey, _, _ := crypto.GenerateEd25519Key(crand.Reader) signingKey, _, _ := crypto.GenerateEd25519Key(crand.Reader) - //n, _ := node.NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, privKey, signingKey, abcicli.NewLocalClient(nil, mockApp), genDoc, log.TestingLogger()) n, _ := node.NewNode(context.Background(), config.NodeConfig{DALayer: "mock"}, privKey, signingKey, abcicli.NewLocalClient(nil, mockApp), genDoc, log.TestingLogger()) rpc := NewClient(n) From 4a70758f147ef46f75dae2995ff485e81fc740ac Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Sun, 25 Dec 2022 13:13:07 -0500 Subject: [PATCH 13/18] goimports and gofmt --- node/full_node.go | 10 +++++---- node/integration_test.go | 2 +- node/light_node.go | 3 ++- rpc/client/client.go | 46 ++++++++++++++++++++-------------------- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/node/full_node.go b/node/full_node.go index a646d36695..6b01ddbf2f 100644 --- a/node/full_node.go +++ b/node/full_node.go @@ -5,9 +5,10 @@ import ( "errors" "fmt" - "github.com/celestiaorg/rollmint/types" "github.com/libp2p/go-libp2p/core/crypto" + "github.com/celestiaorg/rollmint/types" + abciclient "github.com/tendermint/tendermint/abci/client" llcfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/libs/log" @@ -17,6 +18,10 @@ import ( "encoding/base64" "encoding/json" + abci "github.com/tendermint/tendermint/abci/types" + corep2p "github.com/tendermint/tendermint/p2p" + "go.uber.org/multierr" + "github.com/celestiaorg/rollmint/block" "github.com/celestiaorg/rollmint/config" "github.com/celestiaorg/rollmint/da" @@ -27,9 +32,6 @@ import ( "github.com/celestiaorg/rollmint/state/indexer" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/store" - abci "github.com/tendermint/tendermint/abci/types" - corep2p "github.com/tendermint/tendermint/p2p" - "go.uber.org/multierr" ) type FullNode struct { diff --git a/node/integration_test.go b/node/integration_test.go index 1a70428213..e10d5d0f77 100644 --- a/node/integration_test.go +++ b/node/integration_test.go @@ -324,7 +324,7 @@ func createNode(ctx context.Context, n int, isMalicious bool, aggregator bool, d DALayer: "mock", Aggregator: aggregator, BlockManagerConfig: bmConfig, - Light: false, + Light: false, }, keys[n], signingKey, diff --git a/node/light_node.go b/node/light_node.go index de24eb0805..5416041031 100644 --- a/node/light_node.go +++ b/node/light_node.go @@ -9,13 +9,14 @@ import ( "github.com/tendermint/tendermint/libs/log" tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/libs/service" + "github.com/celestiaorg/rollmint/config" "github.com/celestiaorg/rollmint/mempool" "github.com/celestiaorg/rollmint/p2p" "github.com/celestiaorg/rollmint/state/indexer" "github.com/celestiaorg/rollmint/state/txindex" "github.com/celestiaorg/rollmint/store" - "github.com/tendermint/tendermint/libs/service" ) func newLightNode( diff --git a/rpc/client/client.go b/rpc/client/client.go index 7429b98da1..e0001025ab 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -123,7 +123,7 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re // add to mempool and wait for CheckTx result checkTxResCh := make(chan *abci.Response, 1) - mp := c.node.GetMempool() + mp := c.node.GetMempool() err = mp.CheckTx(tx, func(res *abci.Response) { checkTxResCh <- res }, mempool.TxInfo{}) @@ -142,7 +142,7 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re } // broadcast tx - p2p := c.node.GetP2P() + p2p := c.node.GetP2P() err = p2p.GossipTx(ctx, tx) if err != nil { return nil, fmt.Errorf("tx added to local mempool but failure to broadcast: %w", err) @@ -187,13 +187,13 @@ func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.Re // CheckTx nor DeliverTx results. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async func (c *Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - mp := c.node.GetMempool() + mp := c.node.GetMempool() err := mp.CheckTx(tx, nil, mempool.TxInfo{}) if err != nil { return nil, err } // gossipTx optimistically - p2p := c.node.GetP2P() + p2p := c.node.GetP2P() err = p2p.GossipTx(ctx, tx) if err != nil { return nil, fmt.Errorf("tx added to local mempool but failed to gossip: %w", err) @@ -206,7 +206,7 @@ func (c *Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.Res // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync func (c *Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { resCh := make(chan *abci.Response, 1) - mp := c.node.GetMempool() + mp := c.node.GetMempool() err := mp.CheckTx(tx, func(res *abci.Response) { resCh <- res }, mempool.TxInfo{}) @@ -219,7 +219,7 @@ func (c *Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.Resu // gossip the transaction if it's in the mempool. // Note: we have to do this here because, unlike the tendermint mempool reactor, there // is no routine that gossips transactions after they enter the pool - p2p := c.node.GetP2P() + p2p := c.node.GetP2P() if r.Code == abci.CodeTypeOK { err = p2p.GossipTx(ctx, tx) if err != nil { @@ -313,7 +313,7 @@ func (c *Client) GenesisChunked(context context.Context, id uint) (*ctypes.Resul func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { const limit int64 = 20 - store := c.node.GetStore() + store := c.node.GetStore() // Currently blocks are not pruned and are synced linearly so the base height is 0 minHeight, maxHeight, err := filterMinMax( 0, @@ -350,7 +350,7 @@ func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) // NetInfo returns basic information about client P2P connections. func (c *Client) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) { - p2p := c.node.GetP2P() + p2p := c.node.GetP2P() res := ctypes.ResultNetInfo{ Listening: true, } @@ -420,7 +420,7 @@ func (c *Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) { // If height is nil, it returns information about last known block. func (c *Client) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) { heightValue := c.normalizeHeight(height) - store := c.node.GetStore() + store := c.node.GetStore() block, err := store.LoadBlock(heightValue) if err != nil { return nil, err @@ -447,7 +447,7 @@ func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBl var h [32]byte copy(h[:], hash) - store := c.node.GetStore() + store := c.node.GetStore() block, err := store.LoadBlockByHash(h) if err != nil { return nil, err @@ -471,7 +471,7 @@ func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBl // BlockResults returns information about transactions, events and updates of validator set and consensus params. func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) { - store := c.node.GetStore() + store := c.node.GetStore() var h uint64 if height == nil { h = store.Height() @@ -495,7 +495,7 @@ func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.Resul // Commit returns signed header (aka commit) at given height. func (c *Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) { - store := c.node.GetStore() + store := c.node.GetStore() heightValue := c.normalizeHeight(height) com, err := store.LoadCommit(heightValue) if err != nil { @@ -517,7 +517,7 @@ func (c *Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommi // Validators returns paginated list of validators at given height. func (c *Client) Validators(ctx context.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*ctypes.ResultValidators, error) { height := c.normalizeHeight(heightPtr) - store := c.node.GetStore() + store := c.node.GetStore() validators, err := store.LoadValidators(height) if err != nil { return nil, fmt.Errorf("failed to load validators for height %d: %w", height, err) @@ -542,7 +542,7 @@ func (c *Client) Validators(ctx context.Context, heightPtr *int64, pagePtr, perP // Tx returns detailed information about transaction identified by its hash. func (c *Client) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) { - ti := c.node.GetTxIndexer() + ti := c.node.GetTxIndexer() res, err := ti.Get(hash) if err != nil { return nil, err @@ -556,7 +556,7 @@ func (c *Client) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.Resul index := res.Index var proof types.TxProof - store := c.node.GetStore() + store := c.node.GetStore() if prove { block, _ := store.LoadBlock(uint64(height)) blockProof := block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines @@ -584,7 +584,7 @@ func (c *Client) TxSearch(ctx context.Context, query string, prove bool, pagePtr return nil, err } - ti := c.node.GetTxIndexer() + ti := c.node.GetTxIndexer() results, err := ti.Search(ctx, q) if err != nil { return nil, err @@ -653,7 +653,7 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i return nil, err } - bi := c.node.GetBlockIndexer() + bi := c.node.GetBlockIndexer() results, err := bi.Search(ctx, q) if err != nil { return nil, err @@ -688,7 +688,7 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i // Fetch the blocks blocks := make([]*ctypes.ResultBlock, 0, pageSize) - store := c.node.GetStore() + store := c.node.GetStore() for i := skipCount; i < skipCount+pageSize; i++ { b, err := store.LoadBlock(uint64(results[i])) if err != nil { @@ -711,7 +711,7 @@ func (c *Client) BlockSearch(ctx context.Context, query string, page, perPage *i // Status returns detailed information about current status of the node. func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { - store := c.node.GetStore() + store := c.node.GetStore() latest, err := store.LoadBlock(store.Height()) if err != nil { return nil, fmt.Errorf("failed to find latest block: %w", err) @@ -737,7 +737,7 @@ func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { state.Version.Consensus.Block, state.Version.Consensus.App, ) - p2p := c.node.GetP2P() + p2p := c.node.GetP2P() id, addr, network := p2p.Info() txIndexerStatus := "on" @@ -783,7 +783,7 @@ func (c *Client) BroadcastEvidence(ctx context.Context, evidence types.Evidence) // NumUnconfirmedTxs returns information about transactions in mempool. func (c *Client) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) { - mp := c.node.GetMempool() + mp := c.node.GetMempool() return &ctypes.ResultUnconfirmedTxs{ Count: mp.Size(), Total: mp.Size(), @@ -797,7 +797,7 @@ func (c *Client) UnconfirmedTxs(ctx context.Context, limitPtr *int) (*ctypes.Res // reuse per_page validator limit := validatePerPage(limitPtr) - mp := c.node.GetMempool() + mp := c.node.GetMempool() txs := mp.ReapMaxTxs(limit) return &ctypes.ResultUnconfirmedTxs{ Count: len(txs), @@ -871,7 +871,7 @@ func (c *Client) appClient() abcicli.Client { func (c *Client) normalizeHeight(height *int64) uint64 { var heightValue uint64 - store := c.node.GetStore() + store := c.node.GetStore() if height == nil { heightValue = store.Height() } else { From a3dc5f684915ac205edc8121cd7ba4e431e6ecce Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 26 Dec 2022 00:40:05 -0500 Subject: [PATCH 14/18] gofmt config --- config/config.go | 6 +++--- config/defaults.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/config.go b/config/config.go index bc8f44c191..42dfd419b8 100644 --- a/config/config.go +++ b/config/config.go @@ -19,7 +19,7 @@ const ( flagDAStartHeight = "rollmint.da_start_height" flagNamespaceID = "rollmint.namespace_id" flagFraudProofs = "rollmint.experimental_insecure_fraud_proofs" - flagLight = "rollmint.light" + flagLight = "rollmint.light" ) // NodeConfig stores rollmint node configuration. @@ -34,7 +34,7 @@ type NodeConfig struct { BlockManagerConfig `mapstructure:",squash"` DALayer string `mapstructure:"da_layer"` DAConfig string `mapstructure:"da_config"` - Light bool `mapstructure:"light"` + Light bool `mapstructure:"light"` } // BlockManagerConfig consists of all parameters required by BlockManagerConfig @@ -82,5 +82,5 @@ func AddFlags(cmd *cobra.Command) { cmd.Flags().Uint64(flagDAStartHeight, def.DAStartHeight, "starting DA block height (for syncing)") cmd.Flags().BytesHex(flagNamespaceID, def.NamespaceID[:], "namespace identifies (8 bytes in hex)") cmd.Flags().Bool(flagFraudProofs, def.FraudProofs, "enable fraud proofs (experimental & insecure)") - cmd.Flags().Bool(flagLight, def.Light, "run as a light client") + cmd.Flags().Bool(flagLight, def.Light, "run as a light client") } diff --git a/config/defaults.go b/config/defaults.go index 9738ea770c..37af3aac62 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -26,5 +26,5 @@ var DefaultNodeConfig = NodeConfig{ }, DALayer: "mock", DAConfig: "", - Light: false, + Light: false, } From fdd3f5d8df06b702b2e901728d26d6c13c1fe00f Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 2 Jan 2023 22:33:15 -0500 Subject: [PATCH 15/18] NewServer takes a Node interface instead of a FullNode --- rpc/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/server.go b/rpc/server.go index 503b8935c7..8997503e51 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -31,7 +31,7 @@ type Server struct { } // NewServer creates new instance of Server with given configuration. -func NewServer(node *node.FullNode, config *config.RPCConfig, logger log.Logger) *Server { +func NewServer(node node.Node, config *config.RPCConfig, logger log.Logger) *Server { srv := &Server{ config: config, client: client.NewClient(node), From 9e8a9bd2de698e2764a5893120a0441e703e0016 Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 2 Jan 2023 22:34:05 -0500 Subject: [PATCH 16/18] resetored descriptive comment for NewNode --- node/node.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node/node.go b/node/node.go index 2f78fa540e..fe4888536f 100644 --- a/node/node.go +++ b/node/node.go @@ -54,6 +54,7 @@ type Node interface { Stop() error } +// NewNode creates new rollmint node. func NewNode( ctx context.Context, conf config.NodeConfig, From 7d0d4eb3c3953b7a6d5e39eeb06bb7dac44e99eb Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 2 Jan 2023 22:35:12 -0500 Subject: [PATCH 17/18] cleaned up NewNode --- node/node.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/node/node.go b/node/node.go index fe4888536f..7c62172369 100644 --- a/node/node.go +++ b/node/node.go @@ -65,11 +65,9 @@ func NewNode( logger log.Logger, ) (Node, error) { if conf.Light { - n, err := newLightNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) - return n, err + return newLightNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) } else { - n, err := newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) - return n, err + return newFullNode(ctx, conf, p2pKey, signingKey, appClient, genesis, logger) } } From 5476962923ba71e421489904ff674689179883bd Mon Sep 17 00:00:00 2001 From: Connor O'Hara Date: Mon, 2 Jan 2023 22:44:26 -0500 Subject: [PATCH 18/18] added IsRunning to node interface, and updated tests to use NewNode --- node/node.go | 1 + node/node_test.go | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/node/node.go b/node/node.go index 7c62172369..f754bb76eb 100644 --- a/node/node.go +++ b/node/node.go @@ -52,6 +52,7 @@ type Node interface { GetBlockIndexer() indexer.BlockIndexer Start() error Stop() error + IsRunning() bool } // NewNode creates new rollmint node. diff --git a/node/node_test.go b/node/node_test.go index 8121225579..4b19ae88ea 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -31,7 +31,7 @@ func TestStartup(t *testing.T) { app.On("InitChain", mock.Anything).Return(abci.ResponseInitChain{}) key, _, _ := crypto.GenerateEd25519Key(rand.Reader) signingKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) - node, err := newFullNode(context.Background(), config.NodeConfig{DALayer: "mock"}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) + node, err := NewNode(context.Background(), config.NodeConfig{DALayer: "mock", Light: false}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) require.NoError(err) require.NotNil(node) @@ -57,7 +57,8 @@ func TestMempoolDirectly(t *testing.T) { signingKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) anotherKey, _, _ := crypto.GenerateEd25519Key(rand.Reader) - node, err := newFullNode(context.Background(), config.NodeConfig{DALayer: "mock"}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) + newNode, err := NewNode(context.Background(), config.NodeConfig{DALayer: "mock", Light: false}, key, signingKey, abcicli.NewLocalClient(nil, app), &types.GenesisDoc{ChainID: "test"}, log.TestingLogger()) + node := newNode.(*FullNode) require.NoError(err) require.NotNil(node)