-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add precompiled for pay tx #243
base: dev
Are you sure you want to change the base?
Conversation
argsOrNil := ðapi2.CallArgs{ | ||
From: &fromAddressHex, | ||
To: txn.GetTo(), | ||
Gas: (*hexutil.Uint64)(&gas), | ||
GasPrice: newGP, | ||
Value: newValue, | ||
Nonce: (*hexutil.Uint64)(&nonce), | ||
Data: hexUtilityData, | ||
Input: hexUtilityData, | ||
ChainID: (*hexutil.Big)(chainId), | ||
} | ||
|
||
var args ethapi2.CallArgs | ||
// if we actually get CallArgs here, we use them | ||
if argsOrNil != nil { | ||
args = *argsOrNil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you ultimately set args
variable, why not just start with args
and no argsOrNil
?
transfer = new(hexutil.Big) | ||
} | ||
log.Debug("Gas estimation capped by limited funds", "original", hi, "balance", balance, | ||
"sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance) | ||
hi = allowance.Uint64() | ||
} | ||
} | ||
|
||
// Recap the highest gas allowance with specified gascap. | ||
if hi > api.GasCap { | ||
log.Debug("Caller gas above allowance, capping", "requested", hi, "cap", api.GasCap) | ||
hi = api.GasCap | ||
} | ||
gasCap = hi | ||
|
||
chainConfig, err := api.chainConfig(ctx, dbtx) | ||
if err != nil { | ||
return 0, err | ||
} | ||
engine := api.engine() | ||
|
||
latestCanBlockNumber, latestCanHash, isLatest, err := rpchelper.GetCanonicalBlockNumber_zkevm(bNrOrHash, dbtx, api.filters) // DoCall cannot be executed on non-canonical blocks | ||
if err != nil { | ||
return 0, err | ||
} | ||
|
||
// try and get the block from the lru cache first then try DB before failing | ||
block := api.tryBlockFromLru(latestCanHash) | ||
if block == nil { | ||
block, err = api.blockWithSenders(ctx, dbtx, latestCanHash, latestCanBlockNumber) | ||
if err != nil { | ||
return 0, err | ||
} | ||
} | ||
if block == nil { | ||
return 0, fmt.Errorf("could not find latest block in cache or db") | ||
} | ||
|
||
stateReader, err := rpchelper.CreateStateReaderFromBlockNumber(ctx, dbtx, latestCanBlockNumber, isLatest, 0, api.stateCache, api.historyV3(dbtx), chainConfig.ChainName) | ||
if err != nil { | ||
return 0, err | ||
} | ||
header := block.HeaderNoCopy() | ||
|
||
caller, err := transactions.NewReusableCaller(engine, stateReader, nil, header, args, api.GasCap, latestNumOrHash, dbtx, api._blockReader, chainConfig, api.evmCallTimeout, api.VirtualCountersSmtReduction, false) | ||
if err != nil { | ||
return 0, err | ||
} | ||
|
||
// Create a helper to check if a gas allowance results in an executable transaction | ||
executable := func(gas uint64) (bool, *core.ExecutionResult, error) { | ||
result, err := caller.DoCallWithNewGas(ctx, gas) | ||
if err != nil { | ||
if errors.Is(err, core.ErrIntrinsicGas) { | ||
// Special case, raise gas limit | ||
return true, nil, nil | ||
} | ||
|
||
// Bail out | ||
return true, nil, err | ||
} | ||
return result.Failed(), result, nil | ||
} | ||
|
||
// Execute the binary search and hone in on an executable gas limit | ||
for lo+1 < hi { | ||
mid := (hi + lo) / 2 | ||
failed, _, err := executable(mid) | ||
// If the error is not nil(consensus error), it means the provided message | ||
// call or transaction will never be accepted no matter how much gas it is | ||
// assigened. Return the error directly, don't struggle any more. | ||
if err != nil { | ||
return 0, err | ||
} | ||
if failed { | ||
lo = mid | ||
} else { | ||
hi = mid | ||
} | ||
} | ||
|
||
// Reject the transaction as invalid if it still fails at the highest allowance | ||
if hi == gasCap { | ||
failed, result, err := executable(hi) | ||
if err != nil { | ||
return 0, err | ||
} | ||
if failed { | ||
if result != nil && !errors.Is(result.Err, vm.ErrOutOfGas) { | ||
if len(result.Revert()) > 0 { | ||
return 0, ethapi2.NewRevertError(result) | ||
} | ||
return 0, result.Err | ||
} | ||
// Otherwise, the specified gas cap is too low | ||
return 0, fmt.Errorf("gas required exceeds allowance (%d)", gasCap) | ||
} | ||
} | ||
log.Info(fmt.Sprintf("Estimated gas: %d", hi)) | ||
return hexutil.Uint64(hi), nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under turbo/jsonrpc/eth_call.go
, there is an EstimateGas
function that does exactly what this code is doing.
@@ -2248,6 +2248,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C | |||
setGPO(ctx, &cfg.GPO) | |||
|
|||
setTxPool(ctx, cfg) | |||
SetPreRunList(ctx, cfg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: if we are only setting the pre-run cache in X Layer service, why do we need to set config here?
@@ -113,6 +113,7 @@ func init() { | |||
rootCmd.Flags().StringSliceVar(&freeGasExAddrs, utils.TxPoolFreeGasExAddrs.Name, ethconfig.DeprecatedDefaultTxPoolConfig.FreeGasExAddrs, utils.TxPoolFreeGasExAddrs.Usage) | |||
rootCmd.PersistentFlags().Uint64Var(&freeGasCountPerAddr, utils.TxPoolFreeGasCountPerAddr.Name, ethconfig.DeprecatedDefaultTxPoolConfig.FreeGasCountPerAddr, utils.TxPoolFreeGasCountPerAddr.Usage) | |||
rootCmd.PersistentFlags().Uint64Var(&freeGasLimit, utils.TxPoolFreeGasLimit.Name, ethconfig.DeprecatedDefaultTxPoolConfig.FreeGasLimit, utils.TxPoolFreeGasLimit.Usage) | |||
rootCmd.Flags().StringSliceVar(&preRunAddressList, utils.PreRunAddressList.Name, []string{}, utils.PreRunAddressList.Usage) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this variable preRunAddressList
used anywhere? Usually variables defined are used in doTxPool
.
* dev: Support specific project free gas (#236)
No description provided.