From 6f1bdf6d6639b803613114432cec183e3ad86a96 Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Wed, 15 Jan 2025 19:25:25 +0100 Subject: [PATCH 1/5] move execution parameter to separate account --- fvm/executionParameters.go | 6 ++-- fvm/systemcontracts/system_contracts.go | 39 ++++++++++++++++--------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/fvm/executionParameters.go b/fvm/executionParameters.go index 5d4fd4febdd..a57cd755276 100644 --- a/fvm/executionParameters.go +++ b/fvm/executionParameters.go @@ -19,6 +19,7 @@ import ( "github.com/onflow/flow-go/fvm/storage" "github.com/onflow/flow-go/fvm/storage/derived" "github.com/onflow/flow-go/fvm/storage/state" + "github.com/onflow/flow-go/fvm/systemcontracts" ) func ProcedureStateParameters( @@ -143,10 +144,11 @@ func (computer ExecutionParametersComputer) getExecutionParameters() ( derived.StateExecutionParameters, error, ) { + sc := systemcontracts.SystemContractsForChain(computer.ctx.Chain.ChainID()) + // Check that the service account exists because all the settings are // stored in it - serviceAddress := computer.ctx.Chain.ServiceAddress() - service := common.Address(serviceAddress) + service := common.Address(sc.ExecutionParametersAccount.Address) env := environment.NewScriptEnv( context.Background(), diff --git a/fvm/systemcontracts/system_contracts.go b/fvm/systemcontracts/system_contracts.go index 3760044698e..b288630511b 100644 --- a/fvm/systemcontracts/system_contracts.go +++ b/fvm/systemcontracts/system_contracts.go @@ -46,7 +46,8 @@ const ( ContractNameCrypto = "Crypto" // AccountNameEVMStorage is not a contract, but a special account that is used to store EVM state - AccountNameEVMStorage = "EVMStorageAccount" + AccountNameEVMStorage = "EVMStorageAccount" + AccountNameExecutionParametersAccount = "ExecutionParametersAccount" // Unqualified names of service events (not including address prefix or contract name) @@ -149,10 +150,11 @@ type SystemContracts struct { DKG SystemContract // service account related contracts - FlowServiceAccount SystemContract - NodeVersionBeacon SystemContract - RandomBeaconHistory SystemContract - FlowStorageFees SystemContract + FlowServiceAccount SystemContract + NodeVersionBeacon SystemContract + RandomBeaconHistory SystemContract + FlowStorageFees SystemContract + ExecutionParametersAccount SystemContract // token related contracts FlowFees SystemContract @@ -344,16 +346,26 @@ func init() { } } + executionParametersAccountFunc := func(chain flow.ChainID) flow.Address { + switch chain { + case flow.Testnet: + return flow.HexToAddress("b118676e2f11145f") + default: + return serviceAddressFunc(chain) + } + } + contractAddressFunc = map[string]func(id flow.ChainID) flow.Address{ ContractNameIDTableStaking: epochAddressFunc, ContractNameEpoch: epochAddressFunc, ContractNameClusterQC: epochAddressFunc, ContractNameDKG: epochAddressFunc, - ContractNameNodeVersionBeacon: serviceAddressFunc, - ContractNameRandomBeaconHistory: serviceAddressFunc, - ContractNameServiceAccount: serviceAddressFunc, - ContractNameStorageFees: serviceAddressFunc, + ContractNameNodeVersionBeacon: serviceAddressFunc, + ContractNameRandomBeaconHistory: serviceAddressFunc, + ContractNameServiceAccount: serviceAddressFunc, + ContractNameStorageFees: serviceAddressFunc, + AccountNameExecutionParametersAccount: executionParametersAccountFunc, ContractNameFlowFees: nthAddressFunc(FlowFeesAccountIndex), ContractNameFungibleToken: nthAddressFunc(FungibleTokenAccountIndex), @@ -406,10 +418,11 @@ func init() { ClusterQC: addressOfContract(ContractNameClusterQC), DKG: addressOfContract(ContractNameDKG), - FlowServiceAccount: addressOfContract(ContractNameServiceAccount), - NodeVersionBeacon: addressOfContract(ContractNameNodeVersionBeacon), - RandomBeaconHistory: addressOfContract(ContractNameRandomBeaconHistory), - FlowStorageFees: addressOfContract(ContractNameStorageFees), + FlowServiceAccount: addressOfContract(ContractNameServiceAccount), + NodeVersionBeacon: addressOfContract(ContractNameNodeVersionBeacon), + RandomBeaconHistory: addressOfContract(ContractNameRandomBeaconHistory), + FlowStorageFees: addressOfContract(ContractNameStorageFees), + ExecutionParametersAccount: addressOfContract(AccountNameExecutionParametersAccount), FlowFees: addressOfContract(ContractNameFlowFees), FlowToken: addressOfContract(ContractNameFlowToken), From 9f5d2e9877c99019a4a1928edfdd5c43a5a70832 Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Wed, 15 Jan 2025 22:04:28 +0100 Subject: [PATCH 2/5] cleanup --- fvm/executionParameters.go | 7 +++++-- fvm/systemcontracts/system_contracts.go | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/fvm/executionParameters.go b/fvm/executionParameters.go index a57cd755276..48b28d6c2af 100644 --- a/fvm/executionParameters.go +++ b/fvm/executionParameters.go @@ -146,8 +146,11 @@ func (computer ExecutionParametersComputer) getExecutionParameters() ( ) { sc := systemcontracts.SystemContractsForChain(computer.ctx.Chain.ChainID()) - // Check that the service account exists because all the settings are - // stored in it + // The execution parameters are stored in the ExecutionParametersAccount. This is + // just the service account for all networks except mainnet and testnet. + // For mainnet and testnet, the execution parameters are stored in a separate + // account, so that they are separated from the frequently changing data on the + // service account. service := common.Address(sc.ExecutionParametersAccount.Address) env := environment.NewScriptEnv( diff --git a/fvm/systemcontracts/system_contracts.go b/fvm/systemcontracts/system_contracts.go index b288630511b..26428c2875a 100644 --- a/fvm/systemcontracts/system_contracts.go +++ b/fvm/systemcontracts/system_contracts.go @@ -46,7 +46,10 @@ const ( ContractNameCrypto = "Crypto" // AccountNameEVMStorage is not a contract, but a special account that is used to store EVM state - AccountNameEVMStorage = "EVMStorageAccount" + AccountNameEVMStorage = "EVMStorageAccount" + // AccountNameExecutionParametersAccount is not a contract, but a special account that is used to store execution parameters + // This is generally just the service account. For mainnet and testnet, it is a separate account, + // in order to separate it away from the frequently changing data on the service account. AccountNameExecutionParametersAccount = "ExecutionParametersAccount" // Unqualified names of service events (not including address prefix or contract name) @@ -101,6 +104,11 @@ var ( evmStorageAddressTestnet = flow.HexToAddress("1a54ed2be7552821") // evmStorageAddressMainnet is the address of the EVM state storage contract on Mainnet evmStorageAddressMainnet = flow.HexToAddress("d421a63faae318f9") + + // executionParametersAddressTestnet is the address of the Execution Parameters contract on Testnet + executionParametersAddressTestnet = flow.HexToAddress("00000000000") + // executionParametersAddressMainnet is the address of the Execution Parameters contract on Mainnet + executionParametersAddressMainnet = flow.HexToAddress("00000000000") ) // SystemContract represents a system contract on a particular chain. @@ -348,8 +356,10 @@ func init() { executionParametersAccountFunc := func(chain flow.ChainID) flow.Address { switch chain { + case flow.Mainnet: + return executionParametersAddressMainnet case flow.Testnet: - return flow.HexToAddress("b118676e2f11145f") + return executionParametersAddressTestnet default: return serviceAddressFunc(chain) } From 1b095120f7086aa487b90d33aa1c2fffd7d534c7 Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Thu, 16 Jan 2025 15:44:32 +0100 Subject: [PATCH 3/5] set testnet account --- fvm/systemcontracts/system_contracts.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fvm/systemcontracts/system_contracts.go b/fvm/systemcontracts/system_contracts.go index 26428c2875a..0391221a80f 100644 --- a/fvm/systemcontracts/system_contracts.go +++ b/fvm/systemcontracts/system_contracts.go @@ -106,9 +106,10 @@ var ( evmStorageAddressMainnet = flow.HexToAddress("d421a63faae318f9") // executionParametersAddressTestnet is the address of the Execution Parameters contract on Testnet - executionParametersAddressTestnet = flow.HexToAddress("00000000000") + executionParametersAddressTestnet = flow.HexToAddress("a71b77409f5acbc1") // executionParametersAddressMainnet is the address of the Execution Parameters contract on Mainnet - executionParametersAddressMainnet = flow.HexToAddress("00000000000") + // TODO: update this address once the Execution Parameters contract is deployed on Mainnet + executionParametersAddressMainnet = flow.HexToAddress("TODO") ) // SystemContract represents a system contract on a particular chain. From 764c368aef63b74b979adfb163672985c95219ba Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Thu, 16 Jan 2025 18:13:57 +0100 Subject: [PATCH 4/5] fix tests --- .../derived_data_invalidator_test.go | 2 +- fvm/fvm_test.go | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/fvm/environment/derived_data_invalidator_test.go b/fvm/environment/derived_data_invalidator_test.go index 147c03fb57a..9598d93f4b1 100644 --- a/fvm/environment/derived_data_invalidator_test.go +++ b/fvm/environment/derived_data_invalidator_test.go @@ -244,7 +244,7 @@ func TestMeterParamOverridesUpdated(t *testing.T) { snapshotTree := snapshot.NewSnapshotTree(nil) - ctx := fvm.NewContext(fvm.WithChain(flow.Testnet.Chain())) + ctx := fvm.NewContext(fvm.WithChain(flow.Emulator.Chain())) vm := fvm.NewVirtualMachine() executionSnapshot, _, err := vm.Run( diff --git a/fvm/fvm_test.go b/fvm/fvm_test.go index eaa8bef6c85..503b9fb5cc7 100644 --- a/fvm/fvm_test.go +++ b/fvm/fvm_test.go @@ -1083,7 +1083,11 @@ func TestTransactionFeeDeduction(t *testing.T) { func TestSettingExecutionWeights(t *testing.T) { + // change the chain so that the metering settings are read from the service account + chain := flow.Emulator.Chain() + t.Run("transaction should fail with high weights", newVMTest().withBootstrapProcedureOptions( + fvm.WithMinimumStorageReservation(fvm.DefaultMinimumStorageReservation), fvm.WithAccountCreationFee(fvm.DefaultAccountCreationFee), fvm.WithStorageMBPerFLOW(fvm.DefaultStorageMBPerFLOW), @@ -1092,6 +1096,8 @@ func TestSettingExecutionWeights(t *testing.T) { common.ComputationKindLoop: 100_000 << meter.MeterExecutionInternalPrecisionBytes, }, ), + ).withContextOptions( + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { @@ -1140,6 +1146,7 @@ func TestSettingExecutionWeights(t *testing.T) { ), ).withContextOptions( fvm.WithMemoryLimit(10_000_000_000), + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { // Create an account private key. @@ -1190,6 +1197,7 @@ func TestSettingExecutionWeights(t *testing.T) { ), ).withContextOptions( fvm.WithMemoryLimit(10_000_000_000), + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { @@ -1234,6 +1242,8 @@ func TestSettingExecutionWeights(t *testing.T) { fvm.WithExecutionMemoryWeights( memoryWeights, ), + ).withContextOptions( + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { privateKeys, err := testutil.GenerateAccountPrivateKeys(1) @@ -1301,6 +1311,8 @@ func TestSettingExecutionWeights(t *testing.T) { environment.ComputationKindCreateAccount: (fvm.DefaultComputationLimit + 1) << meter.MeterExecutionInternalPrecisionBytes, }, ), + ).withContextOptions( + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { txBody := flow.NewTransactionBody(). @@ -1337,6 +1349,8 @@ func TestSettingExecutionWeights(t *testing.T) { environment.ComputationKindCreateAccount: 100_000_000 << meter.MeterExecutionInternalPrecisionBytes, }, ), + ).withContextOptions( + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { @@ -1374,6 +1388,8 @@ func TestSettingExecutionWeights(t *testing.T) { environment.ComputationKindCreateAccount: 100_000_000 << meter.MeterExecutionInternalPrecisionBytes, }, ), + ).withContextOptions( + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { txBody := flow.NewTransactionBody(). @@ -1417,6 +1433,7 @@ func TestSettingExecutionWeights(t *testing.T) { fvm.WithAccountStorageLimit(true), fvm.WithTransactionFeesEnabled(true), fvm.WithMemoryLimit(math.MaxUint64), + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { // Use the maximum amount of computation so that the transaction still passes. @@ -1510,6 +1527,7 @@ func TestSettingExecutionWeights(t *testing.T) { fvm.WithAccountStorageLimit(true), fvm.WithTransactionFeesEnabled(true), fvm.WithMemoryLimit(math.MaxUint64), + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { // Create an account private key. @@ -2165,6 +2183,8 @@ func TestScriptExecutionLimit(t *testing.T) { t.Parallel() + chain := flow.Emulator.Chain() + script := fvm.Script([]byte(` access(all) fun main() { var s: Int256 = 1024102410241024 @@ -2206,6 +2226,7 @@ func TestScriptExecutionLimit(t *testing.T) { fvm.WithTransactionFeesEnabled(true), fvm.WithAccountStorageLimit(true), fvm.WithComputationLimit(10000), + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { scriptCtx := fvm.NewContextFromParent(ctx) @@ -2228,6 +2249,7 @@ func TestScriptExecutionLimit(t *testing.T) { fvm.WithTransactionFeesEnabled(true), fvm.WithAccountStorageLimit(true), fvm.WithComputationLimit(20000), + fvm.WithChain(chain), ).run( func(t *testing.T, vm fvm.VM, chain flow.Chain, ctx fvm.Context, snapshotTree snapshot.SnapshotTree) { scriptCtx := fvm.NewContextFromParent(ctx) From e657d8953d765043b42450fe39e27535e2c12079 Mon Sep 17 00:00:00 2001 From: Janez Podhostnik Date: Tue, 21 Jan 2025 18:48:53 +0100 Subject: [PATCH 5/5] update accounts --- fvm/systemcontracts/system_contracts.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fvm/systemcontracts/system_contracts.go b/fvm/systemcontracts/system_contracts.go index 0391221a80f..775649c565c 100644 --- a/fvm/systemcontracts/system_contracts.go +++ b/fvm/systemcontracts/system_contracts.go @@ -106,10 +106,9 @@ var ( evmStorageAddressMainnet = flow.HexToAddress("d421a63faae318f9") // executionParametersAddressTestnet is the address of the Execution Parameters contract on Testnet - executionParametersAddressTestnet = flow.HexToAddress("a71b77409f5acbc1") + executionParametersAddressTestnet = flow.HexToAddress("6997a2f2cf57b73a") // executionParametersAddressMainnet is the address of the Execution Parameters contract on Mainnet - // TODO: update this address once the Execution Parameters contract is deployed on Mainnet - executionParametersAddressMainnet = flow.HexToAddress("TODO") + executionParametersAddressMainnet = flow.HexToAddress("f426ff57ee8f6110") ) // SystemContract represents a system contract on a particular chain.