Skip to content
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
105 changes: 81 additions & 24 deletions src/compiler/evm_frontend/evm_imported.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ bool resolveDelegatedCallCodeAddress(zen::runtime::EVMInstance *Instance,
Module->Host->access_account(CodeAddr) == EVMC_ACCESS_COLD
? zen::evm::COLD_ACCOUNT_ACCESS_COST
: zen::evm::WARM_STORAGE_READ_COST;
Instance->chargeGas(DelegateAccessCost);
return true;
return Instance->chargeGas(DelegateAccessCost);
}
} // namespace

Expand Down Expand Up @@ -174,6 +173,7 @@ const RuntimeFunctions &getRuntimeFunctionTable() {
.GetBlobHash = &evmGetBlobHash,
.GetBlobBaseFee = &evmGetBlobBaseFee,
.GetSLoad = &evmGetSLoad,
.GetErrorCode = &evmGetErrorCode,
.SetSStore = &evmSetSStore,
.GetGas = &evmGetGas,
.GetTLoad = &evmGetTLoad,
Expand Down Expand Up @@ -305,7 +305,9 @@ const intx::uint256 *evmGetExp(zen::runtime::EVMInstance *Instance,
const uint64_t GasPerByte = Rev < EVMC_SPURIOUS_DRAGON
? zen::evm::EXP_BYTE_GAS_PRE_SPURIOUS_DRAGON
: zen::evm::EXP_BYTE_GAS;
Instance->chargeGas(ExponentByteSize * GasPerByte);
if (!Instance->chargeGas(ExponentByteSize * GasPerByte)) {
return storeUint256Result(intx::uint256{0});
}

// EVM: (Base ^ Exponent) % (2^256)
return storeUint256Result(intx::exp(Base, Exponent));
Expand All @@ -330,7 +332,9 @@ const intx::uint256 *evmGetBalance(zen::runtime::EVMInstance *Instance,
evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_BERLIN &&
Module->Host->access_account(Addr) == EVMC_ACCESS_COLD) {
Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST);
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST)) {
return storeUint256Result(intx::uint256{0});
}
}

evmc::bytes32 BalanceBytes = Module->Host->get_balance(Addr);
Expand Down Expand Up @@ -406,7 +410,9 @@ uint64_t evmGetExtCodeSize(zen::runtime::EVMInstance *Instance,
evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_BERLIN &&
Module->Host->access_account(Addr) == EVMC_ACCESS_COLD) {
Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST);
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST)) {
return 0;
}
}

uint64_t Size = Module->Host->get_code_size(Addr);
Expand All @@ -423,7 +429,9 @@ const intx::uint256 *evmGetExtCodeHash(zen::runtime::EVMInstance *Instance,
evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_BERLIN &&
Module->Host->access_account(Addr) == EVMC_ACCESS_COLD) {
Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST);
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST)) {
return storeUint256Result(intx::uint256{0});
}
}

evmc::bytes32 Hash = Module->Host->get_code_hash(Addr);
Expand Down Expand Up @@ -597,7 +605,9 @@ void evmSetCallDataCopy(zen::runtime::EVMInstance *Instance,
return;
}
if (uint64_t CopyGas = calculateWordCopyGas(Size)) {
Instance->chargeGas(CopyGas);
if (!Instance->chargeGas(CopyGas)) {
return;
}
}

const evmc_message *Msg = Instance->getCurrentMessage();
Expand Down Expand Up @@ -637,15 +647,19 @@ void evmSetExtCodeCopy(zen::runtime::EVMInstance *Instance,
evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_BERLIN &&
Module->Host->access_account(Addr) == EVMC_ACCESS_COLD) {
Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST);
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST)) {
return;
}
}

if (!Instance->expandMemoryChecked(DestOffset, Size)) {
return;
}

if (uint64_t CopyGas = calculateWordCopyGas(Size)) {
Instance->chargeGas(CopyGas);
if (!Instance->chargeGas(CopyGas)) {
return;
}
}

// When Size is 0, no memory operations are needed
Expand Down Expand Up @@ -694,7 +708,9 @@ uint64_t evmSetReturnDataCopy(zen::runtime::EVMInstance *Instance,
return 0;
}
if (uint64_t CopyGas = calculateWordCopyGas(Size)) {
Instance->chargeGas(CopyGas);
if (!Instance->chargeGas(CopyGas)) {
return 0;
}
}

