Skip to content

Commit

Permalink
Merge pull request #6903 from onflow/janez/execution-parameters-from-…
Browse files Browse the repository at this point in the history
…different-account

Move execution parameter to separate account
  • Loading branch information
janezpodhostnik authored Jan 23, 2025
2 parents bcb042d + e657d89 commit 92d5d24
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 17 deletions.
2 changes: 1 addition & 1 deletion fvm/environment/derived_data_invalidator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
13 changes: 9 additions & 4 deletions fvm/executionParameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -143,10 +144,14 @@ func (computer ExecutionParametersComputer) getExecutionParameters() (
derived.StateExecutionParameters,
error,
) {
// Check that the service account exists because all the settings are
// stored in it
serviceAddress := computer.ctx.Chain.ServiceAddress()
service := common.Address(serviceAddress)
sc := systemcontracts.SystemContractsForChain(computer.ctx.Chain.ChainID())

// 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(
context.Background(),
Expand Down
22 changes: 22 additions & 0 deletions fvm/fvm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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) {

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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().
Expand Down Expand Up @@ -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) {

Expand Down Expand Up @@ -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().
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
47 changes: 35 additions & 12 deletions fvm/systemcontracts/system_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ const (

// AccountNameEVMStorage is not a contract, but a special account that is used to store EVM state
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)

Expand Down Expand Up @@ -100,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("6997a2f2cf57b73a")
// executionParametersAddressMainnet is the address of the Execution Parameters contract on Mainnet
executionParametersAddressMainnet = flow.HexToAddress("f426ff57ee8f6110")
)

// SystemContract represents a system contract on a particular chain.
Expand Down Expand Up @@ -149,10 +158,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
Expand Down Expand Up @@ -344,16 +354,28 @@ func init() {
}
}

executionParametersAccountFunc := func(chain flow.ChainID) flow.Address {
switch chain {
case flow.Mainnet:
return executionParametersAddressMainnet
case flow.Testnet:
return executionParametersAddressTestnet
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),
Expand Down Expand Up @@ -406,10 +428,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),
Expand Down

0 comments on commit 92d5d24

Please sign in to comment.