diff --git a/config/config.go b/config/config.go index 4d793708607..46fd0aac8af 100644 --- a/config/config.go +++ b/config/config.go @@ -47,8 +47,10 @@ import ( "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" "github.com/ava-labs/avalanchego/vms/proposervm" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) const ( @@ -768,7 +770,7 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { if networkID != constants.MainnetID && networkID != constants.FujiID { return genesis.TxFeeConfig{ CreateAssetTxFee: v.GetUint64(CreateAssetTxFeeKey), - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: v.GetUint64(TxFeeKey), CreateSubnetTxFee: v.GetUint64(CreateSubnetTxFeeKey), TransformSubnetTxFee: v.GetUint64(TransformSubnetTxFeeKey), @@ -791,6 +793,12 @@ func getTxFeeConfig(v *viper.Viper, networkID uint32) genesis.TxFeeConfig { MinPrice: gas.Price(v.GetUint64(DynamicFeesMinGasPriceKey)), ExcessConversionConstant: gas.Gas(v.GetUint64(DynamicFeesExcessConversionConstantKey)), }, + ValidatorFeeCapacity: gas.Gas(v.GetUint64(ValidatorFeesCapacityKey)), + ValidatorFeeConfig: validatorfee.Config{ + Target: gas.Gas(v.GetUint64(ValidatorFeesTargetKey)), + MinPrice: gas.Price(v.GetUint64(ValidatorFeesMinPriceKey)), + ExcessConversionConstant: gas.Gas(v.GetUint64(ValidatorFeesExcessConversionConstantKey)), + }, } } return genesis.GetTxFeeConfig(networkID) diff --git a/config/flags.go b/config/flags.go index 9f092c563b3..c20b243c807 100644 --- a/config/flags.go +++ b/config/flags.go @@ -105,6 +105,11 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.IntSlice(ACPObjectKey, nil, "ACPs to object adoption") // AVAX fees: + // Validator fees: + fs.Uint64(ValidatorFeesCapacityKey, uint64(genesis.LocalParams.ValidatorFeeCapacity), "Maximum number of validators") + fs.Uint64(ValidatorFeesTargetKey, uint64(genesis.LocalParams.ValidatorFeeConfig.Target), "Target number of validators") + fs.Uint64(ValidatorFeesMinPriceKey, uint64(genesis.LocalParams.ValidatorFeeConfig.MinPrice), "Minimum validator price in nAVAX per second") + fs.Uint64(ValidatorFeesExcessConversionConstantKey, uint64(genesis.LocalParams.ValidatorFeeConfig.ExcessConversionConstant), "Constant to convert validator excess price") // Dynamic fees: fs.Uint64(DynamicFeesBandwidthWeightKey, genesis.LocalParams.DynamicFeeConfig.Weights[gas.Bandwidth], "Complexity multiplier used to convert Bandwidth into Gas") fs.Uint64(DynamicFeesDBReadWeightKey, genesis.LocalParams.DynamicFeeConfig.Weights[gas.DBRead], "Complexity multiplier used to convert DB Reads into Gas") diff --git a/config/keys.go b/config/keys.go index 714136a7407..dcea2621f6f 100644 --- a/config/keys.go +++ b/config/keys.go @@ -8,63 +8,67 @@ package config const HTTPWriteTimeoutKey = "http-write-timeout" // #nosec G101 const ( - DataDirKey = "data-dir" - ConfigFileKey = "config-file" - ConfigContentKey = "config-file-content" - ConfigContentTypeKey = "config-file-content-type" - VersionKey = "version" - VersionJSONKey = "version-json" - GenesisFileKey = "genesis-file" - GenesisFileContentKey = "genesis-file-content" - UpgradeFileKey = "upgrade-file" - UpgradeFileContentKey = "upgrade-file-content" - NetworkNameKey = "network-id" - ACPSupportKey = "acp-support" - ACPObjectKey = "acp-object" - DynamicFeesBandwidthWeightKey = "dynamic-fees-bandwidth-weight" - DynamicFeesDBReadWeightKey = "dynamic-fees-db-read-weight" - DynamicFeesDBWriteWeightKey = "dynamic-fees-db-write-weight" - DynamicFeesComputeWeightKey = "dynamic-fees-compute-weight" - DynamicFeesMaxGasCapacityKey = "dynamic-fees-max-gas-capacity" - DynamicFeesMaxGasPerSecondKey = "dynamic-fees-max-gas-per-second" - DynamicFeesTargetGasPerSecondKey = "dynamic-fees-target-gas-per-second" - DynamicFeesMinGasPriceKey = "dynamic-fees-min-gas-price" - DynamicFeesExcessConversionConstantKey = "dynamic-fees-excess-conversion-constant" - TxFeeKey = "tx-fee" - CreateAssetTxFeeKey = "create-asset-tx-fee" - CreateSubnetTxFeeKey = "create-subnet-tx-fee" - TransformSubnetTxFeeKey = "transform-subnet-tx-fee" - CreateBlockchainTxFeeKey = "create-blockchain-tx-fee" - AddPrimaryNetworkValidatorFeeKey = "add-primary-network-validator-fee" - AddPrimaryNetworkDelegatorFeeKey = "add-primary-network-delegator-fee" - AddSubnetValidatorFeeKey = "add-subnet-validator-fee" - AddSubnetDelegatorFeeKey = "add-subnet-delegator-fee" - UptimeRequirementKey = "uptime-requirement" - MinValidatorStakeKey = "min-validator-stake" - MaxValidatorStakeKey = "max-validator-stake" - MinDelegatorStakeKey = "min-delegator-stake" - MinDelegatorFeeKey = "min-delegation-fee" - MinStakeDurationKey = "min-stake-duration" - MaxStakeDurationKey = "max-stake-duration" - StakeMaxConsumptionRateKey = "stake-max-consumption-rate" - StakeMinConsumptionRateKey = "stake-min-consumption-rate" - StakeMintingPeriodKey = "stake-minting-period" - StakeSupplyCapKey = "stake-supply-cap" - DBTypeKey = "db-type" - DBReadOnlyKey = "db-read-only" - DBPathKey = "db-dir" - DBConfigFileKey = "db-config-file" - DBConfigContentKey = "db-config-file-content" - PublicIPKey = "public-ip" - PublicIPResolutionFreqKey = "public-ip-resolution-frequency" - PublicIPResolutionServiceKey = "public-ip-resolution-service" - HTTPHostKey = "http-host" - HTTPPortKey = "http-port" - HTTPSEnabledKey = "http-tls-enabled" - HTTPSKeyFileKey = "http-tls-key-file" - HTTPSKeyContentKey = "http-tls-key-file-content" - HTTPSCertFileKey = "http-tls-cert-file" - HTTPSCertContentKey = "http-tls-cert-file-content" + DataDirKey = "data-dir" + ConfigFileKey = "config-file" + ConfigContentKey = "config-file-content" + ConfigContentTypeKey = "config-file-content-type" + VersionKey = "version" + VersionJSONKey = "version-json" + GenesisFileKey = "genesis-file" + GenesisFileContentKey = "genesis-file-content" + UpgradeFileKey = "upgrade-file" + UpgradeFileContentKey = "upgrade-file-content" + NetworkNameKey = "network-id" + ACPSupportKey = "acp-support" + ACPObjectKey = "acp-object" + DynamicFeesBandwidthWeightKey = "dynamic-fees-bandwidth-weight" + DynamicFeesDBReadWeightKey = "dynamic-fees-db-read-weight" + DynamicFeesDBWriteWeightKey = "dynamic-fees-db-write-weight" + DynamicFeesComputeWeightKey = "dynamic-fees-compute-weight" + DynamicFeesMaxGasCapacityKey = "dynamic-fees-max-gas-capacity" + DynamicFeesMaxGasPerSecondKey = "dynamic-fees-max-gas-per-second" + DynamicFeesTargetGasPerSecondKey = "dynamic-fees-target-gas-per-second" + DynamicFeesMinGasPriceKey = "dynamic-fees-min-gas-price" + DynamicFeesExcessConversionConstantKey = "dynamic-fees-excess-conversion-constant" + ValidatorFeesCapacityKey = "validator-fees-capacity" + ValidatorFeesTargetKey = "validator-fees-target" + ValidatorFeesMinPriceKey = "validator-fees-min-price" + ValidatorFeesExcessConversionConstantKey = "validator-fees-excess-conversion-constant" + TxFeeKey = "tx-fee" + CreateAssetTxFeeKey = "create-asset-tx-fee" + CreateSubnetTxFeeKey = "create-subnet-tx-fee" + TransformSubnetTxFeeKey = "transform-subnet-tx-fee" + CreateBlockchainTxFeeKey = "create-blockchain-tx-fee" + AddPrimaryNetworkValidatorFeeKey = "add-primary-network-validator-fee" + AddPrimaryNetworkDelegatorFeeKey = "add-primary-network-delegator-fee" + AddSubnetValidatorFeeKey = "add-subnet-validator-fee" + AddSubnetDelegatorFeeKey = "add-subnet-delegator-fee" + UptimeRequirementKey = "uptime-requirement" + MinValidatorStakeKey = "min-validator-stake" + MaxValidatorStakeKey = "max-validator-stake" + MinDelegatorStakeKey = "min-delegator-stake" + MinDelegatorFeeKey = "min-delegation-fee" + MinStakeDurationKey = "min-stake-duration" + MaxStakeDurationKey = "max-stake-duration" + StakeMaxConsumptionRateKey = "stake-max-consumption-rate" + StakeMinConsumptionRateKey = "stake-min-consumption-rate" + StakeMintingPeriodKey = "stake-minting-period" + StakeSupplyCapKey = "stake-supply-cap" + DBTypeKey = "db-type" + DBReadOnlyKey = "db-read-only" + DBPathKey = "db-dir" + DBConfigFileKey = "db-config-file" + DBConfigContentKey = "db-config-file-content" + PublicIPKey = "public-ip" + PublicIPResolutionFreqKey = "public-ip-resolution-frequency" + PublicIPResolutionServiceKey = "public-ip-resolution-service" + HTTPHostKey = "http-host" + HTTPPortKey = "http-port" + HTTPSEnabledKey = "http-tls-enabled" + HTTPSKeyFileKey = "http-tls-key-file" + HTTPSKeyContentKey = "http-tls-key-file-content" + HTTPSCertFileKey = "http-tls-cert-file" + HTTPSCertContentKey = "http-tls-cert-file-content" HTTPAllowedOrigins = "http-allowed-origins" HTTPAllowedHostsKey = "http-allowed-hosts" diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index 3d59bb72575..82a8ffecaa3 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -11,7 +11,9 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) var ( @@ -22,7 +24,7 @@ var ( FujiParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: 10 * units.MilliAvax, - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 1 * units.Avax, @@ -46,6 +48,16 @@ var ( MinPrice: 1, ExcessConversionConstant: 5_000, }, + ValidatorFeeCapacity: 20_000, + ValidatorFeeConfig: validatorfee.Config{ + Target: 10_000, + MinPrice: gas.Price(512 * units.NanoAvax), + // ExcessConversionConstant = (Capacity - Target) * NumberOfSecondsPerDoubling / ln(2) + // + // ln(2) is a float and the result is consensus critical, so we + // hardcode the result. + ExcessConversionConstant: 51_937_021, // Double every hour + }, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index d3ce77aec96..aefdbf2c25b 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -14,7 +14,9 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) // PrivateKey-vmRQiZeXEXYMyJhEiqdC2z5JhuDbxL8ix9UVvjgMu2Er1NepE => P-local1g65uqn6t77p656w64023nh8nd9updzmxyymev2 @@ -40,7 +42,7 @@ var ( LocalParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: units.MilliAvax, - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 100 * units.MilliAvax, TransformSubnetTxFee: 100 * units.MilliAvax, @@ -64,6 +66,16 @@ var ( MinPrice: 1, ExcessConversionConstant: 5_000, }, + ValidatorFeeCapacity: 20_000, + ValidatorFeeConfig: validatorfee.Config{ + Target: 10_000, + MinPrice: gas.Price(1 * units.NanoAvax), + // ExcessConversionConstant = (Capacity - Target) * NumberOfSecondsPerDoubling / ln(2) + // + // ln(2) is a float and the result is consensus critical, so we + // hardcode the result. + ExcessConversionConstant: 865_617, // Double every minute + }, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 8d4a6d4f777..2395d88d34b 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -11,7 +11,9 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) var ( @@ -22,7 +24,7 @@ var ( MainnetParams = Params{ TxFeeConfig: TxFeeConfig{ CreateAssetTxFee: 10 * units.MilliAvax, - StaticFeeConfig: fee.StaticConfig{ + StaticFeeConfig: txfee.StaticConfig{ TxFee: units.MilliAvax, CreateSubnetTxFee: 1 * units.Avax, TransformSubnetTxFee: 10 * units.Avax, @@ -46,6 +48,16 @@ var ( MinPrice: 1, ExcessConversionConstant: 5_000, }, + ValidatorFeeCapacity: 20_000, + ValidatorFeeConfig: validatorfee.Config{ + Target: 10_000, + MinPrice: gas.Price(512 * units.NanoAvax), + // ExcessConversionConstant = (Capacity - Target) * NumberOfSecondsPerDoubling / ln(2) + // + // ln(2) is a float and the result is consensus critical, so we + // hardcode the result. + ExcessConversionConstant: 1_246_488_515, // Double every day + }, }, StakingConfig: StakingConfig{ UptimeRequirement: .8, // 80% diff --git a/genesis/params.go b/genesis/params.go index e51af8b81c1..43c2f1c1301 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -9,7 +9,9 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) type StakingConfig struct { @@ -36,9 +38,11 @@ type StakingConfig struct { } type TxFeeConfig struct { - CreateAssetTxFee uint64 `json:"createAssetTxFee"` - StaticFeeConfig fee.StaticConfig `json:"staticFeeConfig"` - DynamicFeeConfig gas.Config `json:"dynamicFeeConfig"` + CreateAssetTxFee uint64 `json:"createAssetTxFee"` + StaticFeeConfig txfee.StaticConfig `json:"staticFeeConfig"` + DynamicFeeConfig gas.Config `json:"dynamicFeeConfig"` + ValidatorFeeCapacity gas.Gas `json:"validatorFeeCapacity"` + ValidatorFeeConfig validatorfee.Config `json:"validatorFeeConfig"` } type Params struct { diff --git a/node/node.go b/node/node.go index b2aba931443..5f6ef111858 100644 --- a/node/node.go +++ b/node/node.go @@ -1228,6 +1228,8 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, StaticFeeConfig: n.Config.StaticFeeConfig, DynamicFeeConfig: n.Config.DynamicFeeConfig, + ValidatorFeeCapacity: n.Config.ValidatorFeeCapacity, + ValidatorFeeConfig: n.Config.ValidatorFeeConfig, UptimePercentage: n.Config.UptimeRequirement, MinValidatorStake: n.Config.MinValidatorStake, MaxValidatorStake: n.Config.MaxValidatorStake, diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 406285f0e59..f8bda923455 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -16,7 +16,9 @@ import ( "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" + validatorfee "github.com/ava-labs/avalanchego/vms/platformvm/validators/fee" ) // Struct collecting all foundational parameters of PlatformVM @@ -32,13 +34,17 @@ type Config struct { // calling VM.Initialize. Validators validators.Manager - // Static fees are active before the E-upgrade + // Static fees are active before Etna CreateAssetTxFee uint64 // Override for CreateSubnet and CreateChain before AP3 - StaticFeeConfig fee.StaticConfig + StaticFeeConfig txfee.StaticConfig - // Dynamic fees are active after the E-upgrade + // Dynamic fees are active after Etna DynamicFeeConfig gas.Config + // ACP-77 validator fees are active after Etna + ValidatorFeeCapacity gas.Gas + ValidatorFeeConfig validatorfee.Config + // Provides access to the uptime manager as a thread safe data structure UptimeLockedCalculator uptime.LockedCalculator