-
Notifications
You must be signed in to change notification settings - Fork 661
/
Copy pathmigrations.go
72 lines (56 loc) · 2.55 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
package tendermint
import (
"fmt"
"strings"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
host "github.com/cosmos/ibc-go/v6/modules/core/24-host"
"github.com/cosmos/ibc-go/v6/modules/core/exported"
)
// PruneTendermintConsensusStates prunes all expired tendermint consensus states. This function
// may optionally be called during in-place store migrations. The ibc store key must be provided.
func PruneTendermintConsensusStates(ctx sdk.Context, cdc codec.BinaryCodec, storeKey storetypes.StoreKey) error {
store := ctx.KVStore(storeKey)
// iterate over ibc store with prefix: clients/07-tendermint,
tendermintClientPrefix := []byte(fmt.Sprintf("%s/%s", host.KeyClientStorePrefix, exported.Tendermint))
iterator := sdk.KVStorePrefixIterator(store, tendermintClientPrefix)
var clientIDs []string
// collect all clients to avoid performing store state changes during iteration
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
path := string(iterator.Key())
if !strings.Contains(path, host.KeyClientState) {
// skip non client state keys
continue
}
clientID := host.MustParseClientStatePath(path)
clientIDs = append(clientIDs, clientID)
}
// keep track of the total consensus states pruned so chains can
// understand how much space is saved when the migration is run
var totalPruned int
for _, clientID := range clientIDs {
clientPrefix := []byte(fmt.Sprintf("%s/%s/", host.KeyClientStorePrefix, clientID))
clientStore := prefix.NewStore(ctx.KVStore(storeKey), clientPrefix)
bz := clientStore.Get(host.ClientStateKey())
if bz == nil {
return clienttypes.ErrClientNotFound
}
var clientState exported.ClientState
if err := cdc.UnmarshalInterface(bz, &clientState); err != nil {
return sdkerrors.Wrap(err, "failed to unmarshal client state bytes into tendermint client state")
}
tmClientState, ok := clientState.(*ClientState)
if !ok {
return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "client state is not tendermint even though client id contains 07-tendermint")
}
totalPruned += PruneAllExpiredConsensusStates(ctx, clientStore, cdc, tmClientState)
}
clientLogger := ctx.Logger().With("module", "x/"+host.ModuleName+"/"+clienttypes.SubModuleName)
clientLogger.Info("pruned expired tendermint consensus states", "total", totalPruned)
return nil
}