github.com/okex/exchain@v1.8.0/libs/tendermint/types/results.go (about)

     1  package types
     2  
     3  import (
     4  	gobytes "bytes"
     5  
     6  	abci "github.com/okex/exchain/libs/tendermint/abci/types"
     7  	"github.com/okex/exchain/libs/tendermint/libs/bytes"
     8  
     9  	"github.com/okex/exchain/libs/tendermint/crypto/merkle"
    10  	"github.com/tendermint/go-amino"
    11  )
    12  
    13  //-----------------------------------------------------------------------------
    14  
    15  // ABCIResult is the deterministic component of a ResponseDeliverTx.
    16  // TODO: add tags and other fields
    17  // https://github.com/tendermint/tendermint/issues/1007
    18  type ABCIResult struct {
    19  	Code uint32         `json:"code"`
    20  	Data bytes.HexBytes `json:"data"`
    21  }
    22  
    23  func (a ABCIResult) AminoSize() int {
    24  	var size int
    25  	if a.Code != 0 {
    26  		size += 1 + amino.UvarintSize(uint64(a.Code))
    27  	}
    28  	if len(a.Data) > 0 {
    29  		size += 1 + amino.UvarintSize(uint64(len(a.Data))) + len(a.Data)
    30  	}
    31  	return size
    32  }
    33  
    34  func (a ABCIResult) MarshalToAmino(_ *amino.Codec) ([]byte, error) {
    35  	buf := &gobytes.Buffer{}
    36  	buf.Grow(a.AminoSize())
    37  
    38  	if a.Code != 0 {
    39  		const pbKey = 1<<3 | byte(amino.Typ3_Varint)
    40  		err := amino.EncodeUvarintWithKeyToBuffer(buf, uint64(a.Code), pbKey)
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  	}
    45  
    46  	if len(a.Data) != 0 {
    47  		const pbKey = 2<<3 | byte(amino.Typ3_ByteLength)
    48  		err := amino.EncodeByteSliceWithKeyToBuffer(buf, a.Data, pbKey)
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  	}
    53  
    54  	return buf.Bytes(), nil
    55  }
    56  
    57  // Bytes returns the amino encoded ABCIResult
    58  func (a ABCIResult) Bytes() []byte {
    59  	bz, err := a.MarshalToAmino(cdc)
    60  	if err != nil {
    61  		return cdcEncode(a)
    62  	} else {
    63  		return bz
    64  	}
    65  }
    66  
    67  // ABCIResults wraps the deliver tx results to return a proof
    68  type ABCIResults []ABCIResult
    69  
    70  // NewResults creates ABCIResults from the list of ResponseDeliverTx.
    71  func NewResults(responses []*abci.ResponseDeliverTx) ABCIResults {
    72  	res := make(ABCIResults, len(responses))
    73  	for i, d := range responses {
    74  		res[i] = NewResultFromResponse(d)
    75  	}
    76  	return res
    77  }
    78  
    79  // NewResultFromResponse creates ABCIResult from ResponseDeliverTx.
    80  func NewResultFromResponse(response *abci.ResponseDeliverTx) ABCIResult {
    81  	return ABCIResult{
    82  		Code: response.Code,
    83  		Data: response.Data,
    84  	}
    85  }
    86  
    87  // Bytes serializes the ABCIResponse using amino
    88  func (a ABCIResults) Bytes() []byte {
    89  	bz, err := cdc.MarshalBinaryLengthPrefixed(a)
    90  	if err != nil {
    91  		panic(err)
    92  	}
    93  	return bz
    94  }
    95  
    96  // Hash returns a merkle hash of all results
    97  func (a ABCIResults) Hash() []byte {
    98  	// NOTE: we copy the impl of the merkle tree for txs -
    99  	// we should be consistent and either do it for both or not.
   100  	return merkle.SimpleHashFromByteSlices(a.toByteSlices())
   101  }
   102  
   103  // ProveResult returns a merkle proof of one result from the set
   104  func (a ABCIResults) ProveResult(i int) merkle.SimpleProof {
   105  	_, proofs := merkle.SimpleProofsFromByteSlices(a.toByteSlices())
   106  	return *proofs[i]
   107  }
   108  
   109  func (a ABCIResults) toByteSlices() [][]byte {
   110  	l := len(a)
   111  	bzs := make([][]byte, l)
   112  	for i := 0; i < l; i++ {
   113  		bzs[i] = a[i].Bytes()
   114  	}
   115  	return bzs
   116  }