Skip to content
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

Draft
wants to merge 5 commits into
base: dev
Choose a base branch
from
Draft

Add precompiled for pay tx #243

wants to merge 5 commits into from

Conversation

zjg555543
Copy link

No description provided.

turbo/jsonrpc/eth_api.go Outdated Show resolved Hide resolved
Comment on lines +40 to +56
argsOrNil := &ethapi2.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
}
Copy link
Collaborator

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?

Comment on lines +68 to +237
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
Copy link
Collaborator

@Vui-Chee Vui-Chee Jan 23, 2025

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)
Copy link
Collaborator

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)
Copy link
Collaborator

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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants