github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/cmd/util/ledger/migrations/prune_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/ledger" 12 "github.com/onflow/flow-go/model/flow" 13 ) 14 15 // PruneEmptyMigration removes all the payloads with empty value 16 // this prunes the trie for values that has been deleted 17 func PruneEmptyMigration(payload []ledger.Payload) ([]ledger.Payload, error) { 18 newPayload := make([]ledger.Payload, 0, len(payload)) 19 for _, p := range payload { 20 if len(p.Value()) > 0 { 21 newPayload = append(newPayload, p) 22 } 23 } 24 return newPayload, nil 25 } 26 27 // NewCadence1PruneMigration prunes some values from the service account in the Testnet state 28 func NewCadence1PruneMigration( 29 chainID flow.ChainID, 30 log zerolog.Logger, 31 nWorkers int, 32 ) RegistersMigration { 33 if chainID != flow.Testnet { 34 return nil 35 } 36 37 serviceAccountAddress := common.Address(chainID.Chain().ServiceAddress()) 38 39 migrate := func(storage *runtime.Storage, inter *interpreter.Interpreter) error { 40 41 err := pruneRandomBeaconHistory(storage, inter, log, serviceAccountAddress) 42 if err != nil { 43 return err 44 } 45 46 return nil 47 } 48 49 return NewAccountStorageMigration( 50 serviceAccountAddress, 51 log, 52 chainID, 53 migrate, 54 ) 55 } 56 57 func pruneRandomBeaconHistory( 58 storage *runtime.Storage, 59 inter *interpreter.Interpreter, 60 log zerolog.Logger, 61 serviceAccountAddress common.Address, 62 ) error { 63 64 log.Info().Msgf("pruning RandomBeaconHistory in service account %s", serviceAccountAddress) 65 66 contracts := storage.GetStorageMap(serviceAccountAddress, runtime.StorageDomainContract, false) 67 if contracts == nil { 68 return fmt.Errorf("failed to get contracts storage map") 69 } 70 71 randomBeaconHistory, ok := contracts.ReadValue( 72 nil, 73 interpreter.StringStorageMapKey("RandomBeaconHistory"), 74 ).(*interpreter.CompositeValue) 75 if !ok { 76 return fmt.Errorf("failed to read RandomBeaconHistory contract") 77 } 78 79 randomSourceHistory, ok := randomBeaconHistory.GetField( 80 inter, 81 interpreter.EmptyLocationRange, 82 "randomSourceHistory", 83 ).(*interpreter.ArrayValue) 84 if !ok { 85 return fmt.Errorf("failed to read randomSourceHistory field") 86 } 87 88 // Remove all but the last value from the randomSourceHistory 89 oldCount := randomSourceHistory.Count() 90 removalCount := oldCount - 1 91 92 for i := 0; i < removalCount; i++ { 93 randomSourceHistory.RemoveWithoutTransfer( 94 inter, 95 interpreter.EmptyLocationRange, 96 // NOTE: always remove the first element 97 0, 98 ) 99 } 100 101 // Check 102 if randomSourceHistory.Count() != 1 { 103 return fmt.Errorf("failed to prune randomSourceHistory") 104 } 105 106 log.Info().Msgf( 107 "pruned %d entries in RandomBeaconHistory in service account %s", 108 removalCount, 109 serviceAccountAddress, 110 ) 111 112 return nil 113 }