Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FVM] removing legacy controller from storage #2713

Merged
merged 39 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
15bdb83
remove legacy controller
ramtinms Jun 28, 2022
f2e9a56
fix tests
ramtinms Jun 28, 2022
525064a
update chunk verifier
ramtinms Jun 28, 2022
9594651
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jun 28, 2022
1c5b652
update test
ramtinms Jun 28, 2022
350b57f
Merge branch 'ramtin/fvm-remove-legacy-controller-from-storage' of gi…
ramtinms Jun 28, 2022
3aa817e
update emulator to support controller removal
ramtinms Jun 30, 2022
e31bf71
update flow protobuf version
ramtinms Jun 30, 2022
0a6c9ba
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jun 30, 2022
b1be431
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jun 30, 2022
cf41b3d
go mod tidy
ramtinms Jun 30, 2022
3f13a66
apply PR's comments
ramtinms Jul 5, 2022
a19910a
update flow proto files
ramtinms Jul 5, 2022
c809f99
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 5, 2022
532f26b
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 8, 2022
7015f05
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 8, 2022
9f67777
update flow emulator version
ramtinms Jul 8, 2022
80b77f0
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 8, 2022
5715188
Merge branch 'ramtin/fvm-remove-legacy-controller-from-storage' of gi…
ramtinms Jul 8, 2022
1ceda17
go mod tidy
ramtinms Jul 8, 2022
44527d2
update state commitment
ramtinms Jul 8, 2022
f780410
no in-place payload update
ramtinms Jul 11, 2022
145208f
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 11, 2022
77732a0
expected update to state commitments
ramtinms Jul 11, 2022
5ef08d3
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 11, 2022
0fa917e
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 11, 2022
7e439ba
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 12, 2022
d6e0652
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 12, 2022
5255ed1
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 13, 2022
b07a58b
update recent changes
ramtinms Jul 13, 2022
9e3dc1f
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 13, 2022
9fdd482
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 14, 2022
29a7b31
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 14, 2022
18aaf13
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 15, 2022
30be522
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 15, 2022
6706c4d
apply PR's comment
ramtinms Jul 15, 2022
989ac6d
Merge branch 'ramtin/fvm-remove-legacy-controller-from-storage' of gi…
ramtinms Jul 15, 2022
a1fdcb7
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 15, 2022
652aac3
Merge branch 'master' into ramtin/fvm-remove-legacy-controller-from-s…
ramtinms Jul 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,17 +192,17 @@ func TestExtractExecutionState(t *testing.T) {
func getSampleKeyValues(i int) ([]ledger.Key, []ledger.Value) {
switch i {
case 0:
return []ledger.Key{getKey("", "", "uuid"), getKey("", "", "account_address_state")},
return []ledger.Key{getKey("", "uuid"), getKey("", "account_address_state")},
[]ledger.Value{[]byte{'1'}, []byte{'A'}}
case 1:
return []ledger.Key{getKey("ADDRESS", "ADDRESS", "public_key_count"),
getKey("ADDRESS", "ADDRESS", "public_key_0"),
getKey("ADDRESS", "", "exists"),
getKey("ADDRESS", "", "storage_used")},
return []ledger.Key{getKey("ADDRESS", "public_key_count"),
getKey("ADDRESS", "public_key_0"),
getKey("ADDRESS", "exists"),
getKey("ADDRESS", "storage_used")},
[]ledger.Value{[]byte{1}, []byte("PUBLICKEYXYZ"), []byte{1}, []byte{100}}
case 2:
// TODO change the contract_names to CBOR encoding
return []ledger.Key{getKey("ADDRESS", "ADDRESS", "contract_names"), getKey("ADDRESS", "ADDRESS", "code.mycontract")},
return []ledger.Key{getKey("ADDRESS", "contract_names"), getKey("ADDRESS", "code.mycontract")},
[]ledger.Value{[]byte("mycontract"), []byte("CONTRACT Content")}
default:
keys := make([]ledger.Key, 0)
Expand All @@ -213,17 +213,16 @@ func getSampleKeyValues(i int) ([]ledger.Key, []ledger.Value) {
if err != nil {
panic(err)
}
keys = append(keys, getKey(string(address), "", "test"))
keys = append(keys, getKey(string(address), "test"))
values = append(values, getRandomCadenceValue())
}
return keys, values
}
}

func getKey(owner, controller, key string) ledger.Key {
func getKey(owner, key string) ledger.Key {
return ledger.Key{KeyParts: []ledger.KeyPart{
{Type: uint16(0), Value: []byte(owner)},
{Type: uint16(1), Value: []byte(controller)},
{Type: uint16(2), Value: []byte(key)},
},
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/util/cmd/read-execution-state/list-accounts/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ func run(*cobra.Command, []string) {
log.Fatal().Err(err).Msgf("invalid chain name")
}

ldg := delta.NewView(func(owner, controller, key string) (flow.RegisterValue, error) {
ldg := delta.NewView(func(owner, key string) (flow.RegisterValue, error) {

ledgerKey := executionState.RegisterIDToKey(flow.NewRegisterID(owner, controller, key))
ledgerKey := executionState.RegisterIDToKey(flow.NewRegisterID(owner, key))
path, err := pathfinder.KeyToPath(ledgerKey, complete.DefaultPathFinderVersion)
if err != nil {
log.Fatal().Err(err).Msgf("cannot convert key to path")
Expand Down
22 changes: 6 additions & 16 deletions cmd/util/ledger/migrations/account_status_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ import (
"github.com/onflow/flow-go/ledger/common/utils"
)

func createAccountPayloadKey(a flow.Address, key string) ledger.Key {
return ledger.Key{
KeyParts: []ledger.KeyPart{
ledger.NewKeyPart(0, a.Bytes()),
ledger.NewKeyPart(1, []byte("")),
ledger.NewKeyPart(2, []byte(key)),
},
}
}

func TestAccountStatusMigration(t *testing.T) {
mig := AccountStatusMigration{
Logger: zerolog.Logger{},
Expand All @@ -32,11 +22,11 @@ func TestAccountStatusMigration(t *testing.T) {
address2 := flow.HexToAddress("0x2")

payloads := []ledger.Payload{
{Key: createAccountPayloadKey(address1, state.KeyStorageUsed), Value: utils.Uint64ToBinary(1)},
{Key: createAccountPayloadKey(address1, "other registers"), Value: utils.Uint64ToBinary(2)},
{Key: createAccountPayloadKey(address2, "other registers2"), Value: utils.Uint64ToBinary(3)},
{Key: createAccountPayloadKey(address1, KeyExists), Value: []byte{1}},
{Key: createAccountPayloadKey(address1, KeyAccountFrozen), Value: []byte{1}},
{Key: createPayloadKeyWithLegacyController(address1, state.KeyStorageUsed, true), Value: utils.Uint64ToBinary(1)},
{Key: createPayloadKeyWithLegacyController(address1, "other registers", true), Value: utils.Uint64ToBinary(2)},
{Key: createPayloadKeyWithLegacyController(address2, "other registers2", true), Value: utils.Uint64ToBinary(3)},
{Key: createPayloadKeyWithLegacyController(address1, KeyExists, true), Value: []byte{1}},
{Key: createPayloadKeyWithLegacyController(address1, KeyAccountFrozen, true), Value: []byte{1}},
}

newPayloads, err := mig.Migrate(payloads)
Expand All @@ -48,7 +38,7 @@ func TestAccountStatusMigration(t *testing.T) {
require.True(t, newPayloads[2].Equals(&payloads[2]))

expectedPayload := &ledger.Payload{
Key: createAccountPayloadKey(address1, state.KeyAccountStatus),
Key: createPayloadKeyWithLegacyController(address1, state.KeyAccountStatus, true),
Value: state.NewAccountStatus().ToBytes(),
}
require.True(t, newPayloads[3].Equals(expectedPayload))
Expand Down
40 changes: 19 additions & 21 deletions cmd/util/ledger/migrations/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ func (v *view) MergeView(o state.View) error {
return nil
}

func (v *view) Set(owner, controller, key string, value flow.RegisterValue) error {
return v.Ledger.Set(owner, controller, key, value)
func (v *view) Set(owner, key string, value flow.RegisterValue) error {
return v.Ledger.Set(owner, key, value)
}

func (v *view) Get(owner, controller, key string) (flow.RegisterValue, error) {
value, err := v.Ledger.Get(owner, controller, key)
func (v *view) Get(owner, key string) (flow.RegisterValue, error) {
value, err := v.Ledger.Get(owner, key)
if err != nil {
return nil, err
}
Expand All @@ -58,18 +58,18 @@ func (v *view) Get(owner, controller, key string) (flow.RegisterValue, error) {
}

if v.Parent != nil {
return v.Parent.Get(owner, controller, key)
return v.Parent.Get(owner, key)
}

return nil, nil
}

func (v *view) Touch(owner, controller, key string) error {
return v.Ledger.Touch(owner, controller, key)
func (v *view) Touch(owner, key string) error {
return v.Ledger.Touch(owner, key)
}

func (v *view) Delete(owner, controller, key string) error {
return v.Ledger.Delete(owner, controller, key)
func (v *view) Delete(owner, key string) error {
return v.Ledger.Delete(owner, key)
}

func (v *view) Payloads() []ledger.Payload {
Expand All @@ -88,27 +88,26 @@ type led struct {
payloads map[string]ledger.Payload
}

func (l *led) Set(owner, controller, key string, value flow.RegisterValue) error {
func (l *led) Set(owner, key string, value flow.RegisterValue) error {
keyparts := []ledger.KeyPart{ledger.NewKeyPart(0, []byte(owner)),
ledger.NewKeyPart(1, []byte(controller)),
ledger.NewKeyPart(2, []byte(key))}
fk := fullKey(owner, controller, key)
fk := fullKey(owner, key)
l.payloads[fk] = ledger.Payload{Key: ledger.NewKey(keyparts), Value: ledger.Value(value)}
return nil
}

func (l *led) Get(owner, controller, key string) (flow.RegisterValue, error) {
fk := fullKey(owner, controller, key)
func (l *led) Get(owner, key string) (flow.RegisterValue, error) {
fk := fullKey(owner, key)
return flow.RegisterValue(l.payloads[fk].Value), nil
}

func (l *led) Delete(owner, controller, key string) error {
fk := fullKey(owner, controller, key)
func (l *led) Delete(owner, key string) error {
fk := fullKey(owner, key)
delete(l.payloads, fk)
return nil
}

func (l *led) Touch(owner, controller, key string) error {
func (l *led) Touch(owner, key string) error {
return nil
}

Expand All @@ -124,8 +123,7 @@ func newLed(payloads []ledger.Payload) *led {
mapping := make(map[string]ledger.Payload)
for _, p := range payloads {
fk := fullKey(string(p.Key.KeyParts[0].Value),
string(p.Key.KeyParts[1].Value),
string(p.Key.KeyParts[2].Value))
string(p.Key.KeyParts[1].Value))
mapping[fk] = p
}

Expand All @@ -134,6 +132,6 @@ func newLed(payloads []ledger.Payload) *led {
}
}

func fullKey(owner, controller, key string) string {
return strings.Join([]string{owner, controller, key}, "\x1F")
func fullKey(owner, key string) string {
return strings.Join([]string{owner, key}, "\x1F")
}
38 changes: 20 additions & 18 deletions cmd/util/ledger/migrations/legacy_controller_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (

"github.com/rs/zerolog"

"github.com/onflow/flow-go/fvm/state"
"github.com/onflow/flow-go/engine/execution/state"
fvmState "github.com/onflow/flow-go/fvm/state"
"github.com/onflow/flow-go/ledger"
)

Expand All @@ -19,29 +20,30 @@ type LegacyControllerMigration struct {
}

func (lc *LegacyControllerMigration) Migrate(payload []ledger.Payload) ([]ledger.Payload, error) {
for _, p := range payload {
newPayloads := make([]ledger.Payload, len(payload))
for i, p := range payload {
owner := p.Key.KeyParts[0].Value
controller := p.Key.KeyParts[1].Value
key := p.Key.KeyParts[2].Value

if len(controller) > 0 {
if bytes.Equal(owner, controller) {
//
if string(key) == state.KeyPublicKeyCount || // case - public key count
bytes.HasPrefix(key, []byte("public_key_")) || // case - public keys
string(key) == state.KeyContractNames || // case - contract names
bytes.HasPrefix(key, []byte(state.KeyCode)) { // case - contracts
p.Key.KeyParts[1].Value = []byte("")
continue
}
if bytes.Equal(owner, controller) &&
string(key) != fvmState.KeyPublicKeyCount && // case - public key count
!bytes.HasPrefix(key, []byte("public_key_")) && // case - public keys
string(key) != fvmState.KeyContractNames && // case - contract names
!bytes.HasPrefix(key, []byte(fvmState.KeyCode)) { // case - contracts
lc.Logger.Warn().Msgf("found an unexpected new case of non-empty controller use: %s, %s, %s",
hex.EncodeToString(owner),
hex.EncodeToString(controller),
hex.EncodeToString(key),
)
}
// else we have found an unexpected new case of non-empty controller use
lc.Logger.Warn().Msgf("found an unexpected new case of non-empty controller use: %s, %s, %s",
hex.EncodeToString(owner),
hex.EncodeToString(controller),
hex.EncodeToString(key),
)
}
newKey := ledger.NewKey([]ledger.KeyPart{
ledger.NewKeyPart(state.KeyPartOwner, owner),
ledger.NewKeyPart(state.KeyPartKey, key),
})
newPayloads[i] = *ledger.NewPayload(newKey, p.Value)
}
return payload, nil
return newPayloads, nil
}
45 changes: 36 additions & 9 deletions cmd/util/ledger/migrations/legacy_controller_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ import (
"github.com/onflow/flow-go/ledger/common/utils"
)

func createPayloadKeyWithLegacyController(a flow.Address, key string) ledger.Key {
func createPayloadKeyWithLegacyController(a flow.Address, key string, emptyController bool) ledger.Key {
if emptyController {
return ledger.Key{
KeyParts: []ledger.KeyPart{
ledger.NewKeyPart(0, a.Bytes()),
ledger.NewKeyPart(1, []byte("")),
ledger.NewKeyPart(2, []byte(key)),
},
}
}
return ledger.Key{
KeyParts: []ledger.KeyPart{
ledger.NewKeyPart(0, a.Bytes()),
Expand All @@ -23,6 +32,15 @@ func createPayloadKeyWithLegacyController(a flow.Address, key string) ledger.Key
}
}

func createMigratedPayloadKey(a flow.Address, key string) ledger.Key {
return ledger.Key{
KeyParts: []ledger.KeyPart{
ledger.NewKeyPart(0, a.Bytes()),
ledger.NewKeyPart(2, []byte(key)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use KeyPartOwner | KeyPartController | KeyPartKey here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed at 6706c4d

},
}
}

func TestLegacyControllerMigration(t *testing.T) {
mig := LegacyControllerMigration{
Logger: zerolog.Logger{},
Expand All @@ -32,18 +50,27 @@ func TestLegacyControllerMigration(t *testing.T) {
address2 := flow.HexToAddress("0x2")

payloads := []ledger.Payload{
{Key: createAccountPayloadKey(address1, state.KeyStorageUsed), Value: utils.Uint64ToBinary(1)},
{Key: createPayloadKeyWithLegacyController(address1, state.ContractKey("CoreContract")), Value: utils.Uint64ToBinary(2)},
{Key: createPayloadKeyWithLegacyController(address1, state.KeyContractNames), Value: utils.Uint64ToBinary(3)},
{Key: createPayloadKeyWithLegacyController(address2, state.KeyPublicKey(1)), Value: utils.Uint64ToBinary(4)},
{Key: createPayloadKeyWithLegacyController(address2, state.KeyPublicKeyCount), Value: utils.Uint64ToBinary(4)},
{Key: createPayloadKeyWithLegacyController(address1, state.KeyStorageUsed, false), Value: utils.Uint64ToBinary(1)},
{Key: createPayloadKeyWithLegacyController(address1, state.ContractKey("CoreContract"), true), Value: utils.Uint64ToBinary(2)},
{Key: createPayloadKeyWithLegacyController(address1, state.KeyContractNames, true), Value: utils.Uint64ToBinary(3)},
{Key: createPayloadKeyWithLegacyController(address2, state.KeyPublicKey(1), true), Value: utils.Uint64ToBinary(4)},
{Key: createPayloadKeyWithLegacyController(address2, state.KeyPublicKeyCount, true), Value: utils.Uint64ToBinary(4)},
}

expectedKeys := []ledger.Key{
createMigratedPayloadKey(address1, state.KeyStorageUsed),
createMigratedPayloadKey(address1, state.ContractKey("CoreContract")),
createMigratedPayloadKey(address1, state.KeyContractNames),
createMigratedPayloadKey(address2, state.KeyPublicKey(1)),
createMigratedPayloadKey(address2, state.KeyPublicKeyCount),
}

newPayloads, err := mig.Migrate(payloads)
ramtinms marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(t, err)
require.Equal(t, 5, len(newPayloads))
require.Equal(t, len(payloads), len(newPayloads))

for _, p := range newPayloads {
require.Equal(t, 0, len(p.Key.KeyParts[1].Value))
for i, p := range newPayloads {
require.Equal(t, expectedKeys[i], p.Key)
}

}
5 changes: 2 additions & 3 deletions cmd/util/ledger/migrations/storage_fees_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ func StorageFeesMigration(payload []ledger.Payload) ([]ledger.Payload, error) {

newPayload = append(newPayload, ledger.Payload{
Key: registerIDToKey(flow.RegisterID{
Owner: s,
Controller: "",
Key: "storage_used",
Owner: s,
Key: "storage_used",
}),
Value: utils.Uint64ToBinary(u),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestStorageUsedUpdateMigrationMigration(t *testing.T) {
require.NoError(t, err)

require.Equal(t, len(migratedPayload), len(payload))
require.Equal(t, uint64(52), migratedSize)
require.Equal(t, uint64(48), migratedSize)
})

t.Run("fix storage used if used to high", func(t *testing.T) {
Expand All @@ -50,7 +50,7 @@ func TestStorageUsedUpdateMigrationMigration(t *testing.T) {
require.NoError(t, err)

require.Equal(t, len(migratedPayload), len(payload))
require.Equal(t, uint64(52), migratedSize)
require.Equal(t, uint64(48), migratedSize)
})

t.Run("do not fix storage used if storage used ok", func(t *testing.T) {
Expand All @@ -65,7 +65,7 @@ func TestStorageUsedUpdateMigrationMigration(t *testing.T) {
require.NoError(t, err)

require.Equal(t, len(migratedPayload), len(payload))
require.Equal(t, uint64(52), migratedSize)
require.Equal(t, uint64(48), migratedSize)
})

t.Run("error is storage used does not exist", func(t *testing.T) {
Expand All @@ -81,7 +81,6 @@ func createAccountPayloadKey(a flow.Address, key string) ledger.Key {
return ledger.Key{
KeyParts: []ledger.KeyPart{
ledger.NewKeyPart(state.KeyPartOwner, a.Bytes()),
ledger.NewKeyPart(state.KeyPartController, []byte("")),
ledger.NewKeyPart(state.KeyPartKey, []byte(key)),
},
}
Expand Down
10 changes: 2 additions & 8 deletions cmd/util/ledger/migrations/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ import (
)

func KeyToRegisterID(key ledger.Key) (flow.RegisterID, error) {
if len(key.KeyParts) != 3 ||
if len(key.KeyParts) != 2 ||
key.KeyParts[0].Type != state.KeyPartOwner ||
key.KeyParts[1].Type != state.KeyPartController ||
key.KeyParts[2].Type != state.KeyPartKey {
key.KeyParts[1].Type != state.KeyPartKey {
return flow.RegisterID{}, fmt.Errorf("key not in expected format %s", key.String())
}

return flow.NewRegisterID(
string(key.KeyParts[0].Value),
string(key.KeyParts[1].Value),
string(key.KeyParts[2].Value),
), nil
}

Expand All @@ -33,10 +31,6 @@ func registerIDToKey(registerID flow.RegisterID) ledger.Key {
Type: state.KeyPartOwner,
Value: []byte(registerID.Owner),
},
{
Type: state.KeyPartController,
Value: []byte(registerID.Controller),
},
{
Type: state.KeyPartKey,
Value: []byte(registerID.Key),
Expand Down
Loading