-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(staking)!: binary format for HistoricalInfoKey (#15701)
## Description Closes: #11463 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... * [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title * [ ] added `!` to the type prefix if API or client breaking change * [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) * [ ] provided a link to the relevant issue or specification * [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules) * [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing) * [ ] added a changelog entry to `CHANGELOG.md` * [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) * [ ] updated the relevant documentation or specification * [ ] reviewed "Files changed" and left comments if necessary * [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... * [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title * [ ] confirmed `!` in the type prefix if API or client breaking change * [ ] confirmed all author checklist items have been addressed * [ ] reviewed state machine logic * [ ] reviewed API design and naming * [ ] reviewed documentation is accurate * [ ] reviewed tests and test coverage * [ ] manually tested (if applicable)
- Loading branch information
Showing
12 changed files
with
179 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,15 @@ | ||
package v2 | ||
|
||
import "strconv" | ||
|
||
const ( | ||
// ModuleName is the name of the module | ||
ModuleName = "staking" | ||
) | ||
|
||
var HistoricalInfoKey = []byte{0x50} // prefix for the historical info | ||
|
||
// GetHistoricalInfoKey returns a key prefix for indexing HistoricalInfo objects. | ||
func GetHistoricalInfoKey(height int64) []byte { | ||
return append(HistoricalInfoKey, []byte(strconv.FormatInt(height, 10))...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package v5 | ||
|
||
import "encoding/binary" | ||
|
||
var HistoricalInfoKey = []byte{0x50} // prefix for the historical info | ||
|
||
// GetHistoricalInfoKey returns a key prefix for indexing HistoricalInfo objects. | ||
func GetHistoricalInfoKey(height int64) []byte { | ||
heightBytes := make([]byte, 8) | ||
binary.BigEndian.PutUint64(heightBytes, uint64(height)) | ||
return append(HistoricalInfoKey, heightBytes...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package v5_test | ||
|
||
import ( | ||
"math" | ||
"math/rand" | ||
"testing" | ||
"time" | ||
|
||
storetypes "cosmossdk.io/store/types" | ||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" | ||
"github.com/cosmos/cosmos-sdk/testutil" | ||
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" | ||
v2 "github.com/cosmos/cosmos-sdk/x/staking/migrations/v2" | ||
v5 "github.com/cosmos/cosmos-sdk/x/staking/migrations/v5" | ||
stackingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestHistoricalKeysMigration(t *testing.T) { | ||
storeKey := storetypes.NewKVStoreKey("staking") | ||
tKey := storetypes.NewTransientStoreKey("transient_test") | ||
ctx := testutil.DefaultContext(storeKey, tKey) | ||
store := ctx.KVStore(storeKey) | ||
|
||
type testCase struct { | ||
oldKey, newKey []byte | ||
historicalInfo []byte | ||
} | ||
|
||
testCases := make(map[int64]testCase) | ||
|
||
// edge cases | ||
testCases[0], testCases[1], testCases[math.MaxInt32] = testCase{}, testCase{}, testCase{} | ||
|
||
// random cases | ||
seed := time.Now().UnixNano() | ||
r := rand.New(rand.NewSource(seed)) | ||
for i := 0; i < 10; i++ { | ||
height := r.Intn(math.MaxInt32-2) + 2 | ||
|
||
testCases[int64(height)] = testCase{} | ||
} | ||
|
||
cdc := moduletestutil.MakeTestEncodingConfig().Codec | ||
for height := range testCases { | ||
testCases[height] = testCase{ | ||
oldKey: v2.GetHistoricalInfoKey(height), | ||
newKey: v5.GetHistoricalInfoKey(height), | ||
historicalInfo: cdc.MustMarshal(createHistoricalInfo(height, "testChainID")), | ||
} | ||
} | ||
|
||
// populate store using old key format | ||
for _, tc := range testCases { | ||
store.Set(tc.oldKey, tc.historicalInfo) | ||
} | ||
|
||
// migrate store to new key format | ||
require.NoErrorf(t, v5.MigrateStore(ctx, storeKey), "v5.MigrateStore failed, seed: %d", seed) | ||
|
||
// check results | ||
for _, tc := range testCases { | ||
require.Nilf(t, store.Get(tc.oldKey), "old key should be deleted, seed: %d", seed) | ||
require.NotNilf(t, store.Get(tc.newKey), "new key should be created, seed: %d", seed) | ||
require.Equalf(t, tc.historicalInfo, store.Get(tc.newKey), "seed: %d", seed) | ||
} | ||
} | ||
|
||
func createHistoricalInfo(height int64, chainID string) *stackingtypes.HistoricalInfo { | ||
return &stackingtypes.HistoricalInfo{Header: cmtproto.Header{ChainID: chainID, Height: height}} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package v5 | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
|
||
"cosmossdk.io/log" | ||
"cosmossdk.io/store/prefix" | ||
storetypes "cosmossdk.io/store/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// MigrateStore performs in-place store migrations from v4 to v5. | ||
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey) error { | ||
store := ctx.KVStore(storeKey) | ||
return migrateHistoricalInfoKeys(store, ctx.Logger()) | ||
} | ||
|
||
// migrateHistoricalInfoKeys migrate HistoricalInfo keys to binary format | ||
func migrateHistoricalInfoKeys(store storetypes.KVStore, logger log.Logger) error { | ||
// old key is of format: | ||
// prefix (0x50) || heightBytes (string representation of height in 10 base) | ||
// new key is of format: | ||
// prefix (0x50) || heightBytes (byte array representation using big-endian byte order) | ||
oldStore := prefix.NewStore(store, HistoricalInfoKey) | ||
|
||
oldStoreIter := oldStore.Iterator(nil, nil) | ||
defer sdk.LogDeferred(logger, func() error { return oldStoreIter.Close() }) | ||
|
||
for ; oldStoreIter.Valid(); oldStoreIter.Next() { | ||
strHeight := oldStoreIter.Key() | ||
|
||
intHeight, err := strconv.ParseInt(string(strHeight), 10, 64) | ||
if err != nil { | ||
return fmt.Errorf("can't parse height from key %q to int64: %v", strHeight, err) | ||
} | ||
|
||
newStoreKey := GetHistoricalInfoKey(intHeight) | ||
|
||
// Set new key on store. Values don't change. | ||
store.Set(newStoreKey, oldStoreIter.Value()) | ||
oldStore.Delete(oldStoreIter.Key()) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters