diff --git a/go.mod b/go.mod index 6c8c40a695..3a83bd784d 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ go 1.23.6 require ( github.com/VictoriaMetrics/fastcache v1.12.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/avalanchego v1.13.1-0.20250327151600-3a6bfac46f43 - github.com/ava-labs/libevm v1.13.14-0.2.0.rc.4 + github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418092816-9ff05a7bafa0 + github.com/ava-labs/libevm v1.13.14-0.2.0.release github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set/v2 v2.1.0 github.com/fjl/gencodec v0.1.1 @@ -47,7 +47,7 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/StephenButtolph/canoto v0.15.0 // indirect - github.com/ava-labs/coreth v0.15.0-rc.1.0.20250331083503-0d68be6b92be // indirect + github.com/ava-labs/coreth v0.15.1-rc.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect @@ -73,6 +73,7 @@ require ( github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect diff --git a/go.sum b/go.sum index 7379242c7c..e09d053284 100644 --- a/go.sum +++ b/go.sum @@ -64,12 +64,16 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/avalanchego v1.13.1-0.20250327151600-3a6bfac46f43 h1:N7C2AEHTSme0+MMa6n0TPDD11VbTqSNeT4eG2UKg610= -github.com/ava-labs/avalanchego v1.13.1-0.20250327151600-3a6bfac46f43/go.mod h1:jSJtHEp/1AGaruY53bQhDxbc/8UXh0n01yNTlggX3wk= -github.com/ava-labs/coreth v0.15.0-rc.1.0.20250331083503-0d68be6b92be h1:CQ4v84fgsxab1a1LVFBUPmZx37eOkeezWjEfjcLcbZY= -github.com/ava-labs/coreth v0.15.0-rc.1.0.20250331083503-0d68be6b92be/go.mod h1:yiTX4Xamyw6vRFZbpFiLsCtxmD+Nb1z8pJ6JJhAufVo= -github.com/ava-labs/libevm v1.13.14-0.2.0.rc.4 h1:wnq3x3OE8DnBTBeKFjiywRO/MfnEXWjoSgnZtTQ1LS8= -github.com/ava-labs/libevm v1.13.14-0.2.0.rc.4/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= +github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418085700-57daae4a34ad h1:+f1Pz7StEx80DXV5DGzQb8cTcls3JdW58UfvJEHPGjY= +github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418085700-57daae4a34ad/go.mod h1:rtufRz6xw+3oXpW74vNP1Gj654UdvcabNyZ9a8qiP94= +github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418091922-eb0570f4d348 h1:KvDUzsS6yPDzkOM7Yy9oo5fofJCzQuSgAnFfk0qrtQc= +github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418091922-eb0570f4d348/go.mod h1:rtufRz6xw+3oXpW74vNP1Gj654UdvcabNyZ9a8qiP94= +github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418092816-9ff05a7bafa0 h1:0p7GF3SMziGw9rJwWht1o2I7c5uiNjMRqMJg6Ia5Luo= +github.com/ava-labs/avalanchego v1.13.1-rc.0.0.20250418092816-9ff05a7bafa0/go.mod h1:rtufRz6xw+3oXpW74vNP1Gj654UdvcabNyZ9a8qiP94= +github.com/ava-labs/coreth v0.15.1-rc.0 h1:ahuIyp1hb4xiZ3DTA9uKIpVBMpMyXO3VHvwcxQUboSo= +github.com/ava-labs/coreth v0.15.1-rc.0/go.mod h1:BDKMO8sL2wuvWbtMRzJAsJrleQULHA+CHRbkh5hRG5o= +github.com/ava-labs/libevm v1.13.14-0.2.0.release h1:uKGCc5/ceeBbfAPRVtBUxbQt50WzB2pEDb8Uy93ePgQ= +github.com/ava-labs/libevm v1.13.14-0.2.0.release/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -193,6 +197,8 @@ github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/fjl/gencodec v0.1.1 h1:DhQY29Q6JLXB/GgMqE86NbOEuvckiYcJCbXFu02toms= github.com/fjl/gencodec v0.1.1/go.mod h1:chDHL3wKXuBgauP8x3XNZkl5EIAR5SoCTmmmDTZRzmw= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= @@ -257,10 +263,7 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a 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 h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= diff --git a/plugin/evm/database/database.go b/plugin/evm/database/database.go deleted file mode 100644 index 41f14a9dc4..0000000000 --- a/plugin/evm/database/database.go +++ /dev/null @@ -1,98 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package database - -import ( - "encoding/json" - "fmt" - "path/filepath" - - "github.com/ava-labs/avalanchego/api/metrics" - avalanchenode "github.com/ava-labs/avalanchego/config/node" - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/database/leveldb" - "github.com/ava-labs/avalanchego/database/memdb" - "github.com/ava-labs/avalanchego/database/meterdb" - "github.com/ava-labs/avalanchego/database/pebbledb" - "github.com/ava-labs/avalanchego/database/versiondb" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/prometheus/client_golang/prometheus" -) - -const ( - dbMetricsPrefix = "db" -) - -// createDatabase returns a new database instance with the provided configuration -func NewStandaloneDatabase(dbConfig avalanchenode.DatabaseConfig, gatherer metrics.MultiGatherer, logger logging.Logger) (database.Database, error) { - dbRegisterer, err := metrics.MakeAndRegister( - gatherer, - dbMetricsPrefix, - ) - if err != nil { - return nil, err - } - var db database.Database - // start the db - switch dbConfig.Name { - case leveldb.Name: - dbPath := filepath.Join(dbConfig.Path, leveldb.Name) - db, err = leveldb.New(dbPath, dbConfig.Config, logger, dbRegisterer) - if err != nil { - return nil, fmt.Errorf("couldn't create %s at %s: %w", leveldb.Name, dbPath, err) - } - case memdb.Name: - db = memdb.New() - case pebbledb.Name: - dbPath := filepath.Join(dbConfig.Path, pebbledb.Name) - db, err = NewPebbleDB(dbPath, dbConfig.Config, logger, dbRegisterer) - if err != nil { - return nil, fmt.Errorf("couldn't create %s at %s: %w", pebbledb.Name, dbPath, err) - } - default: - return nil, fmt.Errorf( - "db-type was %q but should have been one of {%s, %s, %s}", - dbConfig.Name, - leveldb.Name, - memdb.Name, - pebbledb.Name, - ) - } - - if dbConfig.ReadOnly && dbConfig.Name != memdb.Name { - db = versiondb.New(db) - } - - meterDBReg, err := metrics.MakeAndRegister( - gatherer, - "meterdb", - ) - if err != nil { - return nil, err - } - - db, err = meterdb.New(meterDBReg, db) - if err != nil { - return nil, fmt.Errorf("failed to create meterdb: %w", err) - } - - return db, nil -} - -func NewPebbleDB(file string, configBytes []byte, log logging.Logger, dbRegisterer prometheus.Registerer) (database.Database, error) { - cfg := pebbledb.DefaultConfig - // Use no sync for pebble db - cfg.Sync = false - if len(configBytes) > 0 { - if err := json.Unmarshal(configBytes, &cfg); err != nil { - return nil, err - } - } - // Marshal the config back to bytes to ensure that new defaults are applied - newCfgBytes, err := json.Marshal(cfg) - if err != nil { - return nil, err - } - return pebbledb.New(file, newCfgBytes, log, dbRegisterer) -} diff --git a/plugin/evm/syncervm_test.go b/plugin/evm/syncervm_test.go index 7aac4fbdcf..eba50de2c2 100644 --- a/plugin/evm/syncervm_test.go +++ b/plugin/evm/syncervm_test.go @@ -38,7 +38,6 @@ import ( "github.com/ava-labs/subnet-evm/core" "github.com/ava-labs/subnet-evm/params" "github.com/ava-labs/subnet-evm/plugin/evm/customrawdb" - "github.com/ava-labs/subnet-evm/plugin/evm/database" "github.com/ava-labs/subnet-evm/predicate" statesyncclient "github.com/ava-labs/subnet-evm/sync/client" "github.com/ava-labs/subnet-evm/sync/statesync" @@ -430,7 +429,7 @@ func testSyncerVM(t *testing.T, vmSetup *syncVMSetup, test syncTest) { if test.expectedErr != nil { require.ErrorIs(err, test.expectedErr) // Note we re-open the database here to avoid a closed error when the test is for a shutdown VM. - chaindb := database.WrapDatabase(prefixdb.NewNested(ethDBPrefix, syncerVM.versiondb)) + chaindb := wrapDatabase(prefixdb.NewNested(ethDBPrefix, syncerVM.versiondb)) assertSyncPerformedHeights(t, chaindb, map[uint64]struct{}{}) return } diff --git a/plugin/evm/vm_database.go b/plugin/evm/vm_database.go index f9d152dcf3..9872f0f071 100644 --- a/plugin/evm/vm_database.go +++ b/plugin/evm/vm_database.go @@ -1,34 +1,42 @@ -// (c) 2019-2021, Ava Labs, Inc. All rights reserved. +// (c) 2019-2020, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package evm import ( "encoding/base64" + "encoding/json" "fmt" "os" "path/filepath" "time" - "github.com/ava-labs/avalanchego/config/node" - avalanchedatabase "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/api/metrics" + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/database/factory" + "github.com/ava-labs/avalanchego/database/pebbledb" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/database/versiondb" - avalancheconstants "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/libevm/common" "github.com/ava-labs/libevm/core/rawdb" "github.com/ava-labs/libevm/log" "github.com/ava-labs/subnet-evm/plugin/evm/config" - "github.com/ava-labs/subnet-evm/plugin/evm/database" +) + +const ( + dbMetricsPrefix = "db" + meterDBGatherer = "meterdb" ) // initializeDBs initializes the databases used by the VM. // If [useStandaloneDB] is true, the chain will use a standalone database for its state. // Otherwise, the chain will use the provided [avaDB] for its state. -func (vm *VM) initializeDBs(avaDB avalanchedatabase.Database) error { +func (vm *VM) initializeDBs(avaDB database.Database) error { db := avaDB // skip standalone database initialization if we are running in unit tests - if vm.ctx.NetworkID != avalancheconstants.UnitTestID { + if vm.ctx.NetworkID != constants.UnitTestID { // first initialize the accepted block database to check if we need to use a standalone database acceptedDB := prefixdb.New(acceptedPrefix, avaDB) useStandAloneDB, err := vm.useStandaloneDatabase(acceptedDB) @@ -43,7 +51,7 @@ func (vm *VM) initializeDBs(avaDB avalanchedatabase.Database) error { return err } log.Info("Using standalone database for the chain state", "DatabaseConfig", dbConfig) - db, err = database.NewStandaloneDatabase(dbConfig, vm.ctx.Metrics, vm.ctx.Log) + db, err = newStandaloneDatabase(dbConfig, vm.ctx.Metrics, vm.ctx.Log) if err != nil { return err } @@ -52,7 +60,7 @@ func (vm *VM) initializeDBs(avaDB avalanchedatabase.Database) error { } // Use NewNested rather than New so that the structure of the database // remains the same regardless of the provided baseDB type. - vm.chaindb = rawdb.NewDatabase(database.WrapDatabase(prefixdb.NewNested(ethDBPrefix, db))) + vm.chaindb = rawdb.NewDatabase(wrapDatabase(prefixdb.NewNested(ethDBPrefix, db))) vm.versiondb = versiondb.New(db) vm.acceptedBlockDB = prefixdb.New(acceptedPrefix, vm.versiondb) vm.metadataDB = prefixdb.New(metadataPrefix, vm.versiondb) @@ -93,7 +101,7 @@ func (vm *VM) inspectDatabases() error { // useStandaloneDatabase returns true if the chain can and should use a standalone database // other than given by [db] in Initialize() -func (vm *VM) useStandaloneDatabase(acceptedDB avalanchedatabase.Database) (bool, error) { +func (vm *VM) useStandaloneDatabase(acceptedDB database.Database) (bool, error) { // no config provided, use default standaloneDBFlag := vm.config.UseStandaloneDatabase if standaloneDBFlag != nil { @@ -102,7 +110,7 @@ func (vm *VM) useStandaloneDatabase(acceptedDB avalanchedatabase.Database) (bool // check if the chain can use a standalone database _, err := acceptedDB.Get(lastAcceptedKey) - if err == avalanchedatabase.ErrNotFound { + if err == database.ErrNotFound { // If there is nothing in the database, we can use the standalone database return true, nil } @@ -111,7 +119,7 @@ func (vm *VM) useStandaloneDatabase(acceptedDB avalanchedatabase.Database) (bool // getDatabaseConfig returns the database configuration for the chain // to be used by separate, standalone database. -func getDatabaseConfig(config config.Config, chainDataDir string) (node.DatabaseConfig, error) { +func getDatabaseConfig(config config.Config, chainDataDir string) (factory.DatabaseConfig, error) { var ( configBytes []byte err error @@ -120,13 +128,13 @@ func getDatabaseConfig(config config.Config, chainDataDir string) (node.Database dbConfigContent := config.DatabaseConfigContent configBytes, err = base64.StdEncoding.DecodeString(dbConfigContent) if err != nil { - return node.DatabaseConfig{}, fmt.Errorf("unable to decode base64 content: %w", err) + return factory.DatabaseConfig{}, fmt.Errorf("unable to decode base64 content: %w", err) } } else if len(config.DatabaseConfigFile) != 0 { configPath := config.DatabaseConfigFile configBytes, err = os.ReadFile(configPath) if err != nil { - return node.DatabaseConfig{}, err + return factory.DatabaseConfig{}, err } } @@ -135,7 +143,7 @@ func getDatabaseConfig(config config.Config, chainDataDir string) (node.Database dbPath = config.DatabasePath } - return node.DatabaseConfig{ + return factory.DatabaseConfig{ Name: config.DatabaseType, ReadOnly: config.DatabaseReadOnly, Path: dbPath, @@ -143,7 +151,7 @@ func getDatabaseConfig(config config.Config, chainDataDir string) (node.Database }, nil } -func inspectDB(db avalanchedatabase.Database, label string) error { +func inspectDB(db database.Database, label string) error { it := db.NewIterator() defer it.Release() @@ -172,3 +180,33 @@ func inspectDB(db avalanchedatabase.Database, label string) error { log.Info("Database statistics", "label", label, "total", total.String(), "count", count) return nil } + +func newStandaloneDatabase(dbConfig factory.DatabaseConfig, gatherer metrics.MultiGatherer, logger logging.Logger) (database.Database, error) { + dbConfig.Path = filepath.Join(dbConfig.Path, dbConfig.Name) + + // If the database is pebble, we need to set the config + // to use no sync. Sync mode in pebble has an issue with OSs like MacOS. + if dbConfig.Name == pebbledb.Name { + cfg := pebbledb.DefaultConfig + // Use no sync for pebble db + cfg.Sync = false + if len(dbConfig.Config) > 0 { + if err := json.Unmarshal(dbConfig.Config, &cfg); err != nil { + return nil, err + } + } + // Marshal the config back to bytes to ensure that new defaults are applied + newCfgBytes, err := json.Marshal(cfg) + if err != nil { + return nil, err + } + dbConfig.Config = newCfgBytes + } + + db, err := factory.NewDatabase(dbConfig, gatherer, logger, dbMetricsPrefix, meterDBGatherer) + if err != nil { + return nil, fmt.Errorf("couldn't create database: %w", err) + } + + return db, nil +} diff --git a/plugin/evm/database/wrapped_database.go b/plugin/evm/wrapped_database.go similarity index 96% rename from plugin/evm/database/wrapped_database.go rename to plugin/evm/wrapped_database.go index 86e3bbd239..6f34a35636 100644 --- a/plugin/evm/database/wrapped_database.go +++ b/plugin/evm/wrapped_database.go @@ -1,7 +1,7 @@ // (c) 2019-2020, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package database +package evm import ( "errors" @@ -19,7 +19,7 @@ var ( // ethDbWrapper implements ethdb.Database type ethDbWrapper struct{ database.Database } -func WrapDatabase(db database.Database) ethdb.KeyValueStore { return ethDbWrapper{db} } +func wrapDatabase(db database.Database) ethdb.KeyValueStore { return ethDbWrapper{db} } // Stat implements ethdb.Database func (db ethDbWrapper) Stat(string) (string, error) { return "", database.ErrNotFound } diff --git a/tests/utils/tmpnet.go b/tests/utils/tmpnet.go index d7c17d1c95..d0fa4fd82c 100644 --- a/tests/utils/tmpnet.go +++ b/tests/utils/tmpnet.go @@ -23,7 +23,7 @@ var DefaultChainConfig = tmpnet.FlagsMap{ func NewTmpnetNodes(count int) []*tmpnet.Node { nodes := make([]*tmpnet.Node, count) for i := range nodes { - node := tmpnet.NewNode("") + node := tmpnet.NewNode() node.EnsureKeys() nodes[i] = node }