Skip to content

Commit

Permalink
test account v2 format migration of service account
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Dec 5, 2024
1 parent a1ca332 commit 8b597cb
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions fvm/accountV2Migration/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,5 @@ func declareGetAccountStorageFormatFunction(environment runtime.Environment, cha
accountV2MigrationLocation,
)
}

const MigratedEventTypeQualifiedIdentifier = ContractName + ".Migrated"
123 changes: 123 additions & 0 deletions fvm/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import (
"testing"

"github.com/onflow/cadence"
"github.com/onflow/cadence/common"
"github.com/onflow/cadence/encoding/ccf"
jsoncdc "github.com/onflow/cadence/encoding/json"
"github.com/onflow/cadence/format"
"github.com/onflow/cadence/runtime"
"github.com/onflow/cadence/stdlib"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/onflow/flow-go/engine/execution/testutil"
"github.com/onflow/flow-go/fvm"
"github.com/onflow/flow-go/fvm/accountV2Migration"
reusableRuntime "github.com/onflow/flow-go/fvm/runtime"
"github.com/onflow/flow-go/fvm/storage/snapshot"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/utils/unittest"
Expand Down Expand Up @@ -1772,6 +1776,43 @@ func TestAccountV2Migration_getAccountStorageFormat(t *testing.T) {
) {
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)
}),
)
}

func TestAccountV2Migration_migrate(t *testing.T) {

t.Run(
"service account",
newVMTest().withContextOptions(
fvm.WithAuthorizationChecksEnabled(false),
fvm.WithSequenceNumberCheckAndIncrementEnabled(false),
).run(func(
t *testing.T,
vm fvm.VM,
chain flow.Chain,
ctx fvm.Context,
snapshotTree snapshot.SnapshotTree,
) {
serviceAddress := chain.ServiceAddress()

// Ensure the account is in V1 format after bootstrapping

script := fvm.Script([]byte(fmt.Sprintf(
`
import AccountV2Migration from %[1]s
Expand All @@ -1787,6 +1828,88 @@ func TestAccountV2Migration_getAccountStorageFormat(t *testing.T) {
_, output, err := vm.Run(ctx, script, snapshotTree)
require.NoError(t, err)
require.NoError(t, output.Err)

// Enable the storage format V2 feature for all subsequent transactions and scripts

ctx = fvm.NewContextFromParent(
ctx,
fvm.WithReusableCadenceRuntimePool(
reusableRuntime.NewReusableCadenceRuntimePool(
1,
runtime.Config{
StorageFormatV2Enabled: true,

This comment has been minimized.

Copy link
@turbolent

turbolent Dec 5, 2024

Author Member

I guess we need to enable this on a per-network basis, starting with all networks but TN and MN, so we can test it in integration tests (Emulator) and localnet? @onflow/flow-cadence-execution WDYT?

},
),
),
)

// Enable the account V2 migration and migrate the first batch

serviceAddressIndex, err := chain.IndexFromAddress(serviceAddress)
require.NoError(t, err)

batchSize := serviceAddressIndex + 1

tx := fvm.Transaction(
flow.NewTransactionBody().
SetScript([]byte(fmt.Sprintf(
`
import AccountV2Migration from %[1]s
transaction {
prepare(signer: auth(Storage) &Account) {
let admin = signer.storage
.borrow<&AccountV2Migration.Admin>(
from: AccountV2Migration.adminStoragePath
)
?? panic("missing account V2 migration admin resource")
admin.setEnabled(true)
admin.setBatchSize(%[2]d)
admin.migrateNextBatch()
}
}
`,
serviceAddress.HexWithPrefix(),
batchSize,
))).
AddAuthorizer(chain.ServiceAddress()),
0,
)
executionSnapshot, output, err := vm.Run(ctx, tx, snapshotTree)
require.NoError(t, err)
require.NoError(t, output.Err)

require.Len(t, output.Events, 1)

event := output.Events[0]

accountV2MigrationLocation := common.AddressLocation{
Address: common.Address(serviceAddress),
Name: accountV2Migration.ContractName,
}
expectedEventTypeID := accountV2MigrationLocation.
TypeID(nil, accountV2Migration.MigratedEventTypeQualifiedIdentifier)
assert.Equal(t, flow.EventType(expectedEventTypeID), event.Type)

snapshotTree = snapshotTree.Append(executionSnapshot)

// Ensure the account is in V2 format after the migration

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.V2)
}
`,
serviceAddress.HexWithPrefix(),
)))

_, output, err = vm.Run(ctx, script, snapshotTree)
require.NoError(t, err)
require.NoError(t, output.Err)
}),
)
}

0 comments on commit 8b597cb

Please sign in to comment.