uint8_t *MemoryBase = Instance->getMemoryBase();
Expand Down Expand Up @@ -736,7 +752,9 @@ static void evmEmitLogGeneric(zen::runtime::EVMInstance *Instance,
}
const uint64_t LogDataCost = 8 * Size;
if (LogDataCost != 0) {
Instance->chargeGas(LogDataCost);
if (!Instance->chargeGas(LogDataCost)) {
return;
}
}
uint8_t *MemoryBase = Instance->getMemoryBase();
Data = MemoryBase + Offset;
Expand Down Expand Up @@ -822,7 +840,10 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance,

evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_SHANGHAI && Size > zen::evm::MAX_SIZE_OF_INITCODE) {
Instance->chargeGas(Instance->getGas() + 1);
if (!Instance->chargeGas(Instance->getGas() + 1)) {
Instance->setReturnData({});
return ZeroAddress;
}
}
uint64_t InitCodeWordCost = 0;
if (CallKind == EVMC_CREATE2) {
Expand All @@ -835,7 +856,10 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance,
uint64_t InitCodeWords = (Size + 31) / 32;
uint64_t InitCodeCost = InitCodeWordCost * InitCodeWords;
if (InitCodeCost != 0) {
Instance->chargeGas(InitCodeCost);
if (!Instance->chargeGas(InitCodeCost)) {
Instance->setReturnData({});
return ZeroAddress;
}
}
}

Expand Down Expand Up @@ -880,7 +904,10 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance,
Result.gas_left > 0 ? static_cast<uint64_t>(Result.gas_left) : 0;
uint64_t GasUsed = ProvidedGas > GasLeft ? ProvidedGas - GasLeft : 0;
if (GasUsed != 0) {
Instance->chargeGas(GasUsed);
if (!Instance->chargeGas(GasUsed)) {
Instance->setReturnData({});
return ZeroAddress;
}
}
// Track subcall refund (may be negative)
Instance->addGasRefund(Result.gas_refund);
Expand Down Expand Up @@ -925,7 +952,10 @@ static uint64_t evmHandleCallInternal(
evmc_revision Rev = Instance->getRevision();
if (Rev >= EVMC_BERLIN &&
Module->Host->access_account(TargetAddr) == EVMC_ACCESS_COLD) {
Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST);
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_ACCOUNT_ACCESS_COST)) {
Instance->setReturnData({});
return 0;
}
}

evmc::address CodeAddr = TargetAddr;
Expand Down Expand Up @@ -979,7 +1009,10 @@ static uint64_t evmHandleCallInternal(
}
}

Instance->chargeGas(GasCost);
if (!Instance->chargeGas(GasCost)) {
Instance->setReturnData({});
return 0;
}
}

