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

Split OutOfGas error to several concrete errors #124

Merged
merged 2 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nil/cmd/nil/internal/smartaccount/call-readonly.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func CallReadonlyCommand(cfg *common.Config) *cobra.Command {
"The path to the ABI file",
)

params.Fee.FeeCredit = types.GasToValue(100_000)
params.Fee.FeeCredit = types.GasToValue(10_000_000)
cmd.Flags().Var(
&params.Fee.FeeCredit,
feeCreditFlag,
Expand Down
2 changes: 1 addition & 1 deletion nil/cmd/nil/internal/smartaccount/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/spf13/cobra"
)

var defaultNewSmartAccountAmount = types.GasToValue(10_000_000)
var defaultNewSmartAccountAmount = types.GasToValue(1_000_000_000)

func NewCommand(cfg *common.Config) *cobra.Command {
serverCmd := &cobra.Command{
Expand Down
4 changes: 2 additions & 2 deletions nil/internal/execution/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ func (es *ExecutionState) SetInitState(addr types.Address, transaction *types.Tr
}
defer es.resetVm()

_, deployAddr, _, err := es.evm.Deploy(addr, vm.AccountRef{}, transaction.Data, uint64(100000) /* gas */, uint256.NewInt(0))
_, deployAddr, _, err := es.evm.Deploy(addr, vm.AccountRef{}, transaction.Data, uint64(100_000_000) /* gas */, uint256.NewInt(0))
if err != nil {
return err
}
Expand Down Expand Up @@ -1547,7 +1547,7 @@ func (es *ExecutionState) CallVerifyExternal(transaction *types.Transaction, acc

ret, leftOverGas, err := es.evm.StaticCall((vm.AccountRef)(account.address), account.address, calldata, gasCreditLimit.Uint64())
if err != nil {
if errors.Is(err, vm.ErrOutOfGas) && gasCreditLimit.Lt(ExternalTransactionVerificationMaxGas) {
if types.IsOutOfGasError(err) && gasCreditLimit.Lt(ExternalTransactionVerificationMaxGas) {
// This condition means that account has not enough balance even to execute the verification.
// So it will be clearer to return `InsufficientBalance` error instead of `OutOfGas`.
return NewExecutionResult().SetError(types.NewError(types.ErrorInsufficientBalance))
Expand Down
2 changes: 1 addition & 1 deletion nil/internal/execution/testaide.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func NewDeployTransaction(payload types.DeployPayload,
Flags: types.NewTransactionFlags(types.TransactionFlagInternal, types.TransactionFlagDeploy),
Data: payload.Bytes(),
Seqno: seqno,
FeeCredit: DefaultGasCredit,
FeeCredit: types.GasToValue(10_000_000),
To: types.CreateAddress(shardId, payload),
MaxFeePerGas: types.MaxFeePerGasDefault,
},
Expand Down
6 changes: 3 additions & 3 deletions nil/internal/execution/zerostate.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,13 @@ func (es *ExecutionState) GenerateZeroState(stateConfig *ZeroStateConfig) error
if err := es.CreateContract(addr); err != nil {
return err
}
if err := es.SetInitState(addr, mainDeployTxn); err != nil {
if err := es.SetBalance(addr, contract.Value); err != nil {
return err
}

if err := es.SetBalance(addr, contract.Value); err != nil {
if err := es.SetInitState(addr, mainDeployTxn); err != nil {
return err
}

logger.Debug().Str("name", contract.Name).Stringer("address", addr).Msg("Created zero state contract")
}
return nil
Expand Down
14 changes: 14 additions & 0 deletions nil/internal/types/exec_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ const (
ErrorSuccess ErrorCode = iota
ErrorUnknown
ErrorExecution

ErrorOutOfGasStart
ErrorOutOfGas
ErrorOutOfGasDynamic
ErrorOutOfGasForPrecompile
ErrorOutOfGasStorage
ErrorOutOfGasEnd

ErrorBounce
ErrorBuyGas
ErrorValidation
Expand Down Expand Up @@ -185,6 +192,13 @@ func IsVmError(err error) bool {
return errors.As(err, &e)
}

func IsOutOfGasError(err error) bool {
if !IsValidError(err) {
return false
}
return GetErrorCode(err) >= ErrorOutOfGasStart && GetErrorCode(err) <= ErrorOutOfGasEnd
}

func GetErrorCode(err error) ErrorCode {
if base := ToBaseError(err); base != nil {
return base.Code()
Expand Down
1 change: 0 additions & 1 deletion nil/internal/vm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
// List evm execution errors
var (
ErrOutOfGas = types.NewVmError(types.ErrorOutOfGas)
ErrCodeStoreOutOfGas = types.NewVmError(types.ErrorCodeStoreOutOfGas)
ErrDepth = types.NewVmError(types.ErrorCallDepthExceeded)
ErrInsufficientBalance = types.NewVmError(types.ErrorInsufficientBalance)
ErrContractAddressCollision = types.NewVmError(types.ErrorContractAddressCollision)
Expand Down
8 changes: 6 additions & 2 deletions nil/internal/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,12 @@ func (evm *EVM) create(caller ContractRef, codeAndHash types.Code, gas uint64, v
}

if err == nil {
// TODO: calculate gas required to store the code
err = evm.StateDB.SetCode(address, ret)
createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas, evm.Config.Tracer, tracing.GasChangeCallCodeStorage) {
err = evm.StateDB.SetCode(address, ret)
} else {
err = types.NewError(types.ErrorOutOfGasStorage)
}
}

// When an error was returned by the EVM or when setting the creation code.
Expand Down
4 changes: 2 additions & 2 deletions nil/internal/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,10 @@ func calcDynamicCosts(contract *Contract, operation *operation, stack *Stack, in
// Cost is explicitly set so that the capture state defer method can get the proper cost.
dynamicCost, err := operation.dynamicGas(in.evm, contract, stack, mem, memorySize)
if err != nil {
return 0, 0, fmt.Errorf("%w: %w", ErrOutOfGas, err)
return 0, 0, types.NewWrapError(types.ErrorOutOfGasDynamic, err)
}
if !contract.UseGas(dynamicCost, in.evm.Config.Tracer, tracing.GasChangeIgnored) {
return 0, 0, fmt.Errorf("%w: %d < %d", ErrOutOfGas, contract.Gas, dynamicCost)
return 0, 0, types.NewVerboseError(types.ErrorOutOfGasDynamic, fmt.Sprintf("%d < %d", contract.Gas, dynamicCost))
}
return memorySize, dynamicCost, nil
}
3 changes: 2 additions & 1 deletion nil/internal/vm/precompiled.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ func RunPrecompiledContract(p PrecompiledContract, evm *EVM, input []byte, suppl
return nil, 0, err
}
if suppliedGas < gasCost {
return nil, 0, fmt.Errorf("%w: %d < %d", ErrOutOfGas, suppliedGas, gasCost)
return nil, 0, types.NewVerboseError(types.ErrorOutOfGasForPrecompile,
fmt.Sprintf("%d < %d", suppliedGas, gasCost))
}
if logger != nil && logger.OnGasChange != nil {
logger.OnGasChange(suppliedGas, suppliedGas-gasCost, tracing.GasChangeCallPrecompiledContract)
Expand Down
2 changes: 1 addition & 1 deletion nil/services/cliservice/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (s *Service) DeployContractViaSmartAccount(shardId types.ShardId, smartAcco
value types.Value,
) (common.Hash, types.Address, error) {
txHash, contractAddr, err := s.client.DeployContract(s.ctx, shardId, smartAccount, deployPayload, value,
types.NewFeePackFromGas(100_000), s.privateKey)
types.NewFeePackFromGas(10_000_000), s.privateKey)
if err != nil {
s.logger.Error().Err(err).Msg("Failed to send new transaction")
return common.EmptyHash, types.EmptyAddress, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (s *TracerNildTestSuite) TestTestContract() {

s.Run("ContractDeploy", func() {
txHash, addr, err := s.Client.DeployContract(
s.Context, s.shardId, s.addrFrom, deployPayload, types.Value{}, types.NewFeePackFromGas(300_000),
s.Context, s.shardId, s.addrFrom, deployPayload, types.Value{}, types.NewFeePackFromGas(3_000_000),
execution.MainPrivateKey)
s.Require().NoError(err)
s.Require().Equal(contractAddr, addr)
Expand Down
8 changes: 4 additions & 4 deletions nil/tests/basic/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (s *SuiteRpc) TestRpcCallWithTransactionSend() { //nolint:maintidx

hash, smartAccountAddr, err = s.Client.DeployContract(
s.Context, callerShardId, types.MainSmartAccountAddress, deployCode, types.GasToValue(10_000_000),
types.NewFeePackFromGas(200_000), execution.MainPrivateKey,
types.NewFeePackFromGas(20_000_000), execution.MainPrivateKey,
)
s.Require().NoError(err)
receipt := s.WaitForReceipt(hash)
Expand All @@ -350,7 +350,7 @@ func (s *SuiteRpc) TestRpcCallWithTransactionSend() { //nolint:maintidx

hash, counterAddr, err = s.Client.DeployContract(
s.Context, calleeShardId, types.MainSmartAccountAddress, deployCode, types.Value{},
types.NewFeePackFromGas(200_000), execution.MainPrivateKey,
types.NewFeePackFromGas(2_000_000), execution.MainPrivateKey,
)
s.Require().NoError(err)
receipt := s.WaitIncludedInMain(hash)
Expand Down Expand Up @@ -835,7 +835,7 @@ func (s *SuiteRpc) TestMultipleRefunds() {
func (s *SuiteRpc) TestRpcBlockContent() {
// Deploy transaction
hash, _, err := s.Client.DeployContract(s.Context, types.BaseShardId, types.MainSmartAccountAddress,
contracts.CounterDeployPayload(s.T()), types.Value{}, types.NewFeePackFromGas(100_000), execution.MainPrivateKey)
contracts.CounterDeployPayload(s.T()), types.Value{}, types.NewFeePackFromGas(1_000_000), execution.MainPrivateKey)
s.Require().NoError(err)

var block *jsonrpc.RPCBlock
Expand All @@ -858,7 +858,7 @@ func (s *SuiteRpc) TestRpcBlockContent() {
func (s *SuiteRpc) TestRpcTransactionContent() {
shardId := types.ShardId(3)
hash, _, err := s.Client.DeployContract(s.Context, shardId, types.MainSmartAccountAddress,
contracts.CounterDeployPayload(s.T()), types.Value{}, types.NewFeePackFromGas(100_000), execution.MainPrivateKey)
contracts.CounterDeployPayload(s.T()), types.Value{}, types.NewFeePackFromGas(1_000_000), execution.MainPrivateKey)
s.Require().NoError(err)

receipt := s.WaitForReceipt(hash)
Expand Down
7 changes: 4 additions & 3 deletions nil/tests/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,16 @@ func DeployContractViaSmartAccount(
t.Helper()

contractAddr := types.CreateAddress(shardId, payload)
txHash, err := client.SendTransactionViaSmartAccount(ctx, addrFrom, types.Code{}, types.NewFeePackFromGas(100_000), initialAmount,
[]types.TokenBalance{}, contractAddr, key)
txHash, err := client.SendTransactionViaSmartAccount(ctx, addrFrom, types.Code{}, types.NewFeePackFromGas(10_000_000),
initialAmount, []types.TokenBalance{}, contractAddr, key)
require.NoError(t, err)
receipt := WaitForReceipt(t, ctx, client, txHash)
require.True(t, receipt.Success)
require.Equal(t, "Success", receipt.Status)
require.Len(t, receipt.OutReceipts, 1)

txHash, addr, err := client.DeployContract(ctx, shardId, addrFrom, payload, types.Value{}, types.NewFeePackFromGas(100_000), key)
txHash, addr, err := client.DeployContract(ctx, shardId, addrFrom, payload, types.Value{},
types.NewFeePackFromGas(10_000_000), key)
require.NoError(t, err)
require.Equal(t, contractAddr, addr)

Expand Down
2 changes: 1 addition & 1 deletion nil/tests/faucet/faucet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (s *SuiteFaucet) TestDeployContractViaFaucet() {
}

txnHash, receiptContractAddress, err := s.DefaultClient.DeployExternal(s.Context, smartAccountAddr.ShardId(), code,
types.NewFeePackFromGas(100_000))
types.NewFeePackFromGas(10_000_000))
s.Require().NoError(err)
s.Require().Equal(smartAccountAddr, receiptContractAddress)
receipt = s.WaitForReceipt(txnHash)
Expand Down
2 changes: 1 addition & 1 deletion nil/tests/smart-account/smart_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (s *SuiteSmartAccountRpc) TestDeploySmartAccountWithValue() {

hash, address, err := s.Client.DeployContract(
s.Context, types.BaseShardId, types.MainSmartAccountAddress, deployCode, types.NewValueFromUint64(500_000),
types.NewFeePackFromGas(500_000), execution.MainPrivateKey,
types.NewFeePackFromGas(5_000_000), execution.MainPrivateKey,
)
s.Require().NoError(err)

Expand Down