Skip to content

Commit

Permalink
Better fix for underestimated gas
Browse files Browse the repository at this point in the history
  • Loading branch information
slundqui committed Oct 10, 2024
1 parent 2b07eaa commit 469ed4d
Showing 1 changed file with 4 additions and 41 deletions.
45 changes: 4 additions & 41 deletions src/agent0/ethpy/base/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,50 +340,13 @@ def build_transaction(
if txn_options_gas is not None:
transaction_kwargs["gas"] = txn_options_gas
else:
# TODO web3 estimate gas getting called is throwing weird errors,
# so we explicitly set gas to a large number to avoid estimating gas
# within web3, and set it ourselves after building transaction.
# A better solution here is to avoid `build_transaction` altogether
# and instead encode the `data` field via `contract_instance.encodeABI(...)`.
transaction_kwargs["gas"] = int(1e9)
# TODO web3 estimate gas is underestimating gas, likely due not
# looking at the pending block within web3py. Hence, we explicitly
# estimate gas with `pending` to solve.
transaction_kwargs["gas"] = func_handle.estimate_gas(transaction_kwargs, block_identifier="pending")

raw_txn = func_handle.build_transaction(TxParams(transaction_kwargs))

if txn_options_gas is None:
# Type narrowing, we expect all of these fields to exist after building transaction
assert "from" in raw_txn
assert "to" in raw_txn
assert "value" in raw_txn
assert "data" in raw_txn
# TODO new web3 version gas estimation seems to underestimate gas.
# We explicitly do an rpc call to estimate gas here to get an accurate gas estimate.
# RPC call to estimate gas

result = web3.provider.make_request(
method=RPCEndpoint("eth_estimateGas"),
params=[
{
"from": str(raw_txn["from"]),
"to": str(raw_txn["to"]),
# Convert integer to hex string
"value": hex(raw_txn["value"]),
"data": str(raw_txn["data"]),
}
],
)
if "result" not in result:
# We do error handling here in case the underlying rpc call fails
# due to a custom error getting thrown
if "error" in result and "data" in result["error"]:
data = result["error"]["data"] # type: ignore
# We emulate web3py by throwing a contract custom error here.
raise ContractCustomError(data, data=data)
# Otherwise, we raise value error with the result.
raise ValueError(f"Failed to estimate gas via RPC call: {result}")
# Hex to int
gas = int(result["result"], 0)
raw_txn["gas"] = gas

return raw_txn


Expand Down

0 comments on commit 469ed4d

Please sign in to comment.