github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/cmd/util/ledger/migrations/account_storage_migration.go (about)

     1  package migrations
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/cadence/runtime"
     7  	"github.com/onflow/cadence/runtime/common"
     8  	"github.com/onflow/cadence/runtime/interpreter"
     9  	"github.com/rs/zerolog"
    10  
    11  	"github.com/onflow/flow-go/cmd/util/ledger/util/registers"
    12  	"github.com/onflow/flow-go/model/flow"
    13  )
    14  
    15  func NewAccountStorageMigration(
    16  	address common.Address,
    17  	log zerolog.Logger,
    18  	chainID flow.ChainID,
    19  	migrate func(*runtime.Storage, *interpreter.Interpreter) error,
    20  ) RegistersMigration {
    21  
    22  	return func(registersByAccount *registers.ByAccount) error {
    23  
    24  		// Create an interpreter migration runtime
    25  		migrationRuntime, err := NewInterpreterMigrationRuntime(
    26  			registersByAccount,
    27  			chainID,
    28  			InterpreterMigrationRuntimeConfig{},
    29  		)
    30  		if err != nil {
    31  			return fmt.Errorf("failed to create interpreter migration runtime: %w", err)
    32  		}
    33  
    34  		// Run the migration
    35  		storage := migrationRuntime.Storage
    36  		inter := migrationRuntime.Interpreter
    37  
    38  		err = migrate(storage, inter)
    39  		if err != nil {
    40  			return fmt.Errorf("failed to migrate storage: %w", err)
    41  		}
    42  
    43  		// Commit the changes
    44  		err = storage.NondeterministicCommit(inter, false)
    45  		if err != nil {
    46  			return fmt.Errorf("failed to commit changes: %w", err)
    47  		}
    48  
    49  		// Check the health of the storage
    50  		err = storage.CheckHealth()
    51  		if err != nil {
    52  			log.Err(err).Msg("storage health check failed")
    53  		}
    54  
    55  		// Finalize the transaction
    56  		result, err := migrationRuntime.TransactionState.FinalizeMainTransaction()
    57  		if err != nil {
    58  			return fmt.Errorf("failed to finalize main transaction: %w", err)
    59  		}
    60  
    61  		// Merge the changes into the registers
    62  		expectedAddresses := map[flow.Address]struct{}{
    63  			flow.Address(address): {},
    64  		}
    65  
    66  		err = registers.ApplyChanges(
    67  			registersByAccount,
    68  			result.WriteSet,
    69  			expectedAddresses,
    70  			log,
    71  		)
    72  		if err != nil {
    73  			return fmt.Errorf("failed to apply register changes: %w", err)
    74  		}
    75  
    76  		return nil
    77  	}
    78  }