diff --git a/.golangci.yml b/.golangci.yml index d85cb585f4..2f943c9884 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,7 +7,7 @@ linters: - errorlint - errcheck - gofmt - - goimports + - gci - gosec - gosimple - govet @@ -44,6 +44,10 @@ linters-settings: - name: exported arguments: - disableStutteringCheck - - goimports: - local-prefixes: github.com/rollkit + gci: + custom-order: true + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - prefix(github.com/rollkit) + - prefix(github.com/rollkit/rollkit) diff --git a/Makefile b/Makefile index 219cf90d12..6931b4d63e 100644 --- a/Makefile +++ b/Makefile @@ -58,11 +58,11 @@ lint: vet .PHONY: lint ## fmt: Run fixes for linters. -fmt: - @echo "--> Formatting markdownlint" - @markdownlint --config .markdownlint.yaml --ignore './cmd/rollkit/docs/*.md' '**/*.md' -f +lint-fix: @echo "--> Formatting go" @golangci-lint run --fix + @echo "--> Formatting markdownlint" + @markdownlint --config .markdownlint.yaml --ignore './cmd/rollkit/docs/*.md' '**/*.md' -f .PHONY: fmt ## vet: Run go vet @@ -74,7 +74,7 @@ vet: ## test: Running unit tests test: vet @echo "--> Running unit tests" - @go test -v -race -covermode=atomic -coverprofile=coverage.txt $(pkgs) -run $(run) -count=$(count) + @go test -race -covermode=atomic -coverprofile=coverage.txt $(pkgs) -run $(run) -count=$(count) .PHONY: test ## proto-gen: Generate protobuf files. Requires docker. diff --git a/block/manager.go b/block/manager.go index 317acab389..68168a4ec6 100644 --- a/block/manager.go +++ b/block/manager.go @@ -12,25 +12,24 @@ import ( "sync/atomic" "time" - cmbytes "github.com/cometbft/cometbft/libs/bytes" - cmstate "github.com/cometbft/cometbft/proto/tendermint/state" - secp256k1 "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/ecdsa" + goheaderstore "github.com/celestiaorg/go-header/store" abci "github.com/cometbft/cometbft/abci/types" cmcrypto "github.com/cometbft/cometbft/crypto" + cmbytes "github.com/cometbft/cometbft/libs/bytes" + cmstate "github.com/cometbft/cometbft/proto/tendermint/state" cmproto "github.com/cometbft/cometbft/proto/tendermint/types" cmtypes "github.com/cometbft/cometbft/types" ds "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/crypto/pb" - goheaderstore "github.com/celestiaorg/go-header/store" - "github.com/rollkit/go-execution" execTypes "github.com/rollkit/go-execution/types" "github.com/rollkit/go-sequencing" "github.com/rollkit/go-sequencing/proxy/grpc" + "github.com/rollkit/rollkit/config" "github.com/rollkit/rollkit/da" "github.com/rollkit/rollkit/store" @@ -177,7 +176,7 @@ type RollkitGenesis struct { // getInitialState tries to load lastState from Store, and if it's not available it reads GenesisDoc. func getInitialState(ctx context.Context, genesis *RollkitGenesis, store store.Store, exec execution.Executor, logger log.Logger) (types.State, error) { // Load the state from store. - s, err := store.GetState(context.Background()) + s, err := store.GetState(ctx) if errors.Is(err, ds.ErrNotFound) { logger.Info("No state found in store, initializing new state") @@ -259,7 +258,7 @@ func NewManager( return nil, err } //set block height in store - store.SetHeight(context.Background(), s.LastBlockHeight) + store.SetHeight(ctx, s.LastBlockHeight) if s.DAHeight < conf.DAStartHeight { s.DAHeight = conf.DAStartHeight @@ -287,7 +286,7 @@ func NewManager( //proposerAddress := s.Validators.Proposer.Address.Bytes() - maxBlobSize, err := dalc.DA.MaxBlobSize(context.Background()) + maxBlobSize, err := dalc.DA.MaxBlobSize(ctx) if err != nil { return nil, err } @@ -307,7 +306,7 @@ func NewManager( } // If lastBatchHash is not set, retrieve the last batch hash from store - lastBatchHash, err := store.GetMetadata(context.Background(), LastBatchHashKey) + lastBatchHash, err := store.GetMetadata(ctx, LastBatchHashKey) if err != nil { logger.Error("error while retrieving last batch hash", "error", err) } @@ -343,7 +342,7 @@ func NewManager( bq: NewBatchQueue(), exec: exec, } - agg.init(context.Background()) + agg.init(ctx) return agg, nil } @@ -675,7 +674,7 @@ func (m *Manager) handleEmptyDataHash(ctx context.Context, header *types.Header) // // SyncLoop processes headers gossiped in P2P network to know what's the latest block height, // block data is retrieved from DA layer. -func (m *Manager) SyncLoop(ctx context.Context, cancel context.CancelFunc) { +func (m *Manager) SyncLoop(ctx context.Context) { daTicker := time.NewTicker(m.conf.DABlockTime) defer daTicker.Stop() blockTicker := time.NewTicker(m.conf.BlockTime) diff --git a/block/sync_service.go b/block/sync_service.go index 3a7c3585e2..fbb127dcc5 100644 --- a/block/sync_service.go +++ b/block/sync_service.go @@ -7,7 +7,11 @@ import ( "fmt" "strings" - "github.com/cometbft/cometbft/libs/log" + "cosmossdk.io/log" + "github.com/celestiaorg/go-header" + goheaderp2p "github.com/celestiaorg/go-header/p2p" + goheaderstore "github.com/celestiaorg/go-header/store" + goheadersync "github.com/celestiaorg/go-header/sync" cmtypes "github.com/cometbft/cometbft/types" ds "github.com/ipfs/go-datastore" pubsub "github.com/libp2p/go-libp2p-pubsub" @@ -16,11 +20,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/net/conngater" "github.com/multiformats/go-multiaddr" - "github.com/celestiaorg/go-header" - goheaderp2p "github.com/celestiaorg/go-header/p2p" - goheaderstore "github.com/celestiaorg/go-header/store" - goheadersync "github.com/celestiaorg/go-header/sync" - "github.com/rollkit/rollkit/config" "github.com/rollkit/rollkit/p2p" "github.com/rollkit/rollkit/types" diff --git a/cmd/rollkit/commands/intercept.go b/cmd/rollkit/commands/intercept.go index 28c6ff3cc3..570ca5edb8 100644 --- a/cmd/rollkit/commands/intercept.go +++ b/cmd/rollkit/commands/intercept.go @@ -8,12 +8,12 @@ import ( "path/filepath" "strings" + cometos "github.com/cometbft/cometbft/libs/os" "github.com/spf13/cobra" "google.golang.org/grpc" - cometos "github.com/cometbft/cometbft/libs/os" - proxy "github.com/rollkit/go-da/proxy/jsonrpc" + rollconf "github.com/rollkit/rollkit/config" ) diff --git a/cmd/rollkit/commands/intercept_test.go b/cmd/rollkit/commands/intercept_test.go index 59d9263c33..bd6eaea022 100644 --- a/cmd/rollkit/commands/intercept_test.go +++ b/cmd/rollkit/commands/intercept_test.go @@ -5,9 +5,9 @@ import ( "os" "testing" - rollconf "github.com/rollkit/rollkit/config" - "github.com/spf13/cobra" + + rollconf "github.com/rollkit/rollkit/config" ) func TestInterceptCommand(t *testing.T) { diff --git a/cmd/rollkit/commands/rebuild.go b/cmd/rollkit/commands/rebuild.go index 369e0a61ba..27ff5cad19 100644 --- a/cmd/rollkit/commands/rebuild.go +++ b/cmd/rollkit/commands/rebuild.go @@ -3,9 +3,9 @@ package commands import ( "log" - rollconf "github.com/rollkit/rollkit/config" - "github.com/spf13/cobra" + + rollconf "github.com/rollkit/rollkit/config" ) // RebuildCmd is a command to rebuild rollup entrypoint diff --git a/cmd/rollkit/commands/root.go b/cmd/rollkit/commands/root.go index 94084f0369..b6f093202c 100644 --- a/cmd/rollkit/commands/root.go +++ b/cmd/rollkit/commands/root.go @@ -1,9 +1,8 @@ package commands import ( - "github.com/spf13/cobra" - cometconfig "github.com/cometbft/cometbft/config" + "github.com/spf13/cobra" ) func init() { diff --git a/cmd/rollkit/commands/run_node.go b/cmd/rollkit/commands/run_node.go index 7b62600441..0b9d04da20 100644 --- a/cmd/rollkit/commands/run_node.go +++ b/cmd/rollkit/commands/run_node.go @@ -11,11 +11,10 @@ import ( "syscall" "time" + "cosmossdk.io/log" cmtcmd "github.com/cometbft/cometbft/cmd/cometbft/commands" cometconf "github.com/cometbft/cometbft/config" cometcli "github.com/cometbft/cometbft/libs/cli" - cometflags "github.com/cometbft/cometbft/libs/cli/flags" - cometlog "github.com/cometbft/cometbft/libs/log" cometos "github.com/cometbft/cometbft/libs/os" cometnode "github.com/cometbft/cometbft/node" cometp2p "github.com/cometbft/cometbft/p2p" @@ -23,25 +22,23 @@ import ( comettypes "github.com/cometbft/cometbft/types" comettime "github.com/cometbft/cometbft/types/time" "github.com/mitchellh/mapstructure" + "github.com/spf13/cobra" + "github.com/spf13/viper" "google.golang.org/grpc" "github.com/rollkit/go-da" proxy "github.com/rollkit/go-da/proxy/jsonrpc" goDATest "github.com/rollkit/go-da/test" + execGRPC "github.com/rollkit/go-execution/proxy/grpc" + execTest "github.com/rollkit/go-execution/test" + execTypes "github.com/rollkit/go-execution/types" + pb "github.com/rollkit/go-execution/types/pb/execution" seqGRPC "github.com/rollkit/go-sequencing/proxy/grpc" seqTest "github.com/rollkit/go-sequencing/test" - "github.com/spf13/cobra" - "github.com/spf13/viper" - rollconf "github.com/rollkit/rollkit/config" rollnode "github.com/rollkit/rollkit/node" rolltypes "github.com/rollkit/rollkit/types" - - execGRPC "github.com/rollkit/go-execution/proxy/grpc" - execTest "github.com/rollkit/go-execution/test" - execTypes "github.com/rollkit/go-execution/types" - pb "github.com/rollkit/go-execution/types/pb/execution" ) var ( @@ -52,7 +49,7 @@ var ( nodeConfig = rollconf.DefaultNodeConfig // initialize the logger with the cometBFT defaults - logger = cometlog.NewTMLogger(cometlog.NewSyncWriter(os.Stdout)) + logger = log.NewLogger(os.Stdout) errDAServerAlreadyRunning = errors.New("DA server already running") errSequencerAlreadyRunning = errors.New("sequencer already running") @@ -78,20 +75,20 @@ func NewRunNodeCmd() *cobra.Command { } // Update log format if the flag is set - if config.LogFormat == cometconf.LogFormatJSON { - logger = cometlog.NewTMJSONLogger(cometlog.NewSyncWriter(os.Stdout)) - } + // if config.LogFormat == cometconf.LogFormatJSON { + // logger = cometlog.NewTMJSONLogger(cometlog.NewSyncWriter(os.Stdout)) + // } - // Parse the log level - logger, err = cometflags.ParseLogLevel(config.LogLevel, logger, cometconf.DefaultLogLevel) - if err != nil { - return err - } + // // Parse the log level + // logger, err = cometflags.ParseLogLevel(config.LogLevel, logger, cometconf.DefaultLogLevel) + // if err != nil { + // return err + // } - // Add tracing to the logger if the flag is set - if viper.GetBool(cometcli.TraceFlag) { - logger = cometlog.NewTracingLogger(logger) - } + // // Add tracing to the logger if the flag is set + // if viper.GetBool(cometcli.TraceFlag) { + // logger = cometlog.NewTracingLogger(logger) + // } logger = logger.With("module", "main") @@ -192,9 +189,12 @@ func NewRunNodeCmd() *cobra.Command { config.ProxyApp = "noop" } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + // create the rollkit node rollnode, err := rollnode.NewNode( - context.Background(), + ctx, nodeConfig, p2pKey, signingKey, @@ -207,7 +207,7 @@ func NewRunNodeCmd() *cobra.Command { } // Start the node - if err := rollnode.Start(); err != nil { + if err := rollnode.Start(ctx); err != nil { return fmt.Errorf("failed to start node: %w", err) } @@ -217,7 +217,7 @@ func NewRunNodeCmd() *cobra.Command { // Stop upon receiving SIGTERM or CTRL-C. cometos.TrapSignal(logger, func() { if rollnode.IsRunning() { - if err := rollnode.Stop(); err != nil { + if err := rollnode.Stop(ctx); err != nil { logger.Error("unable to stop the node", "error", err) } } @@ -239,7 +239,7 @@ func NewRunNodeCmd() *cobra.Command { return fmt.Errorf("node is not running") } - return rollnode.Stop() + return rollnode.Stop(ctx) }, } diff --git a/cmd/rollkit/commands/run_node_test.go b/cmd/rollkit/commands/run_node_test.go index c12f4c11a2..2329548955 100644 --- a/cmd/rollkit/commands/run_node_test.go +++ b/cmd/rollkit/commands/run_node_test.go @@ -14,6 +14,7 @@ import ( "github.com/rollkit/go-da" proxy "github.com/rollkit/go-da/proxy/jsonrpc" + rollconf "github.com/rollkit/rollkit/config" ) diff --git a/cmd/rollkit/commands/toml.go b/cmd/rollkit/commands/toml.go index b431205e27..48070ff198 100644 --- a/cmd/rollkit/commands/toml.go +++ b/cmd/rollkit/commands/toml.go @@ -4,9 +4,9 @@ import ( "fmt" "os" - rollconf "github.com/rollkit/rollkit/config" - "github.com/spf13/cobra" + + rollconf "github.com/rollkit/rollkit/config" ) // NewTomlCmd creates a new cobra command group for TOML file operations. diff --git a/config/config.go b/config/config.go index 2513431cc2..17f016417e 100644 --- a/config/config.go +++ b/config/config.go @@ -4,7 +4,6 @@ import ( "time" cmcfg "github.com/cometbft/cometbft/config" - "github.com/spf13/cobra" "github.com/spf13/viper" ) diff --git a/config/config_test.go b/config/config_test.go index a8cdbf82ae..d528114625 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,7 +5,6 @@ import ( "time" cmcfg "github.com/cometbft/cometbft/config" - "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/stretchr/testify/assert" diff --git a/da/da.go b/da/da.go index ce07652585..d65f038b72 100644 --- a/da/da.go +++ b/da/da.go @@ -10,6 +10,7 @@ import ( "github.com/gogo/protobuf/proto" goDA "github.com/rollkit/go-da" + "github.com/rollkit/rollkit/third_party/log" "github.com/rollkit/rollkit/types" pb "github.com/rollkit/rollkit/types/pb/rollkit" diff --git a/da/da_test.go b/da/da_test.go index 3ce43b826f..cce928fa22 100644 --- a/da/da_test.go +++ b/da/da_test.go @@ -21,6 +21,7 @@ import ( proxygrpc "github.com/rollkit/go-da/proxy/grpc" proxyjsonrpc "github.com/rollkit/go-da/proxy/jsonrpc" goDATest "github.com/rollkit/go-da/test" + testServer "github.com/rollkit/rollkit/test/server" "github.com/rollkit/rollkit/types" ) diff --git a/go.mod b/go.mod index 6916ade7ad..d94f68c067 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,18 @@ module github.com/rollkit/rollkit -go 1.23.3 +go 1.24 retract v0.12.0 // Published by accident require ( + cosmossdk.io/log v1.5.0 github.com/BurntSushi/toml v1.4.0 github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/celestiaorg/go-header v0.6.4 github.com/celestiaorg/utils v0.1.0 github.com/cometbft/cometbft v0.38.15 - github.com/cosmos/gogoproto v1.7.0 // indirect github.com/go-kit/kit v0.13.0 github.com/gogo/protobuf v1.3.2 - github.com/gorilla/websocket v1.5.3 // indirect github.com/ipfs/go-datastore v0.7.0 github.com/ipfs/go-ds-badger4 v0.1.5 github.com/ipfs/go-log v1.0.5 @@ -24,25 +23,26 @@ require ( github.com/multiformats/go-multiaddr v0.14.0 github.com/prometheus/client_golang v1.21.0 github.com/rollkit/go-da v0.9.0 + github.com/rollkit/go-execution v0.2.3 github.com/rollkit/go-sequencing v0.4.1 - github.com/rs/cors v1.11.1 // indirect github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 - golang.org/x/net v0.35.0 // indirect google.golang.org/grpc v1.70.0 google.golang.org/protobuf v1.36.5 ) -require github.com/rollkit/go-execution v0.2.3 - require ( github.com/DataDog/zstd v1.4.5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect + github.com/bytedance/sonic v1.12.3 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -52,6 +52,7 @@ require ( github.com/cometbft/cometbft-db v0.14.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cosmos/gogoproto v1.7.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect @@ -85,6 +86,7 @@ require ( github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect @@ -121,6 +123,7 @@ require ( github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.63 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect @@ -176,6 +179,8 @@ require ( github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rs/cors v1.11.1 // indirect + github.com/rs/zerolog v1.33.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -188,6 +193,7 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/wlynxg/anet v0.0.5 // indirect go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect @@ -201,9 +207,11 @@ require ( go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/crypto v0.33.0 // indirect golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect golang.org/x/mod v0.23.0 // indirect + golang.org/x/net v0.35.0 // indirect golang.org/x/sync v0.11.0 // indirect golang.org/x/sys v0.30.0 // indirect golang.org/x/text v0.22.0 // indirect diff --git a/go.sum b/go.sum index 011ffc0f62..203cae6379 100644 --- a/go.sum +++ b/go.sum @@ -32,6 +32,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cosmossdk.io/log v1.5.0 h1:dVdzPJW9kMrnAYyMf1duqacoidB9uZIl+7c6z0mnq0g= +cosmossdk.io/log v1.5.0/go.mod h1:Tr46PUJjiUthlwQ+hxYtUtPn4D/oCZXAkYevBeh5+FI= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= @@ -111,6 +113,11 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU= +github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/celestiaorg/go-header v0.6.4 h1:3kXi7N3qBc4SCmT+tNVWhLi0Ilw5e/7qq2cxVGbs0ss= github.com/celestiaorg/go-header v0.6.4/go.mod h1:Az4S4NxMOJ1eAzOaF8u5AZt5UzsSzg92uqpdXS3yOZE= @@ -134,6 +141,10 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= @@ -537,6 +548,7 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -700,11 +712,15 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8 github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -1012,6 +1028,9 @@ github.com/rollkit/go-sequencing v0.4.1 h1:P0x1wUFIAhdEeqUbrRAF343iExKhq9UkVOBbi github.com/rollkit/go-sequencing v0.4.1/go.mod h1:QnOk8mqyVgFWdMnjvZVBG4x8GC/TsRtoN5XdPZzfCSs= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -1122,6 +1141,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -1212,6 +1233,8 @@ go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1453,12 +1476,14 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= @@ -1713,6 +1738,7 @@ lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/node/execution_test.go b/node/execution_test.go index 62c91e5fc2..ca8d687d0c 100644 --- a/node/execution_test.go +++ b/node/execution_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/require" "github.com/rollkit/go-execution" - "github.com/rollkit/rollkit/types" - execTest "github.com/rollkit/go-execution/test" execTypes "github.com/rollkit/go-execution/types" + + "github.com/rollkit/rollkit/types" ) func TestBasicExecutionFlow(t *testing.T) { @@ -87,10 +87,10 @@ func TestExecutionWithDASync(t *testing.T) { require.NotNil(seqSrv) // Start node - err := node.Start() + err := node.Start(t.Context()) require.NoError(err) defer func() { - err := node.Stop() + err := node.Stop(t.Context()) require.NoError(err) seqSrv.GracefulStop() }() diff --git a/node/full.go b/node/full.go index 3c8ad1231d..6f2fad9b5e 100644 --- a/node/full.go +++ b/node/full.go @@ -9,8 +9,8 @@ import ( "fmt" "net/http" - execproxy "github.com/rollkit/go-execution/proxy/grpc" - + "cosmossdk.io/log" + cmtypes "github.com/cometbft/cometbft/types" ds "github.com/ipfs/go-datastore" ktds "github.com/ipfs/go-datastore/keytransform" "github.com/libp2p/go-libp2p/core/crypto" @@ -19,18 +19,16 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "github.com/cometbft/cometbft/libs/log" - "github.com/cometbft/cometbft/libs/service" - cmtypes "github.com/cometbft/cometbft/types" - proxyda "github.com/rollkit/go-da/proxy" "github.com/rollkit/go-execution" + execproxy "github.com/rollkit/go-execution/proxy/grpc" seqGRPC "github.com/rollkit/go-sequencing/proxy/grpc" "github.com/rollkit/rollkit/block" "github.com/rollkit/rollkit/config" "github.com/rollkit/rollkit/da" "github.com/rollkit/rollkit/p2p" + "github.com/rollkit/rollkit/pkg/service" "github.com/rollkit/rollkit/store" "github.com/rollkit/rollkit/types" ) @@ -72,8 +70,6 @@ type FullNode struct { // keep context here only because of API compatibility // - it's used in `OnStart` (defined in service.Service interface) - ctx context.Context - cancel context.CancelFunc threadManager *types.ThreadManager seqClient *seqGRPC.Client } @@ -88,23 +84,8 @@ func newFullNode( metricsProvider MetricsProvider, logger log.Logger, ) (fn *FullNode, err error) { - // Create context with cancel so that all services using the context can - // catch the cancel signal when the node shutdowns - ctx, cancel := context.WithCancel(ctx) - defer func() { - // If there is an error, cancel the context - if err != nil { - cancel() - } - }() - seqMetrics, p2pMetrics := metricsProvider(genesis.ChainID) - eventBus, err := initEventBus(logger) - if err != nil { - return nil, err - } - baseKV, err := initBaseKV(nodeConfig, logger) if err != nil { return nil, err @@ -135,13 +116,12 @@ func newFullNode( store := store.New(mainKV) - blockManager, err := initBlockManager(signingKey, nodeConfig, genesis, store, seqClient, dalc, eventBus, logger, headerSyncService, dataSyncService, seqMetrics) + blockManager, err := initBlockManager(signingKey, nodeConfig, genesis, store, seqClient, dalc, logger, headerSyncService, dataSyncService, seqMetrics) if err != nil { return nil, err } node := &FullNode{ - eventBus: eventBus, genesis: genesis, nodeConfig: nodeConfig, p2pClient: p2pClient, @@ -151,8 +131,6 @@ func newFullNode( Store: store, hSyncService: headerSyncService, dSyncService: dataSyncService, - ctx: ctx, - cancel: cancel, threadManager: types.NewThreadManager(), } @@ -161,15 +139,6 @@ func newFullNode( return node, nil } -func initEventBus(logger log.Logger) (*cmtypes.EventBus, error) { - eventBus := cmtypes.NewEventBus() - eventBus.SetLogger(logger.With("module", "events")) - if err := eventBus.Start(); err != nil { - return nil, err - } - return eventBus, nil -} - // initBaseKV initializes the base key-value store. func initBaseKV(nodeConfig config.NodeConfig, logger log.Logger) (ds.TxnDatastore, error) { if nodeConfig.RootDir == "" && nodeConfig.DBPath == "" { // this is used for testing @@ -219,7 +188,7 @@ func initDataSyncService(mainKV ds.TxnDatastore, nodeConfig config.NodeConfig, g return dataSyncService, nil } -func initBlockManager(signingKey crypto.PrivKey, nodeConfig config.NodeConfig, genesis *cmtypes.GenesisDoc, store store.Store, seqClient *seqGRPC.Client, dalc *da.DAClient, eventBus *cmtypes.EventBus, logger log.Logger, headerSyncService *block.HeaderSyncService, dataSyncService *block.DataSyncService, seqMetrics *block.Metrics) (*block.Manager, error) { +func initBlockManager(signingKey crypto.PrivKey, nodeConfig config.NodeConfig, genesis *cmtypes.GenesisDoc, store store.Store, seqClient *seqGRPC.Client, dalc *da.DAClient, logger log.Logger, headerSyncService *block.HeaderSyncService, dataSyncService *block.DataSyncService, seqMetrics *block.Metrics) (*block.Manager, error) { exec, err := initExecutor(nodeConfig) if err != nil { return nil, fmt.Errorf("error while initializing executor: %w", err) @@ -311,11 +280,6 @@ func (n *FullNode) dataPublishLoop(ctx context.Context) { } } -// Cancel calls the underlying context's cancel function. -func (n *FullNode) Cancel() { - n.cancel() -} - // startPrometheusServer starts a Prometheus HTTP server, listening for metrics // collectors on addr. func (n *FullNode) startPrometheusServer() *http.Server { @@ -339,22 +303,22 @@ func (n *FullNode) startPrometheusServer() *http.Server { } // OnStart is a part of Service interface. -func (n *FullNode) OnStart() error { +func (n *FullNode) OnStart(ctx context.Context) error { // begin prometheus metrics gathering if it is enabled if n.nodeConfig.Instrumentation != nil && n.nodeConfig.Instrumentation.IsPrometheusEnabled() { n.prometheusSrv = n.startPrometheusServer() } n.Logger.Info("starting P2P client") - err := n.p2pClient.Start(n.ctx) + err := n.p2pClient.Start(ctx) if err != nil { return fmt.Errorf("error while starting P2P client: %w", err) } - if err = n.hSyncService.Start(n.ctx); err != nil { + if err = n.hSyncService.Start(ctx); err != nil { return fmt.Errorf("error while starting header sync service: %w", err) } - if err = n.dSyncService.Start(n.ctx); err != nil { + if err = n.dSyncService.Start(ctx); err != nil { return fmt.Errorf("error while starting data sync service: %w", err) } @@ -368,17 +332,17 @@ func (n *FullNode) OnStart() error { if n.nodeConfig.Aggregator { n.Logger.Info("working in aggregator mode", "block time", n.nodeConfig.BlockTime) - n.threadManager.Go(func() { n.blockManager.BatchRetrieveLoop(n.ctx) }) - n.threadManager.Go(func() { n.blockManager.AggregationLoop(n.ctx) }) - n.threadManager.Go(func() { n.blockManager.HeaderSubmissionLoop(n.ctx) }) - n.threadManager.Go(func() { n.headerPublishLoop(n.ctx) }) - n.threadManager.Go(func() { n.dataPublishLoop(n.ctx) }) + n.threadManager.Go(func() { n.blockManager.BatchRetrieveLoop(ctx) }) + n.threadManager.Go(func() { n.blockManager.AggregationLoop(ctx) }) + n.threadManager.Go(func() { n.blockManager.HeaderSubmissionLoop(ctx) }) + n.threadManager.Go(func() { n.headerPublishLoop(ctx) }) + n.threadManager.Go(func() { n.dataPublishLoop(ctx) }) return nil } - n.threadManager.Go(func() { n.blockManager.RetrieveLoop(n.ctx) }) - n.threadManager.Go(func() { n.blockManager.HeaderStoreRetrieveLoop(n.ctx) }) - n.threadManager.Go(func() { n.blockManager.DataStoreRetrieveLoop(n.ctx) }) - n.threadManager.Go(func() { n.blockManager.SyncLoop(n.ctx, n.cancel) }) + n.threadManager.Go(func() { n.blockManager.RetrieveLoop(ctx) }) + n.threadManager.Go(func() { n.blockManager.HeaderStoreRetrieveLoop(ctx) }) + n.threadManager.Go(func() { n.blockManager.DataStoreRetrieveLoop(ctx) }) + n.threadManager.Go(func() { n.blockManager.SyncLoop(ctx) }) return nil } @@ -401,27 +365,26 @@ func (n *FullNode) GetGenesisChunks() ([]string, error) { // p2pClient and sync services stop first, ceasing network activities. Then rest of services are halted. // Context is cancelled to signal goroutines managed by thread manager to stop. // Store is closed last because it's used by other services/goroutines. -func (n *FullNode) OnStop() { +func (n *FullNode) OnStop(ctx context.Context) { n.Logger.Info("halting full node...") n.Logger.Info("shutting down full node sub services...") err := errors.Join( n.p2pClient.Close(), - n.hSyncService.Stop(n.ctx), - n.dSyncService.Stop(n.ctx), + n.hSyncService.Stop(ctx), + n.dSyncService.Stop(ctx), n.seqClient.Stop(), ) if n.prometheusSrv != nil { - err = errors.Join(err, n.prometheusSrv.Shutdown(n.ctx)) + err = errors.Join(err, n.prometheusSrv.Shutdown(ctx)) } - n.cancel() n.threadManager.Wait() err = errors.Join(err, n.Store.Close()) n.Logger.Error("errors while stopping node:", "errors", err) } // OnReset is a part of Service interface. -func (n *FullNode) OnReset() error { +func (n *FullNode) OnReset(ctx context.Context) error { panic("OnReset - not implemented!") } @@ -445,13 +408,13 @@ func newPrefixKV(kvStore ds.Datastore, prefix string) ds.TxnDatastore { } // Start implements NodeLifecycle -func (fn *FullNode) Start() error { - return fn.BaseService.Start() +func (fn *FullNode) Start(ctx context.Context) error { + return fn.BaseService.Start(ctx) } // Stop implements NodeLifecycle -func (fn *FullNode) Stop() error { - return fn.BaseService.Stop() +func (fn *FullNode) Stop(ctx context.Context) error { + return fn.BaseService.Stop(ctx) } // IsRunning implements NodeLifecycle diff --git a/node/full_node_integration_test.go b/node/full_node_integration_test.go index 8c093122e4..6df30f8ac8 100644 --- a/node/full_node_integration_test.go +++ b/node/full_node_integration_test.go @@ -6,10 +6,9 @@ import ( "testing" "time" + "cosmossdk.io/log" testutils "github.com/celestiaorg/utils/test" cmcfg "github.com/cometbft/cometbft/config" - - "github.com/cometbft/cometbft/libs/log" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -53,7 +52,7 @@ func (s *FullNodeTestSuite) SetupTest() { signingKey, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), - log.TestingLogger(), + log.NewTestLogger(s.T()), ) require.NoError(s.T(), err) require.NotNil(s.T(), node) @@ -61,7 +60,7 @@ func (s *FullNodeTestSuite) SetupTest() { fn, ok := node.(*FullNode) require.True(s.T(), ok) - err = fn.Start() + err = fn.Start(s.ctx) require.NoError(s.T(), err) s.node = fn @@ -125,7 +124,7 @@ func (s *FullNodeTestSuite) TearDownTest() { s.cancel() } if s.node != nil { - err := s.node.Stop() + err := s.node.Stop(s.ctx) if err != nil { s.T().Logf("Error stopping node in teardown: %v", err) } @@ -309,7 +308,7 @@ func (s *FullNodeTestSuite) TestMaxPending() { require := require.New(s.T()) // Reconfigure node with low max pending - err := s.node.Stop() + err := s.node.Stop(s.ctx) require.NoError(err) config := getTestConfig(1) @@ -328,7 +327,7 @@ func (s *FullNodeTestSuite) TestMaxPending() { signingKey, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), - log.TestingLogger(), + log.NewTestLogger(s.T()), ) require.NoError(err) require.NotNil(node) @@ -336,7 +335,7 @@ func (s *FullNodeTestSuite) TestMaxPending() { fn, ok := node.(*FullNode) require.True(ok) - err = fn.Start() + err = fn.Start(s.ctx) require.NoError(err) s.node = fn @@ -369,8 +368,8 @@ func (s *FullNodeTestSuite) TestStateRecovery() { time.Sleep(2 * s.node.nodeConfig.BlockTime) // Restart node, we don't need to check for errors - _ = s.node.Stop() - _ = s.node.Start() + _ = s.node.Stop(s.ctx) + _ = s.node.Start(s.ctx) // Wait a bit after restart time.Sleep(s.node.nodeConfig.BlockTime) @@ -402,7 +401,7 @@ func (s *FullNodeTestSuite) TestInvalidDAConfig() { signingKey, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), - log.TestingLogger(), + log.NewTestLogger(s.T()), ) // Verify that node creation fails with appropriate error diff --git a/node/full_node_test.go b/node/full_node_test.go index a826167822..90dfffe943 100644 --- a/node/full_node_test.go +++ b/node/full_node_test.go @@ -11,9 +11,9 @@ func TestStartup(t *testing.T) { node, cleanup := setupTestNodeWithCleanup(t) require.IsType(t, new(FullNode), node) require.False(t, node.IsRunning()) - require.NoError(t, node.Start()) + require.NoError(t, node.Start(t.Context())) require.True(t, node.IsRunning()) - require.NoError(t, node.Stop()) + require.NoError(t, node.Stop(t.Context())) require.False(t, node.IsRunning()) cleanup() require.False(t, node.IsRunning()) diff --git a/node/helpers.go b/node/helpers.go index 80d9498298..167ee8f335 100644 --- a/node/helpers.go +++ b/node/helpers.go @@ -51,14 +51,6 @@ func getNodeHeight(node Node, source Source) (uint64, error) { } } -//nolint:unused -func isBlockHashSeen(node Node, blockHash string) bool { - if fn, ok := node.(*FullNode); ok { - return fn.blockManager.IsBlockHashSeen(blockHash) - } - return false -} - func getNodeHeightFromHeader(node Node) (uint64, error) { if fn, ok := node.(*FullNode); ok { return fn.hSyncService.Store().Height(), nil @@ -105,16 +97,6 @@ func waitForAtLeastNBlocks(node Node, n int, source Source) error { }) } -//nolint:unused -func waitUntilBlockHashSeen(node Node, blockHash string) error { - return Retry(300, 100*time.Millisecond, func() error { - if isBlockHashSeen(node, blockHash) { - return nil - } - return fmt.Errorf("block hash %v not seen", blockHash) - }) -} - // Retry attempts to execute the provided function up to the specified number of tries, // with a delay between attempts. It returns nil if the function succeeds, or the last // error encountered if all attempts fail. diff --git a/node/helpers_test.go b/node/helpers_test.go index 89a5006e59..0fbda1e5e0 100644 --- a/node/helpers_test.go +++ b/node/helpers_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" + "cosmossdk.io/log" cmcfg "github.com/cometbft/cometbft/config" - "github.com/cometbft/cometbft/libs/log" "github.com/libp2p/go-libp2p/core/crypto" "github.com/stretchr/testify/require" @@ -54,12 +54,12 @@ func setupTestNodeWithCleanup(t *testing.T) (*FullNode, func()) { p2pKey := generateSingleKey() - node, err := NewNode(ctx, config, p2pKey, signingKey, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), log.TestingLogger()) + node, err := NewNode(ctx, config, p2pKey, signingKey, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), log.NewTestLogger(t)) require.NoError(t, err) cleanup := func() { if fn, ok := node.(*FullNode); ok { - _ = fn.Stop() + _ = fn.Stop(ctx) } } diff --git a/node/light.go b/node/light.go index a0074c2e8c..7fdefa768c 100644 --- a/node/light.go +++ b/node/light.go @@ -5,8 +5,7 @@ import ( "errors" "fmt" - "github.com/cometbft/cometbft/libs/log" - "github.com/cometbft/cometbft/libs/service" + "cosmossdk.io/log" cmtypes "github.com/cometbft/cometbft/types" ds "github.com/ipfs/go-datastore" "github.com/libp2p/go-libp2p/core/crypto" @@ -14,6 +13,7 @@ import ( "github.com/rollkit/rollkit/block" "github.com/rollkit/rollkit/config" "github.com/rollkit/rollkit/p2p" + "github.com/rollkit/rollkit/pkg/service" "github.com/rollkit/rollkit/store" ) @@ -26,9 +26,6 @@ type LightNode struct { P2P *p2p.Client hSyncService *block.HeaderSyncService - - ctx context.Context - cancel context.CancelFunc } func newLightNode( @@ -39,15 +36,6 @@ func newLightNode( metricsProvider MetricsProvider, logger log.Logger, ) (ln *LightNode, err error) { - // Create context with cancel so that all services using the context can - // catch the cancel signal when the node shutdowns - ctx, cancel := context.WithCancel(ctx) - defer func() { - // If there is an error, cancel the context - if err != nil { - cancel() - } - }() _, p2pMetrics := metricsProvider(genesis.ChainID) @@ -68,8 +56,6 @@ func newLightNode( node := &LightNode{ P2P: client, hSyncService: headerSyncService, - cancel: cancel, - ctx: ctx, } node.BaseService = *service.NewBaseService(logger, "LightNode", node) @@ -85,18 +71,13 @@ func openDatastore(conf config.NodeConfig, logger log.Logger) (ds.TxnDatastore, return store.NewDefaultKVStore(conf.RootDir, conf.DBPath, "rollkit-light") } -// Cancel calls the underlying context's cancel function. -func (n *LightNode) Cancel() { - n.cancel() -} - // OnStart starts the P2P and HeaderSync services -func (ln *LightNode) OnStart() error { - if err := ln.P2P.Start(ln.ctx); err != nil { +func (ln *LightNode) OnStart(ctx context.Context) error { + if err := ln.P2P.Start(ctx); err != nil { return err } - if err := ln.hSyncService.Start(ln.ctx); err != nil { + if err := ln.hSyncService.Start(ctx); err != nil { return fmt.Errorf("error while starting header sync service: %w", err) } @@ -104,10 +85,9 @@ func (ln *LightNode) OnStart() error { } // OnStop stops the light node -func (ln *LightNode) OnStop() { +func (ln *LightNode) OnStop(ctx context.Context) { ln.Logger.Info("halting light node...") - ln.cancel() err := ln.P2P.Close() - err = errors.Join(err, ln.hSyncService.Stop(ln.ctx)) + err = errors.Join(err, ln.hSyncService.Stop(ctx)) ln.Logger.Error("errors while stopping node:", "errors", err) } diff --git a/node/node.go b/node/node.go index 28d148b400..1b6f643c1d 100644 --- a/node/node.go +++ b/node/node.go @@ -3,20 +3,18 @@ package node import ( "context" - "github.com/libp2p/go-libp2p/core/crypto" - - "github.com/cometbft/cometbft/libs/log" + "cosmossdk.io/log" cmtypes "github.com/cometbft/cometbft/types" + "github.com/libp2p/go-libp2p/core/crypto" "github.com/rollkit/rollkit/config" ) // Node is the interface for a rollup node type Node interface { - Start() error - Stop() error + Start(ctx context.Context) error + Stop(ctx context.Context) error IsRunning() bool - Cancel() } // NewNode returns a new Full or Light Node based on the config diff --git a/node/node_integration_test.go b/node/node_integration_test.go index 94cedd83ae..2491118f74 100644 --- a/node/node_integration_test.go +++ b/node/node_integration_test.go @@ -6,14 +6,13 @@ import ( "testing" "time" - "github.com/cometbft/cometbft/libs/log" + "cosmossdk.io/log" + testutils "github.com/celestiaorg/utils/test" + cmcfg "github.com/cometbft/cometbft/config" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "google.golang.org/grpc" - testutils "github.com/celestiaorg/utils/test" - cmcfg "github.com/cometbft/cometbft/config" - "github.com/rollkit/rollkit/config" "github.com/rollkit/rollkit/types" ) @@ -53,7 +52,7 @@ func (s *NodeIntegrationTestSuite) SetupTest() { signingKey, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), - log.TestingLogger(), + log.NewTestLogger(s.T()), ) require.NoError(s.T(), err) require.NotNil(s.T(), node) @@ -61,7 +60,7 @@ func (s *NodeIntegrationTestSuite) SetupTest() { fn, ok := node.(*FullNode) require.True(s.T(), ok) - err = fn.Start() + err = fn.Start(s.ctx) require.NoError(s.T(), err) s.node = fn @@ -96,7 +95,7 @@ func (s *NodeIntegrationTestSuite) TearDownTest() { s.cancel() } if s.node != nil { - _ = s.node.Stop() + _ = s.node.Stop(s.ctx) } if s.seqSrv != nil { s.seqSrv.GracefulStop() @@ -171,11 +170,11 @@ func (s *NodeIntegrationTestSuite) setupNodeWithConfig(conf config.NodeConfig) N key, genesis, DefaultMetricsProvider(cmcfg.DefaultInstrumentationConfig()), - log.TestingLogger(), + log.NewTestLogger(s.T()), ) require.NoError(s.T(), err) - err = node.Start() + err = node.Start(s.ctx) require.NoError(s.T(), err) return node diff --git a/node/node_test.go b/node/node_test.go index 168d916fa6..1d6fc59f66 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -8,16 +8,11 @@ import ( "testing" "time" + "cosmossdk.io/log" cmconfig "github.com/cometbft/cometbft/config" cmcrypto "github.com/cometbft/cometbft/crypto" "github.com/stretchr/testify/require" - - "github.com/rollkit/rollkit/config" - test "github.com/rollkit/rollkit/test/log" - "github.com/rollkit/rollkit/types" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" goDAproxy "github.com/rollkit/go-da/proxy/grpc" @@ -28,6 +23,9 @@ import ( pb "github.com/rollkit/go-execution/types/pb/execution" seqGRPC "github.com/rollkit/go-sequencing/proxy/grpc" seqTest "github.com/rollkit/go-sequencing/test" + + "github.com/rollkit/rollkit/config" + "github.com/rollkit/rollkit/types" ) const ( @@ -143,7 +141,7 @@ const ( // startNode starts the full node and stops it when the test is done func startNodeWithCleanup(t *testing.T, node Node) { require.False(t, node.IsRunning()) - require.NoError(t, node.Start()) + require.NoError(t, node.Start(t.Context())) require.True(t, node.IsRunning()) t.Cleanup(func() { cleanUpNode(node, t) @@ -153,7 +151,7 @@ func startNodeWithCleanup(t *testing.T, node Node) { // cleanUpNode stops the node and checks if it is running func cleanUpNode(node Node, t *testing.T) { // Attempt to stop the node - err := node.Stop() + err := node.Stop(t.Context()) require.NoError(t, err) // Now verify that the node is no longer running require.False(t, node.IsRunning()) @@ -194,7 +192,7 @@ func newTestNode(ctx context.Context, t *testing.T, nodeType NodeType, chainID s key := generateSingleKey() - logger := test.NewFileLogger(t) + logger := log.NewTestLogger(t) node, err := NewNode(ctx, config, key, signingKey, genesis, DefaultMetricsProvider(cmconfig.DefaultInstrumentationConfig()), logger) return node, genesisValidatorKey, err } diff --git a/p2p/client.go b/p2p/client.go index 5ef32aa4ee..6931e99d2c 100644 --- a/p2p/client.go +++ b/p2p/client.go @@ -14,7 +14,6 @@ import ( libp2p "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" pubsub "github.com/libp2p/go-libp2p-pubsub" - "github.com/libp2p/go-libp2p/core/crypto" cdiscovery "github.com/libp2p/go-libp2p/core/discovery" "github.com/libp2p/go-libp2p/core/host" diff --git a/p2p/metrics.go b/p2p/metrics.go index b15b716a14..933827e59d 100644 --- a/p2p/metrics.go +++ b/p2p/metrics.go @@ -3,7 +3,6 @@ package p2p import ( "github.com/go-kit/kit/metrics" "github.com/go-kit/kit/metrics/discard" - prometheus "github.com/go-kit/kit/metrics/prometheus" stdprometheus "github.com/prometheus/client_golang/prometheus" ) diff --git a/pkg/service/baseservice.go b/pkg/service/baseservice.go new file mode 100644 index 0000000000..95c0d6d493 --- /dev/null +++ b/pkg/service/baseservice.go @@ -0,0 +1,196 @@ +package service + +import ( + "context" + "errors" + "fmt" + + "cosmossdk.io/log" +) + +/* +type FooService struct { + BaseService + // extra fields for FooService +} +func NewFooService(logger log.Logger) *FooService { + fs := &FooService{} + fs.BaseService = *NewBaseService(logger, "FooService", fs) + return fs +} +func (fs *FooService) OnStart(ctx context.Context) error { + // initialize fields, start goroutines, etc. + go func() { + <-ctx.Done() + // cleanup when context is cancelled + }() + return nil +} +func (fs *FooService) OnStop(ctx context.Context) { + // stop routines, cleanup resources, etc. +} +func (fs *FooService) OnReset(ctx context.Context) error { + // implement reset if desired + return nil +} +*/ + +var ( + // ErrAlreadyStarted is returned when somebody tries to start an already running service. + ErrAlreadyStarted = errors.New("already started") + // ErrNotStarted is returned when somebody tries to stop a not running service. + ErrNotStarted = errors.New("not started") +) + +// Service defines a service that can be started, stopped, and reset. +type Service interface { + // Start the service. If it's already started, returns an error. + Start(context.Context) error + OnStart(context.Context) error + + // Stop the service. If it's not started, returns an error. + Stop(context.Context) error + OnStop(context.Context) + + // Reset the service. Panics by default - must be overwritten to enable reset. + Reset(context.Context) error + OnReset(context.Context) error + + // Return true if the service is running. + IsRunning() bool + + // Quit returns a channel which is closed once the service is stopped. + Quit() <-chan struct{} + + // String returns a string representation of the service. + String() string + + // SetLogger sets a logger. + SetLogger(log.Logger) +} + +// BaseService uses a cancellable context to manage service lifetime. +// Instead of manually handling atomic flags and a quit channel, +// we create a context when the service is started and cancel it when stopping. +type BaseService struct { + Logger log.Logger + name string + impl Service + + // A cancellable context used to signal the service has stopped. + ctx context.Context + cancel context.CancelFunc +} + +// NewBaseService creates a new BaseService. +// The provided implementation (impl) must be the "subclass" that implements OnStart, OnStop, and OnReset. +func NewBaseService(logger log.Logger, name string, impl Service) *BaseService { + if logger == nil { + logger = log.NewNopLogger() + } + return &BaseService{ + Logger: logger, + name: name, + impl: impl, + // ctx and cancel remain nil until Start. + } +} + +// SetLogger sets the logger. +func (bs *BaseService) SetLogger(l log.Logger) { + bs.Logger = l +} + +// Start creates a new cancellable context for the service and calls its OnStart callback. +func (bs *BaseService) Start(ctx context.Context) error { + if bs.IsRunning() { + bs.Logger.Debug("service start", + "msg", fmt.Sprintf("Not starting %v service -- already started", bs.name), + "impl", bs.impl) + return ErrAlreadyStarted + } + + // Create a new cancellable context derived from the provided one. + bs.ctx, bs.cancel = context.WithCancel(ctx) + + bs.Logger.Info("service start", + "msg", fmt.Sprintf("Starting %v service", bs.name), + "impl", bs.impl.String()) + + // Call subclass' OnStart to initialize the service. + if err := bs.impl.OnStart(bs.ctx); err != nil { + // On error, cancel the context and clear it. + bs.cancel() + bs.ctx = nil + return err + } + return nil +} + +// OnStart does nothing by default. +func (bs *BaseService) OnStart(ctx context.Context) error { return nil } + +// Stop cancels the service's context and calls its OnStop callback. +func (bs *BaseService) Stop(ctx context.Context) error { + if !bs.IsRunning() { + bs.Logger.Error(fmt.Sprintf("Not stopping %v service -- has not been started yet", bs.name), + "impl", bs.impl) + return ErrNotStarted + } + + bs.Logger.Info("service stop", + "msg", fmt.Sprintf("Stopping %v service", bs.name), + "impl", bs.impl) + + // Call subclass' OnStop method. + bs.impl.OnStop(bs.ctx) + + // Cancel the context to signal all routines waiting on ctx.Done() that the service is stopping. + bs.cancel() + bs.ctx = nil + + return nil +} + +// OnStop does nothing by default. +func (bs *BaseService) OnStop(ctx context.Context) {} + +// Reset recreates the service's context after verifying that it is not running. +func (bs *BaseService) Reset(ctx context.Context) error { + if bs.IsRunning() { + bs.Logger.Debug("service reset", + "msg", fmt.Sprintf("Can't reset %v service. Service is running", bs.name), + "impl", bs.impl) + return fmt.Errorf("cannot reset running service %s", bs.name) + } + + // Call the subclass' OnReset callback. + return bs.impl.OnReset(ctx) +} + +// OnReset panics by default. +func (bs *BaseService) OnReset(ctx context.Context) error { + panic("The service cannot be reset without implementing OnReset") +} + +// IsRunning returns true when the service's context is not nil. +func (bs *BaseService) IsRunning() bool { + return bs.ctx != nil +} + +// Quit returns the done channel of the service's context. +// When the context is cancelled during Stop, the channel is closed. +func (bs *BaseService) Quit() <-chan struct{} { + if bs.ctx != nil { + return bs.ctx.Done() + } + // In case the service is not running, return a closed channel. + ch := make(chan struct{}) + close(ch) + return ch +} + +// String returns the service name. +func (bs *BaseService) String() string { + return bs.name +} diff --git a/pkg/service/baseservice_test.go b/pkg/service/baseservice_test.go new file mode 100644 index 0000000000..9ee4b1b261 --- /dev/null +++ b/pkg/service/baseservice_test.go @@ -0,0 +1,230 @@ +// Package service_test contains tests for the BaseService implementation. +package service + +import ( + "context" + "errors" + "testing" + + "cosmossdk.io/log" +) + +// dummyService is a simple implementation of the Service interface for testing purposes. +type dummyService struct { + *BaseService + // flags to indicate function calls + started bool + stopped bool + resetCalled bool +} + +// newDummyService creates a new dummy service instance and initializes BaseService. +func newDummyService(name string) *dummyService { + d := &dummyService{} + d.BaseService = NewBaseService(log.NewNopLogger(), name, d) + return d +} + +// OnStart sets the started flag and returns nil. +func (d *dummyService) OnStart(ctx context.Context) error { + d.started = true + return nil +} + +// OnStop sets the stopped flag. +func (d *dummyService) OnStop(ctx context.Context) { + d.stopped = true +} + +// OnReset sets the resetCalled flag and returns nil. +func (d *dummyService) OnReset(ctx context.Context) error { + d.resetCalled = true + return nil +} + +// Reset implements the Reset method of Service. It simply calls BaseService.Reset. +func (d *dummyService) Reset(ctx context.Context) error { + return d.BaseService.Reset(ctx) +} + +// Start and Stop are already implemented by BaseService. +// IsRunning, Quit, String, and SetLogger are also inherited from BaseService. + +func TestBaseService_Start(t *testing.T) { + tests := []struct { + name string + preStart func(d *dummyService) + expectError bool + errorContent string + }{ + { + name: "Successful start", + preStart: nil, + expectError: false, + }, + { + name: "Start already started service", + preStart: func(d *dummyService) { + // Start the service beforehand + err := d.BaseService.Start(context.Background()) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + }, + expectError: true, + errorContent: "already started", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + d := newDummyService("dummy") + if tc.preStart != nil { + tc.preStart(d) + } + + err := d.BaseService.Start(context.Background()) + if tc.expectError { + if err == nil { + t.Errorf("expected error but got nil") + } + if err != nil && !errors.Is(err, ErrAlreadyStarted) && !contains(err.Error(), tc.errorContent) { + t.Errorf("expected error containing '%s', got '%s'", tc.errorContent, err.Error()) + } + } else { + if err != nil { + t.Errorf("expected no error, got %v", err) + } + if !d.started { + t.Error("expected OnStart to be called") + } + if !d.IsRunning() { + t.Error("expected service to be running") + } + } + }) + } +} + +func TestBaseService_Stop(t *testing.T) { + tests := []struct { + name string + setup func(d *dummyService) + expectError bool + errorContent string + }{ + { + name: "Stop without starting", + setup: func(d *dummyService) { + // do nothing + }, + expectError: true, + errorContent: "not started", + }, + { + name: "Start then stop service", + setup: func(d *dummyService) { + err := d.BaseService.Start(context.Background()) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + }, + expectError: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + d := newDummyService("dummy") + tc.setup(d) + err := d.BaseService.Stop(context.Background()) + if tc.expectError { + if err == nil { + t.Errorf("expected error but got nil") + } + if err != nil && !contains(err.Error(), tc.errorContent) { + t.Errorf("expected error containing '%s', got '%s'", tc.errorContent, err.Error()) + } + } else { + if err != nil { + t.Errorf("expected no error on stopping, got %v", err) + } + if !d.stopped { + t.Error("expected OnStop to be called") + } + if d.IsRunning() { + t.Error("expected service not to be running") + } + } + }) + } +} + +func TestBaseService_Reset(t *testing.T) { + tests := []struct { + name string + setup func(d *dummyService) + expectError bool + errorContent string + }{ + { + name: "Reset without starting (should succeed)", + setup: func(d *dummyService) { + // service not started + }, + expectError: false, + }, + { + name: "Reset while running (should error)", + setup: func(d *dummyService) { + // Start the service so that it is running + err := d.BaseService.Start(context.Background()) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + }, + expectError: true, + errorContent: "cannot reset running service", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + d := newDummyService("dummy") + tc.setup(d) + err := d.Reset(context.Background()) + if tc.expectError { + if err == nil { + t.Errorf("expected error but got nil") + } + if err != nil && !contains(err.Error(), tc.errorContent) { + t.Errorf("expected error containing '%s', got '%s'", tc.errorContent, err.Error()) + } + } else { + if err != nil { + t.Errorf("expected no error on reset, got %v", err) + } + if !d.resetCalled { + t.Error("expected OnReset to be called") + } + } + }) + } +} + +// contains is a helper function to check if a substring is present in a string. +func contains(s, substr string) bool { + return indexOf(s, substr) >= 0 +} + +// To avoid importing strings package only for Index, we implement our own simple index calculation. +func indexOf(s, substr string) int { + slen := len(s) + subLen := len(substr) + for i := 0; i <= slen-subLen; i++ { + if s[i:i+subLen] == substr { + return i + } + } + return -1 +} diff --git a/specs/lazy-adr/adr-009-state-fraud-proofs.md b/specs/lazy-adr/adr-009-state-fraud-proofs.md index d1ba78eb52..f19928d70b 100644 --- a/specs/lazy-adr/adr-009-state-fraud-proofs.md +++ b/specs/lazy-adr/adr-009-state-fraud-proofs.md @@ -163,7 +163,7 @@ message StateWitness { repeated WitnessData witness_data = 3; } -// Witness data containing operation, a key/value pair, and Merkle +// Witness data containing operation, a key/value pair, and Merkle // inclusion proofs needed for corresponding operation for key/value pair message WitnessData { Operation operation = 1; diff --git a/store/kv.go b/store/kv.go index 30344e0908..7c43304353 100644 --- a/store/kv.go +++ b/store/kv.go @@ -9,7 +9,6 @@ import ( ds "github.com/ipfs/go-datastore" dsq "github.com/ipfs/go-datastore/query" - badger4 "github.com/ipfs/go-ds-badger4" ) diff --git a/store/store_test.go b/store/store_test.go index 865e920451..b3e8ffa3ce 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -9,7 +9,6 @@ import ( abcitypes "github.com/cometbft/cometbft/abci/types" cmproto "github.com/cometbft/cometbft/proto/tendermint/types" ds "github.com/ipfs/go-datastore" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/types/abci/block_test.go b/types/abci/block_test.go index 45480c82ed..a9f343fea4 100644 --- a/types/abci/block_test.go +++ b/types/abci/block_test.go @@ -1,18 +1,15 @@ package abci import ( - cmbytes "github.com/cometbft/cometbft/libs/bytes" - - cmproto "github.com/cometbft/cometbft/proto/tendermint/types" - "testing" + cmbytes "github.com/cometbft/cometbft/libs/bytes" + cmproto "github.com/cometbft/cometbft/proto/tendermint/types" cmversion "github.com/cometbft/cometbft/proto/tendermint/version" cmtypes "github.com/cometbft/cometbft/types" + "github.com/stretchr/testify/assert" "github.com/rollkit/rollkit/types" - - "github.com/stretchr/testify/assert" ) func TestToABCIHeaderPB(t *testing.T) { diff --git a/types/header.go b/types/header.go index 87bbd608f5..1a3b98cfeb 100644 --- a/types/header.go +++ b/types/header.go @@ -7,11 +7,10 @@ import ( "fmt" "time" - cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" - cmtypes "github.com/cometbft/cometbft/types" - "github.com/celestiaorg/go-header" cmbytes "github.com/cometbft/cometbft/libs/bytes" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmtypes "github.com/cometbft/cometbft/types" ) // Hash is a 32-byte array which is used to represent a hash result. diff --git a/types/serialization_test.go b/types/serialization_test.go index a2a9ccd785..f58c340008 100644 --- a/types/serialization_test.go +++ b/types/serialization_test.go @@ -5,14 +5,13 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/cometbft/cometbft/crypto/ed25519" cmstate "github.com/cometbft/cometbft/proto/tendermint/state" cmproto "github.com/cometbft/cometbft/proto/tendermint/types" cmversion "github.com/cometbft/cometbft/proto/tendermint/version" cmtypes "github.com/cometbft/cometbft/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" pb "github.com/rollkit/rollkit/types/pb/rollkit" ) diff --git a/types/state.go b/types/state.go index 3ae2d66af7..aab180f62c 100644 --- a/types/state.go +++ b/types/state.go @@ -4,8 +4,6 @@ import ( "fmt" "time" - // TODO(tzdybal): copy to local project? - cmstate "github.com/cometbft/cometbft/proto/tendermint/state" cmproto "github.com/cometbft/cometbft/proto/tendermint/types" cmversion "github.com/cometbft/cometbft/proto/tendermint/version"