Skip to content

Commit

Permalink
revert cacheCtx since Revert fails txs automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
Unique-Divine committed Oct 23, 2024
1 parent 62a1b5f commit 7cc070b
Show file tree
Hide file tree
Showing 15 changed files with 527 additions and 531 deletions.
30 changes: 18 additions & 12 deletions x/evm/keeper/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
gethcore "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"

serverconfig "github.com/NibiruChain/nibiru/v2/app/server/config"
"github.com/NibiruChain/nibiru/v2/x/evm"
Expand Down Expand Up @@ -57,7 +58,8 @@ func (e erc20Calls) Mint(
if err != nil {
return nil, fmt.Errorf("failed to pack ABI args: %w", err)
}
return e.CallContractWithInput(ctx, from, &contract, true, input)
evmResp, _, err = e.CallContractWithInput(ctx, from, &contract, true, input)
return
}

/*
Expand All @@ -78,7 +80,7 @@ func (e erc20Calls) Transfer(
if err != nil {
return false, fmt.Errorf("failed to pack ABI args: %w", err)
}
resp, err := e.CallContractWithInput(ctx, from, &contract, true, input)
resp, _, err := e.CallContractWithInput(ctx, from, &contract, true, input)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -118,7 +120,8 @@ func (e erc20Calls) Burn(
return
}
commit := true
return e.CallContractWithInput(ctx, from, &contract, commit, input)
evmResp, _, err = e.CallContractWithInput(ctx, from, &contract, commit, input)
return
}

// CallContract invokes a smart contract on the method specified by [methodName]
Expand Down Expand Up @@ -149,7 +152,8 @@ func (k Keeper) CallContract(
if err != nil {
return nil, fmt.Errorf("failed to pack ABI args: %w", err)
}
return k.CallContractWithInput(ctx, fromAcc, contract, commit, contractInput)
evmResp, _, err = k.CallContractWithInput(ctx, fromAcc, contract, commit, contractInput)
return evmResp, err
}

// CallContractWithInput invokes a smart contract with the given [contractInput].
Expand All @@ -170,7 +174,7 @@ func (k Keeper) CallContractWithInput(
contract *gethcommon.Address,
commit bool,
contractInput []byte,
) (evmResp *evm.MsgEthereumTxResponse, err error) {
) (evmResp *evm.MsgEthereumTxResponse, evmObj *vm.EVM, err error) {
// This is a `defer` pattern to add behavior that runs in the case that the error is
// non-nil, creating a concise way to add extra information.
defer func() {
Expand All @@ -185,7 +189,7 @@ func (k Keeper) CallContractWithInput(
commit, gasLimit, &fromAcc, contract, contractInput, k, ctx,
)
if err != nil {
return nil, err
return
}

unusedBigInt := big.NewInt(0)
Expand All @@ -210,26 +214,28 @@ func (k Keeper) CallContractWithInput(
k.EthChainID(ctx),
)
if err != nil {
return nil, errors.Wrapf(err, "failed to load evm config")
err = errors.Wrapf(err, "failed to load evm config")
return

Check warning on line 218 in x/evm/keeper/erc20.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/erc20.go#L217-L218

Added lines #L217 - L218 were not covered by tests
}

blockHash := gethcommon.BytesToHash(ctx.HeaderHash())
txConfig := statedb.NewEmptyTxConfig(blockHash)
txConfig.TxIndex = uint(k.EvmState.BlockLogSize.GetOr(ctx, 0))
txConfig.LogIndex = uint(k.EvmState.BlockLogSize.GetOr(ctx, 0))

evmResp, err = k.ApplyEvmMsg(
evmResp, evmObj, err = k.ApplyEvmMsg(
ctx, evmMsg, evm.NewNoOpTracer(), commit, evmCfg, txConfig,
)
if err != nil {
return nil, errors.Wrapf(err, "failed to apply EVM message")
err = errors.Wrapf(err, "failed to apply EVM message")
return

Check warning on line 230 in x/evm/keeper/erc20.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/erc20.go#L229-L230

Added lines #L229 - L230 were not covered by tests
}

if evmResp.Failed() {
return nil, errors.Wrapf(err, "EVM execution failed: %s", evmResp.VmError)
err = errors.Wrapf(err, "EVM execution failed: %s", evmResp.VmError)
return

Check warning on line 235 in x/evm/keeper/erc20.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/erc20.go#L234-L235

Added lines #L234 - L235 were not covered by tests
}

return evmResp, err
return evmResp, evmObj, err
}

// computeCommitGasLimit: If the transition is meant to mutate state, this
Expand Down
2 changes: 1 addition & 1 deletion x/evm/keeper/funtoken_from_coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (k *Keeper) deployERC20ForBankCoin(
bytecodeForCall := append(embeds.SmartContract_ERC20Minter.Bytecode, packedArgs...)

// nil address for contract creation
_, err = k.CallContractWithInput(
_, _, err = k.CallContractWithInput(
ctx, evm.EVM_MODULE_ADDRESS, nil, true, bytecodeForCall,
)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions x/evm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func (k *Keeper) EthCall(
txConfig := statedb.NewEmptyTxConfig(gethcommon.BytesToHash(ctx.HeaderHash()))

// pass false to not commit StateDB
res, err := k.ApplyEvmMsg(ctx, msg, nil, false, cfg, txConfig)
res, _, err := k.ApplyEvmMsg(ctx, msg, nil, false, cfg, txConfig)
if err != nil {
return nil, grpcstatus.Error(grpccodes.Internal, err.Error())
}
Expand Down Expand Up @@ -422,7 +422,7 @@ func (k Keeper) EstimateGasForEvmCallType(
WithTransientKVGasConfig(storetypes.GasConfig{})
}
// pass false to not commit StateDB
rsp, err = k.ApplyEvmMsg(tmpCtx, msg, nil, false, cfg, txConfig)
rsp, _, err = k.ApplyEvmMsg(tmpCtx, msg, nil, false, cfg, txConfig)
if err != nil {
if errors.Is(err, core.ErrIntrinsicGas) {
return true, nil, nil // Special case, raise gas limit
Expand Down Expand Up @@ -518,7 +518,7 @@ func (k Keeper) TraceTx(
ctx = ctx.WithGasMeter(eth.NewInfiniteGasMeterWithLimit(msg.Gas())).
WithKVGasConfig(storetypes.GasConfig{}).
WithTransientKVGasConfig(storetypes.GasConfig{})
rsp, err := k.ApplyEvmMsg(ctx, msg, evm.NewNoOpTracer(), true, cfg, txConfig)
rsp, _, err := k.ApplyEvmMsg(ctx, msg, evm.NewNoOpTracer(), true, cfg, txConfig)
if err != nil {
continue
}
Expand Down Expand Up @@ -800,7 +800,7 @@ func (k *Keeper) TraceEthTxMsg(
ctx = ctx.WithGasMeter(eth.NewInfiniteGasMeterWithLimit(msg.Gas())).
WithKVGasConfig(storetypes.GasConfig{}).
WithTransientKVGasConfig(storetypes.GasConfig{})
res, err := k.ApplyEvmMsg(ctx, msg, tracer, commitMessage, cfg, txConfig)
res, _, err := k.ApplyEvmMsg(ctx, msg, tracer, commitMessage, cfg, txConfig)
if err != nil {
return nil, 0, grpcstatus.Error(grpccodes.Internal, err.Error())
}
Expand Down
49 changes: 15 additions & 34 deletions x/evm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ func (k *Keeper) EthereumTx(
return nil, errors.Wrap(err, "failed to return ethereum transaction as core message")
}

tmpCtx, commit := ctx.CacheContext()
tmpCtx, commitCtx := ctx.CacheContext()

// pass true to commit the StateDB
evmResp, err = k.ApplyEvmMsg(tmpCtx, msg, nil, true, evmConfig, txConfig)
evmResp, _, err = k.ApplyEvmMsg(tmpCtx, msg, nil, true, evmConfig, txConfig)
if err != nil {
// when a transaction contains multiple msg, as long as one of the msg fails
// all gas will be deducted. so is not msg.Gas()
Expand All @@ -72,37 +72,18 @@ func (k *Keeper) EthereumTx(

logs := evm.LogsToEthereum(evmResp.Logs)

cumulativeGasUsed := evmResp.GasUsed
if ctx.BlockGasMeter() != nil {
limit := ctx.BlockGasMeter().Limit()
cumulativeGasUsed += ctx.BlockGasMeter().GasConsumed()
if cumulativeGasUsed > limit {
cumulativeGasUsed = limit
}
}

var contractAddr gethcommon.Address
if msg.To() == nil {
contractAddr = crypto.CreateAddress(msg.From(), msg.Nonce())
}

receipt := &gethcore.Receipt{
Type: tx.Type(),
PostState: nil, // TODO: intermediate state root
CumulativeGasUsed: cumulativeGasUsed,
Bloom: k.EvmState.CalcBloomFromLogs(ctx, logs),
Logs: logs,
TxHash: txConfig.TxHash,
ContractAddress: contractAddr,
GasUsed: evmResp.GasUsed,
BlockHash: txConfig.BlockHash,
BlockNumber: big.NewInt(ctx.BlockHeight()),
TransactionIndex: txConfig.TxIndex,
Bloom: k.EvmState.CalcBloomFromLogs(ctx, logs),
Logs: logs,
}

if !evmResp.Failed() {
receipt.Status = gethcore.ReceiptStatusSuccessful
commit()
commitCtx()
}

// refund gas in order to match the Ethereum gas consumption instead of the default SDK one.
Expand Down Expand Up @@ -282,14 +263,14 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
commit bool,
evmConfig *statedb.EVMConfig,
txConfig statedb.TxConfig,
) (*evm.MsgEthereumTxResponse, error) {
) (resp *evm.MsgEthereumTxResponse, evmObj *vm.EVM, err error) {
var (
ret []byte // return bytes from evm execution
vmErr error // vm errors do not effect consensus and are therefore not assigned to err
)

stateDB := statedb.New(ctx, k, txConfig)
evmObj := k.NewEVM(ctx, msg, evmConfig, tracer, stateDB)
evmObj = k.NewEVM(ctx, msg, evmConfig, tracer, stateDB)

leftoverGas := msg.Gas()

Expand All @@ -308,7 +289,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
intrinsicGas, err := k.GetEthIntrinsicGas(ctx, msg, evmConfig.ChainConfig, contractCreation)
if err != nil {
// should have already been checked on Ante Handler
return nil, errors.Wrap(err, "intrinsic gas failed")
return nil, evmObj, errors.Wrap(err, "intrinsic gas failed")

Check warning on line 292 in x/evm/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/msg_server.go#L292

Added line #L292 was not covered by tests
}

// Check if the provided gas in the message is enough to cover the intrinsic
Expand All @@ -319,7 +300,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
// don't go through Ante Handler.
if leftoverGas < intrinsicGas {
// eth_estimateGas will check for this exact error
return nil, errors.Wrapf(
return nil, evmObj, errors.Wrapf(
core.ErrIntrinsicGas,
"apply message msg.Gas = %d, intrinsic gas = %d.",
leftoverGas, intrinsicGas,
Expand All @@ -339,7 +320,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,

msgWei, err := ParseWeiAsMultipleOfMicronibi(msg.Value())
if err != nil {
return nil, err
return nil, evmObj, err
}

if contractCreation {
Expand Down Expand Up @@ -369,7 +350,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,

// calculate gas refund
if msg.Gas() < leftoverGas {
return nil, errors.Wrap(evm.ErrGasOverflow, "apply message")
return nil, evmObj, errors.Wrap(evm.ErrGasOverflow, "apply message")

Check warning on line 353 in x/evm/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/msg_server.go#L353

Added line #L353 was not covered by tests
}
// refund gas
temporaryGasUsed := msg.Gas() - leftoverGas
Expand All @@ -388,7 +369,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
// The dirty states in `StateDB` is either committed or discarded after return
if commit {
if err := stateDB.Commit(); err != nil {
return nil, fmt.Errorf("failed to commit stateDB: %w", err)
return nil, evmObj, fmt.Errorf("failed to commit stateDB: %w", err)

Check warning on line 372 in x/evm/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/msg_server.go#L372

Added line #L372 was not covered by tests
}
}

Expand All @@ -397,11 +378,11 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
minimumGasUsed := gasLimit.Mul(minGasMultiplier)

if !minimumGasUsed.TruncateInt().IsUint64() {
return nil, errors.Wrapf(evm.ErrGasOverflow, "minimumGasUsed(%s) is not a uint64", minimumGasUsed.TruncateInt().String())
return nil, evmObj, errors.Wrapf(evm.ErrGasOverflow, "minimumGasUsed(%s) is not a uint64", minimumGasUsed.TruncateInt().String())

Check warning on line 381 in x/evm/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/msg_server.go#L381

Added line #L381 was not covered by tests
}

if msg.Gas() < leftoverGas {
return nil, errors.Wrapf(evm.ErrGasOverflow, "message gas limit < leftover gas (%d < %d)", msg.Gas(), leftoverGas)
return nil, evmObj, errors.Wrapf(evm.ErrGasOverflow, "message gas limit < leftover gas (%d < %d)", msg.Gas(), leftoverGas)

Check warning on line 385 in x/evm/keeper/msg_server.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/msg_server.go#L385

Added line #L385 was not covered by tests
}

gasUsed := math.LegacyMaxDec(minimumGasUsed, math.LegacyNewDec(int64(temporaryGasUsed))).TruncateInt().Uint64()
Expand All @@ -417,7 +398,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
Ret: ret,
Logs: evm.NewLogsFromEth(stateDB.Logs()),
Hash: txConfig.TxHash.Hex(),
}, nil
}, evmObj, nil
}

func ParseWeiAsMultipleOfMicronibi(weiInt *big.Int) (newWeiInt *big.Int, err error) {
Expand Down
19 changes: 7 additions & 12 deletions x/evm/precompile/funtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,15 @@ func (p precompileFunToken) Run(
defer func() {
err = ErrPrecompileRun(err, p)
}()

res, err := OnRunStart(evm, contract, p.ABI())
start, err := OnRunStart(evm, contract, p.ABI())
if err != nil {
return nil, err
}
method, args, ctx := res.Method, res.Args, res.Ctx

method := start.Method
switch PrecompileMethod(method.Name) {
case FunTokenMethod_BankSend:
bz, err = p.bankSend(ctx, contract.CallerAddress, method, args, readonly)
bz, err = p.bankSend(start, contract.CallerAddress, readonly)
default:
// Note that this code path should be impossible to reach since
// "DecomposeInput" parses methods directly from the ABI.
Expand All @@ -70,11 +69,8 @@ func (p precompileFunToken) Run(
if err != nil {
return nil, err
}

Check warning on line 71 in x/evm/precompile/funtoken.go

View check run for this annotation

Codecov / codecov/patch

x/evm/precompile/funtoken.go#L70-L71

Added lines #L70 - L71 were not covered by tests
if err := OnRunEnd(res.StateDB, res.SnapshotBeforeRun, p.Address()); err != nil {
return nil, err
}
res.WriteCtx()
return bz, nil
// Dirty journal entries in `StateDB` must be committed
return bz, start.StateDB.Commit()
}

func PrecompileFunToken(keepers keepers.PublicKeepers) vm.PrecompiledContract {
Expand Down Expand Up @@ -103,12 +99,11 @@ var executionGuard sync.Mutex
// function bankSend(address erc20, uint256 amount, string memory to) external;
// ```
func (p precompileFunToken) bankSend(
ctx sdk.Context,
start OnRunStartResult,
caller gethcommon.Address,
method *gethabi.Method,
args []any,
readOnly bool,
) (bz []byte, err error) {
ctx, method, args := start.Ctx, start.Method, start.Args
if e := assertNotReadonlyTx(readOnly, true); e != nil {
err = e
return
Expand Down
2 changes: 1 addition & 1 deletion x/evm/precompile/funtoken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (s *FuntokenSuite) TestHappyPath() {
{
input, err := embeds.SmartContract_ERC20Minter.ABI.Pack("mint", deps.Sender.EthAddr, big.NewInt(69_420))
s.NoError(err)
_, err = deps.EvmKeeper.CallContractWithInput(
_, _, err = deps.EvmKeeper.CallContractWithInput(
deps.Ctx, deps.Sender.EthAddr, &erc20, true, input,
)
s.ErrorContains(err, "Ownable: caller is not the owner")
Expand Down
2 changes: 1 addition & 1 deletion x/evm/precompile/oracle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (s *OracleSuite) TestOracle_HappyPath() {
deps.App.OracleKeeper.SetPrice(deps.Ctx, "unibi:uusd", sdk.MustNewDecFromStr("0.067"))
input, err := embeds.SmartContract_Oracle.ABI.Pack("queryExchangeRate", "unibi:uusd")
s.NoError(err)
resp, err := deps.EvmKeeper.CallContractWithInput(
resp, _, err := deps.EvmKeeper.CallContractWithInput(
deps.Ctx, deps.Sender.EthAddr, &precompile.PrecompileAddr_Oracle, true, input,
)
s.NoError(err)
Expand Down
Loading

0 comments on commit 7cc070b

Please sign in to comment.