Bitter Khaki Iguana
Medium
OverwriteParamsAtVersion reorders heightToVersionMap
During upgrades the OverwriteParamsAtVersion
updates the params
for version
in heightToVersionMap
.
It sorts heightToVersionMap
by the Version
. Afterwards it calls SetHeightToVersionMap
. However the heightToVersionMap
must be sorted by the start_height
as it used by GetParamsForBtcHeight -> GetVersionForHeight -> sort.Search
which expects a sorted slice (by height).
type HeightToVersionMap struct {
// Pairs must be sorted by `start_height` in ascending order, without duplicates
Pairs []*HeightVersionPair `protobuf:"bytes,1,rep,name=pairs,proto3" json:"pairs,omitempty"`
}
func (k Keeper) OverwriteParamsAtVersion(ctx context.Context, v uint32, p types.Params) error {
if err := p.Validate(); err != nil {
return fmt.Errorf("cannot overwrite params at version %d: %w", v, err)
}
paramsStore := k.paramsStore(ctx)
sp := types.StoredParams{
Params: p,
Version: v,
}
heightToVersionMap := k.GetHeightToVersionMap(ctx)
if heightToVersionMap == nil {
heightToVersionMap = types.NewHeightToVersionMap()
}
// makes sure it is ordered by the version
@> sort.Slice(heightToVersionMap.Pairs, func(i, j int) bool {
return heightToVersionMap.Pairs[i].Version < heightToVersionMap.Pairs[j].Version
})
if v >= uint32(len(heightToVersionMap.Pairs)) {
if err := heightToVersionMap.AddNewPair(uint64(p.BtcActivationHeight), v); err != nil {
return err
}
} else {
heightToVersionMap.Pairs[v] = types.NewHeightVersionPair(uint64(p.BtcActivationHeight), v)
}
paramsStore.Set(uint32ToBytes(v), k.cdc.MustMarshal(&sp))
@> return k.SetHeightToVersionMap(ctx, heightToVersionMap)
}
func (m *HeightToVersionMap) GetVersionForHeight(height uint64) (uint32, error) {
if m.IsEmpty() {
return 0, fmt.Errorf("height to version map is empty")
}
// Binary search to find the applicable version of the parameters
@> idx := sort.Search(len(m.Pairs), func(i int) bool {
return m.Pairs[i].StartHeight > height
}) - 1
if idx < 0 {
return 0, fmt.Errorf("no parameters found for block height %d", height)
}
return m.Pairs[idx].Version, nil
}
No response
No response
No response
Wrong order heightToVersionMap
is saved. CreateBTCDelegation -> getTimeInfoAndParams -> GetParamsForBtcHeight
will use wrong params.
No response
No response