github.com/Finschia/finschia-sdk@v0.48.1/store/types/commit_info.go (about)

     1  package types
     2  
     3  import (
     4  	fmt "fmt"
     5  
     6  	ics23 "github.com/confio/ics23/go"
     7  	tmcrypto "github.com/tendermint/tendermint/proto/tendermint/crypto"
     8  
     9  	sdkmaps "github.com/Finschia/finschia-sdk/store/internal/maps"
    10  	sdkproofs "github.com/Finschia/finschia-sdk/store/internal/proofs"
    11  )
    12  
    13  // GetHash returns the GetHash from the CommitID.
    14  // This is used in CommitInfo.Hash()
    15  //
    16  // When we commit to this in a merkle proof, we create a map of storeInfo.Name -> storeInfo.GetHash()
    17  // and build a merkle proof from that.
    18  // This is then chained with the substore proof, so we prove the root hash from the substore before this
    19  // and need to pass that (unmodified) as the leaf value of the multistore proof.
    20  func (si StoreInfo) GetHash() []byte {
    21  	return si.CommitId.Hash
    22  }
    23  
    24  func (ci CommitInfo) toMap() map[string][]byte {
    25  	m := make(map[string][]byte, len(ci.StoreInfos))
    26  	for _, storeInfo := range ci.StoreInfos {
    27  		m[storeInfo.Name] = storeInfo.GetHash()
    28  	}
    29  
    30  	return m
    31  }
    32  
    33  // Hash returns the simple merkle root hash of the stores sorted by name.
    34  func (ci CommitInfo) Hash() []byte {
    35  	// we need a special case for empty set, as SimpleProofsFromMap requires at least one entry
    36  	if len(ci.StoreInfos) == 0 {
    37  		return nil
    38  	}
    39  
    40  	rootHash, _, _ := sdkmaps.ProofsFromMap(ci.toMap())
    41  	return rootHash
    42  }
    43  
    44  func (ci CommitInfo) ProofOp(storeName string) tmcrypto.ProofOp {
    45  	cmap := ci.toMap()
    46  	_, proofs, _ := sdkmaps.ProofsFromMap(cmap)
    47  
    48  	proof := proofs[storeName]
    49  	if proof == nil {
    50  		panic(fmt.Sprintf("ProofOp for %s but not registered store name", storeName))
    51  	}
    52  
    53  	// convert merkle.SimpleProof to CommitmentProof
    54  	existProof, err := sdkproofs.ConvertExistenceProof(proof, []byte(storeName), cmap[storeName])
    55  	if err != nil {
    56  		panic(fmt.Errorf("could not convert simple proof to existence proof: %w", err))
    57  	}
    58  
    59  	commitmentProof := &ics23.CommitmentProof{
    60  		Proof: &ics23.CommitmentProof_Exist{
    61  			Exist: existProof,
    62  		},
    63  	}
    64  
    65  	return NewSimpleMerkleCommitmentOp([]byte(storeName), commitmentProof).ProofOp()
    66  }
    67  
    68  func (ci CommitInfo) CommitID() CommitID {
    69  	return CommitID{
    70  		Version: ci.Version,
    71  		Hash:    ci.Hash(),
    72  	}
    73  }