From 30112fe21a1c2c72173da2e7f76e867efd189072 Mon Sep 17 00:00:00 2001 From: Mikhail Rogachev Date: Thu, 18 Sep 2025 20:00:14 +0200 Subject: [PATCH 1/2] Instrument WasmCallCost with multigas --- core/vm/operations_acl_arbitrum.go | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/core/vm/operations_acl_arbitrum.go b/core/vm/operations_acl_arbitrum.go index 26097d08e6..e464d8037f 100644 --- a/core/vm/operations_acl_arbitrum.go +++ b/core/vm/operations_acl_arbitrum.go @@ -111,15 +111,17 @@ func WasmStateStoreCost(db StateDB, program common.Address, key, value common.Ha // The code here is adapted from the following functions with the most recent parameters as of The Merge // - operations_acl.go makeCallVariantGasCallEIP2929() // - gas_table.go gasCall() -func WasmCallCost(db StateDB, contract common.Address, value *uint256.Int, budget uint64) (uint64, error) { - total := uint64(0) - apply := func(amount uint64) bool { - total += amount - return total > budget +func WasmCallCost(db StateDB, contract common.Address, value *uint256.Int, budget uint64) (multigas.MultiGas, error) { + total := multigas.ZeroGas() + apply := func(resource multigas.ResourceKind, amount uint64) bool { + total.SaturatingIncrementInto(resource, amount) + return total.SingleGas() > budget } - // EIP 2929: the static cost - if apply(params.WarmStorageReadCostEIP2929) { + // NOTE: keep ResourceKindWasmComputation, it is used to calculate base cost single gas + + // EIP 2929: the static cost considered as computation + if apply(multigas.ResourceKindWasmComputation, params.WarmStorageReadCostEIP2929) { return total, ErrOutOfGas } @@ -129,7 +131,8 @@ func WasmCallCost(db StateDB, contract common.Address, value *uint256.Int, budge if !warmAccess { db.AddAddressToAccessList(contract) - if apply(coldCost) { + // Cold slot access considered as storage access. + if apply(multigas.ResourceKindStorageAccess, coldCost) { return total, ErrOutOfGas } } @@ -137,12 +140,14 @@ func WasmCallCost(db StateDB, contract common.Address, value *uint256.Int, budge // gasCall() transfersValue := value.Sign() != 0 if transfersValue && db.Empty(contract) { - if apply(params.CallNewAccountGas) { + // Storage slot writes (zero -> nonzero) considered as storage growth. + if apply(multigas.ResourceKindStorageGrowth, params.CallNewAccountGas) { return total, ErrOutOfGas } } if transfersValue { - if apply(params.CallValueTransferGas) { + // Value transfer to non-empty account considered as computation. + if apply(multigas.ResourceKindWasmComputation, params.CallValueTransferGas) { return total, ErrOutOfGas } } @@ -160,11 +165,13 @@ func WasmAccountTouchCost(cfg *params.ChainConfig, db StateDB, addr common.Addre if !db.AddressInAccessList(addr) { db.AddAddressToAccessList(addr) + // Cold slot read -> storage access + computation return cost.SaturatingAdd(multigas.MultiGasFromPairs( multigas.Pair{Kind: multigas.ResourceKindStorageAccess, Amount: params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929}, multigas.Pair{Kind: multigas.ResourceKindComputation, Amount: params.WarmStorageReadCostEIP2929}, )) } + // Warm slot read considered as computation. return cost.SaturatingIncrement(multigas.ResourceKindComputation, params.WarmStorageReadCostEIP2929) } From a230ce368ceeb6eb09cd80455dd1ac39fe248a44 Mon Sep 17 00:00:00 2001 From: Mikhail Rogachev Date: Mon, 22 Sep 2025 18:42:18 +0200 Subject: [PATCH 2/2] Change WasmCallCost comutation cost dimension --- core/vm/operations_acl_arbitrum.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/vm/operations_acl_arbitrum.go b/core/vm/operations_acl_arbitrum.go index e464d8037f..efb290ea59 100644 --- a/core/vm/operations_acl_arbitrum.go +++ b/core/vm/operations_acl_arbitrum.go @@ -118,10 +118,8 @@ func WasmCallCost(db StateDB, contract common.Address, value *uint256.Int, budge return total.SingleGas() > budget } - // NOTE: keep ResourceKindWasmComputation, it is used to calculate base cost single gas - // EIP 2929: the static cost considered as computation - if apply(multigas.ResourceKindWasmComputation, params.WarmStorageReadCostEIP2929) { + if apply(multigas.ResourceKindComputation, params.WarmStorageReadCostEIP2929) { return total, ErrOutOfGas } @@ -147,7 +145,7 @@ func WasmCallCost(db StateDB, contract common.Address, value *uint256.Int, budge } if transfersValue { // Value transfer to non-empty account considered as computation. - if apply(multigas.ResourceKindWasmComputation, params.CallValueTransferGas) { + if apply(multigas.ResourceKindComputation, params.CallValueTransferGas) { return total, ErrOutOfGas } }