From 344461dfca4d7cc341379cc778f4eeabd411e4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ecl=C3=A9sio=20Junior?= Date: Wed, 16 Aug 2023 11:33:35 -0400 Subject: [PATCH] feat(internal/database): replace `chaindb/badgerdb` with `pebbledb` (#3434) --- cmd/gossamer/README.md | 15 +- cmd/gossamer/commands/init.go | 7 +- cmd/gossamer/commands/root.go | 7 +- dot/build_spec_test.go | 2 +- dot/core/helpers_test.go | 3 +- dot/mock_node_builder_test.go | 7 +- dot/network/service.go | 6 + dot/node.go | 50 ++-- dot/node_integration_test.go | 22 +- dot/node_test.go | 17 +- dot/rpc/modules/chain_integration_test.go | 9 +- .../modules/childstate_integration_test.go | 8 +- dot/rpc/modules/state_integration_test.go | 10 +- dot/services.go | 9 +- dot/services_integration_test.go | 5 + dot/state/block.go | 16 +- dot/state/block_race_test.go | 4 +- dot/state/block_test.go | 6 +- dot/state/epoch.go | 24 +- dot/state/grandpa.go | 16 +- dot/state/grandpa_test.go | 4 +- dot/state/initialize.go | 17 +- dot/state/interfaces.go | 4 +- dot/state/mocks_test.go | 6 +- dot/state/offline_pruner.go | 56 +++-- dot/state/service.go | 16 +- dot/state/service_integration_test.go | 8 +- dot/state/slot.go | 12 +- dot/state/slot_test.go | 11 +- dot/state/storage.go | 6 +- dot/state/storage_notify_test.go | 65 ------ dot/state/storage_test.go | 8 +- dot/state/test_helpers.go | 7 +- dot/sync/chain_sync.go | 6 +- dot/sync/syncer.go | 4 +- dot/sync/syncer_integration_test.go | 3 +- go.mod | 15 +- go.sum | 147 +++++++++++- internal/database/database.go | 76 +++++++ internal/database/database_test.go | 65 ++++++ internal/database/pebble.go | 154 +++++++++++++ internal/database/pebble_batch.go | 52 +++++ internal/database/pebble_iterator.go | 19 ++ internal/database/pebble_test.go | 215 ++++++++++++++++++ internal/database/table.go | 61 +++++ internal/database/table_batch.go | 41 ++++ lib/babe/babe.go | 30 ++- lib/babe/babe_integration_test.go | 3 + lib/babe/helpers_test.go | 3 +- lib/babe/verify_integration_test.go | 31 ++- lib/grandpa/grandpa.go | 4 +- lib/grandpa/helpers_integration_test.go | 8 +- lib/grandpa/message_handler.go | 8 +- lib/grandpa/message_tracker_test.go | 4 +- lib/runtime/test_helpers.go | 9 +- lib/runtime/wasmer/imports_test.go | 13 +- lib/runtime/wazero/imports_test.go | 14 +- lib/trie/database.go | 5 +- lib/trie/database_test.go | 11 +- lib/trie/proof/proof_test.go | 10 +- lib/trie/trie_endtoend_test.go | 15 +- lib/utils/utils.go | 40 ---- tests/rpc/rpc_05-state_test.go | 2 +- 63 files changed, 1141 insertions(+), 390 deletions(-) create mode 100644 internal/database/database.go create mode 100644 internal/database/database_test.go create mode 100644 internal/database/pebble.go create mode 100644 internal/database/pebble_batch.go create mode 100644 internal/database/pebble_iterator.go create mode 100644 internal/database/pebble_test.go create mode 100644 internal/database/table.go create mode 100644 internal/database/table_batch.go diff --git a/cmd/gossamer/README.md b/cmd/gossamer/README.md index e27e878603..107190f2be 100644 --- a/cmd/gossamer/README.md +++ b/cmd/gossamer/README.md @@ -14,6 +14,7 @@ cd gossamer ### Compile To put the binary in ./bin, run: + ```bash make build ``` @@ -62,7 +63,7 @@ The node configuration can be modified in the `config.toml` file. ### Start the node ```bash -gossamer --basepath /tmp/gossamer --key alice +gossamer --basepath /tmp/gossamer --key alice ``` **Note: The `init` command is optional. If the node is not initialised, it will be initialised with the default configuration.** @@ -108,12 +109,14 @@ This subcommand provides capabilities that are similar to [Parity's Subkey utility](https://docs.substrate.io/v3/tools/subkey). The account command supports following arguments: + - `generate` - generates a new key pair; specify `--scheme ed25519`, `--scheme secp256k1`, or `--scheme sr25519` (default) - `list` - lists the keys in the Gossamer keystore - `import` - imports a key from a keystore file - `import-raw` - imports a raw key from a keystore file Supported flags: + - `keystore-path` - path to the Gossamer keystore - `keystore-file` - path to the keystore file - `chain` - path to the human-readable chain-spec file @@ -121,6 +124,7 @@ Supported flags: - `--password` - allows the user to provide a password to either encrypt a generated key or unlock the Gossamer keystore Examples: + - `gossamer account generate --scheme ed25519` - generates an `ed25519` key pair - `gossamer account list` - lists the keys in the Gossamer keystore - `gossamer account import --keystore-file keystore.json` - imports a key from a keystore file @@ -145,6 +149,7 @@ represent the Gossamer default configuration. - `--output-path` - path to the file where the compiled chain-spec should be written Examples: + - `gossamer build-spec --chain chain-spec.json --output-path compiled-chain-spec.json` - compiles a human-readable chain-spec into a format that Gossamer can consume - `gossamer build-spec --chain chain-spec.json --raw --output-path compiled-chain-spec.json` - compiles a human-readable @@ -166,6 +171,7 @@ of a JSON file. The input for this subcommand can be retrieved from - `--chain` - path to the human-readable chain-spec file Examples: + - `gossamer import-state --first-slot 1 --header header.json --state state.json --chain chain-spec.json` - seeds Gossamer storage with key-value pairs from a JSON file @@ -185,9 +191,8 @@ What follows is a list that describes the services and capabilities that inform #### State -This service is a wrapper around an instance of [`chaindb`](https://github.com/ChainSafe/chaindb), a key-value database -that is built on top of [BadgerDB](https://github.com/dgraph-io/badger) from [Dgraph](https://dgraph.io/). The state -service provides storage capabilities for the other Gossamer services - each service is assigned a prefix that is added +This service is a wrapper around an instance of [`pebble`](https://github.com/cockroachdb/pebble), a LevelDB/RocksDB inspired key-value database. +The state service provides storage capabilities for the other Gossamer services - each service is assigned a prefix that is added to its storage keys. The state service is defined in [dot/state/service.go](../../dot/state/service.go). #### Network @@ -271,4 +276,4 @@ capabilities are defined in the [dot/telemetry](../../dot/telemetry) package and The default listening address for Prometheus metrics is `localhost:9876`, and Gossamer allows the user to configure this parameter with the `--metrics-address` command-line parameter. The Gossamer telemetry server publishes telemetry data that is compatible with [Polkadot Telemetry](https://github.com/paritytech/substrate-telemetry) and -[its helpful UI](https://telemetry.polkadot.io/). \ No newline at end of file +[its helpful UI](https://telemetry.polkadot.io/). diff --git a/cmd/gossamer/commands/init.go b/cmd/gossamer/commands/init.go index fc3a21efef..ccfd881b2b 100644 --- a/cmd/gossamer/commands/init.go +++ b/cmd/gossamer/commands/init.go @@ -43,7 +43,12 @@ func execInit(cmd *cobra.Command) error { return fmt.Errorf("failed to get --force: %s", err) } - if dot.IsNodeInitialised(config.BasePath) { + isInitialised, err := dot.IsNodeInitialised(config.BasePath) + if err != nil { + return fmt.Errorf("checking if node is initialised: %w", err) + } + + if isInitialised { // prompt user to confirm reinitialization if force || confirmMessage("Are you sure you want to reinitialise the node? [Y/n]") { logger.Info("reinitialising node at base path " + config.BasePath + "...") diff --git a/cmd/gossamer/commands/root.go b/cmd/gossamer/commands/root.go index ba3489f917..3fe733ac4b 100644 --- a/cmd/gossamer/commands/root.go +++ b/cmd/gossamer/commands/root.go @@ -601,8 +601,13 @@ func execRoot(cmd *cobra.Command) error { return fmt.Errorf("failed to ensure root: %s", err) } + isInitialised, err := dot.IsNodeInitialised(config.BasePath) + if err != nil { + return fmt.Errorf("failed to check is not is initialised: %w", err) + } + // if the node is not initialised, initialise it - if !dot.IsNodeInitialised(config.BasePath) { + if !isInitialised { if err := dot.InitNode(config); err != nil { return fmt.Errorf("failed to initialise node: %s", err) } diff --git a/dot/build_spec_test.go b/dot/build_spec_test.go index 990a2a1741..63f836cbd8 100644 --- a/dot/build_spec_test.go +++ b/dot/build_spec_test.go @@ -147,7 +147,7 @@ func TestBuildFromDB(t *testing.T) { }, }}}, {name: "invalid_db_path", path: t.TempDir(), - err: errors.New("cannot start state service: failed to create block state: cannot get block 0: Key not found")}, + err: errors.New("cannot start state service: failed to create block state: cannot get block 0: pebble: not found")}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/dot/core/helpers_test.go b/dot/core/helpers_test.go index f3802c850a..53a2af4d78 100644 --- a/dot/core/helpers_test.go +++ b/dot/core/helpers_test.go @@ -11,6 +11,7 @@ import ( "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" @@ -225,7 +226,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { if stateSrvc != nil { nodeStorage.BaseDB = stateSrvc.Base } else { - nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + nodeStorage.BaseDB, err = database.LoadDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) require.NoError(t, err) } diff --git a/dot/mock_node_builder_test.go b/dot/mock_node_builder_test.go index c6fed7321d..2f52ae3118 100644 --- a/dot/mock_node_builder_test.go +++ b/dot/mock_node_builder_test.go @@ -210,11 +210,12 @@ func (mr *MocknodeBuilderIfaceMockRecorder) initNode(config interface{}) *gomock } // isNodeInitialised mocks base method. -func (m *MocknodeBuilderIface) isNodeInitialised(basepath string) error { +func (m *MocknodeBuilderIface) isNodeInitialised(basepath string) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "isNodeInitialised", basepath) - ret0, _ := ret[0].(error) - return ret0 + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 } // isNodeInitialised indicates an expected call of isNodeInitialised. diff --git a/dot/network/service.go b/dot/network/service.go index fa139d3616..42395d98cd 100644 --- a/dot/network/service.go +++ b/dot/network/service.go @@ -428,6 +428,12 @@ func (s *Service) publishNetworkTelemetry(done <-chan struct{}) { func (s *Service) sentBlockIntervalTelemetry() { for { + select { + case <-s.ctx.Done(): + return + default: + } + best, err := s.blockState.BestBlockHeader() if err != nil { continue diff --git a/dot/node.go b/dot/node.go index 6c7f2922ea..84888742bd 100644 --- a/dot/node.go +++ b/dot/node.go @@ -25,6 +25,7 @@ import ( "github.com/ChainSafe/gossamer/dot/system" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/internal/metrics" "github.com/ChainSafe/gossamer/lib/babe" @@ -34,7 +35,6 @@ import ( "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/lib/services" - "github.com/ChainSafe/gossamer/lib/utils" ) var logger = log.NewFromGlobal(log.AddContext("pkg", "dot")) @@ -49,7 +49,7 @@ type Node struct { } type nodeBuilderIface interface { - isNodeInitialised(basepath string) error + isNodeInitialised(basepath string) (bool, error) initNode(config *cfg.Config) error createStateService(config *cfg.Config) (*state.Service, error) createNetworkService(config *cfg.Config, stateSrvc *state.Service, telemetryMailer Telemetry) (*network.Service, @@ -78,26 +78,37 @@ type nodeBuilder struct{} // IsNodeInitialised returns true if, within the configured data directory for the // node, the state database has been created and the genesis data can been loaded -func IsNodeInitialised(basepath string) bool { +func IsNodeInitialised(basepath string) (bool, error) { nodeInstance := nodeBuilder{} - err := nodeInstance.isNodeInitialised(basepath) - return err == nil + return nodeInstance.isNodeInitialised(basepath) } // isNodeInitialised returns nil if the node is successfully initialised // and an error otherwise. -func (*nodeBuilder) isNodeInitialised(basepath string) error { +func (*nodeBuilder) isNodeInitialised(basepath string) (bool, error) { // check if key registry exists - registry := filepath.Join(basepath, utils.DefaultDatabaseDir, "KEYREGISTRY") + nodeDatabaseDir := filepath.Join(basepath, database.DefaultDatabaseDir) - _, err := os.Stat(registry) - if os.IsNotExist(err) { - return fmt.Errorf("cannot find key registry in database directory: %w", err) + _, err := os.Stat(nodeDatabaseDir) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err } - db, err := utils.SetupDatabase(basepath, false) + entries, err := os.ReadDir(nodeDatabaseDir) if err != nil { - return fmt.Errorf("cannot setup database: %w", err) + return false, fmt.Errorf("failed to read dir %s: %w", nodeDatabaseDir, err) + } + + if len(entries) == 0 { + return false, nil + } + + db, err := database.LoadDatabase(basepath, false) + if err != nil { + return false, fmt.Errorf("cannot setup database: %w", err) } defer func() { @@ -109,10 +120,10 @@ func (*nodeBuilder) isNodeInitialised(basepath string) error { _, err = state.NewBaseState(db).LoadGenesisData() if err != nil { - return fmt.Errorf("cannot load genesis data in base state: %w", err) + return false, fmt.Errorf("cannot load genesis data in base state: %w", err) } - return nil + return true, nil } // InitNode initialise the node with the given Config @@ -204,7 +215,7 @@ func (*nodeBuilder) initNode(config *cfg.Config) error { // LoadGlobalNodeName returns the stored global node name from database func LoadGlobalNodeName(basepath string) (nodename string, err error) { // initialise database using data directory - db, err := utils.SetupDatabase(basepath, false) + db, err := database.LoadDatabase(basepath, false) if err != nil { return "", err } @@ -242,7 +253,12 @@ func newNode(config *cfg.Config, debug.SetGCPercent(prev) } - if builder.isNodeInitialised(config.BasePath) != nil { + isInitialised, err := builder.isNodeInitialised(config.BasePath) + if err != nil { + return nil, fmt.Errorf("checking if node is initialised: %w", err) + } + + if isInitialised { err := builder.initNode(config) if err != nil { return nil, fmt.Errorf("cannot initialise node: %w", err) @@ -450,7 +466,7 @@ func setupTelemetry(config *cfg.Config, genesisData *genesis.Data) (mailer Telem // stores the global node name to reuse func storeGlobalNodeName(name, basepath string) (err error) { - db, err := utils.SetupDatabase(basepath, false) + db, err := database.LoadDatabase(basepath, false) if err != nil { return err } diff --git a/dot/node_integration_test.go b/dot/node_integration_test.go index 99d3694e61..401f71a67f 100644 --- a/dot/node_integration_test.go +++ b/dot/node_integration_test.go @@ -25,6 +25,7 @@ import ( system "github.com/ChainSafe/gossamer/dot/system" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/babe" "github.com/ChainSafe/gossamer/lib/common" @@ -35,7 +36,6 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime" wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" gomock "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -88,7 +88,7 @@ func TestNewNode(t *testing.T) { mockServiceRegistry.EXPECT().RegisterService(gomock.Any()).Times(8) m := NewMocknodeBuilderIface(ctrl) - m.EXPECT().isNodeInitialised(initConfig.BasePath).Return(nil) + m.EXPECT().isNodeInitialised(initConfig.BasePath).Return(false, nil) m.EXPECT().createStateService(initConfig).DoAndReturn(func(config *cfg.Config) (*state.Service, error) { stateSrvc := state.NewService(stateConfig) // create genesis from configuration file @@ -214,9 +214,12 @@ func TestInitNode_Integration(t *testing.T) { require.NoError(t, err) // confirm database was setup - db, err := utils.SetupDatabase(config.BasePath, false) + + db, err := database.LoadDatabase(config.BasePath, false) require.NoError(t, err) require.NotNil(t, db) + err = db.Close() + require.NoError(t, err) } func TestInitNode_GenesisSpec(t *testing.T) { @@ -229,9 +232,12 @@ func TestInitNode_GenesisSpec(t *testing.T) { err := InitNode(config) require.NoError(t, err) // confirm database was setup - db, err := utils.SetupDatabase(config.BasePath, false) + db, err := database.LoadDatabase(config.BasePath, false) require.NoError(t, err) require.NotNil(t, db) + + err = db.Close() + require.NoError(t, err) } func TestNodeInitializedIntegration(t *testing.T) { @@ -241,13 +247,15 @@ func TestNodeInitializedIntegration(t *testing.T) { config.ChainSpec = genFile - result := IsNodeInitialised(config.BasePath) + result, err := IsNodeInitialised(config.BasePath) + require.NoError(t, err) require.False(t, result) - err := InitNode(config) + err = InitNode(config) require.NoError(t, err) - result = IsNodeInitialised(config.BasePath) + result, err = IsNodeInitialised(config.BasePath) + require.NoError(t, err) require.True(t, result) } diff --git a/dot/node_test.go b/dot/node_test.go index a566f8ee33..c0f11d4715 100644 --- a/dot/node_test.go +++ b/dot/node_test.go @@ -16,12 +16,12 @@ import ( "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/state" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/internal/metrics" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/services" - "github.com/ChainSafe/gossamer/lib/utils" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -52,9 +52,13 @@ func TestInitNode(t *testing.T) { err := InitNode(tt.config) assert.ErrorIs(t, err, tt.err) // confirm InitNode has created database dir - registry := filepath.Join(tt.config.BasePath, utils.DefaultDatabaseDir, "KEYREGISTRY") - _, err = os.Stat(registry) + nodeDatabaseDir := filepath.Join(tt.config.BasePath, database.DefaultDatabaseDir) + _, err = os.Stat(nodeDatabaseDir) require.NoError(t, err) + + entries, err := os.ReadDir(nodeDatabaseDir) + require.NoError(t, err) + require.Greater(t, len(entries), 0) }) } } @@ -63,7 +67,7 @@ func TestLoadGlobalNodeName(t *testing.T) { t.Parallel() basePath := t.TempDir() - db, err := utils.SetupDatabase(basePath, false) + db, err := database.LoadDatabase(basePath, false) require.NoError(t, err) basestate := state.NewBaseState(db) @@ -86,7 +90,7 @@ func TestLoadGlobalNodeName(t *testing.T) { { name: "wrong basepath test", basepath: t.TempDir(), - err: errors.New("Key not found"), + err: errors.New("pebble: not found"), }, } for _, tt := range tests { @@ -161,7 +165,8 @@ func TestNodeInitialized(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := IsNodeInitialised(tt.basepath) + got, err := IsNodeInitialised(tt.basepath) + require.NoError(t, err) assert.Equal(t, tt.want, got) }) } diff --git a/dot/rpc/modules/chain_integration_test.go b/dot/rpc/modules/chain_integration_test.go index 7b290b3aec..50ffe41113 100644 --- a/dot/rpc/modules/chain_integration_test.go +++ b/dot/rpc/modules/chain_integration_test.go @@ -11,16 +11,15 @@ import ( "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/runtime" wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" - database "github.com/ChainSafe/chaindb" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/stretchr/testify/require" ) @@ -113,7 +112,7 @@ func TestChainGetHeader_NotFound(t *testing.T) { req := &ChainHashRequest{Bhash: &bhash} err = svc.GetHeader(nil, req, res) - require.EqualError(t, err, database.ErrKeyNotFound.Error()) + require.EqualError(t, err, database.ErrNotFound.Error()) } func TestChainGetBlock_Genesis(t *testing.T) { @@ -212,7 +211,7 @@ func TestChainGetBlock_NoFound(t *testing.T) { req := &ChainHashRequest{Bhash: &bhash} err = svc.GetBlock(nil, req, res) - require.EqualError(t, err, database.ErrKeyNotFound.Error()) + require.EqualError(t, err, database.ErrNotFound.Error()) } func TestChainGetBlockHash_Latest(t *testing.T) { @@ -367,7 +366,7 @@ func newTestStateService(t *testing.T) *state.Service { if stateSrvc != nil { rtCfg.NodeStorage.BaseDB = stateSrvc.Base } else { - rtCfg.NodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + rtCfg.NodeStorage.BaseDB, err = database.LoadDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) require.NoError(t, err) } diff --git a/dot/rpc/modules/childstate_integration_test.go b/dot/rpc/modules/childstate_integration_test.go index a46e8245b5..c9e7481051 100644 --- a/dot/rpc/modules/childstate_integration_test.go +++ b/dot/rpc/modules/childstate_integration_test.go @@ -10,8 +10,8 @@ import ( "fmt" "testing" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/trie" "github.com/stretchr/testify/require" @@ -97,7 +97,7 @@ func TestChildStateGetStorageSize(t *testing.T) { keyChild: []byte(":not_exist"), }, { - err: chaindb.ErrKeyNotFound, + err: database.ErrNotFound, hash: &invalidHash, }, } @@ -155,7 +155,7 @@ func TestGetStorageHash(t *testing.T) { keyChild: []byte(":not_exist"), }, { - err: chaindb.ErrKeyNotFound, + err: database.ErrNotFound, hash: &invalidBlockHash, }, } @@ -195,7 +195,7 @@ func TestGetChildStorage(t *testing.T) { {params: []string{":child_storage_key", ""}, expected: nil}, {params: []string{":child_storage_key", ":child_first"}, expected: []byte(":child_first_value")}, {params: []string{":child_storage_key", ":child_first", blockHash.String()}, expected: []byte(":child_first_value")}, - {params: []string{":child_storage_key", ":child_first", randomHash.String()}, errMsg: "Key not found"}, + {params: []string{":child_storage_key", ":child_first", randomHash.String()}, errMsg: "pebble: not found"}, } for _, test := range testCases { diff --git a/dot/rpc/modules/state_integration_test.go b/dot/rpc/modules/state_integration_test.go index 31ba029260..86ffab0807 100644 --- a/dot/rpc/modules/state_integration_test.go +++ b/dot/rpc/modules/state_integration_test.go @@ -24,7 +24,7 @@ import ( const ( RandomHash = "0x580d77a9136035a0bc3c3cd86286172f7f81291164c5914266073a30466fba21" - ErrKeyNotFound = "Key not found" + ErrKeyNotFound = "pebble: not found" ) func TestStateModule_GetRuntimeVersion(t *testing.T) { @@ -118,7 +118,7 @@ func TestStateModule_GetPairs(t *testing.T) { []string{":key1", "value1"}, []string{":key2", "value2"}}}, {params: []string{":key1", hash.String()}, expected: []interface{}{[]string{":key1", "value1"}}}, - {params: []string{"", randomHash.String()}, errMsg: "Key not found"}, + {params: []string{"", randomHash.String()}, errMsg: "pebble: not found"}, } for _, test := range testCases { @@ -182,7 +182,7 @@ func TestStateModule_GetStorage(t *testing.T) { {params: []string{""}, expected: nil}, {params: []string{":key1"}, expected: []byte("value1")}, {params: []string{":key1", hash.String()}, expected: []byte("value1")}, - {params: []string{"", randomHash.String()}, errMsg: "Key not found"}, + {params: []string{"", randomHash.String()}, errMsg: "pebble: not found"}, } for _, test := range testCases { @@ -235,7 +235,7 @@ func TestStateModule_GetStorageHash(t *testing.T) { {params: []string{""}, expected: hashOfNil}, {params: []string{":key1"}, expected: hash1}, {params: []string{":key1", hash.String()}, expected: hash1}, - {params: []string{"0x", randomHash.String()}, errMsg: "Key not found"}, + {params: []string{"0x", randomHash.String()}, errMsg: "pebble: not found"}, } for _, test := range testCases { @@ -280,7 +280,7 @@ func TestStateModule_GetStorageSize(t *testing.T) { {params: []string{""}}, {params: []string{":key1"}, expected: 6}, {params: []string{":key1", hash.String()}, expected: 6}, - {params: []string{"0x", randomHash.String()}, errMsg: "Key not found"}, + {params: []string{"0x", randomHash.String()}, errMsg: "pebble: not found"}, } for _, test := range testCases { diff --git a/dot/services.go b/dot/services.go index 010b961efd..84c66f6a37 100644 --- a/dot/services.go +++ b/dot/services.go @@ -11,7 +11,6 @@ import ( cfg "github.com/ChainSafe/gossamer/config" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/core" "github.com/ChainSafe/gossamer/dot/digest" "github.com/ChainSafe/gossamer/dot/network" @@ -21,6 +20,7 @@ import ( "github.com/ChainSafe/gossamer/dot/sync" "github.com/ChainSafe/gossamer/dot/system" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/internal/metrics" "github.com/ChainSafe/gossamer/internal/pprof" @@ -34,7 +34,6 @@ import ( "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" - "github.com/ChainSafe/gossamer/lib/utils" ) // BlockProducer to produce blocks @@ -57,8 +56,8 @@ type rpcServiceSettings struct { syncer *sync.Service } -func newInMemoryDB() (*chaindb.BadgerDB, error) { - return utils.SetupDatabase("", true) +func newInMemoryDB() (database.Database, error) { + return database.LoadDatabase("", true) } // createStateService creates the state service and initialise state database @@ -111,7 +110,7 @@ func (nodeBuilder) createRuntimeStorage(st *state.Service) (*runtime.NodeStorage return &runtime.NodeStorage{ LocalStorage: localStorage, - PersistentStorage: chaindb.NewTable(st.DB(), "offlinestorage"), + PersistentStorage: database.NewTable(st.DB(), "offlinestorage"), BaseDB: st.Base, }, nil } diff --git a/dot/services_integration_test.go b/dot/services_integration_test.go index 852be2c126..c8bbfceeef 100644 --- a/dot/services_integration_test.go +++ b/dot/services_integration_test.go @@ -433,6 +433,9 @@ func TestCreateStateService(t *testing.T) { stateSrvc, err := builder.createStateService(config) require.NoError(t, err) require.NotNil(t, stateSrvc) + + err = stateSrvc.DB().Close() + require.NoError(t, err) } func newStateServiceWithoutMock(t *testing.T) *state.Service { @@ -529,6 +532,8 @@ func TestCreateBlockVerifier(t *testing.T) { stateSrvc.Epoch = &state.EpochState{} _ = builder.createBlockVerifier(stateSrvc) + err = stateSrvc.DB().Close() + require.NoError(t, err) } func TestCreateSyncService(t *testing.T) { diff --git a/dot/state/block.go b/dot/state/block.go index be1729b29d..c8ed6afd76 100644 --- a/dot/state/block.go +++ b/dot/state/block.go @@ -11,8 +11,8 @@ import ( "sync" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/blocktree" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/runtime" @@ -73,11 +73,11 @@ type BlockState struct { } // NewBlockState will create a new BlockState backed by the database located at basePath -func NewBlockState(db *chaindb.BadgerDB, trs *Tries, telemetry Telemetry) (*BlockState, error) { +func NewBlockState(db database.Database, trs *Tries, telemetry Telemetry) (*BlockState, error) { bs := &BlockState{ dbPath: db.Path(), baseState: NewBaseState(db), - db: chaindb.NewTable(db, blockPrefix), + db: database.NewTable(db, blockPrefix), unfinalisedBlocks: newHashToBlockMap(), tries: trs, imported: make(map[chan *types.Block]struct{}), @@ -105,12 +105,12 @@ func NewBlockState(db *chaindb.BadgerDB, trs *Tries, telemetry Telemetry) (*Bloc // NewBlockStateFromGenesis initialises a BlockState from a genesis header, // saving it to the database located at basePath -func NewBlockStateFromGenesis(db *chaindb.BadgerDB, trs *Tries, header *types.Header, +func NewBlockStateFromGenesis(db database.Database, trs *Tries, header *types.Header, telemetryMailer Telemetry) (*BlockState, error) { bs := &BlockState{ bt: blocktree.NewBlockTreeFromRoot(header), baseState: NewBaseState(db), - db: chaindb.NewTable(db, blockPrefix), + db: database.NewTable(db, blockPrefix), unfinalisedBlocks: newHashToBlockMap(), tries: trs, imported: make(map[chan *types.Block]struct{}), @@ -211,7 +211,7 @@ func (bs *BlockState) GetHeader(hash common.Hash) (header *types.Header, err err } if has, _ := bs.HasHeader(hash); !has { - return nil, chaindb.ErrKeyNotFound + return nil, database.ErrNotFound } data, err := bs.db.Get(headerKey(hash)) @@ -226,7 +226,7 @@ func (bs *BlockState) GetHeader(hash common.Hash) (header *types.Header, err err } if result.Empty() { - return nil, chaindb.ErrKeyNotFound + return nil, database.ErrNotFound } result.Hash() @@ -644,7 +644,7 @@ func (bs *BlockState) Range(startHash, endHash common.Hash) (hashes []common.Has } endHeader, err := bs.loadHeaderFromDatabase(endHash) - if errors.Is(err, chaindb.ErrKeyNotFound) || + if errors.Is(err, database.ErrNotFound) || errors.Is(err, ErrEmptyHeader) { // end hash is not in the database so we should lookup the // block that could be in memory and in the database as well diff --git a/dot/state/block_race_test.go b/dot/state/block_race_test.go index 18a1c26fdc..3f1ace26bd 100644 --- a/dot/state/block_race_test.go +++ b/dot/state/block_race_test.go @@ -9,10 +9,10 @@ import ( "testing" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/trie" "github.com/golang/mock/gomock" - "github.com/ChainSafe/chaindb" "github.com/stretchr/testify/require" ) @@ -22,7 +22,7 @@ func TestConcurrencySetHeader(t *testing.T) { telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() threads := runtime.NumCPU() - dbs := make([]*chaindb.BadgerDB, threads) + dbs := make([]database.Database, threads) for i := 0; i < threads; i++ { dbs[i] = NewInMemoryDB(t) } diff --git a/dot/state/block_test.go b/dot/state/block_test.go index f4b9cf7f23..09d0ee4541 100644 --- a/dot/state/block_test.go +++ b/dot/state/block_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/blocktree" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/trie" @@ -964,9 +964,9 @@ func TestRange(t *testing.T) { "start_hash_in_memory_while_end_hash_in_database": { blocksToCreate: 128, blocksToPersistAtDisk: 64, - wantErr: chaindb.ErrKeyNotFound, + wantErr: database.ErrNotFound, stringErr: "range start should be in database: " + - "querying database: Key not found", + "querying database: pebble: not found", newBlockState: func(t *testing.T, ctrl *gomock.Controller, genesisHeader *types.Header) *BlockState { telemetryMock := NewMockTelemetry(ctrl) diff --git a/dot/state/epoch.go b/dot/state/epoch.go index 6dc18546b2..c318c3874e 100644 --- a/dot/state/epoch.go +++ b/dot/state/epoch.go @@ -10,8 +10,8 @@ import ( "sync" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/pkg/scale" ) @@ -67,7 +67,7 @@ type EpochState struct { } // NewEpochStateFromGenesis returns a new EpochState given information for the first epoch, fetched from the runtime -func NewEpochStateFromGenesis(db *chaindb.BadgerDB, blockState *BlockState, +func NewEpochStateFromGenesis(db database.Database, blockState *BlockState, genesisConfig *types.BabeConfiguration) (*EpochState, error) { baseState := NewBaseState(db) @@ -76,7 +76,7 @@ func NewEpochStateFromGenesis(db *chaindb.BadgerDB, blockState *BlockState, return nil, err } - epochDB := chaindb.NewTable(db, epochPrefix) + epochDB := database.NewTable(db, epochPrefix) err = epochDB.Put(currentEpochKey, []byte{0, 0, 0, 0, 0, 0, 0, 0}) if err != nil { return nil, err @@ -133,7 +133,7 @@ func NewEpochStateFromGenesis(db *chaindb.BadgerDB, blockState *BlockState, } // NewEpochState returns a new EpochState -func NewEpochState(db *chaindb.BadgerDB, blockState *BlockState) (*EpochState, error) { +func NewEpochState(db database.Database, blockState *BlockState) (*EpochState, error) { baseState := NewBaseState(db) epochLength, err := baseState.loadEpochLength() @@ -149,7 +149,7 @@ func NewEpochState(db *chaindb.BadgerDB, blockState *BlockState) (*EpochState, e return &EpochState{ baseState: baseState, blockState: blockState, - db: chaindb.NewTable(db, epochPrefix), + db: database.NewTable(db, epochPrefix), epochLength: epochLength, skipToEpoch: skipToEpoch, nextEpochData: make(nextEpochMap[types.NextEpochData]), @@ -252,7 +252,7 @@ func (s *EpochState) SetEpochData(epoch uint64, info *types.EpochData) error { // if the header params is nil then it will search only in database func (s *EpochState) GetEpochData(epoch uint64, header *types.Header) (*types.EpochData, error) { epochData, err := s.getEpochDataFromDatabase(epoch) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return nil, fmt.Errorf("failed to retrieve epoch data from database: %w", err) } @@ -335,7 +335,7 @@ func (s *EpochState) setLatestConfigData(epoch uint64) error { func (s *EpochState) GetConfigData(epoch uint64, header *types.Header) (configData *types.ConfigData, err error) { for tryEpoch := int(epoch); tryEpoch >= 0; tryEpoch-- { configData, err = s.getConfigDataFromDatabase(uint64(tryEpoch)) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return nil, fmt.Errorf("failed to retrieve config epoch from database: %w", err) } @@ -445,7 +445,7 @@ func (nem nextEpochMap[T]) Retrieve(blockState *BlockState, epoch uint64, header // sometimes while moving to the next epoch is possible the header // is not fully imported by the blocktree, in this case we will use // its parent header which migth be already imported. - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { parentHeader, err := blockState.GetHeader(header.ParentHash) if err != nil { return nil, fmt.Errorf("cannot get parent header: %w", err) @@ -588,9 +588,9 @@ func (s *EpochState) FinalizeBABENextEpochData(finalizedHeader *types.Header) er epochInDatabase, err := s.getEpochDataFromDatabase(nextEpoch) - // if an error occurs and the error is chaindb.ErrKeyNotFound we ignore + // if an error occurs and the error is database.ErrNotFound we ignore // since this error is what we will handle in the next lines - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return fmt.Errorf("cannot check if next epoch data is already defined for epoch %d: %w", nextEpoch, err) } @@ -649,9 +649,9 @@ func (s *EpochState) FinalizeBABENextConfigData(finalizedHeader *types.Header) e configInDatabase, err := s.getConfigDataFromDatabase(nextEpoch) - // if an error occurs and the error is chaindb.ErrKeyNotFound we ignore + // if an error occurs and the error is database.ErrNotFound we ignore // since this error is what we will handle in the next lines - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return fmt.Errorf("cannot check if next epoch config is already defined for epoch %d: %w", nextEpoch, err) } diff --git a/dot/state/grandpa.go b/dot/state/grandpa.go index e8bebbcaa4..9e5ca23430 100644 --- a/dot/state/grandpa.go +++ b/dot/state/grandpa.go @@ -9,9 +9,9 @@ import ( "fmt" "strconv" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/pkg/scale" ) @@ -46,9 +46,9 @@ type GrandpaState struct { } // NewGrandpaStateFromGenesis returns a new GrandpaState given the grandpa genesis authorities -func NewGrandpaStateFromGenesis(db *chaindb.BadgerDB, bs *BlockState, +func NewGrandpaStateFromGenesis(db database.Database, bs *BlockState, genesisAuthorities []types.GrandpaVoter, telemetry Telemetry) (*GrandpaState, error) { - grandpaDB := chaindb.NewTable(db, grandpaPrefix) + grandpaDB := database.NewTable(db, grandpaPrefix) s := &GrandpaState{ db: grandpaDB, blockState: bs, @@ -77,9 +77,9 @@ func NewGrandpaStateFromGenesis(db *chaindb.BadgerDB, bs *BlockState, } // NewGrandpaState returns a new GrandpaState -func NewGrandpaState(db *chaindb.BadgerDB, bs *BlockState, telemetry Telemetry) *GrandpaState { +func NewGrandpaState(db database.Database, bs *BlockState, telemetry Telemetry) *GrandpaState { return &GrandpaState{ - db: chaindb.NewTable(db, grandpaPrefix), + db: database.NewTable(db, grandpaPrefix), blockState: bs, scheduledChangeRoots: new(changeTree), forcedChanges: new(orderedPendingChanges), @@ -459,7 +459,7 @@ func (s *GrandpaState) GetSetIDByBlockNumber(blockNumber uint) (uint64, error) { for { changeUpper, err := s.GetSetIDChange(curr + 1) - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { if curr == 0 { return 0, nil } @@ -502,7 +502,7 @@ func (s *GrandpaState) SetNextPause(number uint) error { } // GetNextPause returns the block number of the next grandpa pause. -// If the key is not found in the database, the error chaindb.ErrKeyNotFound +// If the key is not found in the database, the error database.ErrNotFound // is returned. func (s *GrandpaState) GetNextPause() (blockNumber uint, err error) { value, err := s.db.Get(pauseKey) @@ -520,7 +520,7 @@ func (s *GrandpaState) SetNextResume(number uint) error { } // GetNextResume returns the block number of the next grandpa resume. -// If the key is not found in the database, the error chaindb.ErrKeyNotFound +// If the key is not found in the database, the error database.ErrNotFound // is returned. func (s *GrandpaState) GetNextResume() (blockNumber uint, err error) { value, err := s.db.Get(resumeKey) diff --git a/dot/state/grandpa_test.go b/dot/state/grandpa_test.go index fefc9ac451..91116790a9 100644 --- a/dot/state/grandpa_test.go +++ b/dot/state/grandpa_test.go @@ -7,9 +7,9 @@ import ( "fmt" "testing" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" @@ -124,7 +124,7 @@ func TestGrandpaState_LatestRound(t *testing.T) { require.Equal(t, uint64(99), r) } -func testBlockState(t *testing.T, db *chaindb.BadgerDB) *BlockState { +func testBlockState(t *testing.T, db database.Database) *BlockState { ctrl := gomock.NewController(t) telemetryMock := NewMockTelemetry(ctrl) telemetryMock.EXPECT().SendMessage(gomock.AssignableToTypeOf(&telemetry.NotifyFinalized{})) diff --git a/dot/state/initialize.go b/dot/state/initialize.go index 5c923efbbf..6be468907e 100644 --- a/dot/state/initialize.go +++ b/dot/state/initialize.go @@ -7,15 +7,14 @@ import ( "fmt" "path/filepath" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" wazero_runtime "github.com/ChainSafe/gossamer/lib/runtime/wazero" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" ) // Initialise initialises the genesis state of the DB using the given storage trie. @@ -29,19 +28,19 @@ func (s *Service) Initialise(gen *genesis.Genesis, header *types.Header, t *trie return fmt.Errorf("failed to read basepath: %s", err) } + if err := database.ClearDatabase(basepath); err != nil { + return fmt.Errorf("while cleaning database: %w", err) + } + // initialise database using data directory - db, err := utils.SetupDatabase(basepath, s.isMemDB) + db, err := database.LoadDatabase(basepath, s.isMemDB) if err != nil { return fmt.Errorf("failed to create database: %s", err) } s.db = db - if err = db.ClearAll(); err != nil { - return fmt.Errorf("failed to clear database: %s", err) - } - - if err = t.WriteDirty(chaindb.NewTable(db, storagePrefix)); err != nil { + if err = t.WriteDirty(database.NewTable(db, storagePrefix)); err != nil { return fmt.Errorf("failed to write genesis trie to database: %w", err) } @@ -137,7 +136,7 @@ func loadGrandpaAuthorities(t *trie.Trie) ([]types.GrandpaVoter, error) { // storeInitialValues writes initial genesis values to the state database func (s *Service) storeInitialValues(data *genesis.Data, t *trie.Trie) error { // write genesis trie to database - if err := t.WriteDirty(chaindb.NewTable(s.db, storagePrefix)); err != nil { + if err := t.WriteDirty(database.NewTable(s.db, storagePrefix)); err != nil { return fmt.Errorf("failed to write trie to database: %s", err) } diff --git a/dot/state/interfaces.go b/dot/state/interfaces.go index bae7631e51..f57caec2db 100644 --- a/dot/state/interfaces.go +++ b/dot/state/interfaces.go @@ -6,8 +6,8 @@ package state import ( "encoding/json" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" ) // GetPutDeleter has methods to get, put and delete key values. @@ -58,7 +58,7 @@ type Haser interface { // NewBatcher creates a new database batch. type NewBatcher interface { - NewBatch() chaindb.Batch + NewBatch() database.Batch } // BabeConfigurer returns the babe configuration of the runtime. diff --git a/dot/state/mocks_test.go b/dot/state/mocks_test.go index 1ca5e3196a..70617922a3 100644 --- a/dot/state/mocks_test.go +++ b/dot/state/mocks_test.go @@ -8,7 +8,7 @@ import ( json "encoding/json" reflect "reflect" - chaindb "github.com/ChainSafe/chaindb" + database "github.com/ChainSafe/gossamer/internal/database" gomock "github.com/golang/mock/gomock" ) @@ -115,10 +115,10 @@ func (mr *MockBlockStateDatabaseMockRecorder) Has(arg0 interface{}) *gomock.Call } // NewBatch mocks base method. -func (m *MockBlockStateDatabase) NewBatch() chaindb.Batch { +func (m *MockBlockStateDatabase) NewBatch() database.Batch { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewBatch") - ret0, _ := ret[0].(chaindb.Batch) + ret0, _ := ret[0].(database.Batch) return ret0 } diff --git a/dot/state/offline_pruner.go b/dot/state/offline_pruner.go index f2104694c9..9bc8fc24cc 100644 --- a/dot/state/offline_pruner.go +++ b/dot/state/offline_pruner.go @@ -5,15 +5,13 @@ package state import ( "bytes" + "errors" "fmt" "os" - "github.com/ChainSafe/chaindb" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" - "github.com/dgraph-io/badger/v2" - "github.com/dgraph-io/badger/v2/pb" ) // OfflinePruner is a tool to prune the stale state with the help of @@ -21,10 +19,10 @@ import ( // - iterate the storage state, reconstruct the relevant state tries // - iterate the database, stream all the targeted keys to new DB type OfflinePruner struct { - inputDB *chaindb.BadgerDB + inputDB database.Database storageState *StorageState blockState *BlockState - filterDatabase *chaindb.BadgerDB + filterDatabase database.Database bestBlockHash common.Hash retainBlockNum uint32 @@ -34,7 +32,7 @@ type OfflinePruner struct { // NewOfflinePruner creates an instance of OfflinePruner. func NewOfflinePruner(inputDBPath string, retainBlockNum uint32) (pruner *OfflinePruner, err error) { - db, err := utils.LoadChainDB(inputDBPath) + db, err := database.LoadDatabase(inputDBPath, false) if err != nil { return nil, fmt.Errorf("failed to load DB %w", err) } @@ -66,10 +64,7 @@ func NewOfflinePruner(inputDBPath string, } }() - filterDatabaseOptions := &chaindb.Config{ - DataDir: filterDatabaseDir, - } - filterDatabase, err := chaindb.NewBadgerDB(filterDatabaseOptions) + filterDatabase, err := database.NewPebble(filterDatabaseDir, false) if err != nil { return nil, fmt.Errorf("creating badger filter database: %w", err) } @@ -155,10 +150,11 @@ func (p *OfflinePruner) SetBloomFilter() (err error) { // Prune starts streaming the data from input db to the pruned db. func (p *OfflinePruner) Prune() error { - inputDB, err := utils.LoadBadgerDB(p.inputDBPath) + inputDB, err := database.LoadDatabase(p.inputDBPath, false) if err != nil { return fmt.Errorf("failed to load DB %w", err) } + defer func() { closeErr := inputDB.Close() switch { @@ -172,30 +168,30 @@ func (p *OfflinePruner) Prune() error { }() storagePrefixBytes := []byte(storagePrefix) - stream := inputDB.NewStream() - stream.ChooseKey = func(item *badger.Item) bool { - key := item.Key() - if !bytes.HasPrefix(key, storagePrefixBytes) { - // Ignore non-storage keys - return false - } + // Ignore non-storage keys + inputDBIter := inputDB.NewPrefixIterator(storagePrefixBytes) + defer inputDBIter.Release() + + writeBatch := inputDB.NewBatch() + + for inputDBIter.First(); inputDBIter.Valid(); inputDBIter.Next() { + key := inputDBIter.Key() // Storage keys not found in filter database are deleted. nodeHash := bytes.TrimPrefix(key, storagePrefixBytes) _, err := p.filterDatabase.Get(nodeHash) - return err == nil - } - - writeBatch := inputDB.NewWriteBatch() - stream.Send = func(l *pb.KVList) error { - keyValues := l.GetKv() - for _, keyValue := range keyValues { - err = writeBatch.Delete(keyValue.Key) - if err != nil { - return err + if err != nil { + if errors.Is(err, database.ErrNotFound) { + continue } + + return fmt.Errorf("checking filter database: %w", err) + } + + err = writeBatch.Del(key) + if err != nil { + return fmt.Errorf("inserting in the batch delete: %w", err) } - return nil } err = writeBatch.Flush() diff --git a/dot/state/service.go b/dot/state/service.go index 674930f922..eb17ca25ea 100644 --- a/dot/state/service.go +++ b/dot/state/service.go @@ -9,13 +9,11 @@ import ( "github.com/ChainSafe/gossamer/dot/state/pruner" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/internal/metrics" "github.com/ChainSafe/gossamer/lib/blocktree" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" - - "github.com/ChainSafe/chaindb" ) var logger = log.NewFromGlobal( @@ -26,7 +24,7 @@ var logger = log.NewFromGlobal( type Service struct { dbPath string logLvl log.Level - db *chaindb.BadgerDB + db database.Database isMemDB bool // set to true if using an in-memory database; only used for testing. Base *BaseState Storage *StorageState @@ -79,7 +77,7 @@ func (s *Service) UseMemDB() { } // DB returns the Service's database -func (s *Service) DB() *chaindb.BadgerDB { +func (s *Service) DB() database.Database { return s.db } @@ -96,7 +94,7 @@ func (s *Service) SetupBase() error { } // initialise database - db, err := utils.SetupDatabase(basepath, false) + db, err := database.LoadDatabase(basepath, false) if err != nil { return err } @@ -262,18 +260,18 @@ func (s *Service) Import(header *types.Header, t *trie.Trie, firstSlot uint64) e var err error // initialise database using data directory if !s.isMemDB { - s.db, err = utils.SetupDatabase(s.dbPath, s.isMemDB) + s.db, err = database.LoadDatabase(s.dbPath, s.isMemDB) if err != nil { return fmt.Errorf("failed to create database: %w", err) } } block := &BlockState{ - db: chaindb.NewTable(s.db, blockPrefix), + db: database.NewTable(s.db, blockPrefix), } storage := &StorageState{ - db: chaindb.NewTable(s.db, storagePrefix), + db: database.NewTable(s.db, storagePrefix), } epoch, err := NewEpochState(s.db, block) diff --git a/dot/state/service_integration_test.go b/dot/state/service_integration_test.go index eeed4ed3db..d5b51186e7 100644 --- a/dot/state/service_integration_test.go +++ b/dot/state/service_integration_test.go @@ -13,13 +13,13 @@ import ( "github.com/ChainSafe/gossamer/dot/state/pruner" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" runtime "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/trie" "github.com/golang/mock/gomock" - "github.com/ChainSafe/chaindb" "github.com/stretchr/testify/require" ) @@ -220,7 +220,7 @@ func TestService_StorageTriePruning(t *testing.T) { require.NoError(t, err, fmt.Sprintf("Got error for block %d", b.Header.Number)) continue } - require.ErrorIs(t, err, chaindb.ErrKeyNotFound, fmt.Sprintf("Expected error for block %d", b.Header.Number)) + require.ErrorIs(t, err, database.ErrNotFound, fmt.Sprintf("Expected error for block %d", b.Header.Number)) } } @@ -357,10 +357,10 @@ func TestService_Rewind(t *testing.T) { require.NoError(t, err) _, err = serv.Grandpa.GetSetIDChange(2) - require.Equal(t, chaindb.ErrKeyNotFound, err) + require.Equal(t, database.ErrNotFound, err) _, err = serv.Grandpa.GetSetIDChange(3) - require.Equal(t, chaindb.ErrKeyNotFound, err) + require.Equal(t, database.ErrNotFound, err) } func TestService_Import(t *testing.T) { diff --git a/dot/state/slot.go b/dot/state/slot.go index 240532c035..f926edbf03 100644 --- a/dot/state/slot.go +++ b/dot/state/slot.go @@ -9,8 +9,8 @@ import ( "errors" "fmt" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/pkg/scale" ) @@ -28,11 +28,11 @@ var ( ) type SlotState struct { - db chaindb.Database + db database.Table } -func NewSlotState(db *chaindb.BadgerDB) *SlotState { - slotStateDB := chaindb.NewTable(db, slotTablePrefix) +func NewSlotState(db database.Database) *SlotState { + slotStateDB := database.NewTable(db, slotTablePrefix) return &SlotState{ db: slotStateDB, @@ -57,7 +57,7 @@ func (s *SlotState) CheckEquivocation(slotNow, slot uint64, header *types.Header currentSlotKey := bytes.Join([][]byte{slotHeaderMapKey, slotEncoded}, nil) encodedHeadersWithSigners, err := s.db.Get(currentSlotKey) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return nil, fmt.Errorf("getting key slot header map key %d: %w", slot, err) } @@ -89,7 +89,7 @@ func (s *SlotState) CheckEquivocation(slotNow, slot uint64, header *types.Header firstSavedSlot := slot firstSavedSlotEncoded, err := s.db.Get(slotHeaderStartKey) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return nil, fmt.Errorf("getting key slot header start key: %w", err) } diff --git a/dot/state/slot_test.go b/dot/state/slot_test.go index a1fe7f5051..481c70a324 100644 --- a/dot/state/slot_test.go +++ b/dot/state/slot_test.go @@ -11,8 +11,8 @@ import ( "io" "testing" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/lib/keystore" @@ -41,7 +41,7 @@ func createHeader(t *testing.T, n uint) (header *types.Header) { return header } -func checkSlotToMapKeyExists(t *testing.T, db chaindb.Database, slotNumber uint64) bool { +func checkSlotToMapKeyExists(t *testing.T, db database.Table, slotNumber uint64) bool { t.Helper() slotEncoded := make([]byte, 8) @@ -51,7 +51,7 @@ func checkSlotToMapKeyExists(t *testing.T, db chaindb.Database, slotNumber uint6 _, err := db.Get(slotToHeaderKey) if err != nil { - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { return false } @@ -62,10 +62,7 @@ func checkSlotToMapKeyExists(t *testing.T, db chaindb.Database, slotNumber uint6 } func Test_checkEquivocation(t *testing.T) { - inMemoryDB, err := chaindb.NewBadgerDB(&chaindb.Config{ - DataDir: t.TempDir(), - InMemory: true, - }) + inMemoryDB, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) kr, err := keystore.NewSr25519Keyring() diff --git a/dot/state/storage.go b/dot/state/storage.go index efaba3acff..b7104b2c68 100644 --- a/dot/state/storage.go +++ b/dot/state/storage.go @@ -8,9 +8,9 @@ import ( "fmt" "sync" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/state/pruner" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/trie" @@ -44,9 +44,9 @@ type StorageState struct { // NewStorageState creates a new StorageState backed by the given block state // and database located at basePath. -func NewStorageState(db *chaindb.BadgerDB, blockState *BlockState, +func NewStorageState(db database.Database, blockState *BlockState, tries *Tries) (*StorageState, error) { - storageTable := chaindb.NewTable(db, storagePrefix) + storageTable := database.NewTable(db, storagePrefix) return &StorageState{ blockState: blockState, diff --git a/dot/state/storage_notify_test.go b/dot/state/storage_notify_test.go index 4751e6137f..564458dc7c 100644 --- a/dot/state/storage_notify_test.go +++ b/dot/state/storage_notify_test.go @@ -4,16 +4,11 @@ package state import ( - "context" - "fmt" - "log" "sync" "testing" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/lib/common" - "github.com/dgraph-io/badger/v4/pb" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -135,63 +130,3 @@ func TestStorageState_RegisterStorageObserver_Multi_Filter(t *testing.T) { ss.UnregisterStorageObserver(observer) } } - -func Test_Example(t *testing.T) { - // this is a working example of how to use db.Subscribe taken from - // https://github.com/dgraph-io/badger/blob/f50343ff404d8198df6dc83755ec2eab863d5ff2/db_test.go#L1939-L1948 - prefix := []byte{'a'} - match := []pb.Match{ - { - Prefix: prefix, - }, - } - - // This key should be printed, since it matches the prefix. - aKey := []byte("a-key") - aValue := []byte("a-value") - - // This key should not be printed. - bKey := []byte("b-key") - bValue := []byte("b-value") - - // Open the DB. - db := NewInMemoryDB(t) - - // Create the context here so we can cancel it after sending the writes. - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // Use the WaitGroup to make sure we wait for the subscription to stop before continuing. - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - cb := func(kvs *chaindb.KVList) error { - for _, kv := range kvs.Kv { - fmt.Printf("%s is now set to %s\n", kv.Key, kv.Value) - } - return nil - } - - if err := db.Subscribe(ctx, cb, match); err != nil && err != context.Canceled { - log.Fatal(err) - } - log.Printf("subscription closed") - }() - - // Write both keys, but only one should be printed in the Output. - err := db.Put(aKey, aValue) - if err != nil { - log.Fatal(err) - } - err = db.Put(bKey, bValue) - if err != nil { - log.Fatal(err) - } - log.Printf("stopping subscription") - cancel() - log.Printf("waiting for subscription to close") - wg.Wait() - // Output: - // a-key is now set to a-value -} diff --git a/dot/state/storage_test.go b/dot/state/storage_test.go index 1af0d3c768..d77cc03e5e 100644 --- a/dot/state/storage_test.go +++ b/dot/state/storage_test.go @@ -9,11 +9,11 @@ import ( "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/trie/node" "github.com/ChainSafe/gossamer/lib/common" runtime "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -45,8 +45,8 @@ func TestStorage_StoreAndLoadTrie(t *testing.T) { trie, err := storage.LoadFromDB(root) require.NoError(t, err) ts2 := runtime.NewTrieState(trie) - new := ts2.Snapshot() - require.Equal(t, ts.Trie(), new) + newSnapshot := ts2.Snapshot() + require.Equal(t, ts.Trie(), newSnapshot) } func TestStorage_GetStorageByBlockHash(t *testing.T) { @@ -167,7 +167,7 @@ func TestStorage_StoreTrie_NotSyncing(t *testing.T) { func TestGetStorageChildAndGetStorageFromChild(t *testing.T) { // initialise database using data directory basepath := t.TempDir() - db, err := utils.SetupDatabase(basepath, false) + db, err := database.LoadDatabase(basepath, false) require.NoError(t, err) _, genTrie, genHeader := newWestendDevGenesisWithTrieAndHeader(t) diff --git a/dot/state/test_helpers.go b/dot/state/test_helpers.go index 9353e2303c..3109fede3d 100644 --- a/dot/state/test_helpers.go +++ b/dot/state/test_helpers.go @@ -9,11 +9,10 @@ import ( "testing" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/stretchr/testify/require" @@ -22,10 +21,10 @@ import ( var inc, _ = time.ParseDuration("1s") // NewInMemoryDB creates a new in-memory database -func NewInMemoryDB(t *testing.T) *chaindb.BadgerDB { +func NewInMemoryDB(t *testing.T) database.Database { testDatadirPath := t.TempDir() - db, err := utils.SetupDatabase(testDatadirPath, true) + db, err := database.LoadDatabase(testDatadirPath, true) require.NoError(t, err) t.Cleanup(func() { _ = db.Close() diff --git a/dot/sync/chain_sync.go b/dot/sync/chain_sync.go index 3d64993130..6457a72e0b 100644 --- a/dot/sync/chain_sync.go +++ b/dot/sync/chain_sync.go @@ -13,7 +13,6 @@ import ( "sync/atomic" "time" - "github.com/ChainSafe/chaindb" "github.com/libp2p/go-libp2p/core/peer" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -23,6 +22,7 @@ import ( "github.com/ChainSafe/gossamer/dot/peerset" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/blocktree" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/common/variadic" @@ -438,7 +438,7 @@ func (cs *chainSync) requestForkBlocks(bestBlockHeader, highestFinalizedHeader, bestBlockHeader.Hash(), bestBlockHeader.Number, highestFinalizedHeader.Hash(), highestFinalizedHeader.Number) parentExists, err := cs.blockState.HasHeader(announcedHeader.ParentHash) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return fmt.Errorf("while checking header exists: %w", err) } @@ -756,7 +756,7 @@ func (cs *chainSync) handleReadyBlock(bd *types.BlockData) error { // block wasn't in the pending set! // let's check the db as maybe we already processed it has, err := cs.blockState.HasHeader(bd.Hash) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { logger.Debugf("failed to check if header is known for hash %s: %s", bd.Hash, err) return err } diff --git a/dot/sync/syncer.go b/dot/sync/syncer.go index 5413b8a002..32ec786f99 100644 --- a/dot/sync/syncer.go +++ b/dot/sync/syncer.go @@ -8,11 +8,11 @@ import ( "fmt" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/peerset" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/libp2p/go-libp2p/core/peer" ) @@ -108,7 +108,7 @@ func (s *Service) HandleBlockAnnounce(from peer.ID, msg *network.BlockAnnounceMe // check if our block hash for that number is the same, if so, do nothing // as we already have that block ourHash, err := s.blockState.GetHashByNumber(blockAnnounceHeader.Number) - if err != nil && !errors.Is(err, chaindb.ErrKeyNotFound) { + if err != nil && !errors.Is(err, database.ErrNotFound) { return fmt.Errorf("get block hash by number: %w", err) } diff --git a/dot/sync/syncer_integration_test.go b/dot/sync/syncer_integration_test.go index 92d4f12970..b12ed27363 100644 --- a/dot/sync/syncer_integration_test.go +++ b/dot/sync/syncer_integration_test.go @@ -12,6 +12,7 @@ import ( "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/genesis" @@ -70,7 +71,7 @@ func newTestSyncer(t *testing.T) *Service { if stateSrvc != nil { rtCfg.NodeStorage.BaseDB = stateSrvc.Base } else { - rtCfg.NodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + rtCfg.NodeStorage.BaseDB, err = database.LoadDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) require.NoError(t, err) } diff --git a/go.mod b/go.mod index d4c6997bdd..2321849cf9 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,15 @@ module github.com/ChainSafe/gossamer require ( - github.com/ChainSafe/chaindb v0.1.5 github.com/ChainSafe/go-schnorrkel v1.0.1-0.20220711122024-027d287d27bf github.com/OneOfOne/xxhash v1.2.8 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/centrifuge/go-substrate-rpc-client/v4 v4.1.0 github.com/chyeh/pubip v0.0.0-20170203095919-b7e679cf541c + github.com/cockroachdb/pebble v0.0.0-20230721221451-fcaeb47a50e0 github.com/cosmos/go-bip39 v1.0.0 github.com/dgraph-io/badger/v2 v2.2007.4 - github.com/dgraph-io/badger/v4 v4.1.0 github.com/dgraph-io/ristretto v0.1.1 github.com/disiqueira/gotree v1.0.0 github.com/ethereum/go-ethereum v1.12.2 @@ -47,13 +46,17 @@ require ( ) require ( - github.com/ChainSafe/log15 v1.0.0 // indirect + github.com/DataDog/zstd v1.5.2 // indirect github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -70,6 +73,7 @@ require ( github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.1 // indirect @@ -80,10 +84,8 @@ require ( github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.0.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/flatbuffers v23.1.21+incompatible // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect @@ -108,6 +110,8 @@ require ( github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/koron/go-ssdp v0.0.4 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect @@ -159,6 +163,7 @@ require ( github.com/quic-go/quic-go v0.33.0 // indirect github.com/quic-go/webtransport-go v0.5.3 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/cors v1.8.2 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/smartystreets/assertions v1.13.0 // indirect diff --git a/go.sum b/go.sum index 12fdb9cdc0..65e190b6df 100644 --- a/go.sum +++ b/go.sum @@ -43,26 +43,31 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/chaindb v0.1.5 h1:aoji9HJxZlaG0J+OZUbjbf3Jrf1iij7qAIfjTwFIWWE= -github.com/ChainSafe/chaindb v0.1.5/go.mod h1:TVmQZ7XoN0YPiWp7dZsRS61vON9C/Igjxs1zl7Pxkxc= github.com/ChainSafe/go-schnorrkel v1.0.1-0.20220711122024-027d287d27bf h1:S195ZBRu20VgXC1i5nHTR6b4BbTQaMCDuq6tzFQN5zU= github.com/ChainSafe/go-schnorrkel v1.0.1-0.20220711122024-027d287d27bf/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= -github.com/ChainSafe/log15 v1.0.0 h1:vRDVtWtVwIH5uSCBvgTTZh6FA58UBJ6+QiiypaZfBf8= -github.com/ChainSafe/log15 v1.0.0/go.mod h1:5v1+ALHtdW0NfAeeoYyKmzCAMcAeqkdhIg4uxXWIgOg= github.com/ChainSafe/wazero v0.0.0-20230710171859-39a4c235ec1f h1:/sI8TMJ77HL2UImQs7pY7khVN96EXQJGVOrX88dTpcY= github.com/ChainSafe/wazero v0.0.0-20230710171859-39a4c235ec1f/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= +github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -116,6 +121,20 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v0.0.0-20230721221451-fcaeb47a50e0 h1:6OwRzk7AKRNumJttanSCJPVMkmXvfioVgijKfJHAceU= +github.com/cockroachdb/pebble v0.0.0-20230721221451-fcaeb47a50e0/go.mod h1:FN5O47SBEz5+kO9fG8UTR64g2WS1u5ZFCgTvxGjoSks= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6 h1:DJK8W/iB+s/qkTtmXSrHA49lp5O3OsR7E6z4byOLy34= +github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -133,6 +152,7 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -151,12 +171,11 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger/v2 v2.2007.3/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/badger/v4 v4.1.0 h1:E38jc0f+RATYrycSUf9LMv/t47XAy+3CApyYSq4APOQ= -github.com/dgraph-io/badger/v4 v4.1.0/go.mod h1:P50u28d39ibBRmIJuQC/NSdBOg46HnHw7al2SW5QRHg= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= @@ -171,6 +190,7 @@ github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= @@ -179,11 +199,15 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/go-ethereum v1.12.2 h1:eGHJ4ij7oyVqUQn48LBz3B7pvQ8sV0wGJiIE6gDq/6Y= github.com/ethereum/go-ethereum v1.12.2/go.mod h1:1cRAEV+rp/xX0zraSCBnu9Py3HQ+geRMj3HdR+k0wfI= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= @@ -196,13 +220,21 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -211,6 +243,7 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -224,7 +257,6 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw= github.com/go-playground/validator/v10 v10.15.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -236,14 +268,20 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -251,7 +289,6 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -277,6 +314,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -284,10 +322,9 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= -github.com/google/flatbuffers v23.1.21+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -354,6 +391,7 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= @@ -369,8 +407,10 @@ github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7 github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -397,6 +437,11 @@ github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= @@ -421,14 +466,23 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -438,11 +492,16 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= @@ -485,18 +544,25 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/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 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= @@ -523,6 +589,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= @@ -552,11 +619,16 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975 h1:zm/Rb2OsnLWCY88Njoqgo4X6yt/lx3oBNWhepX0AOMU= github.com/nanobox-io/golang-scribble v0.0.0-20190309225732-aa3e7c118975/go.mod h1:4Mct/lWCFf1jzQTTAaWtOI7sXqmG+wBeiBfT4CxoaJk= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= @@ -580,6 +652,9 @@ github.com/phuslu/iploc v1.0.20230201 h1:AMhy7j8z0N5iI0jaqh514KTDEB7wVdQJ4Y4DJPC github.com/phuslu/iploc v1.0.20230201/go.mod h1:gsgExGWldwv1AEzZm+Ki9/vGfyjkL33pbSr9HGpt2Xg= github.com/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo= github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -616,12 +691,17 @@ github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2Gk github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= 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/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -649,9 +729,11 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN23diwyr69Qs= github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= @@ -705,14 +787,21 @@ github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefld github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vedhavyas/go-subkey v1.0.4 h1:QwjBZx4w7qXC2lmqol2jJfhaNXPI9BsgLZiMiCwqGDU= github.com/vedhavyas/go-subkey v1.0.4/go.mod h1:aOIil/KS9hJlnr9ZSQKSoXdu/MbnkCxG4x9IOlLsMtI= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= @@ -725,7 +814,14 @@ github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdz github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 h1:Y1/FEOpaCpD21WxrmfeIYCFPuVPRCY2XZTWzTNHGw30= github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -775,14 +871,17 @@ golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= @@ -812,6 +911,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -832,10 +932,12 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -843,6 +945,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -867,6 +970,7 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -913,6 +1017,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -948,12 +1053,16 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/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-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -970,6 +1079,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= @@ -978,15 +1088,18 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1034,6 +1147,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= @@ -1074,6 +1188,7 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -1114,6 +1229,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1133,6 +1250,7 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1154,9 +1272,13 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1166,6 +1288,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/database/database.go b/internal/database/database.go new file mode 100644 index 0000000000..8a1cd639e6 --- /dev/null +++ b/internal/database/database.go @@ -0,0 +1,76 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "io" + "os" + "path/filepath" +) + +type Reader interface { + Get(key []byte) ([]byte, error) + Has(key []byte) (bool, error) +} + +type Writer interface { + Put(key, value []byte) error + Del(key []byte) error + Flush() error +} + +// Iterator iterates over key/value pairs in ascending key order. +// Must be released after use. +type Iterator interface { + Valid() bool + Next() bool + Key() []byte + Value() []byte + First() bool + Release() + SeekGE(key []byte) bool + io.Closer +} + +// Batch is a write-only operation. +type Batch interface { + io.Closer + Writer + + ValueSize() int + Reset() +} + +// Database wraps all database operations. All methods are safe for concurrent use. +type Database interface { + Reader + Writer + io.Closer + + Path() string + NewBatch() Batch + NewIterator() Iterator + NewPrefixIterator(prefix []byte) Iterator +} + +type Table interface { + Reader + Writer + Path() string + NewBatch() Batch + NewIterator() Iterator +} + +const DefaultDatabaseDir = "db" + +// LoadDatabase will return an instance of database based on basepath +func LoadDatabase(basepath string, inMemory bool) (Database, error) { + nodeDatabaseDir := filepath.Join(basepath, DefaultDatabaseDir) + return NewPebble(nodeDatabaseDir, inMemory) +} + +func ClearDatabase(basepath string) error { + nodeDatabaseDir := filepath.Join(basepath, DefaultDatabaseDir) + return os.RemoveAll(nodeDatabaseDir) +} diff --git a/internal/database/database_test.go b/internal/database/database_test.go new file mode 100644 index 0000000000..fb34f1d24b --- /dev/null +++ b/internal/database/database_test.go @@ -0,0 +1,65 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSetupAndClearDatabase(t *testing.T) { + tmpDir := t.TempDir() + + // Setup database and execute some operations + db, err := LoadDatabase(tmpDir, false) + require.NoError(t, err) + + err = db.Put([]byte("key"), []byte("value")) + require.NoError(t, err) + + value, err := db.Get([]byte("key")) + require.NoError(t, err) + require.Equal(t, []byte("value"), value) + + err = db.Close() + require.NoError(t, err) + + shouldExists := true + checkDatbaseDirectory(t, tmpDir, shouldExists) + + ClearDatabase(tmpDir) + + shouldExists = false + checkDatbaseDirectory(t, tmpDir, shouldExists) + + // Setup database after an clear operation + // should be okay + db, err = LoadDatabase(tmpDir, false) + require.NoError(t, err) + + shouldExists = true + checkDatbaseDirectory(t, tmpDir, shouldExists) + + err = db.Close() + require.NoError(t, err) +} + +func checkDatbaseDirectory(t *testing.T, dir string, shouldExists bool) { + t.Helper() + + databaseDir := filepath.Join(dir, DefaultDatabaseDir) + entries, err := os.ReadDir(databaseDir) + if !shouldExists { + require.True(t, os.IsNotExist(err)) + return + } + + require.NoError(t, err) + if shouldExists { + require.Greater(t, len(entries), 0) + } +} diff --git a/internal/database/pebble.go b/internal/database/pebble.go new file mode 100644 index 0000000000..f48e909183 --- /dev/null +++ b/internal/database/pebble.go @@ -0,0 +1,154 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "errors" + "fmt" + "os" + + "github.com/ChainSafe/gossamer/internal/log" + "github.com/cockroachdb/pebble" + "github.com/cockroachdb/pebble/vfs" +) + +var logger = log.NewFromGlobal(log.AddContext("internal", "database")) +var _ Database = (*PebbleDB)(nil) + +var ErrNotFound = pebble.ErrNotFound + +type PebbleDB struct { + path string + db *pebble.DB +} + +// NewPebble return an pebble db implementation of Database interface +func NewPebble(path string, inMemory bool) (*PebbleDB, error) { + opts := &pebble.Options{} + if inMemory { + opts = &pebble.Options{FS: vfs.NewMem()} + } else { + if err := os.MkdirAll(path, os.ModePerm); err != nil { + return nil, err + } + } + + db, err := pebble.Open(path, opts) + if err != nil { + return nil, fmt.Errorf("oppening pebble db: %w", err) + } + + return &PebbleDB{path, db}, nil +} + +func (p *PebbleDB) Path() string { + return p.path +} + +func (p *PebbleDB) Put(key, value []byte) error { + err := p.db.Set(key, value, &pebble.WriteOptions{}) + if err != nil { + return fmt.Errorf("writing 0x%x with value 0x%x to database: %w", + key, value, err) + } + return nil +} + +func (p *PebbleDB) Get(key []byte) (value []byte, err error) { + value, closer, err := p.db.Get(key) + if err != nil { + return nil, err + } + + if err := closer.Close(); err != nil { + return nil, fmt.Errorf("closing after get: %w", err) + } + + valueCpy := make([]byte, len(value)) + copy(valueCpy, value) + return valueCpy, err +} + +func (p *PebbleDB) Has(key []byte) (exists bool, err error) { + value, closer, err := p.db.Get(key) + if err != nil { + if errors.Is(err, pebble.ErrNotFound) { + return false, nil + } + + return false, err + } + + if err := closer.Close(); err != nil { + return false, fmt.Errorf("closing after get: %w", err) + } + + return value != nil, err +} + +func (p *PebbleDB) Del(key []byte) error { + err := p.db.Delete(key, &pebble.WriteOptions{}) + if err != nil { + return err + } + + return nil +} + +func (p *PebbleDB) Close() error { + return p.db.Close() +} + +func (p *PebbleDB) Flush() error { + err := p.db.Flush() + if err != nil { + return fmt.Errorf("flushing database: %w", err) + } + + return nil +} + +// NewBatch returns an implementation of Batch interface using the +// internal database +func (p *PebbleDB) NewBatch() Batch { + return &pebbleBatch{ + batch: p.db.NewBatch(), + } +} + +// NewIterator returns an implementation of Iterator interface using the +// internal database +func (p *PebbleDB) NewIterator() Iterator { + return &pebbleIterator{ + p.db.NewIter(nil), + } +} + +// NewPrefixIterator returns an implementation of Iterator over a specific +// keys that contains the prefix +// more info: https://github.com/ChainSafe/gossamer/pull/3434#discussion_r1291503323 +func (p *PebbleDB) NewPrefixIterator(prefix []byte) Iterator { + keyUpperBound := func(b []byte) []byte { + end := make([]byte, len(b)) + copy(end, b) + + for i := len(end) - 1; i >= 0; i-- { + end[i] = end[i] + 1 + if end[i] != 0 { + return end[:i+1] + } + } + + return nil + } + + prefixIterOptions := &pebble.IterOptions{ + LowerBound: prefix, + UpperBound: keyUpperBound(prefix), + } + + return &pebbleIterator{ + p.db.NewIter(prefixIterOptions), + } +} diff --git a/internal/database/pebble_batch.go b/internal/database/pebble_batch.go new file mode 100644 index 0000000000..dbe20d9df9 --- /dev/null +++ b/internal/database/pebble_batch.go @@ -0,0 +1,52 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "fmt" + + "github.com/cockroachdb/pebble" +) + +var _ Batch = (*pebbleBatch)(nil) + +type pebbleBatch struct { + batch *pebble.Batch +} + +func (pb *pebbleBatch) Put(key, value []byte) error { + err := pb.batch.Set(key, value, nil) + if err != nil { + return fmt.Errorf("setting to batch writer: %w", err) + } + return nil +} +func (pb *pebbleBatch) Del(key []byte) error { + err := pb.batch.Delete(key, &pebble.WriteOptions{}) + if err != nil { + return fmt.Errorf("setting to batch delete: %w", err) + } + return nil +} + +func (pb *pebbleBatch) Flush() error { + err := pb.batch.Commit(&pebble.WriteOptions{}) + if err != nil { + return fmt.Errorf("committing batch: %w", err) + } + + return nil +} + +func (pb *pebbleBatch) ValueSize() int { + return int(pb.batch.Count()) +} + +func (pb *pebbleBatch) Reset() { + pb.batch.Reset() +} + +func (pb *pebbleBatch) Close() error { + return pb.batch.Close() +} diff --git a/internal/database/pebble_iterator.go b/internal/database/pebble_iterator.go new file mode 100644 index 0000000000..4c7b0114f0 --- /dev/null +++ b/internal/database/pebble_iterator.go @@ -0,0 +1,19 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import "github.com/cockroachdb/pebble" + +var _ Iterator = (*pebbleIterator)(nil) + +type pebbleIterator struct { + *pebble.Iterator +} + +func (pi *pebbleIterator) Release() { + err := pi.Close() + if err != nil { + logger.Criticalf("while closing iterator: %s", err) + } +} diff --git a/internal/database/pebble_test.go b/internal/database/pebble_test.go new file mode 100644 index 0000000000..b6ef48818c --- /dev/null +++ b/internal/database/pebble_test.go @@ -0,0 +1,215 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "fmt" + "os" + "testing" + + "github.com/cockroachdb/pebble" + "github.com/stretchr/testify/require" +) + +type testAssertion struct { + input string + expected string +} + +func testSetup() []testAssertion { + tests := []testAssertion{ + {"camel", "camel"}, + {"walrus", "walrus"}, + {"296204", "296204"}, + {"\x00123\x00", "\x00123\x00"}, + } + return tests +} + +func testNewPebble(t *testing.T) Database { + t.Helper() + + db, err := NewPebble(t.TempDir(), false) + if err != nil { + t.Fatal(err) + } + + t.Cleanup(func() { + err := db.Close() + require.NoError(t, err) + }) + + return db +} + +func TestPebbleDatabaseImplementations(t *testing.T) { + db := testNewPebble(t) + + testPutGetter(t, db) + testHasGetter(t, db) + testUpdateGetter(t, db) + testDelGetter(t, db) + testGetPath(t, db) +} + +func TestPebbleDBBatch(t *testing.T) { + db := testNewPebble(t) + testBatchPutAndDelete(t, db) +} + +func TestPebbleDBIterator(t *testing.T) { + db := testNewPebble(t) + testNextKeyIterator(t, db) + testSeekKeyValueIterator(t, db) +} + +func testPutGetter(t *testing.T, db Database) { + tests := testSetup() + for _, v := range tests { + err := db.Put([]byte(v.input), []byte(v.input)) + require.NoError(t, err) + + data, err := db.Get([]byte(v.input)) + require.NoError(t, err) + + require.Equal(t, data, []byte(v.expected)) + } +} + +func testHasGetter(t *testing.T, db Database) { + tests := testSetup() + + for _, v := range tests { + exists, err := db.Has([]byte(v.input)) + require.NoError(t, err) + require.True(t, exists) + } +} + +func testUpdateGetter(t *testing.T, db Database) { + tests := testSetup() + + for _, v := range tests { + err := db.Put([]byte(v.input), []byte("?")) + require.NoError(t, err) + + data, err := db.Get([]byte(v.input)) + require.NoError(t, err) + + require.Equal(t, data, []byte("?")) + } +} + +func testDelGetter(t *testing.T, db Database) { + tests := testSetup() + + for _, v := range tests { + err := db.Del([]byte(v.input)) + require.NoError(t, err) + + d, err := db.Get([]byte(v.input)) + require.ErrorIs(t, err, pebble.ErrNotFound) + require.Zero(t, len(d)) + } +} + +func testGetPath(t *testing.T, db Database) { + dir := db.Path() + fi, err := os.Stat(dir) + require.NoError(t, err) + require.True(t, fi.IsDir()) +} + +func testBatchPutAndDelete(t *testing.T, db Database) { + key := []byte("camel") + value := []byte("camel-value") + + batch := db.NewBatch() + err := batch.Put(key, value) + require.NoError(t, err) + + testFlushAndClose(t, batch, 1) + + deleteBatch := db.NewBatch() + err = deleteBatch.Del(key) + require.NoError(t, err) + + retrievedValue, err := db.Get(key) + require.NoError(t, err) + require.Equal(t, value, retrievedValue) + + testFlushAndClose(t, deleteBatch, 1) + + _, err = db.Get(key) + require.ErrorIs(t, err, ErrNotFound) +} + +func testFlushAndClose(t *testing.T, batch Batch, expectedSize int) { + t.Helper() + + err := batch.Flush() + require.NoError(t, err) + + size := batch.ValueSize() + require.Equal(t, expectedSize, size) + + batch.Close() + size = batch.ValueSize() + require.Equal(t, 0, size) +} + +func testIteratorSetup(t *testing.T, db Database) { + t.Helper() + batch := db.NewBatch() + + for i := 0; i < 5; i++ { + key := []byte(fmt.Sprintf("camel-%d", i)) + value := []byte(fmt.Sprintf("camel-value-%d", i)) + err := batch.Put(key, value) + require.NoError(t, err) + } + + err := batch.Flush() + require.NoError(t, err) +} + +func testNextKeyIterator(t *testing.T, db Database) { + testIteratorSetup(t, db) + + it := db.NewIterator() + defer it.Release() + + counter := 0 + for succ := it.First(); succ; succ = it.Next() { + require.NotNil(t, it.Key()) + require.NotNil(t, it.Value()) + counter++ + } + + // testIteratorSetup creates 5 entries + const expected = 5 + require.Equal(t, expected, counter) +} + +func testSeekKeyValueIterator(t *testing.T, db Database) { + testIteratorSetup(t, db) + kv := map[string]string{ + "camel-0": "camel-value-0", + "camel-1": "camel-value-1", + "camel-2": "camel-value-2", + "camel-3": "camel-value-3", + "camel-4": "camel-value-4", + } + + it := db.NewIterator() + defer it.Release() + + for succ := it.SeekGE([]byte("camel-")); succ; succ = it.Next() { + expectedValue, ok := kv[string(it.Key())] + require.True(t, ok) + + require.True(t, it.Valid()) + require.Equal(t, it.Value(), []byte(expectedValue)) + } +} diff --git a/internal/database/table.go b/internal/database/table.go new file mode 100644 index 0000000000..30b7cc5458 --- /dev/null +++ b/internal/database/table.go @@ -0,0 +1,61 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "bytes" +) + +type table struct { + db Database + prefix []byte +} + +var _ Table = (*table)(nil) + +func NewTable(db Database, prefix string) Table { + return &table{ + db: db, + prefix: []byte(prefix), + } +} + +func (t *table) Path() string { + return string(t.prefix) +} + +func (t *table) Get(key []byte) ([]byte, error) { + tableItemKey := bytes.Join([][]byte{t.prefix, key}, nil) + return t.db.Get(tableItemKey) +} + +func (t *table) Has(key []byte) (bool, error) { + tableItemKey := bytes.Join([][]byte{t.prefix, key}, nil) + return t.db.Has(tableItemKey) +} + +func (t *table) Put(key, value []byte) error { + tableItemKey := bytes.Join([][]byte{t.prefix, key}, nil) + return t.db.Put(tableItemKey, value) +} + +func (t *table) Del(key []byte) error { + tableItemKey := bytes.Join([][]byte{t.prefix, key}, nil) + return t.db.Del(tableItemKey) +} + +func (t *table) Flush() error { + return t.db.Flush() +} + +func (t *table) NewBatch() Batch { + return &tableBatch{ + batch: t.db.NewBatch(), + prefix: t.prefix, + } +} + +func (t *table) NewIterator() Iterator { + return t.db.NewPrefixIterator(t.prefix) +} diff --git a/internal/database/table_batch.go b/internal/database/table_batch.go new file mode 100644 index 0000000000..4ce003a846 --- /dev/null +++ b/internal/database/table_batch.go @@ -0,0 +1,41 @@ +// Copyright 2023 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package database + +import ( + "bytes" +) + +var _ Batch = (*tableBatch)(nil) + +type tableBatch struct { + batch Batch + prefix []byte +} + +func (tb *tableBatch) Put(key, value []byte) error { + tableItemKey := bytes.Join([][]byte{tb.prefix, key}, nil) + return tb.batch.Put(tableItemKey, value) +} + +func (tb *tableBatch) Del(key []byte) error { + tableItemKey := bytes.Join([][]byte{tb.prefix, key}, nil) + return tb.batch.Del(tableItemKey) +} + +func (tb *tableBatch) Flush() error { + return tb.batch.Flush() +} + +func (tb *tableBatch) ValueSize() int { + return tb.batch.ValueSize() +} + +func (tb *tableBatch) Reset() { + tb.batch.Reset() +} + +func (tb *tableBatch) Close() error { + return tb.batch.Close() +} diff --git a/lib/babe/babe.go b/lib/babe/babe.go index d413f041b4..0ef35b8244 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -46,6 +46,7 @@ type Service struct { pause chan struct{} telemetry Telemetry + wg sync.WaitGroup } // ServiceConfig represents a BABE configuration @@ -175,7 +176,11 @@ func (b *Service) Start() error { return nil } - go b.initiate() + b.wg.Add(1) + go func() { + b.initiate() + b.wg.Done() + }() return nil } @@ -212,7 +217,11 @@ func (b *Service) Resume() error { } b.pause = make(chan struct{}) - go b.initiate() + b.wg.Add(1) + go func() { + b.initiate() + b.wg.Done() + }() logger.Debug("service resumed") return nil } @@ -244,6 +253,7 @@ func (b *Service) Stop() error { ethmetrics.Unregister(buildBlockErrors) b.cancel() + b.wg.Wait() return nil } @@ -328,8 +338,14 @@ func (b *Service) runEngine() error { } func (b *Service) handleEpoch(epoch uint64) (next uint64, err error) { + wg := sync.WaitGroup{} + ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + defer func() { + cancel() + wg.Wait() + }() + b.epochHandler, err = b.initiateAndGetEpochHandler(epoch) if err != nil { return 0, fmt.Errorf("cannot initiate and get epoch handler: %w", err) @@ -344,8 +360,12 @@ func (b *Service) handleEpoch(epoch uint64) (next uint64, err error) { nextEpochStartTime := getSlotStartTime(nextEpochStart, b.constants.slotDuration) epochTimer := time.NewTimer(time.Until(nextEpochStartTime)) - errCh := make(chan error) - go b.epochHandler.run(ctx, errCh) + errCh := make(chan error, 1) + wg.Add(1) + go func() { + b.epochHandler.run(ctx, errCh) + wg.Done() + }() select { case <-b.ctx.Done(): diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index df06ea8e55..83f2a9d0cf 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -99,6 +99,9 @@ func TestStartAndStop(t *testing.T) { } func TestService_PauseAndResume(t *testing.T) { + // TODO: https://github.com/ChainSafe/gossamer/issues/3443 + t.Skip() + cfg := ServiceConfig{} genesis, genesisTrie, genesisHeader := newWestendLocalGenesisWithTrieAndHeader(t) babeService := createTestService(t, cfg, genesis, genesisTrie, genesisHeader, nil) diff --git a/lib/babe/helpers_test.go b/lib/babe/helpers_test.go index 9a65244f37..9c57bdd8ed 100644 --- a/lib/babe/helpers_test.go +++ b/lib/babe/helpers_test.go @@ -12,6 +12,7 @@ import ( "github.com/ChainSafe/gossamer/dot/core" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/babe/mocks" "github.com/ChainSafe/gossamer/lib/common" @@ -120,7 +121,7 @@ func newTestCoreService(t *testing.T, cfg *core.Config, genesis genesis.Genesis, if stateSrvc != nil { nodeStorage.BaseDB = stateSrvc.Base } else { - nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + nodeStorage.BaseDB, err = database.LoadDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) require.NoError(t, err) } diff --git a/lib/babe/verify_integration_test.go b/lib/babe/verify_integration_test.go index 49731c502f..ff875df585 100644 --- a/lib/babe/verify_integration_test.go +++ b/lib/babe/verify_integration_test.go @@ -11,11 +11,11 @@ import ( "testing" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/digest" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/pkg/scale" @@ -28,7 +28,7 @@ func TestVerificationManager_OnDisabled_InvalidIndex(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, nil) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -52,7 +52,7 @@ func TestVerificationManager_OnDisabled_NewDigest(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, nil) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -102,7 +102,7 @@ func TestVerificationManager_OnDisabled_DuplicateDigest(t *testing.T) { epochData, err := babeService.initiateEpoch(testEpochIndex) require.NoError(t, err) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) vm := NewVerificationManager(babeService.blockState, slotState, babeService.epochState) @@ -136,7 +136,7 @@ func TestVerificationManager_VerifyBlock_Secondary(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, nil) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -187,7 +187,7 @@ func TestVerificationManager_VerifyBlock_CurrentEpoch(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, nil) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -225,7 +225,7 @@ func TestVerificationManager_VerifyBlock_FutureEpoch(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, babeConfig) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -275,7 +275,7 @@ func TestVerificationManager_VerifyBlock_MultipleEpochs(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, babeConfig) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -335,7 +335,7 @@ func TestVerificationManager_VerifyBlock_InvalidBlockOverThreshold(t *testing.T) genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, babeConfig) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -383,7 +383,7 @@ func TestVerificationManager_VerifyBlock_InvalidBlockAuthority(t *testing.T) { genesisBob, genesisTrieBob, genesisHeaderBob := newWestendDevGenesisWithTrieAndHeader(t) babeServiceBob := createTestService(t, ServiceConfig{}, genesisBob, genesisTrieBob, genesisHeaderBob, babeConfig) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -437,7 +437,7 @@ func TestVerifyPrimarySlotWinner(t *testing.T) { digest, ok := babePreDigest.(types.BabePrimaryPreDigest) require.True(t, ok) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -470,7 +470,7 @@ func TestVerifyAuthorshipRight(t *testing.T) { slot := getSlot(t, runtime, time.Now()) block := createTestBlockWithSlot(t, babeService, &genesisHeader, [][]byte{}, testEpochIndex, epochData, slot) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -488,7 +488,7 @@ func TestVerifyAuthorshipRight_Equivocation(t *testing.T) { genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, nil) - db, err := chaindb.NewBadgerDB(&chaindb.Config{DataDir: t.TempDir(), InMemory: true}) + db, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) slotState := state.NewSlotState(db) @@ -586,10 +586,7 @@ func TestVerifyForkBlocksWithRespectiveEpochData(t *testing.T) { err := stateService.Initialise(&genesis, &genesisHeader, &trie) require.NoError(t, err) - inMemoryDB, err := chaindb.NewBadgerDB(&chaindb.Config{ - InMemory: true, - DataDir: t.TempDir(), - }) + inMemoryDB, err := database.NewPebble(t.TempDir(), true) require.NoError(t, err) epochState, err := state.NewEpochStateFromGenesis(inMemoryDB, stateService.Block, epochBABEConfig) diff --git a/lib/grandpa/grandpa.go b/lib/grandpa/grandpa.go index f971eb4bcc..a625f3d927 100644 --- a/lib/grandpa/grandpa.go +++ b/lib/grandpa/grandpa.go @@ -13,10 +13,10 @@ import ( "sync/atomic" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/blocktree" "github.com/ChainSafe/gossamer/lib/common" @@ -1144,7 +1144,7 @@ func (s *Service) handleCommitMessage(commitMessage *CommitMessage) error { err := verifyBlockHashAgainstBlockNumber(s.blockState, commitMessage.Vote.Hash, uint(commitMessage.Vote.Number)) if err != nil { - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { s.tracker.addCommit(commitMessage) } diff --git a/lib/grandpa/helpers_integration_test.go b/lib/grandpa/helpers_integration_test.go index 3daef7c80a..ed65b1b582 100644 --- a/lib/grandpa/helpers_integration_test.go +++ b/lib/grandpa/helpers_integration_test.go @@ -12,6 +12,7 @@ import ( "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" @@ -133,10 +134,13 @@ func newTestState(t *testing.T) *state.Service { testDatadirPath := t.TempDir() - db, err := utils.SetupDatabase(testDatadirPath, true) + db, err := database.LoadDatabase(testDatadirPath, true) require.NoError(t, err) - t.Cleanup(func() { db.Close() }) + t.Cleanup(func() { + closeErr := db.Close() + require.NoError(t, closeErr) + }) _, genTrie, _ := newWestendDevGenesisWithTrieAndHeader(t) tries := state.NewTries() diff --git a/lib/grandpa/message_handler.go b/lib/grandpa/message_handler.go index 5b821f0469..cb5105324f 100644 --- a/lib/grandpa/message_handler.go +++ b/lib/grandpa/message_handler.go @@ -8,9 +8,9 @@ import ( "errors" "fmt" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/blocktree" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" @@ -166,7 +166,7 @@ func (h *MessageHandler) handleCatchUpResponse(msg *CatchUpResponse) error { err := verifyBlockHashAgainstBlockNumber(h.blockState, msg.Hash, uint(msg.Number)) if err != nil { - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { h.grandpa.tracker.addCatchUpResponse(msg) logger.Infof("we might not have synced to the given block %s yet: %s", msg.Hash, err) return nil @@ -285,7 +285,7 @@ func (h *MessageHandler) verifyPreVoteJustification(msg *CatchUpResponse) (commo for _, pvj := range msg.PreVoteJustification { err := verifyBlockHashAgainstBlockNumber(h.blockState, pvj.Vote.Hash, uint(pvj.Vote.Number)) if err != nil { - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { h.grandpa.tracker.addCatchUpResponse(msg) logger.Infof("we might not have synced to the given block %s yet: %s", pvj.Vote.Hash, err) continue @@ -371,7 +371,7 @@ func (h *MessageHandler) verifyPreCommitJustification(msg *CatchUpResponse) erro err = verifyBlockHashAgainstBlockNumber(h.blockState, just.Vote.Hash, uint(just.Vote.Number)) if err != nil { - if errors.Is(err, chaindb.ErrKeyNotFound) { + if errors.Is(err, database.ErrNotFound) { h.grandpa.tracker.addCatchUpResponse(msg) logger.Infof("we might not have synced to the given block %s yet: %s", just.Vote.Hash, err) continue diff --git a/lib/grandpa/message_tracker_test.go b/lib/grandpa/message_tracker_test.go index 0bf2775fc4..af1584fd02 100644 --- a/lib/grandpa/message_tracker_test.go +++ b/lib/grandpa/message_tracker_test.go @@ -11,9 +11,9 @@ import ( "sync" "testing" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/telemetry" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/ed25519" "github.com/ChainSafe/gossamer/lib/keystore" @@ -65,7 +65,7 @@ func TestMessageTracker_handleTick_commitMessage(t *testing.T) { blockStateMock.EXPECT(). GetHeader(testHash). - Return(nil, chaindb.ErrKeyNotFound) + Return(nil, database.ErrNotFound) grandpaService := &Service{ telemetry: nil, diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index 45b17c3e8a..c6a5e836ac 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -15,8 +15,8 @@ import ( "testing" "time" - "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/babe/inherents" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto" @@ -31,13 +31,10 @@ import ( ) // NewInMemoryDB creates a new in-memory database -func NewInMemoryDB(t *testing.T) *chaindb.BadgerDB { +func NewInMemoryDB(t *testing.T) database.Database { testDatadirPath := t.TempDir() - db, err := chaindb.NewBadgerDB(&chaindb.Config{ - DataDir: testDatadirPath, - InMemory: true, - }) + db, err := database.NewPebble(testDatadirPath, true) require.NoError(t, err) t.Cleanup(func() { _ = db.Close() diff --git a/lib/runtime/wasmer/imports_test.go b/lib/runtime/wasmer/imports_test.go index 7f060d496c..f80b8b80c1 100644 --- a/lib/runtime/wasmer/imports_test.go +++ b/lib/runtime/wasmer/imports_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - "github.com/ChainSafe/chaindb" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/common/types" "github.com/ChainSafe/gossamer/lib/crypto" @@ -50,7 +50,7 @@ func Test_ext_offchain_index_clear_version_1(t *testing.T) { require.NoError(t, err) _, err = inst.ctx.NodeStorage.BaseDB.Get(testKey) - require.ErrorIs(t, err, chaindb.ErrKeyNotFound) + require.ErrorIs(t, err, database.ErrNotFound) } func Test_ext_offchain_timestamp_version_1(t *testing.T) { @@ -238,7 +238,7 @@ func Test_ext_offchain_local_storage_clear_version_1_Persistent(t *testing.T) { require.NoError(t, err) val, err := inst.NodeStorage().PersistentStorage.Get(testkey) - require.EqualError(t, err, "Key not found") + require.EqualError(t, err, "pebble: not found") require.Nil(t, val) } @@ -261,7 +261,7 @@ func Test_ext_offchain_local_storage_clear_version_1_Local(t *testing.T) { require.NoError(t, err) val, err := inst.NodeStorage().LocalStorage.Get(testkey) - require.EqualError(t, err, "Key not found") + require.EqualError(t, err, "pebble: not found") require.Nil(t, val) } @@ -1868,10 +1868,7 @@ func Test_ext_trie_blake2_256_verify_proof_version_1(t *testing.T) { tmp := t.TempDir() - memdb, err := chaindb.NewBadgerDB(&chaindb.Config{ - InMemory: true, - DataDir: tmp, - }) + memdb, err := database.NewPebble(tmp, true) require.NoError(t, err) otherTrie := trie.NewEmptyTrie() diff --git a/lib/runtime/wazero/imports_test.go b/lib/runtime/wazero/imports_test.go index c9d95f0a89..d382df5961 100644 --- a/lib/runtime/wazero/imports_test.go +++ b/lib/runtime/wazero/imports_test.go @@ -14,7 +14,7 @@ import ( "testing" "time" - "github.com/ChainSafe/chaindb" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/common/types" "github.com/ChainSafe/gossamer/lib/crypto" @@ -48,7 +48,7 @@ func Test_ext_offchain_index_clear_version_1(t *testing.T) { require.NoError(t, err) _, err = inst.Context.NodeStorage.BaseDB.Get(testKey) - require.ErrorIs(t, err, chaindb.ErrKeyNotFound) + require.ErrorIs(t, err, database.ErrNotFound) } func Test_ext_crypto_ed25519_generate_version_1(t *testing.T) { @@ -589,11 +589,7 @@ func Test_ext_trie_blake2_256_ordered_root_version_1(t *testing.T) { func Test_ext_trie_blake2_256_verify_proof_version_1(t *testing.T) { tmp := t.TempDir() - - memdb, err := chaindb.NewBadgerDB(&chaindb.Config{ - InMemory: true, - DataDir: tmp, - }) + memdb, err := database.NewPebble(tmp, true) require.NoError(t, err) otherTrie := trie.NewEmptyTrie() @@ -1376,7 +1372,7 @@ func Test_ext_offchain_local_storage_clear_version_1_Persistent(t *testing.T) { require.NoError(t, err) val, err := inst.Context.NodeStorage.PersistentStorage.Get(testkey) - require.EqualError(t, err, "Key not found") + require.EqualError(t, err, "pebble: not found") require.Nil(t, val) } @@ -1398,7 +1394,7 @@ func Test_ext_offchain_local_storage_clear_version_1_Local(t *testing.T) { require.NoError(t, err) val, err := inst.Context.NodeStorage.LocalStorage.Get(testkey) - require.EqualError(t, err, "Key not found") + require.EqualError(t, err, "pebble: not found") require.Nil(t, val) } diff --git a/lib/trie/database.go b/lib/trie/database.go index 7100992a99..7e5c07bef4 100644 --- a/lib/trie/database.go +++ b/lib/trie/database.go @@ -7,11 +7,10 @@ import ( "bytes" "fmt" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/trie/codec" "github.com/ChainSafe/gossamer/internal/trie/node" "github.com/ChainSafe/gossamer/lib/common" - - "github.com/ChainSafe/chaindb" ) // DBGetter gets a value corresponding to the given key. @@ -26,7 +25,7 @@ type DBPutter interface { // NewBatcher creates a new database batch. type NewBatcher interface { - NewBatch() chaindb.Batch + NewBatch() database.Batch } // Load reconstructs the trie from the database from the given root hash. diff --git a/lib/trie/database_test.go b/lib/trie/database_test.go index 2300adb415..037218d237 100644 --- a/lib/trie/database_test.go +++ b/lib/trie/database_test.go @@ -6,19 +6,16 @@ package trie import ( "testing" - "github.com/ChainSafe/chaindb" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func newTestDB(t *testing.T) chaindb.Database { - chainDBConfig := &chaindb.Config{ - InMemory: true, - } - database, err := chaindb.NewBadgerDB(chainDBConfig) +func newTestDB(t *testing.T) database.Table { + db, err := database.NewPebble("", true) require.NoError(t, err) - return chaindb.NewTable(database, "trie") + return database.NewTable(db, "trie") } func Test_Trie_Store_Load(t *testing.T) { diff --git a/lib/trie/proof/proof_test.go b/lib/trie/proof/proof_test.go index 8f813b4f61..40b68ed155 100644 --- a/lib/trie/proof/proof_test.go +++ b/lib/trie/proof/proof_test.go @@ -8,7 +8,7 @@ import ( "fmt" "testing" - "github.com/ChainSafe/chaindb" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/trie/db" "github.com/stretchr/testify/require" @@ -35,16 +35,14 @@ func Test_Generate_Verify(t *testing.T) { rootHash, err := trie.Hash() require.NoError(t, err) - database, err := chaindb.NewBadgerDB(&chaindb.Config{ - InMemory: true, - }) + db, err := database.NewPebble("", true) require.NoError(t, err) - err = trie.WriteDirty(database) + err = trie.WriteDirty(db) require.NoError(t, err) for i, key := range keys { fullKeys := [][]byte{[]byte(key)} - proof, err := Generate(rootHash.ToBytes(), fullKeys, database) + proof, err := Generate(rootHash.ToBytes(), fullKeys, db) require.NoError(t, err) expectedValue := fmt.Sprintf("%x-%d", key, i) diff --git a/lib/trie/trie_endtoend_test.go b/lib/trie/trie_endtoend_test.go index 3ca189ebe5..2fe0fa9b72 100644 --- a/lib/trie/trie_endtoend_test.go +++ b/lib/trie/trie_endtoend_test.go @@ -11,10 +11,10 @@ import ( "sync" "testing" - "github.com/ChainSafe/chaindb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/ChainSafe/gossamer/internal/database" "github.com/ChainSafe/gossamer/internal/trie/codec" "github.com/ChainSafe/gossamer/lib/common" ) @@ -267,11 +267,7 @@ func TestDeleteOddKeyLengths(t *testing.T) { } func TestTrieDiff(t *testing.T) { - cfg := &chaindb.Config{ - DataDir: t.TempDir(), - } - - db, err := chaindb.NewBadgerDB(cfg) + db, err := database.NewPebble(t.TempDir(), false) require.NoError(t, err) t.Cleanup(func() { @@ -279,12 +275,7 @@ func TestTrieDiff(t *testing.T) { require.NoError(t, err) }) - storageDB := chaindb.NewTable(db, "storage") - t.Cleanup(func() { - err = storageDB.Close() - require.NoError(t, err) - }) - + storageDB := database.NewTable(db, "storage") trie := NewEmptyTrie() var testKey = []byte("testKey") diff --git a/lib/utils/utils.go b/lib/utils/utils.go index d94d3e4152..14d35187b1 100644 --- a/lib/utils/utils.go +++ b/lib/utils/utils.go @@ -14,22 +14,9 @@ import ( "strings" "testing" - "github.com/ChainSafe/chaindb" - "github.com/dgraph-io/badger/v2" "github.com/stretchr/testify/require" ) -// DefaultDatabaseDir directory inside basepath where database contents are stored -const DefaultDatabaseDir = "db" - -// SetupDatabase will return an instance of database based on basepath -func SetupDatabase(basepath string, inMemory bool) (*chaindb.BadgerDB, error) { - return chaindb.NewBadgerDB(&chaindb.Config{ - DataDir: filepath.Join(basepath, DefaultDatabaseDir), - InMemory: inMemory, - }) -} - // PathExists returns true if the named file or directory exists, otherwise false func PathExists(p string) bool { if _, err := os.Stat(p); err != nil { @@ -253,30 +240,3 @@ func GetProjectRootPath() (rootPath string, err error) { return rootPath, nil } - -// LoadChainDB load the db at the given path. -func LoadChainDB(basePath string) (*chaindb.BadgerDB, error) { - cfg := &chaindb.Config{ - DataDir: basePath, - } - - // Open already existing DB - db, err := chaindb.NewBadgerDB(cfg) - if err != nil { - return nil, err - } - - return db, nil -} - -// LoadBadgerDB load the db at the given path. -func LoadBadgerDB(basePath string) (*badger.DB, error) { - opts := badger.DefaultOptions(basePath) - // Open already existing DB - db, err := badger.Open(opts) - if err != nil { - return nil, err - } - - return db, nil -} diff --git a/tests/rpc/rpc_05-state_test.go b/tests/rpc/rpc_05-state_test.go index 734e65774b..e40b21e523 100644 --- a/tests/rpc/rpc_05-state_test.go +++ b/tests/rpc/rpc_05-state_test.go @@ -188,7 +188,7 @@ func TestStateRPCAPI(t *testing.T) { const ( randomHash = "0x580d77a9136035a0bc3c3cd86286172f7f81291164c5914266073a30466fba21" - ErrKeyNotFound = "Key not found" + ErrKeyNotFound = "pebble: not found" InvalidHashFormat = "invalid hash format" // `:grandpa_authorities` key GrandpaAuthorityKey = "0x3a6772616e6470615f617574686f726974696573"