Commit d89b5005 authored by Mark Tyneway's avatar Mark Tyneway Committed by Kelvin Fichter

gas-oracle: update to set L1 base fee

The `gas-oracle` will now periodically ping L1 asking
for the latest header and will update the `l1BaseFee`
value in the `OVM_GasPriceOracle` oracle predeploy when
the base fee changes more than a configurable amount.

This is very similar to the way that the `gas-oracle` sets
the L2 gas price based on the amount of gas that has
been used in an amount of time.

Note that this is a breaking change when it comes to config.
Some config options are renamed and some config options are added.

`--ethereum-http-url` now corresponds to the L1 URL and
`--layer-two-http-url` corresponds to the L2 URL. Previously,
only an L2 URL was provided and it was called `--ethereum-http-url`.

Now there are flags for `--l1-chain-id` and `--l2-chain-id` when
previously `--chain-id` corresponded to the L2 chain id.

There are also now flags for turning on and off functionality.
`--enable-l1-base-fee` and `--enable-l2-gas-price` are used
to turn on updating of the corresponding values. They are on by
default.

The `--l1-base-fee-significant-factor` is expected to be a decimal
and determines how much the base fee on L1 must change before the
`gas-oracle` will consider updating the base fee by sending
a transaction to the `OVM_GasPriceOracle`.
parent 1b917041
---
'@eth-optimism/gas-oracle': minor
---
Add L1 base fee, add breaking config options
......@@ -9,6 +9,8 @@ LDFLAGSSTRING +=-X main.GitDate=$(GITDATE)
LDFLAGSSTRING +=-X main.GitVersion=$(GITVERSION)
LDFLAGS :=-ldflags "$(LDFLAGSSTRING)"
CONTRACTS_PATH := "../../packages/contracts/artifacts/contracts"
gas-oracle:
env GO111MODULE=on go build $(LDFLAGS)
......@@ -21,11 +23,16 @@ test:
lint:
golangci-lint run ./...
binding:
abi:
cat $(CONTRACTS_PATH)/L2/predeploys/OVM_GasPriceOracle.sol/OVM_GasPriceOracle.json \
| jq '{abi,bytecode}' \
> abis/OVM_GasPriceOracle.json
binding: abi
$(eval temp := $(shell mktemp))
cat abis/OVM_GasPriceOracle.json \
| jq -r .bin > $(temp)
| jq -r .bytecode > $(temp)
cat abis/OVM_GasPriceOracle.json \
| jq .abi \
......
This diff is collapsed.
This diff is collapsed.
......@@ -8,13 +8,24 @@ var (
EthereumHttpUrlFlag = cli.StringFlag{
Name: "ethereum-http-url",
Value: "http://127.0.0.1:8545",
Usage: "Sequencer HTTP Endpoint",
Usage: "L1 HTTP Endpoint",
EnvVar: "GAS_PRICE_ORACLE_ETHEREUM_HTTP_URL",
}
ChainIDFlag = cli.Uint64Flag{
Name: "chain-id",
LayerTwoHttpUrlFlag = cli.StringFlag{
Name: "layer-two-http-url",
Value: "http://127.0.0.1:9545",
Usage: "Sequencer HTTP Endpoint",
EnvVar: "GAS_PRICE_ORACLE_LAYER_TWO_HTTP_URL",
}
L1ChainIDFlag = cli.Uint64Flag{
Name: "l1-chain-id",
Usage: "L1 Chain ID",
EnvVar: "GAS_PRICE_ORACLE_L1_CHAIN_ID",
}
L2ChainIDFlag = cli.Uint64Flag{
Name: "l2-chain-id",
Usage: "L2 Chain ID",
EnvVar: "GAS_PRICE_ORACLE_CHAIN_ID",
EnvVar: "GAS_PRICE_ORACLE_L2_CHAIN_ID",
}
GasPriceOracleAddressFlag = cli.StringFlag{
Name: "gas-price-oracle-address",
......@@ -32,6 +43,16 @@ var (
Usage: "Hardcoded tx.gasPrice, not setting it uses gas estimation",
EnvVar: "GAS_PRICE_ORACLE_TRANSACTION_GAS_PRICE",
}
EnableL1BaseFeeFlag = cli.BoolFlag{
Name: "enable-l1-base-fee",
Usage: "Enable updating the L1 base fee",
EnvVar: "GAS_PRICE_ORACLE_ENABLE_L1_BASE_FEE",
}
EnableL2GasPriceFlag = cli.BoolFlag{
Name: "enable-l2-gas-price",
Usage: "Enable updating the L2 gas price",
EnvVar: "GAS_PRICE_ORACLE_ENABLE_L2_GAS_PRICE",
}
LogLevelFlag = cli.IntFlag{
Name: "loglevel",
Value: 3,
......@@ -68,7 +89,13 @@ var (
Usage: "length of epochs in seconds",
EnvVar: "GAS_PRICE_ORACLE_EPOCH_LENGTH_SECONDS",
}
SignificanceFactorFlag = cli.Float64Flag{
L1BaseFeeSignificanceFactorFlag = cli.Float64Flag{
Name: "l1-base-fee-significant-factor",
Value: 0.10,
Usage: "only update when the L1 base fee changes by more than this factor",
EnvVar: "GAS_PRICE_ORACLE_L1_BASE_FEE_SIGNIFICANT_FACTOR",
}
L2GasPriceSignificanceFactorFlag = cli.Float64Flag{
Name: "significant-factor",
Value: 0.05,
Usage: "only update when the gas price changes by more than this factor",
......@@ -129,7 +156,10 @@ var (
var Flags = []cli.Flag{
EthereumHttpUrlFlag,
ChainIDFlag,
LayerTwoHttpUrlFlag,
L1ChainIDFlag,
L2ChainIDFlag,
L1BaseFeeSignificanceFactorFlag,
GasPriceOracleAddressFlag,
PrivateKeyFlag,
TransactionGasPriceFlag,
......@@ -139,8 +169,10 @@ var Flags = []cli.Flag{
MaxPercentChangePerEpochFlag,
AverageBlockGasLimitPerEpochFlag,
EpochLengthSecondsFlag,
SignificanceFactorFlag,
L2GasPriceSignificanceFactorFlag,
WaitForReceiptFlag,
EnableL1BaseFeeFlag,
EnableL2GasPriceFlag,
MetricsEnabledFlag,
MetricsHTTPFlag,
MetricsPortFlag,
......
......@@ -3,7 +3,6 @@ module github.com/ethereum-optimism/optimism/go/gas-oracle
go 1.16
require (
github.com/ethereum/go-ethereum v1.10.4
github.com/ethereum/go-ethereum v1.10.8
github.com/urfave/cli v1.20.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
)
This diff is collapsed.
package oracle
import (
"context"
"fmt"
"github.com/ethereum-optimism/optimism/go/gas-oracle/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
)
func wrapUpdateBaseFee(l1Backend bind.ContractTransactor, l2Backend DeployContractBackend, cfg *Config) (func() error, error) {
if cfg.privateKey == nil {
return nil, errNoPrivateKey
}
if cfg.l2ChainID == nil {
return nil, errNoChainID
}
opts, err := bind.NewKeyedTransactorWithChainID(cfg.privateKey, cfg.l2ChainID)
if err != nil {
return nil, err
}
// Once https://github.com/ethereum/go-ethereum/pull/23062 is released
// then we can remove setting the context here
if opts.Context == nil {
opts.Context = context.Background()
}
// Don't send the transaction using the `contract` so that we can inspect
// it beforehand
opts.NoSend = true
// Create a new contract bindings in scope of the updateL2GasPriceFn
// that is returned from this function
contract, err := bindings.NewGasPriceOracle(cfg.gasPriceOracleAddress, l2Backend)
if err != nil {
return nil, err
}
return func() error {
baseFee, err := contract.L1BaseFee(&bind.CallOpts{
Context: context.Background(),
})
tip, err := l1Backend.HeaderByNumber(context.Background(), nil)
if err != nil {
return err
}
if tip.BaseFee == nil {
return errNoBaseFee
}
if !isDifferenceSignificant(baseFee.Uint64(), tip.BaseFee.Uint64(), cfg.l1BaseFeeSignificanceFactor) {
log.Debug("non significant base fee update", "tip", tip.BaseFee, "current", baseFee)
return nil
}
tx, err := contract.SetL1BaseFee(opts, tip.BaseFee)
if err != nil {
return err
}
log.Debug("updating L1 base fee", "tx.gasPrice", tx.GasPrice(), "tx.gasLimit", tx.Gas(),
"tx.data", hexutil.Encode(tx.Data()), "tx.to", tx.To().Hex(), "tx.nonce", tx.Nonce())
if err := l2Backend.SendTransaction(context.Background(), tx); err != nil {
return fmt.Errorf("cannot update base fee: %w", err)
}
log.Info("L1 base fee transaction sent", "hash", tx.Hash().Hex())
if cfg.waitForReceipt {
// Wait for the receipt
receipt, err := waitForReceipt(l2Backend, tx)
if err != nil {
return err
}
log.Info("base-fee transaction confirmed", "hash", tx.Hash().Hex(),
"gas-used", receipt.GasUsed, "blocknumber", receipt.BlockNumber)
}
return nil
}, nil
}
package oracle
import (
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/go/gas-oracle/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
func TestBaseFeeUpdate(t *testing.T) {
key, _ := crypto.GenerateKey()
sim, _ := newSimulatedBackend(key)
chain := sim.Blockchain()
opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
addr, _, gpo, err := bindings.DeployGasPriceOracle(opts, sim, opts.From)
if err != nil {
t.Fatal(err)
}
sim.Commit()
cfg := &Config{
privateKey: key,
l2ChainID: big.NewInt(1337),
gasPriceOracleAddress: addr,
gasPrice: big.NewInt(677228895),
}
update, err := wrapUpdateBaseFee(sim, sim, cfg)
if err != nil {
t.Fatal(err)
}
// Get the initial base fee
l1BaseFee, err := gpo.L1BaseFee(&bind.CallOpts{})
if err != nil {
t.Fatal(err)
}
// base fee should start at 0
if l1BaseFee.Cmp(common.Big0) != 0 {
t.Fatal("does not start at 0")
}
// get the header to know what the base fee
// should be updated to
tip := chain.CurrentHeader()
if tip.BaseFee == nil {
t.Fatal("no base fee found")
}
// Ensure that there is no false negative by
// checking that the values don't start out the same
if l1BaseFee.Cmp(tip.BaseFee) == 0 {
t.Fatal("values are already the same")
}
// Call the update function to do the update
if err := update(); err != nil {
t.Fatal("cannot update base fee")
}
sim.Commit()
// Check the updated base fee
l1BaseFee, err = gpo.L1BaseFee(&bind.CallOpts{})
if err != nil {
t.Fatal(err)
}
// the base fee should be equal to the value
// on the header
if tip.BaseFee.Cmp(l1BaseFee) != 0 {
t.Fatal("base fee not updated")
}
}
......@@ -15,8 +15,10 @@ import (
// Config represents the configuration options for the gas oracle
type Config struct {
chainID *big.Int
l1ChainID *big.Int
l2ChainID *big.Int
ethereumHttpUrl string
layerTwoHttpUrl string
gasPriceOracleAddress common.Address
privateKey *ecdsa.PrivateKey
gasPrice *big.Int
......@@ -26,7 +28,10 @@ type Config struct {
maxPercentChangePerEpoch float64
averageBlockGasLimitPerEpoch float64
epochLengthSeconds uint64
significanceFactor float64
l2GasPriceSignificanceFactor float64
l1BaseFeeSignificanceFactor float64
enableL1BaseFee bool
enableL2GasPrice bool
// Metrics config
MetricsEnabled bool
MetricsHTTP string
......@@ -42,14 +47,18 @@ type Config struct {
func NewConfig(ctx *cli.Context) *Config {
cfg := Config{}
cfg.ethereumHttpUrl = ctx.GlobalString(flags.EthereumHttpUrlFlag.Name)
cfg.layerTwoHttpUrl = ctx.GlobalString(flags.LayerTwoHttpUrlFlag.Name)
addr := ctx.GlobalString(flags.GasPriceOracleAddressFlag.Name)
cfg.gasPriceOracleAddress = common.HexToAddress(addr)
cfg.targetGasPerSecond = ctx.GlobalUint64(flags.TargetGasPerSecondFlag.Name)
cfg.maxPercentChangePerEpoch = ctx.GlobalFloat64(flags.MaxPercentChangePerEpochFlag.Name)
cfg.averageBlockGasLimitPerEpoch = ctx.GlobalFloat64(flags.AverageBlockGasLimitPerEpochFlag.Name)
cfg.epochLengthSeconds = ctx.GlobalUint64(flags.EpochLengthSecondsFlag.Name)
cfg.significanceFactor = ctx.GlobalFloat64(flags.SignificanceFactorFlag.Name)
cfg.l2GasPriceSignificanceFactor = ctx.GlobalFloat64(flags.L2GasPriceSignificanceFactorFlag.Name)
cfg.floorPrice = ctx.GlobalUint64(flags.FloorPriceFlag.Name)
cfg.l1BaseFeeSignificanceFactor = ctx.GlobalFloat64(flags.L1BaseFeeSignificanceFactorFlag.Name)
cfg.enableL1BaseFee = ctx.GlobalBool(flags.EnableL1BaseFeeFlag.Name)
cfg.enableL2GasPrice = ctx.GlobalBool(flags.EnableL2GasPriceFlag.Name)
if ctx.GlobalIsSet(flags.PrivateKeyFlag.Name) {
hex := ctx.GlobalString(flags.PrivateKeyFlag.Name)
......@@ -63,9 +72,13 @@ func NewConfig(ctx *cli.Context) *Config {
log.Crit("No private key configured")
}
if ctx.GlobalIsSet(flags.ChainIDFlag.Name) {
chainID := ctx.GlobalUint64(flags.ChainIDFlag.Name)
cfg.chainID = new(big.Int).SetUint64(chainID)
if ctx.GlobalIsSet(flags.L1ChainIDFlag.Name) {
chainID := ctx.GlobalUint64(flags.L1ChainIDFlag.Name)
cfg.l1ChainID = new(big.Int).SetUint64(chainID)
}
if ctx.GlobalIsSet(flags.L2ChainIDFlag.Name) {
chainID := ctx.GlobalUint64(flags.L2ChainIDFlag.Name)
cfg.l2ChainID = new(big.Int).SetUint64(chainID)
}
if ctx.GlobalIsSet(flags.TransactionGasPriceFlag.Name) {
......
......@@ -16,44 +16,52 @@ import (
"github.com/ethereum/go-ethereum/log"
)
// errInvalidSigningKey represents the error when the signing key used
// is not the Owner of the contract and therefore cannot update the gasprice
var errInvalidSigningKey = errors.New("invalid signing key")
// errNoChainID represents the error when the chain id is not provided
// and it cannot be remotely fetched
var errNoChainID = errors.New("no chain id provided")
// errNoPrivateKey represents the error when the private key is not provided to
// the application
var errNoPrivateKey = errors.New("no private key provided")
// errWrongChainID represents the error when the configured chain id is not
// correct
var errWrongChainID = errors.New("wrong chain id provided")
var (
// errInvalidSigningKey represents the error when the signing key used
// is not the Owner of the contract and therefore cannot update the gasprice
errInvalidSigningKey = errors.New("invalid signing key")
// errNoChainID represents the error when the chain id is not provided
// and it cannot be remotely fetched
errNoChainID = errors.New("no chain id provided")
// errNoPrivateKey represents the error when the private key is not provided to
// the application
errNoPrivateKey = errors.New("no private key provided")
// errWrongChainID represents the error when the configured chain id is not
// correct
errWrongChainID = errors.New("wrong chain id provided")
// errNoBaseFee represents the error when the base fee is not found on the
// block. This means that the block being queried is pre eip1559
errNoBaseFee = errors.New("base fee not found on block")
)
// GasPriceOracle manages a hot key that can update the L2 Gas Price
type GasPriceOracle struct {
chainID *big.Int
l1ChainID *big.Int
l2ChainID *big.Int
ctx context.Context
stop chan struct{}
contract *bindings.GasPriceOracle
backend DeployContractBackend
l2Backend DeployContractBackend
l1Backend bind.ContractTransactor
gasPriceUpdater *gasprices.GasPriceUpdater
config *Config
}
// Start runs the GasPriceOracle
func (g *GasPriceOracle) Start() error {
if g.config.chainID == nil {
return errNoChainID
if g.config.l1ChainID == nil {
return fmt.Errorf("layer-one: %w", errNoChainID)
}
if g.config.l2ChainID == nil {
return fmt.Errorf("layer-two: %w", errNoChainID)
}
if g.config.privateKey == nil {
return errNoPrivateKey
}
address := crypto.PubkeyToAddress(g.config.privateKey.PublicKey)
log.Info("Starting Gas Price Oracle", "chain-id", g.chainID, "address", address.Hex())
log.Info("Starting Gas Price Oracle", "l1-chain-id", g.l1ChainID,
"l2-chain-id", g.l2ChainID, "address", address.Hex())
price, err := g.contract.GasPrice(&bind.CallOpts{
Context: context.Background(),
......@@ -63,7 +71,12 @@ func (g *GasPriceOracle) Start() error {
}
gasPriceGauge.Update(int64(price.Uint64()))
go g.Loop()
if g.config.enableL1BaseFee {
go g.BaseFeeLoop()
}
if g.config.enableL2GasPrice {
go g.Loop()
}
return nil
}
......@@ -97,6 +110,7 @@ func (g *GasPriceOracle) ensure() error {
// Loop is the main logic of the gas-oracle
func (g *GasPriceOracle) Loop() {
timer := time.NewTicker(time.Duration(g.config.epochLengthSeconds) * time.Second)
defer timer.Stop()
for {
select {
case <-timer.C:
......@@ -111,6 +125,28 @@ func (g *GasPriceOracle) Loop() {
}
}
func (g *GasPriceOracle) BaseFeeLoop() {
timer := time.NewTicker(15 * time.Second)
defer timer.Stop()
updateBaseFee, err := wrapUpdateBaseFee(g.l1Backend, g.l2Backend, g.config)
if err != nil {
panic(err)
}
for {
select {
case <-timer.C:
if err := updateBaseFee(); err != nil {
log.Error("cannot update l1 base fee", "messgae", err)
}
case <-g.ctx.Done():
g.Stop()
}
}
}
// Update will update the gas price
func (g *GasPriceOracle) Update() error {
l2GasPrice, err := g.contract.GasPrice(&bind.CallOpts{
......@@ -138,24 +174,27 @@ func (g *GasPriceOracle) Update() error {
// NewGasPriceOracle creates a new GasPriceOracle based on a Config
func NewGasPriceOracle(cfg *Config) (*GasPriceOracle, error) {
client, err := ethclient.Dial(cfg.ethereumHttpUrl)
// Create the L2 client
l2Client, err := ethclient.Dial(cfg.layerTwoHttpUrl)
if err != nil {
return nil, err
}
// Ensure that we can actually connect
t := time.NewTicker(5 * time.Second)
for ; true; <-t.C {
_, err := client.ChainID(context.Background())
if err == nil {
t.Stop()
break
}
log.Error("Unable to connect to remote node", "addr", cfg.ethereumHttpUrl)
l1Client, err := ethclient.Dial(cfg.ethereumHttpUrl)
if err != nil {
return nil, err
}
// Ensure that we can actually connect to both backends
if err := ensureConnection(l2Client); err != nil {
log.Error("Unable to connect to layer two", "addr", cfg.layerTwoHttpUrl)
}
if err := ensureConnection(l1Client); err != nil {
log.Error("Unable to connect to layer one", "addr", cfg.ethereumHttpUrl)
}
address := cfg.gasPriceOracleAddress
contract, err := bindings.NewGasPriceOracle(address, client)
contract, err := bindings.NewGasPriceOracle(address, l2Client)
if err != nil {
return nil, err
}
......@@ -185,26 +224,38 @@ func NewGasPriceOracle(cfg *Config) (*GasPriceOracle, error) {
return nil, err
}
chainID, err := client.ChainID(context.Background())
l2ChainID, err := l2Client.ChainID(context.Background())
if err != nil {
return nil, err
}
l1ChainID, err := l1Client.ChainID(context.Background())
if err != nil {
return nil, err
}
if cfg.l2ChainID != nil {
if cfg.l2ChainID.Cmp(l2ChainID) != 0 {
return nil, fmt.Errorf("%w: L2: configured with %d and got %d",
errWrongChainID, cfg.l2ChainID, l2ChainID)
}
} else {
cfg.l2ChainID = l2ChainID
}
// If the chainid is passed in, exit if the chain id is
// not correct
if cfg.chainID != nil {
if cfg.chainID.Cmp(chainID) != 0 {
return nil, fmt.Errorf("%w: configured with %d and got %d", errWrongChainID, cfg.chainID, chainID)
if cfg.l1ChainID != nil {
if cfg.l1ChainID.Cmp(l1ChainID) != 0 {
return nil, fmt.Errorf("%w: L1: configured with %d and got %d",
errWrongChainID, cfg.l1ChainID, l1ChainID)
}
} else {
cfg.chainID = chainID
cfg.l1ChainID = l1ChainID
}
if cfg.privateKey == nil {
return nil, errNoPrivateKey
}
tip, err := client.HeaderByNumber(context.Background(), nil)
tip, err := l2Client.HeaderByNumber(context.Background(), nil)
if err != nil {
return nil, err
}
......@@ -213,10 +264,10 @@ func NewGasPriceOracle(cfg *Config) (*GasPriceOracle, error) {
epochStartBlockNumber := tip.Number.Uint64()
// getLatestBlockNumberFn is used by the GasPriceUpdater
// to get the latest block number
getLatestBlockNumberFn := wrapGetLatestBlockNumberFn(client)
getLatestBlockNumberFn := wrapGetLatestBlockNumberFn(l2Client)
// updateL2GasPriceFn is used by the GasPriceUpdater to
// update the gas price
updateL2GasPriceFn, err := wrapUpdateL2GasPriceFn(client, cfg)
updateL2GasPriceFn, err := wrapUpdateL2GasPriceFn(l2Client, cfg)
if err != nil {
return nil, err
}
......@@ -239,13 +290,15 @@ func NewGasPriceOracle(cfg *Config) (*GasPriceOracle, error) {
}
gpo := GasPriceOracle{
chainID: chainID,
l2ChainID: l2ChainID,
l1ChainID: l1ChainID,
ctx: context.Background(),
stop: make(chan struct{}),
contract: contract,
gasPriceUpdater: gasPriceUpdater,
config: cfg,
backend: client,
l2Backend: l2Client,
l1Backend: l1Client,
}
if err := gpo.ensure(); err != nil {
......@@ -254,3 +307,18 @@ func NewGasPriceOracle(cfg *Config) (*GasPriceOracle, error) {
return &gpo, nil
}
// Ensure that we can actually connect
func ensureConnection(client *ethclient.Client) error {
t := time.NewTicker(5 * time.Second)
defer t.Stop()
for ; true; <-t.C {
_, err := client.ChainID(context.Background())
if err == nil {
t.Stop()
break
}
return err
}
return nil
}
......@@ -53,11 +53,11 @@ func wrapUpdateL2GasPriceFn(backend DeployContractBackend, cfg *Config) (func(ui
if cfg.privateKey == nil {
return nil, errNoPrivateKey
}
if cfg.chainID == nil {
if cfg.l2ChainID == nil {
return nil, errNoChainID
}
opts, err := bind.NewKeyedTransactorWithChainID(cfg.privateKey, cfg.chainID)
opts, err := bind.NewKeyedTransactorWithChainID(cfg.privateKey, cfg.l2ChainID)
if err != nil {
return nil, err
}
......@@ -111,8 +111,8 @@ func wrapUpdateL2GasPriceFn(backend DeployContractBackend, cfg *Config) (func(ui
// Only update the gas price when it must be changed by at least
// a paramaterizable amount.
if !isDifferenceSignificant(currentPrice.Uint64(), updatedGasPrice, cfg.significanceFactor) {
log.Info("gas price did not significantly change", "min-factor", cfg.significanceFactor,
if !isDifferenceSignificant(currentPrice.Uint64(), updatedGasPrice, cfg.l2GasPriceSignificanceFactor) {
log.Info("gas price did not significantly change", "min-factor", cfg.l2GasPriceSignificanceFactor,
"current-price", currentPrice, "next-price", updatedGasPrice)
txNotSignificantCounter.Inc(1)
return nil
......@@ -124,14 +124,14 @@ func wrapUpdateL2GasPriceFn(backend DeployContractBackend, cfg *Config) (func(ui
return err
}
log.Debug("sending transaction", "tx.gasPrice", tx.GasPrice(), "tx.gasLimit", tx.Gas(),
log.Debug("updating L2 gas price", "tx.gasPrice", tx.GasPrice(), "tx.gasLimit", tx.Gas(),
"tx.data", hexutil.Encode(tx.Data()), "tx.to", tx.To().Hex(), "tx.nonce", tx.Nonce())
pre := time.Now()
if err := backend.SendTransaction(context.Background(), tx); err != nil {
return err
}
txSendTimer.Update(time.Since(pre))
log.Info("transaction sent", "hash", tx.Hash().Hex())
log.Info("L2 gas price transaction sent", "hash", tx.Hash().Hex())
gasPriceGauge.Update(int64(updatedGasPrice))
txSendCounter.Inc(1)
......@@ -146,7 +146,7 @@ func wrapUpdateL2GasPriceFn(backend DeployContractBackend, cfg *Config) (func(ui
}
txConfTimer.Update(time.Since(pre))
log.Info("transaction confirmed", "hash", tx.Hash().Hex(),
log.Info("L2 gas price transaction confirmed", "hash", tx.Hash().Hex(),
"gas-used", receipt.GasUsed, "blocknumber", receipt.BlockNumber)
}
return nil
......
......@@ -56,7 +56,7 @@ func TestWrapUpdateL2GasPriceFn(t *testing.T) {
sim, _ := newSimulatedBackend(key)
opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
addr, _, gpo, err := bindings.DeployGasPriceOracle(opts, sim, opts.From, big.NewInt(0))
addr, _, gpo, err := bindings.DeployGasPriceOracle(opts, sim, opts.From)
if err != nil {
t.Fatal(err)
}
......@@ -64,9 +64,9 @@ func TestWrapUpdateL2GasPriceFn(t *testing.T) {
cfg := &Config{
privateKey: key,
chainID: big.NewInt(1337),
l2ChainID: big.NewInt(1337),
gasPriceOracleAddress: addr,
gasPrice: big.NewInt(676167759),
gasPrice: big.NewInt(783460975),
}
updateL2GasPriceFn, err := wrapUpdateL2GasPriceFn(sim, cfg)
......@@ -96,7 +96,7 @@ func TestWrapUpdateL2GasPriceFnNoUpdates(t *testing.T) {
opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
// Deploy the contract
addr, _, gpo, err := bindings.DeployGasPriceOracle(opts, sim, opts.From, big.NewInt(0))
addr, _, gpo, err := bindings.DeployGasPriceOracle(opts, sim, opts.From)
if err != nil {
t.Fatal(err)
}
......@@ -104,11 +104,11 @@ func TestWrapUpdateL2GasPriceFnNoUpdates(t *testing.T) {
cfg := &Config{
privateKey: key,
chainID: big.NewInt(1337),
l2ChainID: big.NewInt(1337),
gasPriceOracleAddress: addr,
gasPrice: big.NewInt(772763153),
// the new gas price must change be 50% for it to actually update
significanceFactor: 0.5,
l2GasPriceSignificanceFactor: 0.5,
}
updateL2GasPriceFn, err := wrapUpdateL2GasPriceFn(sim, cfg)
if err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment