Co-authored-by: marbar3778 <marbar3778@yahoo.com> Co-authored-by: Marko <marko@baricevic.me> Co-authored-by: Alex | Interchain Labs <alex@skip.money>
87 lines
2.1 KiB
Go
87 lines
2.1 KiB
Go
package proof
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
func (si StoreInfo) GetHash() []byte {
|
|
return si.CommitId.Hash
|
|
}
|
|
|
|
// Hash returns the root hash of all committed stores represented by CommitInfo,
|
|
// sorted by store name/key.
|
|
func (ci *CommitInfo) Hash() []byte {
|
|
if len(ci.StoreInfos) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if len(ci.CommitHash) != 0 {
|
|
return ci.CommitHash
|
|
}
|
|
|
|
rootHash, _, _ := ci.GetStoreProof([]byte{})
|
|
return rootHash
|
|
}
|
|
|
|
// GetStoreCommitID returns the CommitID for the given store key.
|
|
func (ci *CommitInfo) GetStoreCommitID(storeKey []byte) *CommitID {
|
|
for _, si := range ci.StoreInfos {
|
|
if strings.EqualFold(si.Name, string(storeKey)) {
|
|
return si.CommitId
|
|
}
|
|
}
|
|
return &CommitID{}
|
|
}
|
|
|
|
// GetStoreProof takes in a storeKey and returns a proof of the store key in addition
|
|
// to the root hash it should be proved against. If an empty string is provided, the first
|
|
// store based on lexographical ordering will be proved.
|
|
func (ci *CommitInfo) GetStoreProof(storeKey []byte) ([]byte, *CommitmentOp, error) {
|
|
sort.Slice(ci.StoreInfos, func(i, j int) bool {
|
|
return strings.Compare(ci.StoreInfos[i].Name, ci.StoreInfos[j].Name) < 0
|
|
})
|
|
|
|
isEmpty := len(storeKey) == 0
|
|
index := -1
|
|
leaves := make([][]byte, len(ci.StoreInfos))
|
|
for i, si := range ci.StoreInfos {
|
|
var err error
|
|
leaves[i], err = LeafHash([]byte(si.Name), si.GetHash())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if !isEmpty && strings.EqualFold(si.Name, string(storeKey)) {
|
|
index = i
|
|
}
|
|
}
|
|
|
|
if index == -1 {
|
|
if isEmpty {
|
|
index = 0
|
|
} else {
|
|
return nil, nil, fmt.Errorf("store key %s not found", storeKey)
|
|
}
|
|
}
|
|
|
|
rootHash, inners := ProofFromByteSlices(leaves, index)
|
|
commitmentOp := ConvertCommitmentOp(inners, storeKey, ci.StoreInfos[index].GetHash())
|
|
return rootHash, &commitmentOp, nil
|
|
}
|
|
|
|
func (ci *CommitInfo) CommitID() *CommitID {
|
|
return &CommitID{
|
|
Version: ci.Version,
|
|
Hash: ci.Hash(),
|
|
}
|
|
}
|
|
|
|
func (cid *CommitID) String() string {
|
|
return fmt.Sprintf("CommitID{%v:%X}", cid.Hash, cid.Version)
|
|
}
|
|
|
|
func (cid *CommitID) IsZero() bool {
|
|
return cid.Version == 0 && len(cid.Hash) == 0
|
|
}
|