From 7e5932da81e107bb0050a71102f0cbd1d35226be Mon Sep 17 00:00:00 2001 From: Jernej Kos Date: Tue, 23 Apr 2024 12:24:05 +0200 Subject: [PATCH] go/consensus: Add global minimum gas price --- .changelog/5657.breaking.md | 1 + go/consensus/api/api.go | 4 + go/consensus/api/grpc.go | 34 ++++ go/consensus/api/submission.go | 34 +--- go/consensus/cometbft/abci/state.go | 2 +- go/consensus/cometbft/abci/transaction.go | 11 ++ go/consensus/cometbft/api/state.go | 6 +- .../cometbft/apps/staking/state/gas.go | 2 +- go/consensus/cometbft/config/config.go | 2 +- go/consensus/cometbft/full/common.go | 30 +++- go/consensus/cometbft/full/full.go | 11 +- go/consensus/genesis/genesis.go | 3 + go/consensus/pricediscovery/pricediscovery.go | 145 ++++++++++++++++++ go/consensus/pricediscovery/static.go | 26 ++++ go/oasis-node/cmd/debug/txsource/txsource.go | 3 +- .../cmd/debug/txsource/workload/oversized.go | 2 +- .../cmd/debug/txsource/workload/workload.go | 2 +- go/oasis-test-runner/scenario/e2e/upgrade.go | 24 +++ go/upgrade/migrations/consensus_240.go | 1 + 19 files changed, 303 insertions(+), 40 deletions(-) create mode 100644 .changelog/5657.breaking.md create mode 100644 go/consensus/pricediscovery/pricediscovery.go create mode 100644 go/consensus/pricediscovery/static.go diff --git a/.changelog/5657.breaking.md b/.changelog/5657.breaking.md new file mode 100644 index 00000000000..e84764e6fe5 --- /dev/null +++ b/.changelog/5657.breaking.md @@ -0,0 +1 @@ +go/consensus: Add global minimum gas price diff --git a/go/consensus/api/api.go b/go/consensus/api/api.go index 180862b4367..ea08ca8877d 100644 --- a/go/consensus/api/api.go +++ b/go/consensus/api/api.go @@ -15,6 +15,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/keyformat" "github.com/oasisprotocol/oasis-core/go/common/node" "github.com/oasisprotocol/oasis-core/go/common/pubsub" + "github.com/oasisprotocol/oasis-core/go/common/quantity" "github.com/oasisprotocol/oasis-core/go/common/service" "github.com/oasisprotocol/oasis-core/go/common/version" "github.com/oasisprotocol/oasis-core/go/consensus/api/transaction" @@ -129,6 +130,9 @@ type ClientBackend interface { // EstimateGas calculates the amount of gas required to execute the given transaction. EstimateGas(ctx context.Context, req *EstimateGasRequest) (transaction.Gas, error) + // MinGasPrice returns the minimum gas price. + MinGasPrice(ctx context.Context) (*quantity.Quantity, error) + // GetBlock returns a consensus block at a specific height. GetBlock(ctx context.Context, height int64) (*Block, error) diff --git a/go/consensus/api/grpc.go b/go/consensus/api/grpc.go index f592e6bb812..d7b3b37f1f6 100644 --- a/go/consensus/api/grpc.go +++ b/go/consensus/api/grpc.go @@ -8,6 +8,7 @@ import ( beacon "github.com/oasisprotocol/oasis-core/go/beacon/api" cmnGrpc "github.com/oasisprotocol/oasis-core/go/common/grpc" "github.com/oasisprotocol/oasis-core/go/common/pubsub" + "github.com/oasisprotocol/oasis-core/go/common/quantity" "github.com/oasisprotocol/oasis-core/go/consensus/api/transaction" genesis "github.com/oasisprotocol/oasis-core/go/genesis/api" governance "github.com/oasisprotocol/oasis-core/go/governance/api" @@ -32,6 +33,8 @@ var ( methodStateToGenesis = serviceName.NewMethod("StateToGenesis", int64(0)) // methodEstimateGas is the EstimateGas method. methodEstimateGas = serviceName.NewMethod("EstimateGas", &EstimateGasRequest{}) + // methodMinGasPrice is the MinGasPrice method. + methodMinGasPrice = serviceName.NewMethod("MinGasPrice", nil) // methodGetSignerNonce is a GetSignerNonce method. methodGetSignerNonce = serviceName.NewMethod("GetSignerNonce", &GetSignerNonceRequest{}) // methodGetBlock is the GetBlock method. @@ -93,6 +96,10 @@ var ( MethodName: methodEstimateGas.ShortName(), Handler: handlerEstimateGas, }, + { + MethodName: methodMinGasPrice.ShortName(), + Handler: handlerMinGasPrice, + }, { MethodName: methodGetSignerNonce.ShortName(), Handler: handlerGetSignerNonce, @@ -283,6 +290,25 @@ func handlerEstimateGas( return interceptor(ctx, rq, info, handler) } +func handlerMinGasPrice( + srv interface{}, + ctx context.Context, + _ func(interface{}) error, + interceptor grpc.UnaryServerInterceptor, +) (interface{}, error) { + if interceptor == nil { + return srv.(ClientBackend).MinGasPrice(ctx) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: methodMinGasPrice.FullName(), + } + handler := func(ctx context.Context, _ interface{}) (interface{}, error) { + return srv.(ClientBackend).MinGasPrice(ctx) + } + return interceptor(ctx, nil, info, handler) +} + func handlerGetSignerNonce( srv interface{}, ctx context.Context, @@ -700,6 +726,14 @@ func (c *consensusClient) EstimateGas(ctx context.Context, req *EstimateGasReque return gas, nil } +func (c *consensusClient) MinGasPrice(ctx context.Context) (*quantity.Quantity, error) { + var rsp quantity.Quantity + if err := c.conn.Invoke(ctx, methodMinGasPrice.FullName(), nil, &rsp); err != nil { + return nil, err + } + return &rsp, nil +} + func (c *consensusClient) GetSignerNonce(ctx context.Context, req *GetSignerNonceRequest) (uint64, error) { var nonce uint64 if err := c.conn.Invoke(ctx, methodGetSignerNonce.FullName(), req, &nonce); err != nil { diff --git a/go/consensus/api/submission.go b/go/consensus/api/submission.go index 400aae3c4e8..9cbbcc1de8f 100644 --- a/go/consensus/api/submission.go +++ b/go/consensus/api/submission.go @@ -25,31 +25,7 @@ const ( // PriceDiscovery is the consensus fee price discovery interface. type PriceDiscovery interface { // GasPrice returns the current consensus gas price. - GasPrice(ctx context.Context) (*quantity.Quantity, error) -} - -type staticPriceDiscovery struct { - price quantity.Quantity -} - -// NewStaticPriceDiscovery creates a price discovery mechanism which always returns the same static -// price specified at construction time. -func NewStaticPriceDiscovery(price uint64) (PriceDiscovery, error) { - pd := &staticPriceDiscovery{} - if err := pd.price.FromUint64(price); err != nil { - return nil, fmt.Errorf("submission: failed to convert gas price: %w", err) - } - return pd, nil -} - -func (pd *staticPriceDiscovery) GasPrice(context.Context) (*quantity.Quantity, error) { - return pd.price.Clone(), nil -} - -type noOpPriceDiscovery struct{} - -func (pd *noOpPriceDiscovery) GasPrice(context.Context) (*quantity.Quantity, error) { - return nil, transaction.ErrMethodNotSupported + GasPrice() (*quantity.Quantity, error) } // SubmissionManager is a transaction submission manager interface. @@ -108,7 +84,7 @@ func (m *submissionManager) EstimateGasAndSetFee(ctx context.Context, signer sig // Fetch current consensus gas price and compute the fee. var amount *quantity.Quantity - amount, err = m.priceDiscovery.GasPrice(ctx) + amount, err = m.priceDiscovery.GasPrice() if err != nil { return fmt.Errorf("failed to determine gas price: %w", err) } @@ -292,6 +268,12 @@ func SignAndSubmitTxWithProof(ctx context.Context, backend Backend, signer signa return backend.SubmissionManager().SignAndSubmitTxWithProof(ctx, signer, tx) } +type noOpPriceDiscovery struct{} + +func (pd *noOpPriceDiscovery) GasPrice() (*quantity.Quantity, error) { + return nil, transaction.ErrMethodNotSupported +} + // NoOpSubmissionManager implements a submission manager that doesn't support submitting transactions. type NoOpSubmissionManager struct{} diff --git a/go/consensus/cometbft/abci/state.go b/go/consensus/cometbft/abci/state.go index ea9bd9e5ad2..a48f1e744eb 100644 --- a/go/consensus/cometbft/abci/state.go +++ b/go/consensus/cometbft/abci/state.go @@ -340,7 +340,7 @@ func (s *applicationState) EpochChanged(ctx *api.Context) (bool, beacon.EpochTim return true, currentEpoch } -func (s *applicationState) MinGasPrice() *quantity.Quantity { +func (s *applicationState) LocalMinGasPrice() *quantity.Quantity { return &s.minGasPrice } diff --git a/go/consensus/cometbft/abci/transaction.go b/go/consensus/cometbft/abci/transaction.go index 32d03e701a1..0c950fac590 100644 --- a/go/consensus/cometbft/abci/transaction.go +++ b/go/consensus/cometbft/abci/transaction.go @@ -7,6 +7,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/cbor" "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" + "github.com/oasisprotocol/oasis-core/go/common/quantity" consensus "github.com/oasisprotocol/oasis-core/go/consensus/api" "github.com/oasisprotocol/oasis-core/go/consensus/api/transaction" "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/api" @@ -92,6 +93,16 @@ func (mux *abciMux) processTx(ctx *api.Context, tx *transaction.Transaction, txS return err } + // Ensure a minimum gas price. + if params.MinGasPrice > 0 && !ctx.IsSimulation() { + if tx.Fee == nil { + return transaction.ErrGasPriceTooLow + } + if tx.Fee.GasPrice().Cmp(quantity.NewFromUint64(params.MinGasPrice)) < 0 { + return transaction.ErrGasPriceTooLow + } + } + // Route to correct handler. ctx.Logger().Debug("dispatching", "app", app.Name(), diff --git a/go/consensus/cometbft/api/state.go b/go/consensus/cometbft/api/state.go index f044d790f51..6f5a4c4746c 100644 --- a/go/consensus/cometbft/api/state.go +++ b/go/consensus/cometbft/api/state.go @@ -56,8 +56,8 @@ type ApplicationState interface { // last block. As a matter of convenience, the current epoch is returned. EpochChanged(ctx *Context) (bool, beacon.EpochTime) - // MinGasPrice returns the configured minimum gas price. - MinGasPrice() *quantity.Quantity + // LocalMinGasPrice returns the configured local minimum gas price. + LocalMinGasPrice() *quantity.Quantity // OwnTxSigner returns the transaction signer identity of the local node. OwnTxSigner() signature.PublicKey @@ -171,7 +171,7 @@ func (ms *mockApplicationState) EpochChanged(*Context) (bool, beacon.EpochTime) return ms.cfg.EpochChanged, ms.cfg.CurrentEpoch } -func (ms *mockApplicationState) MinGasPrice() *quantity.Quantity { +func (ms *mockApplicationState) LocalMinGasPrice() *quantity.Quantity { return ms.cfg.MinGasPrice } diff --git a/go/consensus/cometbft/apps/staking/state/gas.go b/go/consensus/cometbft/apps/staking/state/gas.go index eb1a2c317ce..1a9691a3eed 100644 --- a/go/consensus/cometbft/apps/staking/state/gas.go +++ b/go/consensus/cometbft/apps/staking/state/gas.go @@ -99,7 +99,7 @@ func AuthenticateAndPayFees( // configuration, but as long as it is only done in CheckTx, this is ok. if !ctx.AppState().OwnTxSignerAddress().Equal(addr) { callerGasPrice := fee.GasPrice() - if fee.Gas > 0 && callerGasPrice.Cmp(ctx.AppState().MinGasPrice()) < 0 { + if fee.Gas > 0 && callerGasPrice.Cmp(ctx.AppState().LocalMinGasPrice()) < 0 { return transaction.ErrGasPriceTooLow } } diff --git a/go/consensus/cometbft/config/config.go b/go/consensus/cometbft/config/config.go index bffbf2356ce..612e0df7813 100644 --- a/go/consensus/cometbft/config/config.go +++ b/go/consensus/cometbft/config/config.go @@ -203,7 +203,7 @@ func DefaultConfig() Config { MinGasPrice: 0, Submission: SubmissionConfig{ GasPrice: 0, - MaxFee: 0, + MaxFee: 10_000_000_000, }, HaltEpoch: 0, HaltHeight: 0, diff --git a/go/consensus/cometbft/full/common.go b/go/consensus/cometbft/full/common.go index f380abe0894..d16952bbc97 100644 --- a/go/consensus/cometbft/full/common.go +++ b/go/consensus/cometbft/full/common.go @@ -23,6 +23,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/logging" "github.com/oasisprotocol/oasis-core/go/common/node" "github.com/oasisprotocol/oasis-core/go/common/pubsub" + "github.com/oasisprotocol/oasis-core/go/common/quantity" cmservice "github.com/oasisprotocol/oasis-core/go/common/service" "github.com/oasisprotocol/oasis-core/go/common/version" "github.com/oasisprotocol/oasis-core/go/config" @@ -43,6 +44,7 @@ import ( tmroothash "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/roothash" tmscheduler "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/scheduler" tmstaking "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/staking" + consensusGenesis "github.com/oasisprotocol/oasis-core/go/consensus/genesis" genesisAPI "github.com/oasisprotocol/oasis-core/go/genesis/api" governanceAPI "github.com/oasisprotocol/oasis-core/go/governance/api" keymanagerAPI "github.com/oasisprotocol/oasis-core/go/keymanager/api" @@ -340,6 +342,16 @@ func (n *commonNode) StateToGenesis(ctx context.Context, blockHeight int64) (*ge return nil, err } + // Query root consensus parameters. + cs, err := coreState.NewImmutableState(ctx, n.mux.State(), blockHeight) + if err != nil { + return nil, err + } + cp, err := cs.ConsensusParameters(ctx) + if err != nil { + return nil, err + } + // Call StateToGenesis on all backends and merge the results together. beaconGenesis, err := n.Beacon().StateToGenesis(ctx, blockHeight) if err != nil { @@ -387,7 +399,10 @@ func (n *commonNode) StateToGenesis(ctx context.Context, blockHeight int64) (*ge Governance: *governanceGenesis, KeyManager: *keymanagerGenesis, Scheduler: *schedulerGenesis, - Consensus: genesisDoc.Consensus, + Consensus: consensusGenesis.Genesis{ + Backend: api.BackendName, + Parameters: *cp, + }, }, nil } @@ -456,6 +471,19 @@ func (n *commonNode) EstimateGas(_ context.Context, req *consensusAPI.EstimateGa return n.mux.EstimateGas(req.Signer, req.Transaction) } +// Implements consensusAPI.Backend. +func (n *commonNode) MinGasPrice(ctx context.Context) (*quantity.Quantity, error) { + cs, err := coreState.NewImmutableState(ctx, n.mux.State(), consensusAPI.HeightLatest) + if err != nil { + return nil, err + } + cp, err := cs.ConsensusParameters(ctx) + if err != nil { + return nil, err + } + return quantity.NewFromUint64(cp.MinGasPrice), nil +} + // Implements consensusAPI.Backend. func (n *commonNode) Pruner() api.StatePruner { return n.mux.Pruner() diff --git a/go/consensus/cometbft/full/full.go b/go/consensus/cometbft/full/full.go index 320bc24a3fd..2b94e881d96 100644 --- a/go/consensus/cometbft/full/full.go +++ b/go/consensus/cometbft/full/full.go @@ -47,6 +47,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/db" lightAPI "github.com/oasisprotocol/oasis-core/go/consensus/cometbft/light/api" "github.com/oasisprotocol/oasis-core/go/consensus/metrics" + "github.com/oasisprotocol/oasis-core/go/consensus/pricediscovery" genesisAPI "github.com/oasisprotocol/oasis-core/go/genesis/api" cmflags "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/flags" cmmetrics "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common/metrics" @@ -943,12 +944,14 @@ func New( t.Logger.Info("starting a full consensus node") - // Create the submission manager. - pd, err := consensusAPI.NewStaticPriceDiscovery(config.GlobalConfig.Consensus.Submission.GasPrice) + // Create price discovery mechanism and the submission manager. + pd, err := pricediscovery.New(ctx, t, config.GlobalConfig.Consensus.Submission.GasPrice) if err != nil { - return nil, fmt.Errorf("cometbft: failed to create submission manager: %w", err) + return nil, fmt.Errorf("failed to create price discovery: %w", err) } - t.submissionMgr = consensusAPI.NewSubmissionManager(t, pd, config.GlobalConfig.Consensus.Submission.MaxFee) + t.submissionMgr = consensusAPI.NewSubmissionManager(t, pd, + config.GlobalConfig.Consensus.Submission.MaxFee, + ) if err := t.lazyInit(); err != nil { return nil, fmt.Errorf("lazy init: %w", err) diff --git a/go/consensus/genesis/genesis.go b/go/consensus/genesis/genesis.go index be58ac24df2..9b021508f45 100644 --- a/go/consensus/genesis/genesis.go +++ b/go/consensus/genesis/genesis.go @@ -27,6 +27,9 @@ type Parameters struct { // nolint: maligned MaxBlockGas transaction.Gas `json:"max_block_gas"` MaxEvidenceSize uint64 `json:"max_evidence_size"` + // MinGasPrice is the minimum gas price. + MinGasPrice uint64 `json:"min_gas_price,omitempty"` + // StateCheckpointInterval is the expected state checkpoint interval (in blocks). StateCheckpointInterval uint64 `json:"state_checkpoint_interval"` // StateCheckpointNumKept is the expected minimum number of state checkpoints to keep. diff --git a/go/consensus/pricediscovery/pricediscovery.go b/go/consensus/pricediscovery/pricediscovery.go new file mode 100644 index 00000000000..689c4602107 --- /dev/null +++ b/go/consensus/pricediscovery/pricediscovery.go @@ -0,0 +1,145 @@ +// Package pricediscovery implements gas price discovery. +package pricediscovery + +import ( + "context" + "fmt" + "sync" + + "github.com/oasisprotocol/oasis-core/go/common/logging" + "github.com/oasisprotocol/oasis-core/go/common/pubsub" + "github.com/oasisprotocol/oasis-core/go/common/quantity" + consensus "github.com/oasisprotocol/oasis-core/go/consensus/api" +) + +const ( + // defaultWindowSize is the default number of recent blocks to use for calculating min gas + // price. + // + // NOTE: Code assumes that this is relatively small. + windowSize int = 6 +) + +type priceDiscovery struct { + mu sync.RWMutex + + // finalGasPrice is protected by the mutex. + finalGasPrice *quantity.Quantity + + fallbackGasPrice *quantity.Quantity + minGasPrice *quantity.Quantity + computedGasPrice *quantity.Quantity + // blockPrices is a rolling-array containing minimum transaction prices for last up to + // `windowSize` blocks. + blockPrices []*quantity.Quantity + // tracks the current index of the blockPrices rolling array. + blockPricesCurrentIdx int + + client consensus.ClientBackend + + logger *logging.Logger +} + +// GasPrice implements consensus.PriceDiscovery. +func (pd *priceDiscovery) GasPrice() (*quantity.Quantity, error) { + pd.mu.RLock() + defer pd.mu.RUnlock() + + return pd.finalGasPrice, nil +} + +// refreshMinGasPrice refreshes minimum gas price reported by the consensus layer. +func (pd *priceDiscovery) refreshMinGasPrice(ctx context.Context) { + mgp, err := pd.client.MinGasPrice(ctx) + if err != nil { + pd.logger.Warn("failed to fetch minimum gas price", + "err", err, + ) + return + } + + pd.minGasPrice = mgp +} + +// processBlock computes the gas price based on transactions in a block. +func (pd *priceDiscovery) processBlock(_ context.Context, _ *consensus.Block) { + // Currently transactions are not ordered by price, so track price as zero. After the mempool + // is refactored, change this to properly compute the median gas price. Note that simply sorting + // transactions here wouldn't work as it wouldn't reflect the actual queuing process until the + // mempool is updated. + // + // We should also make sure to add some margin over the median in case of full blocks. + pd.trackPrice(quantity.NewQuantity()) +} + +// trackPrice records the price for a block. +func (pd *priceDiscovery) trackPrice(price *quantity.Quantity) { + pd.blockPrices[pd.blockPricesCurrentIdx] = price + pd.blockPricesCurrentIdx = (pd.blockPricesCurrentIdx + 1) % windowSize + + // Find maximum gas price. + maxPrice := quantity.NewFromUint64(0) + for _, price := range pd.blockPrices { + if price.Cmp(maxPrice) > 0 { + maxPrice = price + } + } + + // No full blocks among last `windowSize` blocks. + if maxPrice.IsZero() { + maxPrice = nil + } + pd.computedGasPrice = maxPrice +} + +func (pd *priceDiscovery) worker(ctx context.Context, ch <-chan *consensus.Block, sub pubsub.ClosableSubscription) { + defer sub.Close() + + for { + select { + case <-ctx.Done(): + return + case blk := <-ch: + pd.refreshMinGasPrice(ctx) + pd.processBlock(ctx, blk) + + // Choose the maximum of (fallback, min, computed) gas prices. + gasPrice := pd.fallbackGasPrice + if pd.computedGasPrice != nil && pd.computedGasPrice.Cmp(gasPrice) > 0 { + gasPrice = pd.computedGasPrice + } + if pd.minGasPrice.Cmp(gasPrice) > 0 { + gasPrice = pd.minGasPrice + } + + pd.mu.Lock() + pd.finalGasPrice = gasPrice.Clone() + pd.mu.Unlock() + } + } +} + +// New creates a new dynamic price discovery implementation. +func New(ctx context.Context, client consensus.ClientBackend, fallbackGasPrice uint64) (consensus.PriceDiscovery, error) { + pd := &priceDiscovery{ + fallbackGasPrice: quantity.NewFromUint64(fallbackGasPrice), + minGasPrice: quantity.NewQuantity(), + computedGasPrice: quantity.NewQuantity(), + client: client, + logger: logging.GetLogger("consensus/pricediscovery"), + } + + pd.blockPrices = make([]*quantity.Quantity, windowSize) + for i := range windowSize { + pd.blockPrices[i] = quantity.NewQuantity() + } + + // Subscribe to consensus layer blocks and start watching. + ch, sub, err := pd.client.WatchBlocks(ctx) + if err != nil { + return nil, fmt.Errorf("failed to subscribe to block updates: %w", err) + } + go pd.worker(ctx, ch, sub) + + return pd, nil +} diff --git a/go/consensus/pricediscovery/static.go b/go/consensus/pricediscovery/static.go new file mode 100644 index 00000000000..0f9a9947708 --- /dev/null +++ b/go/consensus/pricediscovery/static.go @@ -0,0 +1,26 @@ +package pricediscovery + +import ( + "fmt" + + "github.com/oasisprotocol/oasis-core/go/common/quantity" + consensus "github.com/oasisprotocol/oasis-core/go/consensus/api" +) + +type staticPriceDiscovery struct { + price quantity.Quantity +} + +// NewStatic creates a price discovery mechanism which always returns the same static price +// specified at construction time. +func NewStatic(price uint64) (consensus.PriceDiscovery, error) { + pd := &staticPriceDiscovery{} + if err := pd.price.FromUint64(price); err != nil { + return nil, fmt.Errorf("submission: failed to convert gas price: %w", err) + } + return pd, nil +} + +func (pd *staticPriceDiscovery) GasPrice() (*quantity.Quantity, error) { + return pd.price.Clone(), nil +} diff --git a/go/oasis-node/cmd/debug/txsource/txsource.go b/go/oasis-node/cmd/debug/txsource/txsource.go index 982f9c65da6..82836e835e5 100644 --- a/go/oasis-node/cmd/debug/txsource/txsource.go +++ b/go/oasis-node/cmd/debug/txsource/txsource.go @@ -19,6 +19,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/logging" "github.com/oasisprotocol/oasis-core/go/config" consensus "github.com/oasisprotocol/oasis-core/go/consensus/api" + "github.com/oasisprotocol/oasis-core/go/consensus/pricediscovery" "github.com/oasisprotocol/oasis-core/go/control/api" genesisFile "github.com/oasisprotocol/oasis-core/go/genesis/file" "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common" @@ -102,7 +103,7 @@ func doRun(cmd *cobra.Command, _ []string) error { // Set up the consensus client and submission manager. cnsc := consensus.NewConsensusClient(conn) - pd, err := consensus.NewStaticPriceDiscovery(viper.GetUint64(CfgGasPrice)) + pd, err := pricediscovery.NewStatic(viper.GetUint64(CfgGasPrice)) if err != nil { return fmt.Errorf("failed to create submission manager: %w", err) } diff --git a/go/oasis-node/cmd/debug/txsource/workload/oversized.go b/go/oasis-node/cmd/debug/txsource/workload/oversized.go index 8e91f082fdd..edb23193aba 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/oversized.go +++ b/go/oasis-node/cmd/debug/txsource/workload/oversized.go @@ -64,7 +64,7 @@ func (o *oversized) Run( return fmt.Errorf("failed to query consensus parameters: %w", err) } - gasPrice, err := sm.PriceDiscovery().GasPrice(ctx) + gasPrice, err := sm.PriceDiscovery().GasPrice() if err != nil { return fmt.Errorf("failed to get gas price: %w", err) } diff --git a/go/oasis-node/cmd/debug/txsource/workload/workload.go b/go/oasis-node/cmd/debug/txsource/workload/workload.go index 4740533c358..9e509c949ef 100644 --- a/go/oasis-node/cmd/debug/txsource/workload/workload.go +++ b/go/oasis-node/cmd/debug/txsource/workload/workload.go @@ -90,7 +90,7 @@ func (bw *BaseWorkload) Consensus() consensus.ClientBackend { // GasPrice returns the configured consensus gas price. func (bw *BaseWorkload) GasPrice() uint64 { // NOTE: This cannot fail as workloads use static price discovery. - gasPrice, _ := bw.sm.PriceDiscovery().GasPrice(context.Background()) + gasPrice, _ := bw.sm.PriceDiscovery().GasPrice() return gasPrice.ToBigInt().Uint64() } diff --git a/go/oasis-test-runner/scenario/e2e/upgrade.go b/go/oasis-test-runner/scenario/e2e/upgrade.go index 6e9247dba03..194cecabd8d 100644 --- a/go/oasis-test-runner/scenario/e2e/upgrade.go +++ b/go/oasis-test-runner/scenario/e2e/upgrade.go @@ -127,6 +127,18 @@ func (c *upgrade240Checker) PreUpgradeFn(ctx context.Context, ctrl *oasis.Contro return fmt.Errorf("proposal metadata is allowed") } + // Check root parameters. + rootParams, err := ctrl.Consensus.GetParameters(ctx, consensus.HeightLatest) + if err != nil { + return fmt.Errorf("can't get root consensus parameters: %w", err) + } + if rootParams.Parameters.MinGasPrice != 0 { + return fmt.Errorf("min gas price is non-zero") + } + if rootParams.Parameters.MaxBlockGas != 0 { + return fmt.Errorf("max block gas is non-zero") + } + return nil } @@ -192,6 +204,18 @@ func (c *upgrade240Checker) PostUpgradeFn(ctx context.Context, ctrl *oasis.Contr return fmt.Errorf("proposal metadata is not allowed") } + // Check updated root parameters. + rootParams, err := ctrl.Consensus.GetParameters(ctx, consensus.HeightLatest) + if err != nil { + return fmt.Errorf("can't get root consensus parameters: %w", err) + } + if rootParams.Parameters.MinGasPrice != 0 { + return fmt.Errorf("min gas price is non-zero") + } + if rootParams.Parameters.MaxBlockGas != 5_000_000 { + return fmt.Errorf("max block gas is incorrect") + } + return nil } diff --git a/go/upgrade/migrations/consensus_240.go b/go/upgrade/migrations/consensus_240.go index 438156a2c48..8ea512512d9 100644 --- a/go/upgrade/migrations/consensus_240.go +++ b/go/upgrade/migrations/consensus_240.go @@ -54,6 +54,7 @@ func (h *Handler240) ConsensusUpgrade(privateCtx interface{}) error { } consParams.MaxTxSize = 131072 // 32 KiB -> 128 KiB consParams.MaxBlockSize = 4194304 // 1 MiB -> 4 MiB + consParams.MaxBlockGas = 5_000_000 if err = consState.SetConsensusParameters(abciCtx, consParams); err != nil { return fmt.Errorf("failed to set consensus parameters: %w", err)