From f9ddf88c934bb512a4a8ed1c4cb28aa7e38cbb24 Mon Sep 17 00:00:00 2001 From: arnaubennassar Date: Wed, 24 Mar 2021 16:41:48 +0100 Subject: [PATCH] Add configuration option to choose recommended fee strategy, and add static strategy --- api/api_test.go | 9 +++- api/stateapiupdater/stateapiupdater.go | 67 +++++++++++++++++++++++--- cli/node/cfg.buidler.toml | 8 +++ config/config.go | 6 ++- node/node.go | 11 ++++- 5 files changed, 88 insertions(+), 13 deletions(-) diff --git a/api/api_test.go b/api/api_test.go index a6ff1a9..25046fc 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -522,11 +522,16 @@ func TestMain(m *testing.M) { WithdrawalDelay: uint64(3000), } - stateAPIUpdater = stateapiupdater.NewUpdater(hdb, nodeConfig, &common.SCVariables{ + stateAPIUpdater, err = stateapiupdater.NewUpdater(hdb, nodeConfig, &common.SCVariables{ Rollup: rollupVars, Auction: auctionVars, WDelayer: wdelayerVars, - }, constants) + }, constants, &stateapiupdater.RecommendedFeePolicy{ + PolicyType: stateapiupdater.RecommendedFeePolicyTypeAvgLastHour, + }) + if err != nil { + panic(err) + } // Generate test data, as expected to be received/sended from/to the API testCoords := genTestCoordinators(commonCoords) diff --git a/api/stateapiupdater/stateapiupdater.go b/api/stateapiupdater/stateapiupdater.go index d8cc325..55eff6f 100644 --- a/api/stateapiupdater/stateapiupdater.go +++ b/api/stateapiupdater/stateapiupdater.go @@ -2,10 +2,12 @@ package stateapiupdater import ( "database/sql" + "fmt" "sync" "github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/db/historydb" + "github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/tracerr" ) @@ -17,11 +19,45 @@ type Updater struct { vars common.SCVariablesPtr consts historydb.Constants rw sync.RWMutex + rfp *RecommendedFeePolicy +} + +// RecommendedFeePolicy describes how the recommended fee is calculated +type RecommendedFeePolicy struct { + PolicyType RecommendedFeePolicyType `validate:"required"` + StaticValue float64 +} + +// RecommendedFeePolicyType describes the different available recommended fee strategies +type RecommendedFeePolicyType string + +const ( + // RecommendedFeePolicyTypeStatic always give the same StaticValue as recommended fee + RecommendedFeePolicyTypeStatic RecommendedFeePolicyType = "Static" + // RecommendedFeePolicyTypeAvgLastHour set the recommended fee using the average fee of the last hour + RecommendedFeePolicyTypeAvgLastHour RecommendedFeePolicyType = "AvgLastHour" +) + +func (rfp *RecommendedFeePolicy) valid() bool { + switch rfp.PolicyType { + case RecommendedFeePolicyTypeStatic: + if rfp.StaticValue == 0 { + log.Warn("RcommendedFee is set to 0 USD, and the policy is static") + } + return true + case RecommendedFeePolicyTypeAvgLastHour: + return true + default: + return false + } } // NewUpdater creates a new Updater func NewUpdater(hdb *historydb.HistoryDB, config *historydb.NodeConfig, vars *common.SCVariables, - consts *historydb.Constants) *Updater { + consts *historydb.Constants, rfp *RecommendedFeePolicy) (*Updater, error) { + if ok := rfp.valid(); !ok { + return nil, tracerr.Wrap(fmt.Errorf("Invalid recommended fee policy: %v", rfp.PolicyType)) + } u := Updater{ hdb: hdb, config: *config, @@ -31,9 +67,10 @@ func NewUpdater(hdb *historydb.HistoryDB, config *historydb.NodeConfig, vars *co ForgeDelay: config.ForgeDelay, }, }, + rfp: rfp, } u.SetSCVars(vars.AsPtr()) - return &u + return &u, nil } // Store the State in the HistoryDB @@ -65,13 +102,27 @@ func (u *Updater) SetSCVars(vars *common.SCVariablesPtr) { // UpdateRecommendedFee update Status.RecommendedFee information func (u *Updater) UpdateRecommendedFee() error { - recommendedFee, err := u.hdb.GetRecommendedFee(u.config.MinFeeUSD, u.config.MaxFeeUSD) - if err != nil { - return tracerr.Wrap(err) + switch u.rfp.PolicyType { + case RecommendedFeePolicyTypeStatic: + u.rw.Lock() + u.state.RecommendedFee = common.RecommendedFee{ + ExistingAccount: u.rfp.StaticValue, + CreatesAccount: u.rfp.StaticValue, + CreatesAccountInternal: u.rfp.StaticValue, + } + u.rw.Unlock() + case RecommendedFeePolicyTypeAvgLastHour: + recommendedFee, err := u.hdb.GetRecommendedFee(u.config.MinFeeUSD, u.config.MaxFeeUSD) + if err != nil { + return tracerr.Wrap(err) + } + u.rw.Lock() + u.state.RecommendedFee = *recommendedFee + u.rw.Unlock() + default: + return tracerr.New("Invalid recommende fee policy") } - u.rw.Lock() - u.state.RecommendedFee = *recommendedFee - u.rw.Unlock() + return nil } diff --git a/cli/node/cfg.buidler.toml b/cli/node/cfg.buidler.toml index f2d561e..e9f0467 100644 --- a/cli/node/cfg.buidler.toml +++ b/cli/node/cfg.buidler.toml @@ -145,3 +145,11 @@ Coordinator = true BatchPath = "/tmp/iden3-test/hermez/batchesdebug" LightScrypt = true # RollupVerifierIndex = 0 + +[RecommendedFeePolicy] +# Strategy used to calculate the recommended fee that the API will expose. +# Available options: +# - Static: always return the same value (StaticValue) in USD +# - AvgLastHour: calculate using the average fee of the forged transactions during the last hour +PolicyType = "Static" +StaticValue = 0.99 \ No newline at end of file diff --git a/config/config.go b/config/config.go index 419617f..0fb0e13 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,7 @@ import ( "github.com/BurntSushi/toml" ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/hermeznetwork/hermez-node/api/stateapiupdater" "github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/priceupdater" "github.com/hermeznetwork/tracerr" @@ -347,8 +348,9 @@ type Node struct { // can wait to stablish a SQL connection SQLConnectionTimeout Duration } `validate:"required"` - Debug NodeDebug `validate:"required"` - Coordinator Coordinator `validate:"-"` + RecommendedFeePolicy stateapiupdater.RecommendedFeePolicy `validate:"required"` + Debug NodeDebug `validate:"required"` + Coordinator Coordinator `validate:"-"` } // APIServer is the api server configuration parameters diff --git a/node/node.go b/node/node.go index 3445933..900ab1c 100644 --- a/node/node.go +++ b/node/node.go @@ -288,7 +288,16 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) { return nil, tracerr.Wrap(err) } - stateAPIUpdater := stateapiupdater.NewUpdater(historyDB, &hdbNodeCfg, initSCVars, &hdbConsts) + stateAPIUpdater, err := stateapiupdater.NewUpdater( + historyDB, + &hdbNodeCfg, + initSCVars, + &hdbConsts, + &cfg.RecommendedFeePolicy, + ) + if err != nil { + return nil, tracerr.Wrap(err) + } var coord *coordinator.Coordinator if mode == ModeCoordinator {