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

Add feature to enable migrations to fix references to non-existent registers #387

Merged

Conversation

fxamacker
Copy link
Member

@fxamacker fxamacker commented Apr 11, 2024

Updates #386

Problem

In testnet, broken references seem to have resulted from a bug that was fixed 2 years ago by onflow/cadence#1565.

A broken reference is a StorageID referencing a non-existent register. So far, only 10 registers in testnet (none on mainnet) were found to contain broken references.

Solution

This PR adds a feature to enable migration programs in onflow/flow-go to fix broken references in maps.

FixLoadedBrokenReferences() traverses loaded slabs and replaces broken map (if any) with empty map having the same StorageID and also removes all slabs in the old map.

Limitations:

  • only fix broken references in map (this is intentional)
  • only traverse loaded slabs in deltas and cache

IMPORTANT: This should not be used to silently fix unknown problems. It should only be used by migration programs to fix known problems which were determined to be appropriate to fix in this manner.

TODO:

  • Add more tests and increase code coverage

  • Targeted PR against main branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work
  • Code follows the standards mentioned here
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

The intended use case is to enable migration programs in onflow/flow-go to fix
broken references.  As of April 2024, only 10 registers in testnet (not mainnet)
were found to have broken references and they seem to have resulted from a bug
that was fixed 2 years ago by onflow/cadence#1565.

A broken reference is a StorageID referencing a non-existent slab.

This commit adds FixLoadedBrokenReferences(), which traverses loaded slabs and
fixes broken references in maps.  To fix a map containing broken references,
new function replaces broken map with empty map having the same StorageID and
also removes all slabs in the old map.

Limitations:
- only fix broken references in map (this is intentional)
- only traverse loaded slabs in deltas and cache

IMPORTANT: This should not be used to silently fix unknown problems. It
should only be used by migration programs to fix known problems which
were determined to be appropriate to fix.
@fxamacker fxamacker added the enhancement New feature or request label Apr 11, 2024
@fxamacker fxamacker self-assigned this Apr 11, 2024
@fxamacker fxamacker marked this pull request as draft April 11, 2024 20:06
@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 75.15924% with 39 lines in your changes are missing coverage. Please review.

Project coverage is 66.48%. Comparing base (dc825c2) to head (d5cb164).

❗ Current head d5cb164 differs from pull request most recent head a887780. Consider uploading reports for the commit a887780 to get more accurate results

Files Patch % Lines
storage.go 75.15% 27 Missing and 12 partials ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##           feature/stable-cadence     #387      +/-   ##
==========================================================
+ Coverage                   66.09%   66.48%   +0.38%     
==========================================================
  Files                          14       14              
  Lines                        8233     8390     +157     
==========================================================
+ Hits                         5442     5578     +136     
- Misses                       2113     2124      +11     
- Partials                      678      688      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@fxamacker fxamacker marked this pull request as ready for review April 11, 2024 21:05
Copy link
Member

@SupunS SupunS left a comment

Choose a reason for hiding this comment

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

I mostly reviewed from cadence perspective and for general Go-code.
LGTM!

storage.go Show resolved Hide resolved
storage.go Show resolved Hide resolved
storage.go Show resolved Hide resolved
storage.go Outdated Show resolved Hide resolved
storage.go Show resolved Hide resolved
Co-authored-by: Bastian Müller <[email protected]>
Currently, calls to this function can be limited by migration
programs by specifying the 9 testnet accounts affected by 10
registers with broken references on testnet.

This commit allows callers to implement additional restrictions,
so calling FixLoadedBrokenReferences for the affected 9 testnet
accounts can be even more limited at the callers discretion.

In practice, this change is not expected to produce different
migration results because full migration tests before this change
correctly fixed the 10 known registers in the 9 testnet accounts.

This commit added predicate func(old Value) bool to
PersistentSlabStorage.FixLoadedBrokenReferences() to control
whether to fix a atree.Value containing broken references.

Also modified PersistentSlabStorage.FixLoadedBrokenReferences()
to return fixed storage IDs and skipped storage IDs.  Both returned
values are of type map[StorageID][]StorageID, with key as
root slab ID and value as all slab IDs containing broken references
connected to the root.

Also added more tests and improved existing tests.
@fxamacker fxamacker force-pushed the fxamacker/add-fix-broken-reference-function branch from 46df965 to 40aea0d Compare April 16, 2024 19:37
Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

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

Great work!

Good idea to return the fixed and skipped storage IDs 👍

@turbolent turbolent requested a review from SupunS April 16, 2024 20:04
This commit adds GetAllChildReferences() which essentially wraps
an existing internal function.
…ences

Add PersistentSlabStorage.GetAllChildReferences()
@fxamacker fxamacker merged commit f4568c0 into feature/stable-cadence Apr 16, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants