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
53 changes: 44 additions & 9 deletions fvm/environment/meter.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,51 @@ const (
ComputationKindEVMDecodeABI
)

// MainnetExecutionEffortWeights are the execution effort weights as they are
// on mainnet from crescendo spork
// MainnetExecutionEffortWeights are the execution effort weights as they are on mainnet
var MainnetExecutionEffortWeights = meter.ExecutionEffortWeights{
common.ComputationKindStatement: 314,
common.ComputationKindLoop: 314,
common.ComputationKindFunctionInvocation: 314,
ComputationKindGetValue: 162,
ComputationKindCreateAccount: 567534,
ComputationKindSetValue: 153,
ComputationKindEVMGasUsage: 13,
ComputationKindCreateAccount: 2143437,
ComputationKindBLSVerifyPOP: 1538600,
ComputationKindGetAccountBalance: 485476,
ComputationKindBLSAggregatePublicKeys: 402728,
ComputationKindGetStorageCapacity: 397087,
ComputationKindGetAccountAvailableBalance: 375235,
ComputationKindUpdateAccountContractCode: 369407,
ComputationKindBLSAggregateSignatures: 325309,
ComputationKindGenerateAccountLocalID: 75507,
ComputationKindGetAccountContractNames: 32771,
ComputationKindGetStorageUsed: 25416,
ComputationKindAccountKeysCount: 24709,
ComputationKindAllocateSlabIndex: 15372,
common.ComputationKindAtreeMapGet: 8837,
common.ComputationKindAtreeMapRemove: 7373,
common.ComputationKindCreateArrayValue: 4364,
common.ComputationKindCreateDictionaryValue: 3818,
common.ComputationKindAtreeMapSet: 3656,
common.ComputationKindAtreeArrayInsert: 3652,
common.ComputationKindAtreeMapReadIteration: 3325,
ComputationKindEncodeEvent: 2911,
common.ComputationKindTransferCompositeValue: 2358,
common.ComputationKindAtreeArrayAppend: 1907,
common.ComputationKindStatement: 1770,
common.ComputationKindAtreeArraySet: 1737,
common.ComputationKindFunctionInvocation: 1399,
common.ComputationKindAtreeMapPopIteration: 1210,
common.ComputationKindAtreeArrayPopIteration: 736,
ComputationKindRLPDecoding: 516,
common.ComputationKindGraphemesIteration: 278,
common.ComputationKindUfixParse: 257,
common.ComputationKindFixParse: 223,
common.ComputationKindLoop: 179,
common.ComputationKindAtreeArrayBatchConstruction: 177,
common.ComputationKindTransferDictionaryValue: 125,
common.ComputationKindBigIntParse: 69,
common.ComputationKindTransferArrayValue: 48,
ComputationKindSetValue: 48,
common.ComputationKindUintParse: 31,
common.ComputationKindIntParse: 28,
ComputationKindGetValue: 23,
common.ComputationKindStringToLower: 5,
ComputationKindEVMGasUsage: 3,
}

type Meter interface {
Expand Down
22 changes: 5 additions & 17 deletions fvm/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3672,7 +3672,7 @@ func TestEVMFileSystemContract(t *testing.T) {
require.Equal(t, blockEventPayload.TotalGasUsed-feeTranferEventPayload.GasConsumed, txEventPayload.GasConsumed)
require.Empty(t, txEventPayload.ContractAddress)

require.Greater(t, int(output.ComputationUsed), 400)
require.Greater(t, int(output.ComputationUsed), 900)
},
fvm.WithExecutionEffortWeights(
environment.MainnetExecutionEffortWeights,
Expand All @@ -3692,7 +3692,7 @@ func TestEVMFileSystemContract(t *testing.T) {
testContract *TestContract,
testAccount *EOATestAccount,
) {
state, output := runFileSystemContract(ctx, vm, snapshot, testContract, testAccount, 400)
state, output := runFileSystemContract(ctx, vm, snapshot, testContract, testAccount, 500)
snapshot = snapshot.Append(state)

require.Len(t, output.Events, 0)
Expand All @@ -3708,7 +3708,7 @@ func TestEVMFileSystemContract(t *testing.T) {
require.Equal(t, uint64(0), blockEventPayload.TotalGasUsed)

// only a small amount of computation was used due to the EVM transaction never being executed
require.Less(t, int(output.ComputationUsed), 20)
require.Less(t, int(output.ComputationUsed), 900)
},
fvm.WithExecutionEffortWeights(
environment.MainnetExecutionEffortWeights,
Expand Down Expand Up @@ -4007,13 +4007,7 @@ func getEVMAccountNonce(
func RunWithNewEnvironment(
t *testing.T,
chain flow.Chain,
f func(
fvm.Context,
fvm.VM,
snapshot.SnapshotTree,
*TestContract,
*EOATestAccount,
),
f func(fvm.Context, fvm.VM, snapshot.SnapshotTree, *TestContract, *EOATestAccount),
) {
rootAddr := evm.StorageAccountAddress(chain.ChainID())
RunWithTestBackend(t, func(backend *TestBackend) {
Expand Down Expand Up @@ -4069,13 +4063,7 @@ func RunContractWithNewEnvironment(
t *testing.T,
chain flow.Chain,
tc *TestContract,
f func(
fvm.Context,
fvm.VM,
snapshot.SnapshotTree,
*TestContract,
*EOATestAccount,
),
f func(fvm.Context, fvm.VM, snapshot.SnapshotTree, *TestContract, *EOATestAccount),
Copy link
Contributor Author

@janezpodhostnik janezpodhostnik Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My IDE and my linter constantly disagreed on the formatting of this, so I put it in a single line.

bootstrapOpts ...fvm.BootstrapProcedureOption,
) {
rootAddr := evm.StorageAccountAddress(chain.ChainID())
Expand Down
2 changes: 1 addition & 1 deletion integration/internal/emulator/tests/script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func TestScriptExecutionLimit(t *testing.T) {

t.Parallel()

const limit = 19000
const limit = 25000
b, err := emulator.New(
emulator.WithScriptGasLimit(limit),
)
Expand Down
2 changes: 1 addition & 1 deletion integration/internal/emulator/tests/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1847,7 +1847,7 @@ func TestTransactionExecutionLimit(t *testing.T) {

t.Parallel()

const limit = 19000
const limit = 25000

b, adapter := setupTransactionTests(
t,
Expand Down
9 changes: 4 additions & 5 deletions model/flow/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,14 @@ func paddedDomainTag(s string) [DomainTagLength]byte {
}

// EstimatedComputationPerMillisecond is the approximate number of computation units that can be performed in a millisecond.
// this was calibrated during the Variable Transaction Fees: Execution Effort FLIP https://github.com/onflow/flow/pull/753.
// Updated after the FLIP:
// https://github.com/onflow/flips/blob/14c5ec4/governance/20240508-computation-limit-hike.md#flip-267-increasing-the-transaction-computation-limit
const EstimatedComputationPerMillisecond = 9999.0 / 1000.0
// this was calibrated during the FLIP 346: Variable Transaction Fees - Execution Effort II. https://github.com/onflow/flips/pull/347.
const EstimatedComputationPerMillisecond = 9999.0 / 333.4118

// NormalizedExecutionTimePerComputationUnit returns the normalized time per computation unit
// If the computation estimation is correct (as per the FLIP https://github.com/onflow/flow/pull/753) the value should be 1.
// If the computation estimation is correct (as per the FLIP https://github.com/onflow/flips/pull/347) the value should be 1.
// If the value is greater than 1, the computation estimation is too low; we are underestimating transaction complexity (and thus undercharging).
// If the value is less than 1, the computation estimation is too high; we are overestimating transaction complexity (and thus overcharging).
// This is only used for metrics reporting
func NormalizedExecutionTimePerComputationUnit(execTime time.Duration, computationUsed uint64) float64 {
if computationUsed == 0 {
return 0
Expand Down
10 changes: 6 additions & 4 deletions module/metrics/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,14 +878,16 @@ func (ec *ExecutionCollector) ExecutionBlockCachedPrograms(programs int) {
func (ec *ExecutionCollector) ExecutionTransactionExecuted(
dur time.Duration,
stats module.TransactionExecutionResultStats,
info module.TransactionExecutionResultInfo,
_ module.TransactionExecutionResultInfo,
) {
ec.totalExecutedTransactionsCounter.Inc()
ec.transactionExecutionTime.Observe(float64(dur.Milliseconds()))
ec.transactionConflictRetries.Observe(float64(stats.NumberOfTxnConflictRetries))
ec.transactionComputationUsed.Observe(float64(stats.ComputationUsed))
ec.transactionNormalizedTimePerComputation.Observe(
flow.NormalizedExecutionTimePerComputationUnit(dur, stats.ComputationUsed))
if stats.ComputationUsed > 0 {
ec.transactionNormalizedTimePerComputation.Observe(
flow.NormalizedExecutionTimePerComputationUnit(dur, stats.ComputationUsed))
}
ec.transactionMemoryEstimate.Observe(float64(stats.MemoryUsed))
ec.transactionEmittedEvents.Observe(float64(stats.EventCounts))
ec.transactionEventSize.Observe(float64(stats.EventSize))
Expand All @@ -900,7 +902,7 @@ func (ec *ExecutionCollector) ExecutionChunkDataPackGenerated(proofSize, numberO
ec.chunkDataPackCollectionSize.Observe(float64(numberOfTransactions))
}

// ScriptExecuted reports the time spent executing a single script
// ExecutionScriptExecuted reports the time spent executing a single script
func (ec *ExecutionCollector) ExecutionScriptExecuted(dur time.Duration, compUsed, memoryUsed, memoryEstimated uint64) {
ec.totalExecutedScriptsCounter.Inc()
ec.scriptExecutionTime.Observe(float64(dur.Milliseconds()))
Expand Down
Loading