Skip to content

Commit

Permalink
Merge pull request #6322 from onflow/supun/refactor-storage-cap-migra…
Browse files Browse the repository at this point in the history
…tion

Improve storage capability migration
  • Loading branch information
turbolent authored Aug 12, 2024
2 parents 24c54c5 + 5807882 commit d63da0e
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 35 deletions.
18 changes: 11 additions & 7 deletions cmd/util/ledger/migrations/cadence.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ type IssueStorageCapConMigration struct {
accountsCapabilities *capcons.AccountsCapabilities
interpreterMigrationRuntimeConfig InterpreterMigrationRuntimeConfig
programs map[runtime.Location]*interpreter.Program
mapping *capcons.CapabilityMapping
mapping *capcons.PathTypeCapabilityMapping
reporter reporters.ReportWriter
logVerboseDiff bool
verboseErrorOutput bool
Expand All @@ -243,7 +243,7 @@ func NewIssueStorageCapConMigration(
chainID flow.ChainID,
storageDomainCapabilities *capcons.AccountsCapabilities,
programs map[runtime.Location]*interpreter.Program,
capabilityMapping *capcons.CapabilityMapping,
storageCapabilityMapping *capcons.PathTypeCapabilityMapping,
opts Options,
) *IssueStorageCapConMigration {
return &IssueStorageCapConMigration{
Expand All @@ -252,7 +252,7 @@ func NewIssueStorageCapConMigration(
chainID: chainID,
accountsCapabilities: storageDomainCapabilities,
programs: programs,
mapping: capabilityMapping,
mapping: storageCapabilityMapping,
logVerboseDiff: opts.LogVerboseDiff,
verboseErrorOutput: opts.VerboseErrorOutput,
errorMessageHandler: errorMessageHandler,
Expand Down Expand Up @@ -384,7 +384,10 @@ func NewCadence1ValueMigrations(

// Populated by CadenceLinkValueMigration,
// used by CadenceCapabilityValueMigration
capabilityMapping := &capcons.CapabilityMapping{}
privatePublicCapabilityMapping := &capcons.PathCapabilityMapping{}
// Populated by IssueStorageCapConMigration
// used by CadenceCapabilityValueMigration
storageCapabilityMapping := &capcons.PathTypeCapabilityMapping{}

// Populated by StorageCapMigration,
// used by IssueStorageCapConMigration
Expand Down Expand Up @@ -445,7 +448,7 @@ func NewCadence1ValueMigrations(
opts.ChainID,
storageDomainCapabilities,
programs,
capabilityMapping,
storageCapabilityMapping,
opts,
)
return migration.name, migration
Expand All @@ -456,7 +459,7 @@ func NewCadence1ValueMigrations(
rwf,
errorMessageHandler,
programs,
capabilityMapping,
privatePublicCapabilityMapping,
opts,
)
return migration.name, migration
Expand All @@ -466,7 +469,8 @@ func NewCadence1ValueMigrations(
rwf,
errorMessageHandler,
programs,
capabilityMapping,
privatePublicCapabilityMapping,
storageCapabilityMapping,
opts,
)
return migration.name, migration
Expand Down
10 changes: 6 additions & 4 deletions cmd/util/ledger/migrations/cadence_values_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func NewCadence1LinkValueMigration(
rwf reporters.ReportWriterFactory,
errorMessageHandler *errorMessageHandler,
programs map[runtime.Location]*interpreter.Program,
capabilityMapping *capcons.CapabilityMapping,
capabilityMapping *capcons.PathCapabilityMapping,
opts Options,
) *CadenceBaseMigration {
var diffReporter reporters.ReportWriter
Expand Down Expand Up @@ -380,7 +380,8 @@ func NewCadence1CapabilityValueMigration(
rwf reporters.ReportWriterFactory,
errorMessageHandler *errorMessageHandler,
programs map[runtime.Location]*interpreter.Program,
capabilityMapping *capcons.CapabilityMapping,
privatePublicCapabilityMapping *capcons.PathCapabilityMapping,
storageCapabilityMapping *capcons.PathTypeCapabilityMapping,
opts Options,
) *CadenceBaseMigration {
var diffReporter reporters.ReportWriter
Expand All @@ -402,8 +403,9 @@ func NewCadence1CapabilityValueMigration(
) []migrations.ValueMigration {
return []migrations.ValueMigration{
&capcons.CapabilityValueMigration{
CapabilityMapping: capabilityMapping,
Reporter: reporter,
PrivatePublicCapabilityMapping: privatePublicCapabilityMapping,
StorageCapabilityMapping: storageCapabilityMapping,
Reporter: reporter,
},
}
},
Expand Down
137 changes: 122 additions & 15 deletions cmd/util/ledger/migrations/cadence_values_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/onflow/cadence/runtime"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/interpreter"
"github.com/onflow/cadence/runtime/sema"
Expand Down Expand Up @@ -2162,16 +2163,47 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
addressB, err := common.HexToAddress("0xe5a8b7f23e8b548f")
require.NoError(t, err)

runtime, err := NewInterpreterMigrationRuntime(
addressC, err := common.HexToAddress("0x1")
require.NoError(t, err)

// Store a contract in `addressC`.

const contractName = "Test"
contractAddress := addressC

err = registersByAccount.Set(
string(contractAddress[:]),
flow.ContractKey(contractName),
[]byte(`
pub contract Test {
access(all) resource R {}
}
`),
)
require.NoError(t, err)

encodedContractNames, err := environment.EncodeContractNames([]string{contractName})
require.NoError(t, err)

err = registersByAccount.Set(
string(contractAddress[:]),
flow.ContractNamesKey,
encodedContractNames,
)
require.NoError(t, err)

migrationRuntime, err := NewInterpreterMigrationRuntime(
registersByAccount,
chainID,
InterpreterMigrationRuntimeConfig{},
)
require.NoError(t, err)

storage := runtime.Storage
storage := migrationRuntime.Storage
storageDomain := common.PathDomainStorage.Identifier()

// Store a capability with storage path

storageMap := storage.GetStorageMap(
addressA,
storageDomain,
Expand All @@ -2184,8 +2216,6 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
interpreter.PrimitiveStaticTypeAnyStruct,
)

// Store a capability with storage path

fooCapStorageMapKey := interpreter.StringStorageMapKey("fooCap")

capabilityFoo := &interpreter.PathCapabilityValue{
Expand All @@ -2198,7 +2228,7 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
}

storageMap.WriteValue(
runtime.Interpreter,
migrationRuntime.Interpreter,
fooCapStorageMapKey,
capabilityFoo,
)
Expand All @@ -2216,16 +2246,47 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
}

storageMap.WriteValue(
runtime.Interpreter,
migrationRuntime.Interpreter,
barCapStorageMapKey,
capabilityBar,
)

err = storage.NondeterministicCommit(runtime.Interpreter, false)
// Store a third capability with storage path, and with a broken type

bazBorrowType := interpreter.NewReferenceStaticType(
nil,
interpreter.UnauthorizedAccess,
interpreter.NewCompositeStaticTypeComputeTypeID(
nil,
common.NewAddressLocation(nil, contractAddress, "Test"),
"Test.R",
),
)

bazCapStorageMapKey := interpreter.StringStorageMapKey("bazCap")

bazCapability := &interpreter.PathCapabilityValue{
BorrowType: bazBorrowType,
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "baz"),

// Important: Capability must be for a different address,
// compared to where the capability is stored.
Address: interpreter.AddressValue(addressB),
}

storageMap.WriteValue(
migrationRuntime.Interpreter,
bazCapStorageMapKey,
bazCapability,
)

// Commit

err = storage.NondeterministicCommit(migrationRuntime.Interpreter, false)
require.NoError(t, err)

// finalize the transaction
result, err := runtime.TransactionState.FinalizeMainTransaction()
result, err := migrationRuntime.TransactionState.FinalizeMainTransaction()
require.NoError(t, err)

// Merge the changes into the registers
Expand Down Expand Up @@ -2275,26 +2336,43 @@ func TestStoragePathCapabilityMigration(t *testing.T) {

reporter := rwf.reportWriters[capabilityValueMigrationReporterName]
require.NotNil(t, reporter)
require.Len(t, reporter.entries, 3)
require.Len(t, reporter.entries, 5)

require.Equal(
t,
[]any{
capabilityMissingCapabilityIDEntry{
storageCapConsMissingBorrowTypeEntry{
AccountAddress: addressA,
AddressPath: interpreter.AddressPath{
Address: addressB,
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "bar"),
},
},
capabilityMigrationEntry{
AccountAddress: addressA,
AddressPath: interpreter.AddressPath{
Address: addressB,
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "baz"),
},
BorrowType: bazBorrowType,
CapabilityID: 3,
},
cadenceValueMigrationEntry{
StorageKey: interpreter.StorageKey{
Key: storageDomain,
Address: addressA,
},
StorageMapKey: bazCapStorageMapKey,
Migration: "CapabilityValueMigration",
},
capabilityMigrationEntry{
AccountAddress: addressA,
AddressPath: interpreter.AddressPath{
Address: addressB,
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "foo"),
},
BorrowType: borrowType,
CapabilityID: 3,
CapabilityID: 4,
},
cadenceValueMigrationEntry{
StorageKey: interpreter.StorageKey{
Expand All @@ -2310,7 +2388,7 @@ func TestStoragePathCapabilityMigration(t *testing.T) {

issueStorageCapConReporter := rwf.reportWriters[issueStorageCapConMigrationReporterName]
require.NotNil(t, issueStorageCapConReporter)
require.Len(t, issueStorageCapConReporter.entries, 2)
require.Len(t, issueStorageCapConReporter.entries, 3)
require.Equal(
t,
[]any{
Expand All @@ -2321,14 +2399,23 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "bar"),
},
},
storageCapConIssuedEntry{
AccountAddress: addressB,
AddressPath: interpreter.AddressPath{
Address: addressB,
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "baz"),
},
BorrowType: bazBorrowType,
CapabilityID: 3,
},
storageCapConIssuedEntry{
AccountAddress: addressB,
AddressPath: interpreter.AddressPath{
Address: addressB,
Path: interpreter.NewUnmeteredPathValue(common.PathDomainStorage, "foo"),
},
BorrowType: borrowType,
CapabilityID: 3,
CapabilityID: 4,
},
},
issueStorageCapConReporter.entries,
Expand All @@ -2347,7 +2434,7 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
let storage = getAuthAccount<auth(Storage) &Account>(%s).storage
let fooCap = storage.copy<Capability>(from: /storage/fooCap)!
let barCap = storage.copy<Capability>(from: /storage/barCap)!
assert(fooCap.id == 3)
assert(fooCap.id == 4)
assert(barCap.id == 0)
}
`,
Expand All @@ -2356,6 +2443,26 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
)
require.NoError(t, err)

// check the cap with the broken type

_, err = runScript(
chainID,
registersByAccount,
fmt.Sprintf(
//language=Cadence
`
access(all)
fun main() {
let storage = getAuthAccount<auth(Storage) &Account>(%s).storage
let bazCap = storage.copy<Capability>(from: /storage/bazCap)!
}
`,
addressA.HexWithPrefix(),
),
)
require.Error(t, err)
require.ErrorAs(t, &runtime.ParsingCheckingError{}, &err)

// Check account B

_, err = runScript(
Expand All @@ -2369,7 +2476,7 @@ func TestStoragePathCapabilityMigration(t *testing.T) {
let capabilities = getAuthAccount<auth(Capabilities) &Account>(%s).capabilities.storage
let fooCapCons = capabilities.getControllers(forPath: /storage/foo)
assert(fooCapCons.length == 1)
assert(fooCapCons[0].capabilityID == 3)
assert(fooCapCons[0].capabilityID == 4)
}
`,
addressB.HexWithPrefix(),
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ require (
github.com/multiformats/go-multiaddr-dns v0.3.1
github.com/multiformats/go-multihash v0.2.3
github.com/onflow/atree v0.8.0-rc.5
github.com/onflow/cadence v1.0.0-preview.44
github.com/onflow/cadence v1.0.0-preview.45
github.com/onflow/crypto v0.25.1
github.com/onflow/flow v0.3.4
github.com/onflow/flow-core-contracts/lib/go/contracts v1.3.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2167,8 +2167,8 @@ github.com/onflow/atree v0.8.0-rc.5/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/
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.0.0-M3/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8=
github.com/onflow/cadence v1.0.0-preview.44 h1:APQ8DzIS6kX4FMZsaYoucbvF/PPwjHEerr+aGRDcPz4=
github.com/onflow/cadence v1.0.0-preview.44/go.mod h1:BCoenp1TYp+SmG7FGWStjehvvzcvNQ3xvpK5rkthq3Y=
github.com/onflow/cadence v1.0.0-preview.45 h1:vWX+HI1SvxaG47FL2XW80rxjAhV88oySLB5vAoOtnXI=
github.com/onflow/cadence v1.0.0-preview.45/go.mod h1:BCoenp1TYp+SmG7FGWStjehvvzcvNQ3xvpK5rkthq3Y=
github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI=
github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A=
github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI=
Expand Down
2 changes: 1 addition & 1 deletion insecure/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ require (
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onflow/atree v0.8.0-rc.5 // indirect
github.com/onflow/cadence v1.0.0-preview.44 // indirect
github.com/onflow/cadence v1.0.0-preview.45 // indirect
github.com/onflow/flow-core-contracts/lib/go/contracts v1.3.1 // indirect
github.com/onflow/flow-core-contracts/lib/go/templates v1.3.1 // indirect
github.com/onflow/flow-ft/lib/go/contracts v1.0.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions insecure/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2157,8 +2157,8 @@ github.com/onflow/atree v0.6.1-0.20230711151834-86040b30171f/go.mod h1:xvP61FoOs
github.com/onflow/atree v0.8.0-rc.5 h1:1sU+c6UfDzq/EjM8nTw4EI8GvEMarcxkWkJKy6piFSY=
github.com/onflow/atree v0.8.0-rc.5/go.mod h1:yccR+LR7xc1Jdic0mrjocbHvUD7lnVvg8/Ct1AA5zBo=
github.com/onflow/cadence v1.0.0-M3/go.mod h1:odXGZZ/wGNA5mwT8bC9v8u8EXACHllB2ABSZK65TGL8=
github.com/onflow/cadence v1.0.0-preview.44 h1:APQ8DzIS6kX4FMZsaYoucbvF/PPwjHEerr+aGRDcPz4=
github.com/onflow/cadence v1.0.0-preview.44/go.mod h1:BCoenp1TYp+SmG7FGWStjehvvzcvNQ3xvpK5rkthq3Y=
github.com/onflow/cadence v1.0.0-preview.45 h1:vWX+HI1SvxaG47FL2XW80rxjAhV88oySLB5vAoOtnXI=
github.com/onflow/cadence v1.0.0-preview.45/go.mod h1:BCoenp1TYp+SmG7FGWStjehvvzcvNQ3xvpK5rkthq3Y=
github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI=
github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A=
github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI=
Expand Down
2 changes: 1 addition & 1 deletion integration/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/ipfs/go-ds-badger2 v0.1.3
github.com/ipfs/go-ds-pebble v0.3.1
github.com/libp2p/go-libp2p v0.32.2
github.com/onflow/cadence v1.0.0-preview.44
github.com/onflow/cadence v1.0.0-preview.45
github.com/onflow/crypto v0.25.1
github.com/onflow/flow-core-contracts/lib/go/contracts v1.3.1
github.com/onflow/flow-core-contracts/lib/go/templates v1.3.1
Expand Down
Loading

0 comments on commit d63da0e

Please sign in to comment.