Commit 06d06428 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

indexer: Pad gas estimates (#9329)

* indexer: Pad gas estimates

Indexer tests flake fairly often due to out of gas errors. Case in point below, from a recent test run. This PR updates the indexer tests to pad gas estimates by 20%. This technique is used elsewhere in the indexer E2E tests, but wasn't being applied consistently.

```json
{
  "from": "0x15d34aaf54267db7d7c367839aaf71a00a2c6a65",
  "gas": "0x1f3cc",
  "gasUsed": "0x1edb1",
  "to": "0x978e3286eb805934215a88694d80b09aded68d90",
  "input": "0x",
  "error": "execution reverted",
  "calls": [
    {
      "from": "0x978e3286eb805934215a88694d80b09aded68d90",
      "gas": "0x1889b",
      "gasUsed": "0x1889b",
      "to": "0x8887e7568e81405c4e0d4caaabdda949e3b9d4e4",
      "input": "0x",
      "error": "out of gas",
      "calls": [
        {
          "from": "0x978e3286eb805934215a88694d80b09aded68d90",
          "gas": "0x15560",
          "gasUsed": "0x1f37",
          "to": "0x1c23a6d89f95ef3148bcda8e242cab145bf9c0e4",
          "input": "0xcc731b02",
          "output": "0x0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff",
          "calls": [
            {
              "from": "0x1c23a6d89f95ef3148bcda8e242cab145bf9c0e4",
              "gas": "0x13d07",
              "gasUsed": "0xba8",
              "to": "0xffba8944650e26653823658d76a122946f27e2f2",
              "input": "0xcc731b02",
              "output": "0x0000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000ffffffffffffffffffffffffffffffff",
              "value": "0x0",
              "type": "DELEGATECALL"
            }
          ],
          "type": "STATICCALL"
        }
      ],
      "value": "0xde0b6b3a7640000",
      "type": "DELEGATECALL"
    }
  ],
  "value": "0xde0b6b3a7640000",
  "type": "CALL"
}
```

* Update indexer/e2e_tests/bridge_transactions_e2e_test.go
Co-authored-by: default avatarrefcell <abigger87@gmail.com>

---------
Co-authored-by: default avatarrefcell <abigger87@gmail.com>
parent 0ea5e0b9
......@@ -6,6 +6,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
......@@ -34,7 +36,9 @@ func TestE2EBridgeL1CrossDomainMessenger(t *testing.T) {
l1Opts.Value = big.NewInt(params.Ether)
// (1) Send the Message
sentMsgTx, err := l1CrossDomainMessenger.SendMessage(l1Opts, aliceAddr, calldata, 100_000)
sentMsgTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l1CrossDomainMessenger.SendMessage(opts, aliceAddr, calldata, 100_000)
})
require.NoError(t, err)
sentMsgReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, sentMsgTx.Hash())
require.NoError(t, err)
......@@ -113,7 +117,9 @@ func TestE2EBridgeL2CrossDomainMessenger(t *testing.T) {
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
require.NoError(t, err)
l1Opts.Value = l2Opts.Value
depositTx, err := optimismPortal.Receive(l1Opts)
depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.Receive(opts)
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
......@@ -124,7 +130,9 @@ func TestE2EBridgeL2CrossDomainMessenger(t *testing.T) {
require.NoError(t, err)
// (1) Send the Message
sentMsgTx, err := l2CrossDomainMessenger.SendMessage(l2Opts, aliceAddr, calldata, 100_000)
sentMsgTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2CrossDomainMessenger.SendMessage(opts, aliceAddr, calldata, 100_000)
})
require.NoError(t, err)
sentMsgReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, sentMsgTx.Hash())
require.NoError(t, err)
......
......@@ -6,6 +6,8 @@ import (
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
......@@ -37,7 +39,9 @@ func TestE2EBridgeTransactionsOptimismPortalDeposits(t *testing.T) {
// In the same deposit transaction, transfer, 0.5ETH to Bob. We do this to ensure we're only indexing
// bridged funds from the source address versus any transferred value to a recipient in the same L2 transaction
depositTx, err := optimismPortal.DepositTransaction(l1Opts, bobAddr, big.NewInt(params.Ether/2), 100_000, false, calldata)
depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.DepositTransaction(opts, bobAddr, big.NewInt(params.Ether/2), 100_000, false, calldata)
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
......@@ -92,7 +96,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserWithdrawal(t *testing.T) {
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
require.NoError(t, err)
l1Opts.Value = l2Opts.Value
depositTx, err := optimismPortal.Receive(l1Opts)
depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.Receive(opts)
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
......@@ -102,7 +108,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserWithdrawal(t *testing.T) {
_, err = wait.ForReceiptOK(context.Background(), testSuite.L2Client, depositL2TxHash)
require.NoError(t, err)
withdrawTx, err := l2ToL1MessagePasser.InitiateWithdrawal(l2Opts, aliceAddr, big.NewInt(100_000), calldata)
withdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2ToL1MessagePasser.InitiateWithdrawal(opts, aliceAddr, big.NewInt(100_000), calldata)
})
require.NoError(t, err)
withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash())
require.NoError(t, err)
......@@ -186,7 +194,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserFailedWithdrawal(t *testing.T)
require.NoError(t, err)
l2Opts.Value = big.NewInt(params.Ether)
withdrawTx, err := l2ToL1MessagePasser.InitiateWithdrawal(l2Opts, aliceAddr, big.NewInt(100_000), nil)
withdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2ToL1MessagePasser.InitiateWithdrawal(opts, aliceAddr, big.NewInt(100_000), nil)
})
require.NoError(t, err)
withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash())
require.NoError(t, err)
......
......@@ -38,7 +38,9 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) {
l1Opts.Value = big.NewInt(params.Ether)
// (1) Test Deposit Initiation
depositTx, err := l1StandardBridge.DepositETH(l1Opts, 200_000, []byte{byte(1)})
depositTx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l1StandardBridge.DepositETH(opts, 200_000, []byte{byte(1)})
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
......@@ -105,7 +107,9 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) {
l1Opts.Value = big.NewInt(params.Ether)
// (1) Test Deposit Initiation
portalDepositTx, err := optimismPortal.Receive(l1Opts)
portalDepositTx, err := transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.Receive(opts)
})
require.NoError(t, err)
portalDepositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, portalDepositTx.Hash())
require.NoError(t, err)
......@@ -238,7 +242,9 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) {
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
require.NoError(t, err)
l1Opts.Value = l2Opts.Value
depositTx, err := optimismPortal.Receive(l1Opts)
depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.Receive(opts)
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
......@@ -249,7 +255,9 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) {
require.NoError(t, err)
// (1) Test Withdrawal Initiation
withdrawTx, err := l2StandardBridge.Withdraw(l2Opts, predeploys.LegacyERC20ETHAddr, l2Opts.Value, 200_000, []byte{byte(1)})
withdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2StandardBridge.Withdraw(opts, predeploys.LegacyERC20ETHAddr, l2Opts.Value, 200_000, []byte{byte(1)})
})
require.NoError(t, err)
withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash())
require.NoError(t, err)
......@@ -327,7 +335,9 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) {
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
require.NoError(t, err)
l1Opts.Value = l2Opts.Value
depositTx, err := optimismPortal.Receive(l1Opts)
depositTx, err := transactions.PadGasEstimate(l1Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.Receive(opts)
})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
......@@ -338,7 +348,9 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) {
require.NoError(t, err)
// (1) Test Withdrawal Initiation
l2ToL1MessagePasserWithdrawTx, err := l2ToL1MessagePasser.Receive(l2Opts)
l2ToL1MessagePasserWithdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.2, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2ToL1MessagePasser.Receive(opts)
})
require.NoError(t, err)
l2ToL1WithdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, l2ToL1MessagePasserWithdrawTx.Hash())
require.NoError(t, err)
......@@ -532,7 +544,9 @@ func TestClientBridgeFunctions(t *testing.T) {
mintSum = new(big.Int).Add(mintSum, depositTx.Value())
// (3.b) Initiate withdrawal transaction via L2ToL1MessagePasser contract
l2ToL1MessagePasserWithdrawTx, err := l2ToL1MessagePasser.Receive(l2Opts)
l2ToL1MessagePasserWithdrawTx, err := transactions.PadGasEstimate(l2Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2ToL1MessagePasser.Receive(opts)
})
require.NoError(t, err)
l2ToL1WithdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, l2ToL1MessagePasserWithdrawTx.Hash())
require.NoError(t, err)
......
......@@ -17,14 +17,15 @@ type TxBuilder func(opts *bind.TransactOpts) (*types.Transaction, error)
// 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
oCopy := *opts
o := &oCopy
o.NoSend = true
tx, err := builder(&o)
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)
return builder(o)
}
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