diff --git a/cmd/util/ledger/migrations/deduplicate_contract_names_migration.go b/cmd/util/ledger/migrations/deduplicate_contract_names_migration.go index 5d79da0590c..80707e39d95 100644 --- a/cmd/util/ledger/migrations/deduplicate_contract_names_migration.go +++ b/cmd/util/ledger/migrations/deduplicate_contract_names_migration.go @@ -1,14 +1,11 @@ package migrations import ( - "bytes" "context" "fmt" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - "github.com/fxamacker/cbor/v2" + "github.com/rs/zerolog" "github.com/onflow/cadence/runtime/common" @@ -26,6 +23,10 @@ type DeduplicateContractNamesMigration struct { log zerolog.Logger } +func (d *DeduplicateContractNamesMigration) Close() error { + return nil +} + func (d *DeduplicateContractNamesMigration) InitMigration( log zerolog.Logger, _ []*ledger.Payload, @@ -56,46 +57,40 @@ func (d *DeduplicateContractNamesMigration) MigrateAccount( if err != nil { return nil, fmt.Errorf("failed to get contract names: %w", err) } - if len(contractNames) == 0 { + if len(contractNames) == 1 { return payloads, nil } - contractNamesSet := make(map[string]struct{}) - removeIndexes := make([]int, 0) - for i, name := range contractNames { - if _, ok := contractNamesSet[name]; ok { - // duplicate contract name - removeIndexes = append(removeIndexes, i) + var foundDuplicate bool + i := 1 + for i < len(contractNames) { + if contractNames[i-1] != contractNames[i] { + i++ continue } - - contractNamesSet[name] = struct{}{} + // Found duplicate (contactNames[i-1] == contactNames[i]) + // Remove contractNames[i] + copy(contractNames[i:], contractNames[i+1:]) + contractNames = contractNames[:len(contractNames)-1] + foundDuplicate = true } - if len(removeIndexes) == 0 { + if !foundDuplicate { return payloads, nil } - log.Info(). + d.log.Info(). Str("address", address.Hex()). Strs("contract_names", contractNames). Msg("removing duplicate contract names") - // remove the duplicate contract names, keeping the original order - for i := len(removeIndexes) - 1; i >= 0; i-- { - contractNames = append(contractNames[:removeIndexes[i]], contractNames[removeIndexes[i]+1:]...) - } - - var buf bytes.Buffer - cborEncoder := cbor.NewEncoder(&buf) - err = cborEncoder.Encode(contractNames) + newContractNames, err := cbor.Marshal(contractNames) if err != nil { return nil, fmt.Errorf( "cannot encode contract names: %s", contractNames, ) } - newContractNames := buf.Bytes() id := flow.ContractNamesRegisterID(flowAddress) err = accounts.SetValue(id, newContractNames)