uint64_t GasLeft = Instance->getGas();
Expand All @@ -995,7 +1028,10 @@ static uint64_t evmHandleCallInternal(

if (HasValueArgs && HasValue) {
CallGas += zen::evm::CALL_GAS_STIPEND;
Instance->addGas(zen::evm::CALL_GAS_STIPEND);
if (!Instance->addGas(zen::evm::CALL_GAS_STIPEND)) {
Instance->setReturnData({});
return 0;
}
const auto CallerBalance = Module->Host->get_balance(CurrentMsg->recipient);
const intx::uint256 CallerValue =
intx::be::load<intx::uint256>(CallerBalance);
Expand Down Expand Up @@ -1052,7 +1088,10 @@ static uint64_t evmHandleCallInternal(
GasLeft = Result.gas_left > 0 ? static_cast<uint64_t>(Result.gas_left) : 0;
uint64_t GasUsed = CallGas > GasLeft ? CallGas - GasLeft : 0;
if (GasUsed > 0) {
Instance->chargeGas(GasUsed);
if (!Instance->chargeGas(GasUsed)) {
Instance->setReturnData({});
return 0;
}
}

// Track subcall refund (may be negative)
Expand Down Expand Up @@ -1171,7 +1210,9 @@ void evmSetCodeCopy(zen::runtime::EVMInstance *Instance, uint64_t DestOffset,
return;
}
if (uint64_t CopyGas = calculateWordCopyGas(Size)) {
Instance->chargeGas(CopyGas);
if (!Instance->chargeGas(CopyGas)) {
return;
}
}

const zen::runtime::EVMModule *Module = Instance->getModule();
Expand Down Expand Up @@ -1203,7 +1244,9 @@ const uint8_t *evmGetKeccak256(zen::runtime::EVMInstance *Instance,
}
const uint64_t ExtraGas =
static_cast<uint64_t>(numWords(static_cast<uint64_t>(Length))) * 6;
Instance->chargeGas(ExtraGas);
if (!Instance->chargeGas(ExtraGas)) {
return nullptr;
}
uint8_t *MemoryBase = Instance->getMemoryBase();
InputData = MemoryBase + Offset;
}
Expand Down Expand Up @@ -1281,11 +1324,19 @@ const intx::uint256 *evmGetSLoad(zen::runtime::EVMInstance *Instance,
const auto Key = intx::be::store<evmc::bytes32>(Index);
if (Rev >= EVMC_BERLIN &&
Module->Host->access_storage(Msg->recipient, Key) == EVMC_ACCESS_COLD) {
Instance->chargeGas(zen::evm::ADDITIONAL_COLD_SLOAD_COST);
if (!Instance->chargeGas(zen::evm::ADDITIONAL_COLD_SLOAD_COST)) {
return storeUint256Result(intx::uint256{0});
}
}
const auto Value = Module->Host->get_storage(Msg->recipient, Key);
return storeUint256Result(intx::be::load<intx::uint256>(Value));
}

uint64_t evmGetErrorCode(zen::runtime::EVMInstance *Instance) {
return static_cast<uint64_t>(
zen::common::to_underlying(Instance->getError().getCode()));
}

void evmSetSStore(zen::runtime::EVMInstance *Instance,
const intx::uint256 &Index, const intx::uint256 &Value) {
const zen::runtime::EVMModule *Module = Instance->getModule();
Expand Down Expand Up @@ -1315,7 +1366,9 @@ void evmSetSStore(zen::runtime::EVMInstance *Instance,
const auto [GasCostWarm, GasReFund] = zen::evm::SSTORE_COSTS[Rev][Status];

const auto GasCost = GasCostCold + GasCostWarm;
Instance->chargeGas(GasCost);
if (!Instance->chargeGas(GasCost)) {
return;
}
Instance->addGasRefund(GasReFund);
}

Expand Down Expand Up @@ -1363,7 +1416,9 @@ void evmHandleSelfDestruct(zen::runtime::EVMInstance *Instance,
const bool IsCold =
Module->Host->access_account(BenefAddr) == EVMC_ACCESS_COLD;
if (IsCold) {
Instance->chargeGas(zen::evm::COLD_ACCOUNT_ACCESS_COST);
if (!Instance->chargeGas(zen::evm::COLD_ACCOUNT_ACCESS_COST)) {
return;
}
}
}

Expand All @@ -1372,7 +1427,9 @@ void evmHandleSelfDestruct(zen::runtime::EVMInstance *Instance,
if (Rev == EVMC_TANGERINE_WHISTLE ||
Module->Host->get_balance(Msg->recipient)) {
if (!Module->Host->account_exists(BenefAddr)) {
Instance->chargeGas(zen::evm::ACCOUNT_CREATION_COST);
if (!Instance->chargeGas(zen::evm::ACCOUNT_CREATION_COST)) {
return;
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/evm_frontend/evm_imported.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ using Bytes32WithUInt64UInt64Fn =
using VoidFn = void (*)(zen::runtime::EVMInstance *);
using U256WithU256Fn = const intx::uint256 *(*)(zen::runtime::EVMInstance *,
const intx::uint256 &);
using ErrorCodeFn = uint64_t (*)(zen::runtime::EVMInstance *);
using VoidWithU256U256Fn = void (*)(zen::runtime::EVMInstance *,
const intx::uint256 &,
const intx::uint256 &);
Expand Down Expand Up @@ -111,6 +112,7 @@ struct RuntimeFunctions {
Bytes32WithUint64Fn GetBlobHash;
U256Fn GetBlobBaseFee;
U256WithU256Fn GetSLoad;
ErrorCodeFn GetErrorCode;
VoidWithU256U256Fn SetSStore;
SizeFn GetGas;
U256WithU256Fn GetTLoad;
Expand Down Expand Up @@ -259,6 +261,7 @@ const uint8_t *evmGetKeccak256(zen::runtime::EVMInstance *Instance,
void evmHandleFallback(zen::runtime::EVMInstance *Instance, uint64_t PC);
const intx::uint256 *evmGetSLoad(zen::runtime::EVMInstance *Instance,
const intx::uint256 &Index);
uint64_t evmGetErrorCode(zen::runtime::EVMInstance *Instance);
void evmSetSStore(zen::runtime::EVMInstance *Instance,
const intx::uint256 &Index, const intx::uint256 &Value);
uint64_t evmGetGas(zen::runtime::EVMInstance *Instance);
Expand Down
Loading
Loading