From 7bc59b2e89f45f787574494d3e5c9ff0a95e988b Mon Sep 17 00:00:00 2001 From: Jeremy Pansier Date: Fri, 26 Apr 2024 12:19:25 +0200 Subject: [PATCH] document validator node settings --- accessnode/main.go | 4 +- validatornode/README.md | 144 ++++++++++++++++-- .../configuration/network_settings.go | 7 + .../configuration/protocol_settings.go | 5 +- .../registry_settings_provider.go | 7 - .../infrastructure/log/console/logger.go | 42 ++--- validatornode/main.go | 4 +- validatornode/presentation/api/host.go | 2 +- validatornode/settings.json | 2 +- 9 files changed, 174 insertions(+), 43 deletions(-) delete mode 100644 validatornode/infrastructure/configuration/registry_settings_provider.go diff --git a/accessnode/main.go b/accessnode/main.go index 0e3cc02d..c001ccbd 100644 --- a/accessnode/main.go +++ b/accessnode/main.go @@ -23,8 +23,8 @@ func main() { logLevel := flag.String("log-level", environment.NewVariable("LOG_LEVEL").GetStringValue("info"), "The log level (possible values: 'debug', 'info', 'warn', 'error', 'fatal')") flag.Parse() - logger := console.NewLogger(console.ParseLevel(*logLevel)) - validatorNeighbor, err := p2p.NewNeighbor(*validatorIp, strconv.Itoa(*validatorPort), time.Minute, console.NewLogger(console.Fatal)) + logger := console.NewLogger(*logLevel) + validatorNeighbor, err := p2p.NewNeighbor(*validatorIp, strconv.Itoa(*validatorPort), time.Minute, console.NewFatalLogger()) if err != nil { logger.Fatal(fmt.Errorf("unable to find blockchain client: %w", err).Error()) } diff --git a/validatornode/README.md b/validatornode/README.md index 76656a61..572e9dfc 100644 --- a/validatornode/README.md +++ b/validatornode/README.md @@ -11,20 +11,148 @@ At root level (ruthenium folder), run the validator node using the command `go r go run validatornode/main.go -private-key=0x48913790c2bebc48417491f96a7e07ec94c76ccd0fe1562dc1749479d9715afd ``` -## Program arguments: +## Program Arguments ``` --mnemonic: The mnemonic (required if the private key is not provided) --derivation-path: The derivation path (unused if the mnemonic is omitted, default: "m/44'/60'/0'/0/0") --password: The mnemonic password (unused if the mnemonic is omitted) --private-key: The private key (required if the mnemonic is not provided, unused if the mnemonic is provided) -infura-key: The infura key (required to check the proof of humanity) -ip: The validator node IP or DNS address (detected if not provided) -port: The TCP port number of the validator node (accepted values: "10600" for mainnet, "10601" to "10699" for testnet, default: "10600") --settings-path: The settings file path (default: "config/settings.json") +-settings-path: The settings file path (default: "validatornode/settings.json") -seeds-path: The seeds file path (default: "config/seeds.json") -log-level: The log level (accepted values: "debug", "info", "warn", "error", "fatal", default: "info") ``` - + +## Application Settings + + + + + + + + + +
+Schema + +Description + +Example +
+ +``` +{ + "host": { + "ip": string + "port": int + }, + "network": { + "maxOutboundsCount": int + "seeds": []string + "synchronizationIntervalInSeconds": int + "connectionTimeoutInSeconds": int + }, + "protocol": { + "blocksCountLimit": uint64 + "coinDigitsCount": uint8 + "genesisAmount": uint64 + "halfLifeInDays": 373.float6 + "incomeBase": uint64 + "incomeLimit": uint64 + "minimalTransactionFee": uint64 + "validationIntervalInSeconds": int64 + "validationTimeoutInSeconds": int64 + "verificationsCountPerValidation": int64 + }, + "registry": { + "synchronizationIntervalInSeconds": int + }, + "validator": { + "address": string + "infuraKey": string + }, + "log": { + "logLevel": string + } +} +``` + + +``` + + +The validator node IP or DNS address (detected if not provided) +The TCP port number of the validator node (accepted values: "10600" for mainnet, "10601" to "10699" for testnet) + + +The maximum validator node outbounds count +The initial validator node neighbors +The neighbors blockchain synchronization interval in seconds +The neighbors connection timeout in seconds + + +The maximum returned blocks for a blocks request +The coin digits count +The genesis transaction reward amount +The coin half-life +The income amount after a period of one half-life for an empty initial balance +The balance limit to receive the income +The minimal transaction fee +The validation interval in seconds +The validation timeout in seconds +The verifications count per validation + + +The synchronization interval in seconds + + +The validator wallet address +The infura key (required to check the proof of humanity) + + +The log level (accepted values: "debug", "info", "warn", "error", "fatal") + + +``` + + +``` +{ + "host": { + "ip": "", + "port": 10600 + }, + "network": { + "maxOutboundsCount": 8, + "seeds": ["seed-styx.ruthenium.my-cloud.me:10600"], + "synchronizationIntervalInSeconds": 6, + "connectionTimeoutInSeconds": 3 + }, + "protocol": { + "blocksCountLimit": 1440, + "coinDigitsCount": 8, + "genesisAmount": 5000000000000, + "halfLifeInDays": 373.59, + "incomeBase": 100000000000, + "incomeLimit": 5000000000000, + "minimalTransactionFee": 1000, + "validationIntervalInSeconds": 3, + "validationTimeoutInSeconds": 3, + "verificationsCountPerValidation": 6 + }, + "registry": { + "synchronizationIntervalInSeconds": 3600 + }, + "validator": { + "address": "", + "infuraKey": "" + }, + "log": { + "logLevel": "info" + } +} +``` +
+ ## API Base URL: `:` (example: seed-styx.ruthenium.my-cloud.me:10600) @@ -467,5 +595,3 @@ The value at the transaction timestamp - -[1]: https://go.dev/blog/gob "Gobs official documentation" diff --git a/validatornode/infrastructure/configuration/network_settings.go b/validatornode/infrastructure/configuration/network_settings.go index 09caeff2..00c1bb00 100644 --- a/validatornode/infrastructure/configuration/network_settings.go +++ b/validatornode/infrastructure/configuration/network_settings.go @@ -6,12 +6,14 @@ import ( ) type networkSettingsDto struct { + ConnectionTimeoutInSeconds int MaxOutboundsCount int Seeds []string SynchronizationIntervalInSeconds int } type NetworkSettings struct { + connectionTimeout time.Duration maxOutboundsCount int seeds []string synchronizationTimer time.Duration @@ -23,12 +25,17 @@ func (settings *NetworkSettings) UnmarshalJSON(data []byte) error { if err != nil { return err } + settings.connectionTimeout = time.Duration(dto.ConnectionTimeoutInSeconds) * time.Second settings.maxOutboundsCount = dto.MaxOutboundsCount settings.seeds = dto.Seeds settings.synchronizationTimer = time.Duration(dto.SynchronizationIntervalInSeconds) * time.Second return nil } +func (settings *NetworkSettings) ConnectionTimeout() time.Duration { + return settings.connectionTimeout +} + func (settings *NetworkSettings) MaxOutboundsCount() int { return settings.maxOutboundsCount } diff --git a/validatornode/infrastructure/configuration/protocol_settings.go b/validatornode/infrastructure/configuration/protocol_settings.go index 12660049..806f0179 100644 --- a/validatornode/infrastructure/configuration/protocol_settings.go +++ b/validatornode/infrastructure/configuration/protocol_settings.go @@ -2,17 +2,18 @@ package configuration import ( "encoding/json" + "math" "time" ) type protocolSettingsDto struct { BlocksCountLimit uint64 + CoinDigitsCount uint8 GenesisAmount uint64 HalfLifeInDays float64 IncomeBase uint64 IncomeLimit uint64 MinimalTransactionFee uint64 - SmallestUnitsPerCoin uint64 ValidationIntervalInSeconds int64 ValidationTimeoutInSeconds int64 VerificationsCountPerValidation int64 @@ -47,7 +48,7 @@ func (settings *ProtocolSettings) UnmarshalJSON(data []byte) error { settings.incomeBase = dto.IncomeBase settings.incomeLimit = dto.IncomeLimit settings.minimalTransactionFee = dto.MinimalTransactionFee - settings.smallestUnitsPerCoin = dto.SmallestUnitsPerCoin + settings.smallestUnitsPerCoin = uint64(math.Pow10(int(dto.CoinDigitsCount))) settings.validationTimeout = time.Duration(dto.ValidationTimeoutInSeconds) * time.Second settings.validationTimer = time.Duration(dto.ValidationIntervalInSeconds) * time.Second settings.validationTimestamp = dto.ValidationIntervalInSeconds * time.Second.Nanoseconds() diff --git a/validatornode/infrastructure/configuration/registry_settings_provider.go b/validatornode/infrastructure/configuration/registry_settings_provider.go deleted file mode 100644 index df440d04..00000000 --- a/validatornode/infrastructure/configuration/registry_settings_provider.go +++ /dev/null @@ -1,7 +0,0 @@ -package configuration - -import "time" - -type RegistrySettingsProvider interface { - SynchronizationTimer() time.Duration -} diff --git a/validatornode/infrastructure/log/console/logger.go b/validatornode/infrastructure/log/console/logger.go index 2aabe59a..834329fd 100644 --- a/validatornode/infrastructure/log/console/logger.go +++ b/validatornode/infrastructure/log/console/logger.go @@ -8,63 +8,67 @@ import ( type Level uint32 const ( - Debug Level = iota - Info - Warn - Error - Fatal + debug Level = iota + info + warn + err + fatal ) -func ParseLevel(level string) Level { +func parseLevel(level string) Level { switch strings.ToLower(level) { case "debug": - return Debug + return debug case "info": - return Info + return info case "warn": - return Warn + return warn case "error": - return Error + return err case "fatal": - return Fatal + return fatal } - return Info + return info } type Logger struct { level Level } -func NewLogger(level Level) *Logger { - return &Logger{level} +func NewLogger(level string) *Logger { + return &Logger{parseLevel(level)} +} + +func NewFatalLogger() *Logger { + return &Logger{fatal} } func (logger *Logger) Debug(msg string) { - if logger.level <= Debug { + if logger.level <= debug { log.Println("DEBUG:", msg) } } func (logger *Logger) Info(msg string) { - if logger.level <= Info { + if logger.level <= info { log.Println("INFO:", msg) } } func (logger *Logger) Warn(msg string) { - if logger.level <= Warn { + if logger.level <= warn { log.Println("WARN:", msg) } } func (logger *Logger) Error(msg string) { - if logger.level <= Error { + if logger.level <= err { log.Println("ERROR:", msg) } } func (logger *Logger) Fatal(msg string) { - if logger.level <= Fatal { + if logger.level <= fatal { log.Panicln("FATAL:", msg) } } diff --git a/validatornode/main.go b/validatornode/main.go index f1708be8..3107e9f9 100644 --- a/validatornode/main.go +++ b/validatornode/main.go @@ -28,7 +28,7 @@ func main() { if err != nil { panic(err.Error()) } - logger := console.NewLogger(console.ParseLevel(settings.Log().LogLevel())) + logger := console.NewLogger(settings.Log().LogLevel()) node, err := createHostNode(settings, logger) if err != nil { logger.Fatal(err.Error()) @@ -67,7 +67,7 @@ func createNeighborhood(settings *configuration.Settings, watch *clock.Watch, lo scoresBySeedTargetValue[seedStringTargetValue] = 0 } ipFinder := net.NewIpFinderImplementation(logger) - neighborFactory := p2p.NewNeighborFactory(ipFinder, settings.Protocol().ValidationTimeout(), console.NewLogger(console.Fatal)) + neighborFactory := p2p.NewNeighborFactory(ipFinder, settings.Network().ConnectionTimeout(), console.NewFatalLogger()) hostIp, err := findHostPublicIp(settings.Host().Ip(), logger) if err != nil { return nil, err diff --git a/validatornode/presentation/api/host.go b/validatornode/presentation/api/host.go index 4f054e8f..3087c1c3 100644 --- a/validatornode/presentation/api/host.go +++ b/validatornode/presentation/api/host.go @@ -36,7 +36,7 @@ func NewHost(blocksManager application.BlocksManager, if err != nil { return nil, fmt.Errorf("failed to instantiate host on port %s: %w", port, err) } - server.SetLogger(console.NewLogger(console.Fatal)) + server.SetLogger(console.NewFatalLogger()) serverSettings := gp2p.NewServerSettings() serverSettings.SetConnTimeout(validationTimeout) server.SetSettings(serverSettings) diff --git a/validatornode/settings.json b/validatornode/settings.json index a91bcbc0..4990abda 100644 --- a/validatornode/settings.json +++ b/validatornode/settings.json @@ -14,12 +14,12 @@ }, "protocol": { "blocksCountLimit": 1440, + "coinDigitsCount": 8, "genesisAmount": 5000000000000, "halfLifeInDays": 373.59, "incomeBase": 100000000000, "incomeLimit": 5000000000000, "minimalTransactionFee": 1000, - "smallestUnitsPerCoin": 100000000, "validationIntervalInSeconds": 3, "validationTimeoutInSeconds": 3, "verificationsCountPerValidation": 6