diff --git a/hedera-mirror-rosetta/app/config/config.go b/hedera-mirror-rosetta/app/config/config.go index 575f3a593d0..37e695b98ce 100644 --- a/hedera-mirror-rosetta/app/config/config.go +++ b/hedera-mirror-rosetta/app/config/config.go @@ -62,12 +62,13 @@ hedera: apiConfigEnvKey = "HEDERA_MIRROR_ROSETTA_API_CONFIG" configName = "application" configTypeYaml = "yml" + configPrefix = "hedera::mirror::rosetta" // use "::" since it's the delimiter set for viper envKeyDelimiter = "_" keyDelimiter = "::" ) // LoadConfig loads configuration from yaml files and env variables -func LoadConfig() (*Rosetta, error) { +func LoadConfig() (*Config, error) { // NodeMap's key has '.', set viper key delimiter to avoid parsing it as a nested key v := viper.NewWithOptions(viper.KeyDelimiter(keyDelimiter)) v.SetConfigType(configTypeYaml) @@ -97,16 +98,16 @@ func LoadConfig() (*Rosetta, error) { v.SetEnvKeyReplacer(strings.NewReplacer(keyDelimiter, envKeyDelimiter)) var config Config - if err := v.Unmarshal(&config, viper.DecodeHook(nodeMapDecodeHookFunc)); err != nil { + if err := v.UnmarshalKey(configPrefix, &config, viper.DecodeHook(nodeMapDecodeHookFunc)); err != nil { return nil, err } - var password = config.Hedera.Mirror.Rosetta.Db.Password - config.Hedera.Mirror.Rosetta.Db.Password = "" - log.Infof("Using configuration: %+v", config.Hedera.Mirror.Rosetta) - config.Hedera.Mirror.Rosetta.Db.Password = password + var password = config.Db.Password + config.Db.Password = "" + log.Infof("Using configuration: %+v", config) + config.Db.Password = password - return &config.Hedera.Mirror.Rosetta, nil + return &config, nil } func mergeExternalConfigFile(v *viper.Viper) error { diff --git a/hedera-mirror-rosetta/app/config/config_test.go b/hedera-mirror-rosetta/app/config/config_test.go index 77caaa647c4..ccc1cd72285 100644 --- a/hedera-mirror-rosetta/app/config/config_test.go +++ b/hedera-mirror-rosetta/app/config/config_test.go @@ -218,8 +218,16 @@ func createYamlConfigFile(content string, t *testing.T) (string, string) { return tempDir, customConfig } -func getDefaultConfig() *Rosetta { - config := Config{} +type FullConfig struct { + Hedera struct { + Mirror struct { + Rosetta Config + } + } +} + +func getDefaultConfig() *Config { + config := FullConfig{} yaml.Unmarshal([]byte(defaultConfig), &config) return &config.Hedera.Mirror.Rosetta } diff --git a/hedera-mirror-rosetta/app/config/types.go b/hedera-mirror-rosetta/app/config/types.go index e47b755f8ac..4d606e7f72a 100644 --- a/hedera-mirror-rosetta/app/config/types.go +++ b/hedera-mirror-rosetta/app/config/types.go @@ -27,18 +27,6 @@ import ( ) type Config struct { - Hedera Hedera -} - -type Hedera struct { - Mirror Mirror -} - -type Mirror struct { - Rosetta Rosetta -} - -type Rosetta struct { Db Db Log Log Network string diff --git a/hedera-mirror-rosetta/main.go b/hedera-mirror-rosetta/main.go index e1c4461a5f0..c6e445827f0 100644 --- a/hedera-mirror-rosetta/main.go +++ b/hedera-mirror-rosetta/main.go @@ -74,9 +74,9 @@ func configLogger(level string) { // ref: https://www.rosetta-api.org/docs/node_deployment.html#online-mode-endpoints func newBlockchainOnlineRouter( asserter *rosettaAsserter.Asserter, + config config.Config, dbClient interfaces.DbClient, network *rTypes.NetworkIdentifier, - rosetta config.Rosetta, version *rTypes.Version, ) (http.Handler, error) { accountRepo := persistence.NewAccountRepository(dbClient) @@ -99,7 +99,7 @@ func newBlockchainOnlineRouter( constructionAPIService, err := services.NewConstructionAPIService( baseService, network.Network, - rosetta.Nodes, + config.Nodes, construction.NewTransactionConstructor(tokenRepo), ) if err != nil { @@ -109,7 +109,7 @@ func newBlockchainOnlineRouter( accountAPIService := services.NewAccountAPIService(baseService, accountRepo) accountAPIController := server.NewAccountAPIController(accountAPIService, asserter) - healthController, err := middleware.NewHealthController(rosetta.Db) + healthController, err := middleware.NewHealthController(config.Db) metricsController := middleware.NewMetricsController() if err != nil { return nil, err @@ -131,8 +131,8 @@ func newBlockchainOnlineRouter( // ref: https://www.rosetta-api.org/docs/node_deployment.html#offline-mode-endpoints func newBlockchainOfflineRouter( asserter *rosettaAsserter.Asserter, + config config.Config, network *rTypes.NetworkIdentifier, - rosetta config.Rosetta, version *rTypes.Version, ) (http.Handler, error) { baseService := services.NewOfflineBaseService() @@ -140,14 +140,14 @@ func newBlockchainOfflineRouter( constructionAPIService, err := services.NewConstructionAPIService( baseService, network.Network, - rosetta.Nodes, + config.Nodes, construction.NewTransactionConstructor(nil), ) if err != nil { return nil, err } constructionAPIController := server.NewConstructionAPIController(constructionAPIService, asserter) - healthController, err := middleware.NewHealthController(rosetta.Db) + healthController, err := middleware.NewHealthController(config.Db) if err != nil { return nil, err } @@ -202,14 +202,14 @@ func main() { if rosettaConfig.Online { dbClient := db.ConnectToDb(rosettaConfig.Db) - router, err = newBlockchainOnlineRouter(asserter, dbClient, network, *rosettaConfig, version) + router, err = newBlockchainOnlineRouter(asserter, *rosettaConfig, dbClient, network, version) if err != nil { log.Fatal(err) } log.Info("Serving Rosetta API in ONLINE mode") } else { - router, err = newBlockchainOfflineRouter(asserter, network, *rosettaConfig, version) + router, err = newBlockchainOfflineRouter(asserter, *rosettaConfig, network, version) if err != nil { log.Fatal(err) } diff --git a/hedera-mirror-rosetta/test/bdd-client/README.md b/hedera-mirror-rosetta/test/bdd-client/README.md index 3dab34a1431..022c35c9ce6 100644 --- a/hedera-mirror-rosetta/test/bdd-client/README.md +++ b/hedera-mirror-rosetta/test/bdd-client/README.md @@ -13,7 +13,7 @@ The client currently supports basic crypto create, crypto transfer, and HTS scen ## Requirements - golang 1.17+ -- a testnet account with private key +- two testnet accounts with private key - aws / gcp credentials with requester pay enabled to access the Hedera network cloud storage ## Test Client Configuration @@ -21,7 +21,7 @@ The client currently supports basic crypto create, crypto transfer, and HTS scen Configuration properties can be customized in an `application.yml` file in the test client source directory. Most properties have default values and should work out of the box. -The only required property is an operator account and its private key, for example: +The only required property is two operator accounts and the corresponding private keys, for example: ```yaml hedera: @@ -31,8 +31,12 @@ hedera: operators: - privateKey: 90e42b7c... id: 0.0.65342 + - privateKey: 91e33b87... + id: 0.0.65345 ``` +Note for crypto create and crypto transfer scenarios, only one operator account is required. + Please refer to the [appendix](#test-configuration-properties) for the complete list of properties. ## Run the Test @@ -72,6 +76,14 @@ Please refer to the [appendix](#test-configuration-properties) for the complete $ go test -v ``` + Note you can run tests with the `--godog.tags` flag to filter features, for example, to run `crypto` scenarions: + + ```shell + $ go test -v --godog.tags=crypto + ``` + + `--godog.tags` also supports complex expressions, please refer to the [official documentation](https://github.com/cucumber/godog#tags). + ## Appendix ### Test Configuration Properties @@ -82,12 +94,13 @@ The following table lists the available properties along with their default valu | ------------------------------------------------------- | --------------------- | -------------------------------------------------------------------------- | | `hedera.mirror.rosetta.test.log.level` | debug | The log level | | `hedera.mirror.rosetta.test.operators` | [] | A list of operators with the account ids and corresponding private keys | -| `hedera.mirror.rosetta.test.operators.id` | | The operator account id, in the format of shard.realm.num | -| `hedera.mirror.rosetta.test.operators.privateKey` | | The operator's private key in hex | +| `hedera.mirror.rosetta.test.operators[].id` | | The operator account id, in the format of shard.realm.num | +| `hedera.mirror.rosetta.test.operators[].privateKey` | | The operator's private key in hex | | `hedera.mirror.rosetta.test.server.dataRetry.backOff` | 1s | The amount of time to wait between data request retries, if the request can be retried. | | `hedera.mirror.rosetta.test.server.dataRetry.max` | 20 | The max retries of a data request | +| `hedera.mirror.rosetta.test.server.httpTimeout` | 25s | The timeout of an http request sent to the rosetta server | +| `hedera.mirror.rosetta.test.server.network` | {} | A map of main nodes with its service endpoint as the key and the node account id as its value | | `hedera.mirror.rosetta.test.server.offlineUrl` | http://localhost:5701 | The url of the offline rosetta server | | `hedera.mirror.rosetta.test.server.onlineUrl` | http://localhost:5700 | The url of the online rosetta server | -| `hedera.mirror.rosetta.test.server.httpTimeout` | 25s | The timeout of an http request sent to the rosetta server | | `hedera.mirror.rosetta.test.server.submitRetry.backOff` | 200ms | The amount of time to wait between submit request retries | | `hedera.mirror.rosetta.test.server.submitRetry.max` | 5 | The max retries of a submit request |