From 71b47e86623ef3c3b2943467698a6c9c8657ec0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 9 Aug 2024 19:34:27 -0700 Subject: [PATCH 1/3] merge changes after issuing cap cons --- cmd/util/ledger/migrations/cadence.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cmd/util/ledger/migrations/cadence.go b/cmd/util/ledger/migrations/cadence.go index 9ad27a8f699..e5c0105defe 100644 --- a/cmd/util/ledger/migrations/cadence.go +++ b/cmd/util/ledger/migrations/cadence.go @@ -337,6 +337,27 @@ func (m *IssueStorageCapConMigration) MigrateAccount( m.mapping, ) + // finalize the transaction + result, err := migrationRuntime.TransactionState.FinalizeMainTransaction() + if err != nil { + return fmt.Errorf("failed to finalize main transaction: %w", err) + } + + // Merge the changes into the registers + expectedAddresses := map[flow.Address]struct{}{ + flow.Address(address): {}, + } + + err = registers.ApplyChanges( + accountRegisters, + result.WriteSet, + expectedAddresses, + m.log, + ) + if err != nil { + return fmt.Errorf("failed to apply changes: %w", err) + } + return nil } From c8d1209c93dead2f27ec8cbf165f35762a9d7906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 9 Aug 2024 20:30:29 -0700 Subject: [PATCH 2/3] commit changes to storage --- cmd/util/ledger/migrations/cadence.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmd/util/ledger/migrations/cadence.go b/cmd/util/ledger/migrations/cadence.go index e5c0105defe..69b3948951c 100644 --- a/cmd/util/ledger/migrations/cadence.go +++ b/cmd/util/ledger/migrations/cadence.go @@ -328,8 +328,10 @@ func (m *IssueStorageCapConMigration) MigrateAccount( m.verboseErrorOutput, ) + inter := migrationRuntime.Interpreter + capcons.IssueAccountCapabilities( - migrationRuntime.Interpreter, + inter, reporter, address, accountCapabilities, @@ -337,6 +339,11 @@ func (m *IssueStorageCapConMigration) MigrateAccount( m.mapping, ) + err = migrationRuntime.Storage.NondeterministicCommit(inter, false) + if err != nil { + return fmt.Errorf("failed to commit changes: %w", err) + } + // finalize the transaction result, err := migrationRuntime.TransactionState.FinalizeMainTransaction() if err != nil { From 31f8c0974de8772b15db57326b0dab7db2835d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Fri, 9 Aug 2024 20:30:37 -0700 Subject: [PATCH 3/3] add tests --- .../cadence_values_migration_test.go | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/cmd/util/ledger/migrations/cadence_values_migration_test.go b/cmd/util/ledger/migrations/cadence_values_migration_test.go index 41cfb014803..6bf3a3977b9 100644 --- a/cmd/util/ledger/migrations/cadence_values_migration_test.go +++ b/cmd/util/ledger/migrations/cadence_values_migration_test.go @@ -9,6 +9,7 @@ import ( "testing" _ "github.com/glebarez/go-sqlite" + "github.com/onflow/cadence" migrations2 "github.com/onflow/cadence/migrations" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" @@ -21,6 +22,8 @@ import ( "github.com/onflow/flow-go/cmd/util/ledger/reporters" "github.com/onflow/flow-go/cmd/util/ledger/util" "github.com/onflow/flow-go/cmd/util/ledger/util/registers" + "github.com/onflow/flow-go/engine/execution/computation" + "github.com/onflow/flow-go/fvm" "github.com/onflow/flow-go/fvm/environment" "github.com/onflow/flow-go/fvm/systemcontracts" "github.com/onflow/flow-go/model/flow" @@ -2134,7 +2137,7 @@ func TestCadenceValueMigrationEntry_MarshalJSON(t *testing.T) { ) } -func TestCapabilityMigration(t *testing.T) { +func TestStoragePathCapabilityMigration(t *testing.T) { t.Parallel() rwf := &testReportWriterFactory{} @@ -2330,6 +2333,50 @@ func TestCapabilityMigration(t *testing.T) { }, issueStorageCapConReporter.entries, ) + + // Check account A + + _, err = runScript( + chainID, + registersByAccount, + fmt.Sprintf( + //language=Cadence + ` + access(all) + fun main() { + let storage = getAuthAccount(%s).storage + let fooCap = storage.copy(from: /storage/fooCap)! + let barCap = storage.copy(from: /storage/barCap)! + assert(fooCap.id == 3) + assert(barCap.id == 0) + } + `, + addressA.HexWithPrefix(), + ), + ) + require.NoError(t, err) + + // Check account B + + _, err = runScript( + chainID, + registersByAccount, + fmt.Sprintf( + //language=Cadence + ` + access(all) + fun main() { + let capabilities = getAuthAccount(%s).capabilities.storage + let fooCapCons = capabilities.getControllers(forPath: /storage/foo) + assert(fooCapCons.length == 1) + assert(fooCapCons[0].capabilityID == 3) + } + `, + addressB.HexWithPrefix(), + ), + ) + require.NoError(t, err) + } func TestStorageCapConIssuedEntry_MarshalJSON(t *testing.T) { @@ -2399,3 +2446,35 @@ func TestStorageCapConsMissingBorrowTypeEntry_MarshalJSON(t *testing.T) { string(actual), ) } + +func runScript(chainID flow.ChainID, registersByAccount *registers.ByAccount, script string) (cadence.Value, error) { + options := computation.DefaultFVMOptions(chainID, false, false) + options = append(options, + fvm.WithContractDeploymentRestricted(false), + fvm.WithContractRemovalRestricted(false), + fvm.WithAuthorizationChecksEnabled(false), + fvm.WithSequenceNumberCheckAndIncrementEnabled(false), + fvm.WithTransactionFeesEnabled(false)) + ctx := fvm.NewContext(options...) + + storageSnapshot := registers.StorageSnapshot{ + Registers: registersByAccount, + } + + vm := fvm.NewVirtualMachine() + + _, res, err := vm.Run( + ctx, + fvm.Script([]byte(script)), + storageSnapshot, + ) + if err != nil { + return nil, fmt.Errorf("failed to run transaction: %w", err) + } + + if res.Err != nil { + return nil, fmt.Errorf("transaction failed: %w", res.Err) + } + + return res.Value, nil +}