diff --git a/cmd/util/ledger/util/atree_util.go b/cmd/util/ledger/util/atree_util.go index 73fd30812e3..5354247f805 100644 --- a/cmd/util/ledger/util/atree_util.go +++ b/cmd/util/ledger/util/atree_util.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/onflow/atree" + "github.com/onflow/cadence/interpreter" "github.com/onflow/cadence/common" "github.com/onflow/cadence/runtime" @@ -104,10 +105,11 @@ func LoadAtreeSlabsInStorage( } func CheckStorageHealth( + inter *interpreter.Interpreter, address common.Address, storage *runtime.Storage, registers registers.Registers, - domains []string, + domains []common.StorageDomain, nWorkers int, ) error { @@ -117,7 +119,7 @@ func CheckStorageHealth( } for _, domain := range domains { - _ = storage.GetStorageMap(address, domain, false) + _ = storage.GetDomainStorageMap(inter, address, domain, false) } return storage.CheckHealth() diff --git a/cmd/util/ledger/util/util.go b/cmd/util/ledger/util/util.go index 14af2ae3b29..62fcf601dc7 100644 --- a/cmd/util/ledger/util/util.go +++ b/cmd/util/ledger/util/util.go @@ -10,8 +10,6 @@ import ( "github.com/onflow/atree" "github.com/onflow/cadence/common" - "github.com/onflow/cadence/runtime" - "github.com/onflow/cadence/stdlib" "github.com/onflow/flow-go/fvm/environment" "github.com/onflow/flow-go/ledger" @@ -247,15 +245,3 @@ func (p *PayloadsLedger) AllocateSlabIndex(owner []byte) (atree.SlabIndex, error panic("AllocateSlabIndex not expected to be called") } - -var StorageMapDomains = []string{ - common.PathDomainStorage.Identifier(), - common.PathDomainPrivate.Identifier(), - common.PathDomainPublic.Identifier(), - runtime.StorageDomainContract, - stdlib.InboxStorageDomain, - stdlib.CapabilityControllerStorageDomain, - stdlib.CapabilityControllerTagStorageDomain, - stdlib.PathCapabilityStorageDomain, - stdlib.AccountCapabilityStorageDomain, -} diff --git a/engine/execution/computation/computer/computer_test.go b/engine/execution/computation/computer/computer_test.go index 0d7899100ad..620bdf30bc1 100644 --- a/engine/execution/computation/computer/computer_test.go +++ b/engine/execution/computation/computer/computer_test.go @@ -598,7 +598,8 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { // create a block with 2 collections with 2 transactions each block := generateBlock(collectionCount, transactionsPerCollection, rag) - serviceEvents := systemcontracts.ServiceEventsForChain(execCtx.Chain.ChainID()) + chainID := execCtx.Chain.ChainID() + serviceEvents := systemcontracts.ServiceEventsForChain(chainID) randomSource := unittest.EpochSetupRandomSourceFixture() payload, err := ccf.Decode(nil, unittest.EpochSetupFixtureCCF(randomSource)) @@ -700,6 +701,7 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { reusableRuntime.NewCustomReusableCadenceRuntimePool( 0, runtime.Config{}, + chainID, func(_ runtime.Config) runtime.Runtime { return emittingRuntime }, @@ -747,7 +749,7 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { // make sure event index sequence are valid for i := 0; i < result.BlockExecutionResult.Size(); i++ { collectionResult := result.CollectionExecutionResultAt(i) - unittest.EnsureEventsIndexSeq(t, collectionResult.Events(), execCtx.Chain.ChainID()) + unittest.EnsureEventsIndexSeq(t, collectionResult.Events(), chainID) } sEvents := result.AllServiceEvents() // all events should have been collected @@ -815,6 +817,7 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { reusableRuntime.NewCustomReusableCadenceRuntimePool( 0, runtime.Config{}, + execCtx.Chain.ChainID(), func(_ runtime.Config) runtime.Runtime { return rt })), @@ -930,6 +933,7 @@ func TestBlockExecutor_ExecuteBlock(t *testing.T) { reusableRuntime.NewCustomReusableCadenceRuntimePool( 0, runtime.Config{}, + execCtx.Chain.ChainID(), func(_ runtime.Config) runtime.Runtime { return rt })), diff --git a/engine/execution/computation/manager.go b/engine/execution/computation/manager.go index e13a2d03791..b3f76a433cf 100644 --- a/engine/execution/computation/manager.go +++ b/engine/execution/computation/manager.go @@ -233,6 +233,7 @@ func DefaultFVMOptions(chainID flow.ChainID, cadenceTracing bool, extensiveTraci runtime.Config{ TracingEnabled: cadenceTracing, }, + chainID, )), fvm.WithEVMEnabled(true), } diff --git a/engine/execution/computation/manager_benchmark_test.go b/engine/execution/computation/manager_benchmark_test.go index d22b1ec9a8b..338bda23129 100644 --- a/engine/execution/computation/manager_benchmark_test.go +++ b/engine/execution/computation/manager_benchmark_test.go @@ -160,6 +160,7 @@ func benchmarkComputeBlock( reusableRuntime.NewReusableCadenceRuntimePool( ReusableCadenceRuntimePoolSize, runtime.Config{}, + chainID, )), ) snapshotTree := testutil.RootBootstrappedLedger( diff --git a/fvm/accountV2Migration/AccountV2Migration.cdc b/fvm/accountV2Migration/AccountV2Migration.cdc new file mode 100644 index 00000000000..67c73c8e94d --- /dev/null +++ b/fvm/accountV2Migration/AccountV2Migration.cdc @@ -0,0 +1,102 @@ +access(all) +contract AccountV2Migration { + + access(all) + enum StorageFormat: UInt8 { + access(all) + case Unknown + + access(all) + case V1 + + access(all) + case V2 + } + + access(all) + event Migrated( + addressStartIndex: UInt64, + count: UInt64 + ) + + access(all) + resource Admin { + access(all) + fun setEnabled(_ isEnabled: Bool) { + AccountV2Migration.isEnabled = isEnabled + } + + access(all) + fun setNextAddressStartIndex(_ nextAddressStartIndex: UInt64) { + AccountV2Migration.nextAddressStartIndex = nextAddressStartIndex + } + + access(all) + fun setBatchSize(_ batchSize: UInt64) { + AccountV2Migration.batchSize = batchSize + } + + access(all) + fun migrateNextBatch() { + AccountV2Migration.migrateNextBatch() + } + } + + access(all) + let adminStoragePath: StoragePath + + access(all) + var isEnabled: Bool + + access(all) + var nextAddressStartIndex: UInt64 + + access(all) + var batchSize: UInt64 + + init() { + self.adminStoragePath = /storage/accountV2MigrationAdmin + self.isEnabled = false + self.nextAddressStartIndex = 1 + self.batchSize = 10 + + self.account.storage.save( + <-create Admin(), + to: self.adminStoragePath + ) + } + + access(contract) + fun migrateNextBatch() { + if !self.isEnabled { + return + } + + let batchSize = self.batchSize + if batchSize <= 0 { + return + } + + let startIndex = self.nextAddressStartIndex + + if !scheduleAccountV2Migration( + addressStartIndex: startIndex, + count: batchSize + ) { + return + } + + self.nextAddressStartIndex = startIndex + batchSize + + emit Migrated( + addressStartIndex: startIndex, + count: batchSize + ) + } + + access(all) + fun getAccountStorageFormat(address: Address): StorageFormat? { + let rawStorageFormat = getAccountStorageFormat(address: address) + return StorageFormat(rawValue: rawStorageFormat) + } +} diff --git a/fvm/accountV2Migration/contract.go b/fvm/accountV2Migration/contract.go new file mode 100644 index 00000000000..17c807cbaaf --- /dev/null +++ b/fvm/accountV2Migration/contract.go @@ -0,0 +1,224 @@ +package accountV2Migration + +import ( + _ "embed" + + "github.com/onflow/cadence/common" + cadenceErrors "github.com/onflow/cadence/errors" + "github.com/onflow/cadence/interpreter" + "github.com/onflow/cadence/runtime" + "github.com/onflow/cadence/sema" + "github.com/onflow/cadence/stdlib" + + "github.com/onflow/flow-go/fvm/errors" + "github.com/onflow/flow-go/model/flow" +) + +//go:embed AccountV2Migration.cdc +var ContractCode []byte + +const ContractName = "AccountV2Migration" + +const scheduleAccountV2MigrationFunctionName = "scheduleAccountV2Migration" + +// scheduleAccountV2MigrationType is the type of the `scheduleAccountV2Migration` function. +// This defines the signature as `func(addressStartIndex: UInt64, count: UInt64): Bool` +var scheduleAccountV2MigrationType = &sema.FunctionType{ + Parameters: []sema.Parameter{ + { + Identifier: "addressStartIndex", + TypeAnnotation: sema.UInt64TypeAnnotation, + }, + { + Identifier: "count", + TypeAnnotation: sema.UInt64TypeAnnotation, + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.BoolType), +} + +func DeclareFunctions(environment runtime.Environment, chainID flow.ChainID) { + declareScheduleAccountV2MigrationFunction(environment, chainID) + declareGetAccountStorageFormatFunction(environment) +} + +func declareScheduleAccountV2MigrationFunction(environment runtime.Environment, chainID flow.ChainID) { + + functionType := scheduleAccountV2MigrationType + + functionValue := stdlib.StandardLibraryValue{ + Name: scheduleAccountV2MigrationFunctionName, + Type: functionType, + Kind: common.DeclarationKindFunction, + Value: interpreter.NewUnmeteredStaticHostFunctionValue( + functionType, + func(invocation interpreter.Invocation) interpreter.Value { + inter := invocation.Interpreter + + // Get interpreter storage + + storage := inter.Storage() + + runtimeStorage, ok := storage.(*runtime.Storage) + if !ok { + panic(cadenceErrors.NewUnexpectedError("interpreter storage is not a runtime.Storage")) + } + + // Check the number of arguments + + actualArgumentCount := len(invocation.Arguments) + expectedArgumentCount := len(functionType.Parameters) + + if actualArgumentCount != expectedArgumentCount { + panic(errors.NewInvalidArgumentErrorf( + "incorrect number of arguments: got %d, expected %d", + actualArgumentCount, + expectedArgumentCount, + )) + } + + // Get addressStartIndex argument + + firstArgument := invocation.Arguments[0] + addressStartIndexValue, ok := firstArgument.(interpreter.UInt64Value) + if !ok { + panic(errors.NewInvalidArgumentErrorf( + "incorrect type for argument 0: got `%s`, expected `%s`", + firstArgument.StaticType(inter), + sema.UInt64Type, + )) + } + addressStartIndex := uint64(addressStartIndexValue) + + // Get count argument + + secondArgument := invocation.Arguments[1] + countValue, ok := secondArgument.(interpreter.UInt64Value) + if !ok { + panic(errors.NewInvalidArgumentErrorf( + "incorrect type for argument 1: got `%s`, expected `%s`", + secondArgument.StaticType(inter), + sema.UInt64Type, + )) + } + count := uint64(countValue) + + // Schedule the account V2 migration for addresses + + addressGenerator := chainID.Chain().NewAddressGeneratorAtIndex(addressStartIndex) + for i := uint64(0); i < count; i++ { + address, err := addressGenerator.NextAddress() + if err != nil { + panic(err) + } + + if !runtimeStorage.ScheduleV2Migration(common.Address(address)) { + return interpreter.FalseValue + } + } + + return interpreter.TrueValue + }, + ), + } + + // TODO: restrict, but requires to be set during bootstrapping + //sc := systemcontracts.SystemContractsForChain(chainID) + // + //accountV2MigrationLocation := common.NewAddressLocation( + // nil, + // common.Address(sc.AccountV2Migration.Address), + // ContractName, + //) + + environment.DeclareValue( + functionValue, + // TODO: accountV2MigrationLocation, + nil, + ) +} + +const getAccountStorageFormatFunctionName = "getAccountStorageFormat" + +// getAccountStorageFormatType is the type of the `getAccountStorageFormat` function. +// This defines the signature as `func(address: Address): UInt8` +var getAccountStorageFormatType = &sema.FunctionType{ + Parameters: []sema.Parameter{ + { + Identifier: "address", + TypeAnnotation: sema.AddressTypeAnnotation, + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.UInt8Type), +} + +func declareGetAccountStorageFormatFunction(environment runtime.Environment) { + + functionType := getAccountStorageFormatType + + functionValue := stdlib.StandardLibraryValue{ + Name: getAccountStorageFormatFunctionName, + Type: functionType, + Kind: common.DeclarationKindFunction, + Value: interpreter.NewUnmeteredStaticHostFunctionValue( + functionType, + func(invocation interpreter.Invocation) interpreter.Value { + inter := invocation.Interpreter + + // Get interpreter storage + + storage := inter.Storage() + + runtimeStorage, ok := storage.(*runtime.Storage) + if !ok { + panic(cadenceErrors.NewUnexpectedError("interpreter storage is not a runtime.Storage")) + } + + // Check the number of arguments + + actualArgumentCount := len(invocation.Arguments) + expectedArgumentCount := len(functionType.Parameters) + + if actualArgumentCount != expectedArgumentCount { + panic(errors.NewInvalidArgumentErrorf( + "incorrect number of arguments: got %d, expected %d", + actualArgumentCount, + expectedArgumentCount, + )) + } + + // Get addressStartIndex argument + + firstArgument := invocation.Arguments[0] + addressValue, ok := firstArgument.(interpreter.AddressValue) + if !ok { + panic(errors.NewInvalidArgumentErrorf( + "incorrect type for argument 0: got `%s`, expected `%s`", + firstArgument.StaticType(inter), + sema.TheAddressType, + )) + } + address := common.Address(addressValue) + + // Get and return the storage format for the account + + return interpreter.UInt8Value(runtimeStorage.AccountStorageFormat(address)) + }, + ), + } + + // TODO: restrict, but requires to be set during bootstrapping + //sc := systemcontracts.SystemContractsForChain(chainID) + // + //accountV2MigrationLocation := common.NewAddressLocation( + // nil, + // common.Address(sc.AccountV2Migration.Address), + // ContractName, + //) + + environment.DeclareValue( + functionValue, + // TODO: accountV2MigrationLocation, + nil, + ) +} diff --git a/fvm/accounts_test.go b/fvm/accounts_test.go index 3cbffead859..a43e293cadb 100644 --- a/fvm/accounts_test.go +++ b/fvm/accounts_test.go @@ -1758,3 +1758,35 @@ func TestGetStorageCapacity(t *testing.T) { }), ) } + +func TestAccountV2Migration_getAccountStorageFormat(t *testing.T) { + + t.Run( + "service account", + newVMTest().run(func( + t *testing.T, + vm fvm.VM, + chain flow.Chain, + ctx fvm.Context, + snapshotTree snapshot.SnapshotTree, + ) { + serviceAddress := chain.ServiceAddress() + + script := fvm.Script([]byte(fmt.Sprintf( + ` + import AccountV2Migration from %[1]s + + access(all) fun main() { + let storageFormat = AccountV2Migration.getAccountStorageFormat(address: %[1]s) + assert(storageFormat == AccountV2Migration.StorageFormat.V1) + } + `, + serviceAddress.HexWithPrefix(), + ))) + + _, output, err := vm.Run(ctx, script, snapshotTree) + require.NoError(t, err) + require.NoError(t, output.Err) + }), + ) +} diff --git a/fvm/blueprints/scripts/systemChunkTransactionTemplate.cdc b/fvm/blueprints/scripts/systemChunkTransactionTemplate.cdc index 7c9564e1486..5e868aa66b7 100644 --- a/fvm/blueprints/scripts/systemChunkTransactionTemplate.cdc +++ b/fvm/blueprints/scripts/systemChunkTransactionTemplate.cdc @@ -2,6 +2,7 @@ import FlowEpoch from "FlowEpoch" import NodeVersionBeacon from "NodeVersionBeacon" import RandomBeaconHistory from "RandomBeaconHistory" import EVM from "EVM" +import AccountV2Migration from "AccountV2Migration" transaction { prepare(serviceAccount: auth(BorrowValue) &Account) { @@ -19,9 +20,12 @@ transaction { ?? panic("Couldn't borrow RandomBeaconHistory.Heartbeat Resource") randomBeaconHistoryHeartbeat.heartbeat(randomSourceHistory: randomSourceHistory()) - let evmHeartbeat = serviceAccount.storage.borrow<&EVM.Heartbeat>(from: /storage/EVMHeartbeat) - if evmHeartbeat != nil { // skip if not available - evmHeartbeat!.heartbeat() - } + let evmHeartbeat = serviceAccount.storage + .borrow<&EVM.Heartbeat>(from: /storage/EVMHeartbeat) + evmHeartbeat?.heartbeat() + + let accountV2MigrationAdmin = serviceAccount.storage + .borrow<&AccountV2Migration.Admin>(from: AccountV2Migration.adminStoragePath) + accountV2MigrationAdmin?.migrateNextBatch() } } diff --git a/fvm/blueprints/system.go b/fvm/blueprints/system.go index 466f8ee47f9..46c5ffb61a7 100644 --- a/fvm/blueprints/system.go +++ b/fvm/blueprints/system.go @@ -21,7 +21,9 @@ var systemChunkTransactionTemplate string // TODO: when the EVM contract is moved to the flow-core-contracts, we can // just directly use the replace address functionality of the templates package. -var placeholderEVMAddress = "\"EVM\"" +const placeholderEVMAddress = "\"EVM\"" + +const placeholderAccountV2MigrationAddress = "\"AccountV2Migration\"" func prepareSystemContractCode(chainID flow.ChainID) string { sc := systemcontracts.SystemContractsForChain(chainID) @@ -34,6 +36,11 @@ func prepareSystemContractCode(chainID flow.ChainID) string { placeholderEVMAddress, sc.EVMContract.Address.HexWithPrefix(), ) + code = strings.ReplaceAll( + code, + placeholderAccountV2MigrationAddress, + sc.AccountV2Migration.Address.HexWithPrefix(), + ) return code } diff --git a/fvm/bootstrap.go b/fvm/bootstrap.go index 0f3526c8d83..10e89692cb8 100644 --- a/fvm/bootstrap.go +++ b/fvm/bootstrap.go @@ -8,6 +8,7 @@ import ( "github.com/onflow/flow-core-contracts/lib/go/contracts" "github.com/onflow/flow-core-contracts/lib/go/templates" + "github.com/onflow/flow-go/fvm/accountV2Migration" "github.com/onflow/flow-go/fvm/blueprints" "github.com/onflow/flow-go/fvm/environment" "github.com/onflow/flow-go/fvm/errors" @@ -447,6 +448,8 @@ func (b *bootstrapExecutor) Execute() error { // set the list of nodes which are allowed to stake in this network b.setStakingAllowlist(service, b.identities.NodeIDs()) + b.deployAccountV2MigrationContract(service) + return nil } @@ -1067,6 +1070,19 @@ func (b *bootstrapExecutor) deployStakingCollection( panicOnMetaInvokeErrf("failed to deploy FlowStakingCollection contract: %s", txError, err) } +func (b *bootstrapExecutor) deployAccountV2MigrationContract(deployTo flow.Address) { + tx := blueprints.DeployContractTransaction( + deployTo, + accountV2Migration.ContractCode, + accountV2Migration.ContractName, + ) + txError, err := b.invokeMetaTransaction( + b.ctx, + Transaction(tx, 0), + ) + panicOnMetaInvokeErrf("failed to deploy AccountV2Migration contract: %s", txError, err) +} + func (b *bootstrapExecutor) setContractDeploymentRestrictions( service flow.Address, deployment *bool, diff --git a/fvm/context.go b/fvm/context.go index fd198633b54..9c9f212cd0e 100644 --- a/fvm/context.go +++ b/fvm/context.go @@ -95,8 +95,8 @@ func WithChain(chain flow.Chain) Option { } } -// WithGasLimit sets the computation limit for a virtual machine context. -// @depricated, please use WithComputationLimit instead. +// Deprecated: WithGasLimit sets the computation limit for a virtual machine context. +// Use WithComputationLimit instead. func WithGasLimit(limit uint64) Option { return func(ctx Context) Context { ctx.ComputationLimit = limit diff --git a/fvm/environment/env.go b/fvm/environment/env.go index e23e9c64deb..31538eee086 100644 --- a/fvm/environment/env.go +++ b/fvm/environment/env.go @@ -113,11 +113,11 @@ type EnvironmentParams struct { } func DefaultEnvironmentParams() EnvironmentParams { + const chainID = flow.Mainnet return EnvironmentParams{ - Chain: flow.Mainnet.Chain(), + Chain: chainID.Chain(), ServiceAccountEnabled: true, - - RuntimeParams: DefaultRuntimeParams(), + RuntimeParams: DefaultRuntimeParams(chainID), ProgramLoggerParams: DefaultProgramLoggerParams(), EventEmitterParams: DefaultEventEmitterParams(), BlockInfoParams: DefaultBlockInfoParams(), diff --git a/fvm/environment/runtime.go b/fvm/environment/runtime.go index ace1bfce698..a542989212f 100644 --- a/fvm/environment/runtime.go +++ b/fvm/environment/runtime.go @@ -4,17 +4,19 @@ import ( cadenceRuntime "github.com/onflow/cadence/runtime" "github.com/onflow/flow-go/fvm/runtime" + "github.com/onflow/flow-go/model/flow" ) type RuntimeParams struct { runtime.ReusableCadenceRuntimePool } -func DefaultRuntimeParams() RuntimeParams { +func DefaultRuntimeParams(chainID flow.ChainID) RuntimeParams { return RuntimeParams{ ReusableCadenceRuntimePool: runtime.NewReusableCadenceRuntimePool( 0, cadenceRuntime.Config{}, + chainID, ), } } diff --git a/fvm/environment/system_contracts_test.go b/fvm/environment/system_contracts_test.go index e5870107956..77e8ea4a6a0 100644 --- a/fvm/environment/system_contracts_test.go +++ b/fvm/environment/system_contracts_test.go @@ -54,10 +54,13 @@ func TestSystemContractsInvoke(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + const chainID = flow.Mainnet + tracer := tracing.NewTracerSpan() runtimePool := reusableRuntime.NewCustomReusableCadenceRuntimePool( 0, runtime.Config{}, + chainID, func(_ runtime.Config) runtime.Runtime { return &testutil.TestInterpreterRuntime{ InvokeContractFunc: tc.contractFunction, @@ -70,7 +73,7 @@ func TestSystemContractsInvoke(t *testing.T) { }, ) invoker := environment.NewSystemContracts( - flow.Mainnet.Chain(), + chainID.Chain(), tracer, environment.NewProgramLogger( tracer, diff --git a/fvm/executionParameters_test.go b/fvm/executionParameters_test.go index da40c12c281..cc81703a1f1 100644 --- a/fvm/executionParameters_test.go +++ b/fvm/executionParameters_test.go @@ -19,6 +19,7 @@ import ( "github.com/onflow/flow-go/fvm/meter" reusableRuntime "github.com/onflow/flow-go/fvm/runtime" "github.com/onflow/flow-go/fvm/runtime/testutil" + "github.com/onflow/flow-go/model/flow" ) func TestGetExecutionMemoryWeights(t *testing.T) { @@ -36,6 +37,7 @@ func TestGetExecutionMemoryWeights(t *testing.T) { ReadStoredFunc: readStored, }, runtime.Config{}, + flow.Emulator, ), ) envMock.On("ReturnCadenceRuntime", mock.Anything).Return() @@ -166,6 +168,7 @@ func TestGetExecutionEffortWeights(t *testing.T) { ReadStoredFunc: readStored, }, runtime.Config{}, + flow.Emulator, ), ) envMock.On("ReturnCadenceRuntime", mock.Anything).Return() diff --git a/fvm/fvm_bench_test.go b/fvm/fvm_bench_test.go index 566cf81653a..4c0d97f23f5 100644 --- a/fvm/fvm_bench_test.go +++ b/fvm/fvm_bench_test.go @@ -165,6 +165,7 @@ func NewBasicBlockExecutor(tb testing.TB, chain flow.Chain, logger zerolog.Logge reusableRuntime.NewReusableCadenceRuntimePool( computation.ReusableCadenceRuntimePoolSize, runtime.Config{}, + chain.ChainID(), ), ), fvm.WithEVMEnabled(true), diff --git a/fvm/fvm_test.go b/fvm/fvm_test.go index eedc9e50c8b..651f422e3c5 100644 --- a/fvm/fvm_test.go +++ b/fvm/fvm_test.go @@ -2451,6 +2451,7 @@ func TestCapabilityControllers(t *testing.T) { reusableRuntime.NewReusableCadenceRuntimePool( 1, runtime.Config{}, + flow.Emulator, ), ), ). @@ -2505,6 +2506,7 @@ func TestStorageIterationWithBrokenValues(t *testing.T) { reusableRuntime.NewReusableCadenceRuntimePool( 1, runtime.Config{}, + flow.Emulator, ), ), fvm.WithContractDeploymentRestricted(false), diff --git a/fvm/runtime/reusable_cadence_runtime.go b/fvm/runtime/reusable_cadence_runtime.go index 138156897b1..e3aa21955b3 100644 --- a/fvm/runtime/reusable_cadence_runtime.go +++ b/fvm/runtime/reusable_cadence_runtime.go @@ -8,7 +8,9 @@ import ( "github.com/onflow/cadence/sema" "github.com/onflow/cadence/stdlib" + "github.com/onflow/flow-go/fvm/accountV2Migration" "github.com/onflow/flow-go/fvm/errors" + "github.com/onflow/flow-go/model/flow" ) // Note: this is a subset of environment.Environment, redeclared to handle @@ -20,9 +22,8 @@ type Environment interface { } // randomSourceFunctionType is the type of the `randomSource` function. -// This defies the signature as `func (): [UInt8]` +// This defines the signature as `func(): [UInt8]` var randomSourceFunctionType = &sema.FunctionType{ - Parameters: []sema.Parameter{}, ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType), } @@ -34,13 +35,25 @@ type ReusableCadenceRuntime struct { fvmEnv Environment } -func NewReusableCadenceRuntime(rt runtime.Runtime, config runtime.Config) *ReusableCadenceRuntime { +func NewReusableCadenceRuntime( + rt runtime.Runtime, + config runtime.Config, + chainID flow.ChainID, +) *ReusableCadenceRuntime { reusable := &ReusableCadenceRuntime{ Runtime: rt, TxRuntimeEnv: runtime.NewBaseInterpreterEnvironment(config), ScriptRuntimeEnv: runtime.NewScriptInterpreterEnvironment(config), } + reusable.declareRandomSourceHistory() + accountV2Migration.DeclareFunctions(reusable.TxRuntimeEnv, chainID) + + return reusable +} + +func (reusable *ReusableCadenceRuntime) declareRandomSourceHistory() { + // Declare the `randomSourceHistory` function. This function is **only** used by the // System transaction, to fill the `RandomBeaconHistory` contract via the heartbeat // resource. This allows the `RandomBeaconHistory` contract to be a standard contract, @@ -49,22 +62,32 @@ func NewReusableCadenceRuntime(rt runtime.Runtime, config runtime.Config) *Reusa // it is not part of the cadence standard library, and can just be injected from here. // It also doesnt need user documentation, since it is not (and should not) // be called by the user. If it is called by the user it will panic. + functionType := randomSourceFunctionType + blockRandomSource := stdlib.StandardLibraryValue{ Name: "randomSourceHistory", - Type: randomSourceFunctionType, + Type: functionType, Kind: common.DeclarationKindFunction, Value: interpreter.NewUnmeteredStaticHostFunctionValue( - randomSourceFunctionType, + functionType, func(invocation interpreter.Invocation) interpreter.Value { - if len(invocation.Arguments) != 0 { + + actualArgumentCount := len(invocation.Arguments) + expectedArgumentCount := len(functionType.Parameters) + + if actualArgumentCount != expectedArgumentCount { panic(errors.NewInvalidArgumentErrorf( - "randomSourceHistory should be called without arguments")) + "incorrect number of arguments: got %d, expected %d", + actualArgumentCount, + expectedArgumentCount, + )) } var err error var source []byte - if reusable.fvmEnv != nil { - source, err = reusable.fvmEnv.RandomSourceHistory() + fvmEnv := reusable.fvmEnv + if fvmEnv != nil { + source, err = fvmEnv.RandomSourceHistory() } else { err = errors.NewOperationNotSupportedError("randomSourceHistory") } @@ -81,8 +104,6 @@ func NewReusableCadenceRuntime(rt runtime.Runtime, config runtime.Config) *Reusa } reusable.TxRuntimeEnv.DeclareValue(blockRandomSource, nil) - - return reusable } func (reusable *ReusableCadenceRuntime) SetFvmEnvironment(fvmEnv Environment) { @@ -165,6 +186,8 @@ type ReusableCadenceRuntimePool struct { config runtime.Config + chainID flow.ChainID + // When newCustomRuntime is nil, the pool will create standard cadence // interpreter runtimes via runtime.NewInterpreterRuntime. Otherwise, the // pool will create runtimes using this function. @@ -176,6 +199,7 @@ type ReusableCadenceRuntimePool struct { func newReusableCadenceRuntimePool( poolSize int, config runtime.Config, + chainID flow.ChainID, newCustomRuntime CadenceRuntimeConstructor, ) ReusableCadenceRuntimePool { var pool chan *ReusableCadenceRuntime @@ -186,6 +210,7 @@ func newReusableCadenceRuntimePool( return ReusableCadenceRuntimePool{ pool: pool, config: config, + chainID: chainID, newCustomRuntime: newCustomRuntime, } } @@ -193,10 +218,12 @@ func newReusableCadenceRuntimePool( func NewReusableCadenceRuntimePool( poolSize int, config runtime.Config, + chainID flow.ChainID, ) ReusableCadenceRuntimePool { return newReusableCadenceRuntimePool( poolSize, config, + chainID, nil, ) } @@ -204,11 +231,13 @@ func NewReusableCadenceRuntimePool( func NewCustomReusableCadenceRuntimePool( poolSize int, config runtime.Config, + chainID flow.ChainID, newCustomRuntime CadenceRuntimeConstructor, ) ReusableCadenceRuntimePool { return newReusableCadenceRuntimePool( poolSize, config, + chainID, newCustomRuntime, ) } @@ -233,6 +262,7 @@ func (pool ReusableCadenceRuntimePool) Borrow( pool.newRuntime(), }, pool.config, + pool.chainID, ) } diff --git a/fvm/runtime/reusable_cadence_runtime_test.go b/fvm/runtime/reusable_cadence_runtime_test.go index 758fa2f7426..590a31a4034 100644 --- a/fvm/runtime/reusable_cadence_runtime_test.go +++ b/fvm/runtime/reusable_cadence_runtime_test.go @@ -5,10 +5,12 @@ import ( "github.com/onflow/cadence/runtime" "github.com/stretchr/testify/require" + + "github.com/onflow/flow-go/model/flow" ) func TestReusableCadenceRuntimePoolUnbuffered(t *testing.T) { - pool := NewReusableCadenceRuntimePool(0, runtime.Config{}) + pool := NewReusableCadenceRuntimePool(0, runtime.Config{}, flow.Emulator) require.Nil(t, pool.pool) entry := pool.Borrow(nil) @@ -23,7 +25,7 @@ func TestReusableCadenceRuntimePoolUnbuffered(t *testing.T) { } func TestReusableCadenceRuntimePoolBuffered(t *testing.T) { - pool := NewReusableCadenceRuntimePool(100, runtime.Config{}) + pool := NewReusableCadenceRuntimePool(100, runtime.Config{}, flow.Emulator) require.NotNil(t, pool.pool) select { @@ -50,7 +52,7 @@ func TestReusableCadenceRuntimePoolBuffered(t *testing.T) { } func TestReusableCadenceRuntimePoolSharing(t *testing.T) { - pool := NewReusableCadenceRuntimePool(100, runtime.Config{}) + pool := NewReusableCadenceRuntimePool(100, runtime.Config{}, flow.Emulator) require.NotNil(t, pool.pool) select { @@ -59,7 +61,7 @@ func TestReusableCadenceRuntimePoolSharing(t *testing.T) { default: } - var otherPool ReusableCadenceRuntimePool = pool + var otherPool = pool entry := otherPool.Borrow(nil) require.NotNil(t, entry) diff --git a/fvm/systemcontracts/system_contracts.go b/fvm/systemcontracts/system_contracts.go index ad9f66c4a65..efb1d250678 100644 --- a/fvm/systemcontracts/system_contracts.go +++ b/fvm/systemcontracts/system_contracts.go @@ -44,6 +44,7 @@ const ( ContractNameEVM = "EVM" ContractNameBurner = "Burner" ContractNameCrypto = "Crypto" + ContractNameAccountV2Migration = "AccountV2Migration" // AccountNameEVMStorage is not a contract, but a special account that is used to store EVM state AccountNameEVMStorage = "EVMStorageAccount" @@ -174,6 +175,9 @@ type SystemContracts struct { // Utility contracts Burner SystemContract Crypto SystemContract + + // Migration contracts + AccountV2Migration SystemContract } // AsTemplateEnv returns a template environment with all system contracts filled in. @@ -233,6 +237,8 @@ func (c SystemContracts) All() []SystemContract { c.Burner, c.Crypto, + + c.AccountV2Migration, } } @@ -371,6 +377,8 @@ func init() { ContractNameBurner: burnerAddressFunc, ContractNameCrypto: serviceAddressFunc, + + ContractNameAccountV2Migration: serviceAddressFunc, } getSystemContractsForChain := func(chainID flow.ChainID) *SystemContracts { @@ -427,6 +435,8 @@ func init() { Burner: addressOfContract(ContractNameBurner), Crypto: addressOfContract(ContractNameCrypto), + + AccountV2Migration: addressOfContract(ContractNameAccountV2Migration), } return contracts diff --git a/go.mod b/go.mod index eacd5e0ded0..3be00ad2a69 100644 --- a/go.mod +++ b/go.mod @@ -47,8 +47,8 @@ require ( github.com/multiformats/go-multiaddr v0.12.2 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multihash v0.2.3 - github.com/onflow/atree v0.8.0 - github.com/onflow/cadence v1.2.2 + github.com/onflow/atree v0.8.1 + github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a github.com/onflow/crypto v0.25.2 github.com/onflow/flow v0.3.4 github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 @@ -68,7 +68,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/vmihailenco/msgpack v4.0.4+incompatible github.com/vmihailenco/msgpack/v4 v4.3.11 go.opentelemetry.io/otel v1.24.0 @@ -297,7 +297,7 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect diff --git a/go.sum b/go.sum index 15ec48eea52..0e794d33c79 100644 --- a/go.sum +++ b/go.sum @@ -711,7 +711,6 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -909,12 +908,12 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= -github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= +github.com/onflow/atree v0.8.1 h1:DAnPnL9/Ks3LaAnkQVokokTBG/znTW0DJfovDtJDhLI= +github.com/onflow/atree v0.8.1/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= github.com/onflow/boxo v0.0.0-20240201202436-f2477b92f483 h1:LpiQhTAfM9CAmNVEs0n//cBBgCg+vJSiIxTHYUklZ84= github.com/onflow/boxo v0.0.0-20240201202436-f2477b92f483/go.mod h1:pIZgTWdm3k3pLF9Uq6MB8JEcW07UDwNJjlXW1HELW80= -github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= -github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= +github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a h1:6Fabl4+VgUu4CT4d2UNAGZ6LU11dczZdCX9WhI0vV/4= +github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a/go.mod h1:9GseQ6usHUS1z+B05g86CH+w406XdMxMIpr+RFrTr/4= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow v0.3.4 h1:FXUWVdYB90f/rjNcY0Owo30gL790tiYff9Pb/sycXYE= @@ -1169,8 +1168,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -1230,11 +1229,10 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/insecure/go.mod b/insecure/go.mod index 2690e0f7796..9ad0b159793 100644 --- a/insecure/go.mod +++ b/insecure/go.mod @@ -14,7 +14,7 @@ require ( github.com/onflow/flow-go v0.36.2-0.20240717162253-d5d2e606ef53 github.com/rs/zerolog v1.29.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/yhassanzadeh13/go-libp2p-pubsub v0.6.11-flow-expose-msg.0.20240220190333-03695dea34a3 // libp2p v0.32.0 go.uber.org/atomic v1.11.0 google.golang.org/grpc v1.63.2 @@ -202,8 +202,8 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onflow/atree v0.8.0 // indirect - github.com/onflow/cadence v1.2.2 // indirect + github.com/onflow/atree v0.8.1 // indirect + github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a // indirect github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 // indirect github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 // indirect github.com/onflow/flow-ft/lib/go/contracts v1.0.1 // indirect @@ -266,7 +266,7 @@ require ( github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect diff --git a/insecure/go.sum b/insecure/go.sum index 8e25d6b07da..f51ddb45d5c 100644 --- a/insecure/go.sum +++ b/insecure/go.sum @@ -660,7 +660,6 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -854,10 +853,10 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= -github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= -github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= -github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= +github.com/onflow/atree v0.8.1 h1:DAnPnL9/Ks3LaAnkQVokokTBG/znTW0DJfovDtJDhLI= +github.com/onflow/atree v0.8.1/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= +github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a h1:6Fabl4+VgUu4CT4d2UNAGZ6LU11dczZdCX9WhI0vV/4= +github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a/go.mod h1:9GseQ6usHUS1z+B05g86CH+w406XdMxMIpr+RFrTr/4= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 h1:R86HaOuk6vpuECZnriEUE7bw9inC2AtdSn8lL/iwQLQ= @@ -1107,8 +1106,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -1170,11 +1169,10 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= diff --git a/integration/go.mod b/integration/go.mod index eff334d5a9d..e10fb1abc5b 100644 --- a/integration/go.mod +++ b/integration/go.mod @@ -20,7 +20,7 @@ require ( github.com/ipfs/go-ds-badger2 v0.1.3 github.com/ipfs/go-ds-pebble v0.3.1-0.20240828032824-d745b9d3200b github.com/libp2p/go-libp2p v0.32.2 - github.com/onflow/cadence v1.2.2 + github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a github.com/onflow/crypto v0.25.2 github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 github.com/onflow/flow-core-contracts/lib/go/templates v1.4.0 @@ -34,7 +34,7 @@ require ( github.com/prometheus/common v0.46.0 github.com/psiemens/graceland v1.0.0 github.com/rs/zerolog v1.29.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 go.einride.tech/pid v0.1.0 go.uber.org/atomic v1.11.0 go.uber.org/mock v0.4.0 @@ -241,7 +241,7 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onflow/atree v0.8.0 // indirect + github.com/onflow/atree v0.8.1 // indirect github.com/onflow/flow-ft/lib/go/contracts v1.0.1 // indirect github.com/onflow/flow-ft/lib/go/templates v1.0.1 // indirect github.com/onflow/flow-nft/lib/go/contracts v1.2.2 // indirect @@ -307,7 +307,7 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/yhassanzadeh13/go-libp2p-pubsub v0.6.11-flow-expose-msg.0.20240220190333-03695dea34a3 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect diff --git a/integration/go.sum b/integration/go.sum index 851b9d536cc..07953dbfb93 100644 --- a/integration/go.sum +++ b/integration/go.sum @@ -560,7 +560,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -732,10 +731,10 @@ github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onflow/atree v0.8.0 h1:qg5c6J1gVDNObughpEeWm8oxqhPGdEyGrda121GM4u0= -github.com/onflow/atree v0.8.0/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo= -github.com/onflow/cadence v1.2.2 h1:LwigF/2lPiXlwX5rFn71KeMpmW5Iu/f/JtsPLLULBCc= -github.com/onflow/cadence v1.2.2/go.mod h1:PYX1xLejqswtDsQzN93x/VpfSKNyjUk6hrkc/mpv7xs= +github.com/onflow/atree v0.8.1 h1:DAnPnL9/Ks3LaAnkQVokokTBG/znTW0DJfovDtJDhLI= +github.com/onflow/atree v0.8.1/go.mod h1:FT6udJF9Q7VQTu3wknDhFX+VV4D44ZGdqtTAE5iztck= +github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a h1:6Fabl4+VgUu4CT4d2UNAGZ6LU11dczZdCX9WhI0vV/4= +github.com/onflow/cadence v1.2.3-0.20241127215308-d0026257ee4a/go.mod h1:9GseQ6usHUS1z+B05g86CH+w406XdMxMIpr+RFrTr/4= github.com/onflow/crypto v0.25.2 h1:GjHunqVt+vPcdqhxxhAXiMIF3YiLX7gTuTR5O+VG2ns= github.com/onflow/crypto v0.25.2/go.mod h1:fY7eLqUdMKV8EGOw301unP8h7PvLVy8/6gVR++/g0BY= github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 h1:R86HaOuk6vpuECZnriEUE7bw9inC2AtdSn8lL/iwQLQ= @@ -965,8 +964,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -1023,11 +1023,10 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= diff --git a/model/flow/address_test.go b/model/flow/address_test.go index 706ae4f7861..e575ff8ea97 100644 --- a/model/flow/address_test.go +++ b/model/flow/address_test.go @@ -149,7 +149,7 @@ func testAddressConstants(t *testing.T) { assert.Equal(t, address, chain.ServiceAddress()) // check high state values: generation should fail for high value states - state = chain.newAddressGeneratorAtIndex(maxIndex - 1) + state = chain.NewAddressGeneratorAtIndex(maxIndex - 1) _, err = state.NextAddress() assert.NoError(t, err) _, err = state.NextAddress() @@ -200,7 +200,7 @@ func testAddressGeneration(t *testing.T) { // this is only a sanity check of the implementation and not an exhaustive proof if chainID == Mainnet { r := uint64(rand.Intn(maxIndex - loop)) - state = chain.newAddressGeneratorAtIndex(r) + state = chain.NewAddressGeneratorAtIndex(r) for i := 0; i < loop; i++ { address, err := state.NextAddress() require.NoError(t, err) @@ -213,7 +213,7 @@ func testAddressGeneration(t *testing.T) { // All distances between any two addresses must be larger than d. // this is only a sanity check of the implementation and not an exhaustive proof r := uint64(rand.Intn(maxIndex - loop - 1)) - state = chain.newAddressGeneratorAtIndex(r) + state = chain.NewAddressGeneratorAtIndex(r) refAddress, err := state.NextAddress() require.NoError(t, err) for i := 0; i < loop; i++ { @@ -226,7 +226,7 @@ func testAddressGeneration(t *testing.T) { // sanity check of valid account addresses. // All valid addresses must pass IsValid. r = uint64(rand.Intn(maxIndex - loop)) - state = chain.newAddressGeneratorAtIndex(r) + state = chain.NewAddressGeneratorAtIndex(r) for i := 0; i < loop; i++ { address, err := state.NextAddress() require.NoError(t, err) @@ -241,7 +241,7 @@ func testAddressGeneration(t *testing.T) { assert.False(t, check, "account address format should be invalid") r = uint64(rand.Intn(maxIndex - loop)) - state = chain.newAddressGeneratorAtIndex(r) + state = chain.NewAddressGeneratorAtIndex(r) for i := 0; i < loop; i++ { address, err := state.NextAddress() require.NoError(t, err) @@ -271,7 +271,7 @@ func testAddressesIntersection(t *testing.T) { // a valid address in one network must be invalid in all other networks r := uint64(rand.Intn(maxIndex - loop)) - state := chain.newAddressGeneratorAtIndex(r) + state := chain.NewAddressGeneratorAtIndex(r) for k := 0; k < loop; k++ { address, err := state.NextAddress() require.NoError(t, err) @@ -297,7 +297,7 @@ func testAddressesIntersection(t *testing.T) { // build invalid addresses using `invalidCodeWord` and make sure they all // fail the check for all networks r = uint64(rand.Intn(maxIndex - loop)) - state = chain.newAddressGeneratorAtIndex(r) + state = chain.NewAddressGeneratorAtIndex(r) for k := 0; k < loop; k++ { address, err := state.NextAddress() require.NoError(t, err) @@ -328,7 +328,7 @@ func testIndexFromAddress(t *testing.T) { // random valid index r := uint64(rand.Intn(maxIndex)) + 1 // generate the address - address := chain.newAddressGeneratorAtIndex(r).CurrentAddress() + address := chain.NewAddressGeneratorAtIndex(r).CurrentAddress() // extract the index and compare index, err := chain.IndexFromAddress(address) assert.NoError(t, err) // address should be valid diff --git a/model/flow/chain.go b/model/flow/chain.go index 1a17e5a164e..1aeed8313e2 100644 --- a/model/flow/chain.go +++ b/model/flow/chain.go @@ -82,7 +82,7 @@ func (c ChainID) getChainCodeWord() uint64 { } type chainImpl interface { - newAddressGeneratorAtIndex(index uint64) AddressGenerator + NewAddressGeneratorAtIndex(index uint64) AddressGenerator // IsValid returns true if a given address is a valid account address on a given chain, // and false otherwise. // @@ -102,7 +102,7 @@ type chainImpl interface { // where addresses are simply the index of the account. type monotonicImpl struct{} -func (m *monotonicImpl) newAddressGeneratorAtIndex(index uint64) AddressGenerator { +func (m *monotonicImpl) NewAddressGeneratorAtIndex(index uint64) AddressGenerator { return &MonotonicAddressGenerator{ index: index, } @@ -131,7 +131,7 @@ type linearCodeImpl struct { chainID ChainID } -func (l *linearCodeImpl) newAddressGeneratorAtIndex(index uint64) AddressGenerator { +func (l *linearCodeImpl) NewAddressGeneratorAtIndex(index uint64) AddressGenerator { return &linearCodeAddressGenerator{ index: index, chainCodeWord: l.chainID.getChainCodeWord(), @@ -262,6 +262,7 @@ func (c ChainID) String() string { // Chain is the interface for address generation implementations. type Chain interface { NewAddressGenerator() AddressGenerator + NewAddressGeneratorAtIndex(index uint64) AddressGenerator AddressAtIndex(index uint64) (Address, error) ServiceAddress() Address BytesToAddressGenerator(b []byte) AddressGenerator @@ -271,13 +272,12 @@ type Chain interface { ChainID() ChainID // required for tests zeroAddress() Address - newAddressGeneratorAtIndex(index uint64) AddressGenerator } // NewAddressGenerator returns a new AddressGenerator with an // initialized index. func (id *addressedChain) NewAddressGenerator() AddressGenerator { - return id.newAddressGeneratorAtIndex(0) + return id.NewAddressGeneratorAtIndex(0) } // AddressAtIndex returns the index-th generated account address. @@ -285,7 +285,7 @@ func (id *addressedChain) AddressAtIndex(index uint64) (Address, error) { if index > maxIndex { return EmptyAddress, fmt.Errorf("index must be less or equal to %x", maxIndex) } - return id.newAddressGeneratorAtIndex(index).CurrentAddress(), nil + return id.NewAddressGeneratorAtIndex(index).CurrentAddress(), nil } // ServiceAddress returns the root (first) generated account address. @@ -307,7 +307,7 @@ func (id *addressedChain) BytesToAddressGenerator(b []byte) AddressGenerator { bytes := slices.EnsureByteSliceSize(b, addressIndexLength) index := uint48(bytes[:]) - return id.newAddressGeneratorAtIndex(index) + return id.NewAddressGeneratorAtIndex(index) } // ChainID returns the chain ID of the chain.