Skip to content
This repository was archived by the owner on Apr 11, 2021. It is now read-only.

Commit ad78282

Browse files
committed
fix: revert DoEstimateGas changes introduced as a temp fix in #22
1 parent 4290b08 commit ad78282

File tree

1 file changed

+59
-6
lines changed

1 file changed

+59
-6
lines changed

internal/ethapi/api.go

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -997,13 +997,66 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOr
997997
}
998998

999999
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap *big.Int) (hexutil.Uint64, error) {
1000-
// Retrieve the block to act as the gas ceiling
1001-
block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash)
1002-
if err != nil {
1003-
return 0, err
1000+
// Binary search the gas requirement, as it may be higher than the amount used
1001+
var (
1002+
lo uint64 = params.TxGas - 1
1003+
hi uint64
1004+
cap uint64
1005+
)
1006+
if args.Gas != nil && uint64(*args.Gas) >= params.TxGas {
1007+
hi = uint64(*args.Gas)
1008+
} else {
1009+
// Retrieve the block to act as the gas ceiling
1010+
block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash)
1011+
if err != nil {
1012+
return 0, err
1013+
}
1014+
hi = block.GasLimit()
1015+
}
1016+
if gasCap != nil && hi > gasCap.Uint64() {
1017+
log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
1018+
hi = gasCap.Uint64()
1019+
}
1020+
cap = hi
1021+
1022+
// Set sender address or use a default if none specified
1023+
if args.From == nil {
1024+
if wallets := b.AccountManager().Wallets(); len(wallets) > 0 {
1025+
if accounts := wallets[0].Accounts(); len(accounts) > 0 {
1026+
args.From = &accounts[0].Address
1027+
}
1028+
}
1029+
}
1030+
// Use zero-address if none other is available
1031+
if args.From == nil {
1032+
args.From = &common.Address{}
1033+
}
1034+
// Create a helper to check if a gas allowance results in an executable transaction
1035+
executable := func(gas uint64) bool {
1036+
args.Gas = (*hexutil.Uint64)(&gas)
1037+
1038+
_, _, failed, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap)
1039+
if err != nil || failed {
1040+
return false
1041+
}
1042+
return true
1043+
}
1044+
// Execute the binary search and hone in on an executable gas limit
1045+
for lo+1 < hi {
1046+
mid := (hi + lo) / 2
1047+
if !executable(mid) {
1048+
lo = mid
1049+
} else {
1050+
hi = mid
1051+
}
1052+
}
1053+
// Reject the transaction as invalid if it still fails at the highest allowance
1054+
if hi == cap {
1055+
if !executable(hi) {
1056+
return 0, fmt.Errorf("gas required exceeds allowance (%d) or always failing transaction", cap)
1057+
}
10041058
}
1005-
// For now always return the gas limit
1006-
return hexutil.Uint64(block.GasLimit() - 1), nil
1059+
return hexutil.Uint64(hi), nil
10071060
}
10081061

10091062
// EstimateGas returns an estimate of the amount of gas needed to execute the

0 commit comments

Comments
 (0)