Commit 5acf69c0 authored by Adrian Sutton's avatar Adrian Sutton

op-e2e: Extract helper for sending transactions with padded gas limit

parent f622695a
...@@ -15,12 +15,14 @@ import ( ...@@ -15,12 +15,14 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/fault/alphabet" "github.com/ethereum-optimism/optimism/op-challenger/fault/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/fault/cannon" "github.com/ethereum-optimism/optimism/op-challenger/fault/cannon"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -106,14 +108,9 @@ func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet s ...@@ -106,14 +108,9 @@ func (h *FactoryHelper) StartAlphabetGame(ctx context.Context, claimedAlphabet s
extraData := make([]byte, 64) extraData := make([]byte, 64)
binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber) binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber)
binary.BigEndian.PutUint64(extraData[56:], l1Head.Uint64()) binary.BigEndian.PutUint64(extraData[56:], l1Head.Uint64())
h.opts.NoSend = true tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
tx, err := h.factory.Create(h.opts, alphabetGameType, rootClaim, extraData) return h.factory.Create(opts, alphabetGameType, rootClaim, extraData)
h.require.NoError(err, "create fault dispute game (estimate gas)") })
// Now send with increased gas. This provides a buffer if the output oracle search is now more expensive
h.opts.NoSend = false
h.opts.GasLimit = tx.Gas() * 2
tx, err = h.factory.Create(h.opts, alphabetGameType, rootClaim, extraData)
h.require.NoError(err, "create fault dispute game") h.require.NoError(err, "create fault dispute game")
h.opts.GasLimit = 0 h.opts.GasLimit = 0
rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash()) rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash())
...@@ -199,16 +196,10 @@ func (h *FactoryHelper) createCannonGame(ctx context.Context, l2BlockNumber uint ...@@ -199,16 +196,10 @@ func (h *FactoryHelper) createCannonGame(ctx context.Context, l2BlockNumber uint
extraData := make([]byte, 64) extraData := make([]byte, 64)
binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber) binary.BigEndian.PutUint64(extraData[24:], l2BlockNumber)
binary.BigEndian.PutUint64(extraData[56:], l1Head.Uint64()) binary.BigEndian.PutUint64(extraData[56:], l1Head.Uint64())
h.opts.NoSend = true tx, err := transactions.PadGasEstimate(h.opts, 2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
tx, err := h.factory.Create(h.opts, cannonGameType, rootClaim, extraData) return h.factory.Create(opts, cannonGameType, rootClaim, extraData)
h.require.NoError(err, "create fault dispute game (estimate gas)") })
// Now send with increased gas. This provides a buffer if the output oracle search is now more expensive
h.opts.NoSend = false
h.opts.GasLimit = tx.Gas() * 2
tx, err = h.factory.Create(h.opts, cannonGameType, rootClaim, extraData)
h.require.NoError(err, "create fault dispute game") h.require.NoError(err, "create fault dispute game")
h.opts.GasLimit = 0
rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash()) rcpt, err := wait.ForReceiptOK(ctx, h.client, tx.Hash())
h.require.NoError(err, "wait for create fault dispute game receipt to be OK") h.require.NoError(err, "wait for create fault dispute game receipt to be OK")
h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event") h.require.Len(rcpt.Logs, 1, "should have emitted a single DisputeGameCreated event")
......
package transactions
import (
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
)
// TxBuilder creates and sends a transaction using the supplied bind.TransactOpts.
// Returns the created transaction and any error reported.
type TxBuilder func(opts *bind.TransactOpts) (*types.Transaction, error)
// PadGasEstimate multiplies the gas estimate for a transaction by the specified paddingFactor before sending the
// actual transaction. Useful for cases where the gas required is variable.
// The builder will be invoked twice, first with NoSend=true to estimate the gas and the second time with
// NoSend=false and GasLimit including the requested padding.
func PadGasEstimate(opts *bind.TransactOpts, paddingFactor float64, builder TxBuilder) (*types.Transaction, error) {
// Take a copy of the opts to avoid mutating the original
o := *opts
o.NoSend = true
tx, err := builder(&o)
if err != nil {
return nil, fmt.Errorf("failed to estimate gas: %w", err)
}
gas := float64(tx.Gas()) * paddingFactor
o.GasLimit = uint64(gas)
o.NoSend = false
return builder(&o)
}
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive" "github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
...@@ -29,19 +30,12 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l ...@@ -29,19 +30,12 @@ func SendDepositTx(t *testing.T, cfg SystemConfig, l1Client *ethclient.Client, l
require.Nil(t, err) require.Nil(t, err)
// Finally send TX // Finally send TX
l1Opts.NoSend = true
tx, err := depositContract.DepositTransaction(l1Opts, l2Opts.ToAddr, l2Opts.Value, l2Opts.GasLimit, l2Opts.IsCreation, l2Opts.Data)
require.Nil(t, err, "with deposit tx")
l1Opts.NoSend = false
// Add 10% padding for the L1 gas limit because the estimation process can be affected by the 1559 style cost scale // Add 10% padding for the L1 gas limit because the estimation process can be affected by the 1559 style cost scale
// for buying L2 gas in the portal contracts. // for buying L2 gas in the portal contracts.
l1Opts.GasLimit = tx.Gas() + (tx.Gas() / 10) tx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return depositContract.DepositTransaction(opts, l2Opts.ToAddr, l2Opts.Value, l2Opts.GasLimit, l2Opts.IsCreation, l2Opts.Data)
// Now resend with gas specified })
tx, err = depositContract.DepositTransaction(l1Opts, l2Opts.ToAddr, l2Opts.Value, l2Opts.GasLimit, l2Opts.IsCreation, l2Opts.Data)
require.Nil(t, err, "with deposit tx") require.Nil(t, err, "with deposit tx")
l1Opts.GasLimit = 0
// Wait for transaction on L1 // Wait for transaction on L1
receipt, err := waitForTransaction(tx.Hash(), l1Client, 10*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second) receipt, err := waitForTransaction(tx.Hash(), l1Client, 10*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
......
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