2019-12-18 05:20:02 -08:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sort"
|
|
|
|
|
2020-10-23 05:07:52 -07:00
|
|
|
"github.com/gogo/protobuf/proto"
|
2020-08-14 10:58:53 -07:00
|
|
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
2019-12-18 05:20:02 -08:00
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
2020-10-23 05:07:52 -07:00
|
|
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
2021-01-27 02:24:00 -08:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2019-12-18 05:20:02 -08:00
|
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewHistoricalInfo will create a historical information struct from header and valset
|
|
|
|
// it will first sort valset before inclusion into historical info
|
2021-01-27 02:24:00 -08:00
|
|
|
func NewHistoricalInfo(header tmproto.Header, valSet Validators, powerReduction sdk.Int) HistoricalInfo {
|
2020-10-29 05:17:37 -07:00
|
|
|
// Must sort in the same way that tendermint does
|
2021-01-27 02:24:00 -08:00
|
|
|
sort.SliceStable(valSet, func(i, j int) bool {
|
2021-02-01 19:12:05 -08:00
|
|
|
return ValidatorsByVotingPower(valSet).Less(i, j, powerReduction)
|
2021-01-27 02:24:00 -08:00
|
|
|
})
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-12-18 05:20:02 -08:00
|
|
|
return HistoricalInfo{
|
|
|
|
Header: header,
|
2020-02-06 11:21:02 -08:00
|
|
|
Valset: valSet,
|
2019-12-18 05:20:02 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MustUnmarshalHistoricalInfo wll unmarshal historical info and panic on error
|
2021-04-29 03:46:22 -07:00
|
|
|
func MustUnmarshalHistoricalInfo(cdc codec.BinaryCodec, value []byte) HistoricalInfo {
|
2019-12-18 05:20:02 -08:00
|
|
|
hi, err := UnmarshalHistoricalInfo(cdc, value)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2019-12-18 05:20:02 -08:00
|
|
|
return hi
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalHistoricalInfo will unmarshal historical info and return any error
|
2021-04-29 03:46:22 -07:00
|
|
|
func UnmarshalHistoricalInfo(cdc codec.BinaryCodec, value []byte) (hi HistoricalInfo, err error) {
|
|
|
|
err = cdc.Unmarshal(value, &hi)
|
2019-12-18 05:20:02 -08:00
|
|
|
return hi, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// ValidateBasic will ensure HistoricalInfo is not nil and sorted
|
|
|
|
func ValidateBasic(hi HistoricalInfo) error {
|
2020-02-06 11:21:02 -08:00
|
|
|
if len(hi.Valset) == 0 {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(ErrInvalidHistoricalInfo, "validator set is empty")
|
2019-12-18 05:20:02 -08:00
|
|
|
}
|
2020-05-02 12:26:59 -07:00
|
|
|
|
2020-02-06 11:21:02 -08:00
|
|
|
if !sort.IsSorted(Validators(hi.Valset)) {
|
2019-12-27 09:57:54 -08:00
|
|
|
return sdkerrors.Wrap(ErrInvalidHistoricalInfo, "validator set is not sorted by address")
|
2019-12-18 05:20:02 -08:00
|
|
|
}
|
2020-02-06 11:21:02 -08:00
|
|
|
|
2019-12-18 05:20:02 -08:00
|
|
|
return nil
|
|
|
|
}
|
2020-10-23 05:07:52 -07:00
|
|
|
|
|
|
|
// Equal checks if receiver is equal to the parameter
|
|
|
|
func (hi *HistoricalInfo) Equal(hi2 *HistoricalInfo) bool {
|
|
|
|
if !proto.Equal(&hi.Header, &hi2.Header) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if len(hi.Valset) != len(hi2.Valset) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
for i := range hi.Valset {
|
|
|
|
if !hi.Valset[i].Equal(&hi2.Valset[i]) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
|
|
|
func (hi HistoricalInfo) UnpackInterfaces(c codectypes.AnyUnpacker) error {
|
|
|
|
for i := range hi.Valset {
|
|
|
|
if err := hi.Valset[i].UnpackInterfaces(c); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|