-
Notifications
You must be signed in to change notification settings - Fork 548
/
migrations.go
80 lines (65 loc) · 2.5 KB
/
migrations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
)
// Migrator is a struct for handling in-place store migrations.
type Migrator struct {
keeper Keeper
}
// NewMigrator returns a new Migrator.
func NewMigrator(keeper Keeper) Migrator {
return Migrator{keeper: keeper}
}
// MigrateTraces migrates the DenomTraces to the correct format, accounting for slashes in the BaseDenom.
func (m Migrator) MigrateTraces(ctx sdk.Context) error {
// list of traces that must replace the old traces in store
var newTraces []types.DenomTrace
m.keeper.IterateDenomTraces(ctx,
func(dt types.DenomTrace) (stop bool) {
// check if the new way of splitting FullDenom
// is the same as the current DenomTrace.
// If it isn't then store the new DenomTrace in the list of new traces.
newTrace := types.ParseDenomTrace(dt.GetFullDenomPath())
err := newTrace.Validate()
if err != nil {
panic(err)
}
if dt.IBCDenom() != newTrace.IBCDenom() {
// The new form of parsing will result in a token denomination change.
// A bank migration is required. A panic should occur to prevent the
// chain from using corrupted state.
panic(fmt.Sprintf("migration will result in corrupted state. Previous IBC token (%s) requires a bank migration. Expected denom trace (%s)", dt, newTrace))
}
if !equalTraces(newTrace, dt) {
newTraces = append(newTraces, newTrace)
}
return false
})
// replace the outdated traces with the new trace information
for _, nt := range newTraces {
m.keeper.SetDenomTrace(ctx, nt)
}
return nil
}
// MigrateTotalEscrowForDenom migrates the total amount of source chain tokens in escrow.
func (m Migrator) MigrateTotalEscrowForDenom(ctx sdk.Context) error {
var totalEscrowed sdk.Coins
portID := m.keeper.GetPort(ctx)
transferChannels := m.keeper.channelKeeper.GetAllChannelsWithPortPrefix(ctx, portID)
for _, channel := range transferChannels {
escrowAddress := types.GetEscrowAddress(portID, channel.ChannelId)
escrowBalances := m.keeper.bankKeeper.GetAllBalances(ctx, escrowAddress)
totalEscrowed = totalEscrowed.Add(escrowBalances...)
}
for _, totalEscrow := range totalEscrowed {
m.keeper.SetTotalEscrowForDenom(ctx, totalEscrow)
}
logger := m.keeper.Logger(ctx)
logger.Info("successfully set total escrow for %d denominations", totalEscrowed.Len())
return nil
}
func equalTraces(dtA, dtB types.DenomTrace) bool {
return dtA.BaseDenom == dtB.BaseDenom && dtA.Path == dtB.Path
}