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

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"io"
     8  	"strings"
     9  	"sync"
    10  	"time"
    11  
    12  	gogotypes "github.com/gogo/protobuf/types"
    13  	"github.com/okex/exchain/libs/system/trace"
    14  	"github.com/okex/exchain/libs/tendermint/libs/compress"
    15  	tmtime "github.com/okex/exchain/libs/tendermint/types/time"
    16  
    17  	"github.com/tendermint/go-amino"
    18  
    19  	"github.com/pkg/errors"
    20  
    21  	"github.com/okex/exchain/libs/tendermint/crypto"
    22  	"github.com/okex/exchain/libs/tendermint/crypto/merkle"
    23  	"github.com/okex/exchain/libs/tendermint/crypto/tmhash"
    24  	"github.com/okex/exchain/libs/tendermint/libs/bits"
    25  	tmbytes "github.com/okex/exchain/libs/tendermint/libs/bytes"
    26  	tmmath "github.com/okex/exchain/libs/tendermint/libs/math"
    27  	tmproto "github.com/okex/exchain/libs/tendermint/proto/types"
    28  	tmversion "github.com/okex/exchain/libs/tendermint/proto/version"
    29  	"github.com/okex/exchain/libs/tendermint/version"
    30  )
    31  
    32  const (
    33  	// MaxHeaderBytes is a maximum header size (including amino overhead).
    34  	MaxHeaderBytes int64 = 632
    35  
    36  	// MaxAminoOverheadForBlock - maximum amino overhead to encode a block (up to
    37  	// MaxBlockSizeBytes in size) not including it's parts except Data.
    38  	// This means it also excludes the overhead for individual transactions.
    39  	// To compute individual transactions' overhead use types.ComputeAminoOverhead(tx types.Tx, fieldNum int).
    40  	//
    41  	// Uvarint length of MaxBlockSizeBytes: 4 bytes
    42  	// 2 fields (2 embedded):               2 bytes
    43  	// Uvarint length of Data.Txs:          4 bytes
    44  	// Data.Txs field:                      1 byte
    45  	MaxAminoOverheadForBlock int64 = 11
    46  
    47  	// CompressDividing is used to divide compressType and compressFlag of compressSign
    48  	// the compressSign = CompressType * CompressDividing + CompressFlag
    49  	CompressDividing int = 10
    50  
    51  	FlagBlockCompressType      = "block-compress-type"
    52  	FlagBlockCompressFlag      = "block-compress-flag"
    53  	FlagBlockCompressThreshold = "block-compress-threshold"
    54  )
    55  
    56  var (
    57  	BlockCompressType      = 0x00
    58  	BlockCompressFlag      = 0
    59  	BlockCompressThreshold = 1024000
    60  )
    61  
    62  type BlockExInfo struct {
    63  	BlockCompressType int
    64  	BlockCompressFlag int
    65  	BlockPartSize     int
    66  }
    67  
    68  func (info BlockExInfo) IsCompressed() bool {
    69  	return info.BlockCompressType != 0
    70  }
    71  
    72  // Block defines the atomic unit of a Tendermint blockchain.
    73  type Block struct {
    74  	mtx sync.Mutex
    75  
    76  	Header     `json:"header"`
    77  	Data       `json:"data"`
    78  	Evidence   EvidenceData `json:"evidence"`
    79  	LastCommit *Commit      `json:"last_commit"`
    80  }
    81  
    82  func (b *Block) AminoSize(cdc *amino.Codec) int {
    83  	var size = 0
    84  
    85  	headerSize := b.Header.AminoSize(cdc)
    86  	if headerSize > 0 {
    87  		size += 1 + amino.UvarintSize(uint64(headerSize)) + headerSize
    88  	}
    89  
    90  	dataSize := b.Data.AminoSize(cdc)
    91  	if dataSize > 0 {
    92  		size += 1 + amino.UvarintSize(uint64(dataSize)) + dataSize
    93  	}
    94  
    95  	evidenceSize := b.Evidence.AminoSize(cdc)
    96  	if evidenceSize > 0 {
    97  		size += 1 + amino.UvarintSize(uint64(evidenceSize)) + evidenceSize
    98  	}
    99  
   100  	if b.LastCommit != nil {
   101  		commitSize := b.LastCommit.AminoSize(cdc)
   102  		size += 1 + amino.UvarintSize(uint64(commitSize)) + commitSize
   103  	}
   104  
   105  	return size
   106  }
   107  
   108  func (b *Block) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
   109  	var dataLen uint64 = 0
   110  	var subData []byte
   111  
   112  	for {
   113  		data = data[dataLen:]
   114  
   115  		if len(data) == 0 {
   116  			break
   117  		}
   118  
   119  		pos, aminoType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
   120  		if err != nil {
   121  			return err
   122  		}
   123  		data = data[1:]
   124  
   125  		if aminoType == amino.Typ3_ByteLength {
   126  			var n int
   127  			dataLen, n, err = amino.DecodeUvarint(data)
   128  			if err != nil {
   129  				return err
   130  			}
   131  
   132  			data = data[n:]
   133  			if len(data) < int(dataLen) {
   134  				return fmt.Errorf("not enough data to read field %d", pos)
   135  			}
   136  			subData = data[:dataLen]
   137  		}
   138  
   139  		switch pos {
   140  		case 1:
   141  			err = b.Header.UnmarshalFromAmino(cdc, subData)
   142  			if err != nil {
   143  				return err
   144  			}
   145  		case 2:
   146  			err = b.Data.UnmarshalFromAmino(cdc, subData)
   147  			if err != nil {
   148  				return err
   149  			}
   150  		case 3:
   151  			err = b.Evidence.UnmarshalFromAmino(cdc, subData)
   152  			if err != nil {
   153  				return err
   154  			}
   155  		case 4:
   156  			b.LastCommit = new(Commit)
   157  			err = b.LastCommit.UnmarshalFromAmino(cdc, subData)
   158  			if err != nil {
   159  				return err
   160  			}
   161  		default:
   162  			return fmt.Errorf("unexpect feild num %d", pos)
   163  		}
   164  	}
   165  	return nil
   166  }
   167  
   168  // ValidateBasic performs basic validation that doesn't involve state data.
   169  // It checks the internal consistency of the block.
   170  // Further validation is done using state#ValidateBlock.
   171  func (b *Block) ValidateBasic() error {
   172  	if b == nil {
   173  		return errors.New("nil block")
   174  	}
   175  
   176  	b.mtx.Lock()
   177  	defer b.mtx.Unlock()
   178  
   179  	if err := b.Header.ValidateBasic(); err != nil {
   180  		return fmt.Errorf("invalid header: %w", err)
   181  	}
   182  
   183  	// Validate the last commit and its hash.
   184  	if b.Header.Height > GetStartBlockHeight()+1 {
   185  		if b.LastCommit == nil {
   186  			return errors.New("nil LastCommit")
   187  		}
   188  		if err := b.LastCommit.ValidateBasic(); err != nil {
   189  			return fmt.Errorf("wrong LastCommit: %v", err)
   190  		}
   191  	}
   192  
   193  	if !bytes.Equal(b.LastCommitHash, b.LastCommit.Hash()) {
   194  		return fmt.Errorf("wrong Header.LastCommitHash. Expected %v, got %v",
   195  			b.LastCommit.Hash(),
   196  			b.LastCommitHash,
   197  		)
   198  	}
   199  
   200  	// NOTE: b.Data.Txs may be nil, but b.Data.Hash() still works fine.
   201  	if !bytes.Equal(b.DataHash, b.Data.Hash(b.Height)) {
   202  		return fmt.Errorf(
   203  			"wrong Header.DataHash. Expected %v, got %v",
   204  			b.Data.Hash(b.Height),
   205  			b.DataHash,
   206  		)
   207  	}
   208  
   209  	// NOTE: b.Evidence.Evidence may be nil, but we're just looping.
   210  	for i, ev := range b.Evidence.Evidence {
   211  		if err := ev.ValidateBasic(); err != nil {
   212  			return fmt.Errorf("invalid evidence (#%d): %v", i, err)
   213  		}
   214  	}
   215  
   216  	if !bytes.Equal(b.EvidenceHash, b.Evidence.Hash()) {
   217  		return fmt.Errorf("wrong Header.EvidenceHash. Expected %v, got %v",
   218  			b.EvidenceHash,
   219  			b.Evidence.Hash(),
   220  		)
   221  	}
   222  
   223  	return nil
   224  }
   225  
   226  // fillHeader fills in any remaining header fields that are a function of the block data
   227  func (b *Block) fillHeader() {
   228  	if b.LastCommitHash == nil {
   229  		b.LastCommitHash = b.LastCommit.Hash()
   230  	}
   231  	if b.DataHash == nil {
   232  		b.DataHash = b.Data.Hash(b.Height)
   233  	}
   234  	if b.EvidenceHash == nil {
   235  		b.EvidenceHash = b.Evidence.Hash()
   236  	}
   237  }
   238  
   239  // Hash computes and returns the block hash.
   240  // If the block is incomplete, block hash is nil for safety.
   241  func (b *Block) Hash() tmbytes.HexBytes {
   242  	if b == nil {
   243  		return nil
   244  	}
   245  	b.mtx.Lock()
   246  	defer b.mtx.Unlock()
   247  
   248  	if b.LastCommit == nil {
   249  		return nil
   250  	}
   251  	b.fillHeader()
   252  
   253  	return b.Header.Hash()
   254  }
   255  
   256  // MakePartSet returns a PartSet containing parts of a serialized block.
   257  // This is the form in which the block is gossipped to peers.
   258  // CONTRACT: partSize is greater than zero.
   259  func (b *Block) MakePartSet(partSize int) *PartSet {
   260  	return b.MakePartSetByExInfo(&BlockExInfo{
   261  		BlockCompressType: BlockCompressType,
   262  		BlockCompressFlag: BlockCompressFlag,
   263  		BlockPartSize:     partSize,
   264  	})
   265  }
   266  
   267  func (b *Block) MakePartSetByExInfo(exInfo *BlockExInfo) *PartSet {
   268  	if b == nil {
   269  		return nil
   270  	}
   271  	if exInfo == nil {
   272  		exInfo = &BlockExInfo{
   273  			BlockCompressType: BlockCompressType,
   274  			BlockCompressFlag: BlockCompressFlag,
   275  			BlockPartSize:     BlockPartSizeBytes,
   276  		}
   277  	}
   278  	b.mtx.Lock()
   279  	defer b.mtx.Unlock()
   280  
   281  	// We prefix the byte length, so that unmarshaling
   282  	// can easily happen via a reader.
   283  	bz, err := cdc.MarshalBinaryLengthPrefixed(b)
   284  	if err != nil {
   285  		panic(err)
   286  	}
   287  
   288  	payload := compressBlock(bz, exInfo.BlockCompressType, exInfo.BlockCompressFlag)
   289  
   290  	return NewPartSetFromData(payload, exInfo.BlockPartSize)
   291  
   292  }
   293  
   294  func compressBlock(bz []byte, compressType, compressFlag int) []byte {
   295  	if compressType == 0 || len(bz) <= BlockCompressThreshold {
   296  		return bz
   297  	}
   298  	if compressType >= CompressDividing || compressFlag >= CompressDividing {
   299  		// unsupported compressType or compressFlag
   300  		return bz
   301  	}
   302  
   303  	t0 := tmtime.Now()
   304  	cz, err := compress.Compress(compressType, compressFlag, bz)
   305  	if err != nil {
   306  		return bz
   307  	}
   308  	t1 := tmtime.Now()
   309  
   310  	trace.GetElapsedInfo().AddInfo(trace.CompressBlock, fmt.Sprintf("%dms", t1.Sub(t0).Milliseconds()))
   311  	// tell receiver which compress type and flag
   312  	// tens digit is compressType and unit digit is compressFlag
   313  	// compressSign: XY means, compressType: X, compressFlag: Y
   314  	compressSign := compressType*CompressDividing + compressFlag
   315  	return append(cz, byte(compressSign))
   316  }
   317  
   318  func UncompressBlockFromReader(pbpReader io.Reader) (io.Reader, error) {
   319  	// received compressed block bytes, uncompress with the flag:Proposal.CompressBlock
   320  	compressed, err := io.ReadAll(pbpReader)
   321  	if err != nil {
   322  		return nil, err
   323  	}
   324  	t0 := tmtime.Now()
   325  	original, compressSign, err := UncompressBlockFromBytes(compressed)
   326  	if err != nil {
   327  		return nil, err
   328  	}
   329  	t1 := tmtime.Now()
   330  
   331  	if compressSign != 0 {
   332  		compressRatio := float64(len(compressed)) / float64(len(original))
   333  		trace.GetElapsedInfo().AddInfo(trace.UncompressBlock, fmt.Sprintf("%.2f/%dms",
   334  			compressRatio, t1.Sub(t0).Milliseconds()))
   335  	}
   336  
   337  	return bytes.NewBuffer(original), nil
   338  }
   339  
   340  // UncompressBlockFromBytes uncompress from compressBytes to blockPart bytes, and returns the compressSign
   341  // compressSign contains compressType and compressFlag
   342  // the compressSign: XY means, compressType: X, compressFlag: Y
   343  func UncompressBlockFromBytes(payload []byte) (res []byte, compressSign int, err error) {
   344  	var buf bytes.Buffer
   345  	compressSign, err = UncompressBlockFromBytesTo(payload, &buf)
   346  	if err == nil && compressSign == 0 {
   347  		return payload, 0, nil
   348  	}
   349  	res = buf.Bytes()
   350  	return
   351  }
   352  
   353  func IsBlockDataCompressed(payload []byte) bool {
   354  	// try parse Uvarint to check if it is compressed
   355  	compressBytesLen, n := binary.Uvarint(payload)
   356  	if compressBytesLen == uint64(len(payload)-n) {
   357  		return false
   358  	} else {
   359  		return true
   360  	}
   361  }
   362  
   363  // UncompressBlockFromBytesTo uncompress payload to buf, and returns the compressSign,
   364  // if payload is not compressed, compressSign will be 0, and buf will not be changed.
   365  func UncompressBlockFromBytesTo(payload []byte, buf *bytes.Buffer) (compressSign int, err error) {
   366  	if IsBlockDataCompressed(payload) {
   367  		// the block has compressed and the last byte is compressSign
   368  		compressSign = int(payload[len(payload)-1])
   369  		err = compress.UnCompressTo(compressSign/CompressDividing, payload[:len(payload)-1], buf)
   370  	}
   371  	return
   372  }
   373  
   374  // HashesTo is a convenience function that checks if a block hashes to the given argument.
   375  // Returns false if the block is nil or the hash is empty.
   376  func (b *Block) HashesTo(hash []byte) bool {
   377  	if len(hash) == 0 {
   378  		return false
   379  	}
   380  	if b == nil {
   381  		return false
   382  	}
   383  	return bytes.Equal(b.Hash(), hash)
   384  }
   385  
   386  // Size returns size of the block in bytes.
   387  func (b *Block) Size() int {
   388  	bz, err := cdc.MarshalBinaryBare(b)
   389  	if err != nil {
   390  		return 0
   391  	}
   392  	return len(bz)
   393  }
   394  
   395  // TODO : Replace the original logic of Size with the logic of FastSize
   396  
   397  // FastSize returns size of the block in bytes. and more efficient than Size().
   398  // But we can't make sure it's completely correct yet, when we're done testing, we'll replace Size with FastSize
   399  func (b *Block) FastSize() (size int) {
   400  	defer func() {
   401  		if r := recover(); r != nil {
   402  			size = 0
   403  		}
   404  	}()
   405  	return b.AminoSize(cdc)
   406  }
   407  
   408  // String returns a string representation of the block
   409  func (b *Block) String() string {
   410  	return b.StringIndented("")
   411  }
   412  
   413  // StringIndented returns a string representation of the block
   414  func (b *Block) StringIndented(indent string) string {
   415  	if b == nil {
   416  		return "nil-Block"
   417  	}
   418  	return fmt.Sprintf(`Block{
   419  %s  %v
   420  %s  %v
   421  %s  %v
   422  %s  %v
   423  %s}#%v`,
   424  		indent, b.Header.StringIndented(indent+"  "),
   425  		indent, b.Data.StringIndented(indent+"  ", b.Height),
   426  		indent, b.Evidence.StringIndented(indent+"  "),
   427  		indent, b.LastCommit.StringIndented(indent+"  "),
   428  		indent, b.Hash())
   429  }
   430  
   431  // StringShort returns a shortened string representation of the block
   432  func (b *Block) StringShort() string {
   433  	if b == nil {
   434  		return "nil-Block"
   435  	}
   436  	return fmt.Sprintf("Block#%v", b.Hash())
   437  }
   438  
   439  //-----------------------------------------------------------
   440  // These methods are for Protobuf Compatibility
   441  
   442  // Marshal returns the amino encoding.
   443  func (b *Block) Marshal() ([]byte, error) {
   444  	return cdc.MarshalBinaryBare(b)
   445  }
   446  
   447  // MarshalTo calls Marshal and copies to the given buffer.
   448  func (b *Block) MarshalTo(data []byte) (int, error) {
   449  	bs, err := b.Marshal()
   450  	if err != nil {
   451  		return -1, err
   452  	}
   453  	return copy(data, bs), nil
   454  }
   455  
   456  // Unmarshal deserializes from amino encoded form.
   457  func (b *Block) Unmarshal(bs []byte) error {
   458  	return cdc.UnmarshalBinaryBare(bs, b)
   459  }
   460  
   461  //-----------------------------------------------------------------------------
   462  
   463  // MaxDataBytes returns the maximum size of block's data.
   464  //
   465  // XXX: Panics on negative result.
   466  func MaxDataBytes(maxBytes int64, valsCount, evidenceCount int) int64 {
   467  	maxDataBytes := maxBytes -
   468  		MaxAminoOverheadForBlock -
   469  		MaxHeaderBytes -
   470  		int64(valsCount)*MaxVoteBytes -
   471  		int64(evidenceCount)*MaxEvidenceBytes
   472  
   473  	if maxDataBytes < 0 {
   474  		panic(fmt.Sprintf(
   475  			"Negative MaxDataBytes. Block.MaxBytes=%d is too small to accommodate header&lastCommit&evidence=%d",
   476  			maxBytes,
   477  			-(maxDataBytes - maxBytes),
   478  		))
   479  	}
   480  
   481  	return maxDataBytes
   482  
   483  }
   484  
   485  // MaxDataBytesUnknownEvidence returns the maximum size of block's data when
   486  // evidence count is unknown. MaxEvidencePerBlock will be used for the size
   487  // of evidence.
   488  //
   489  // XXX: Panics on negative result.
   490  func MaxDataBytesUnknownEvidence(maxBytes int64, valsCount int) int64 {
   491  	_, maxEvidenceBytes := MaxEvidencePerBlock(maxBytes)
   492  	maxDataBytes := maxBytes -
   493  		MaxAminoOverheadForBlock -
   494  		MaxHeaderBytes -
   495  		int64(valsCount)*MaxVoteBytes -
   496  		maxEvidenceBytes
   497  
   498  	if maxDataBytes < 0 {
   499  		panic(fmt.Sprintf(
   500  			"Negative MaxDataBytesUnknownEvidence. Block.MaxBytes=%d is too small to accommodate header&lastCommit&evidence=%d",
   501  			maxBytes,
   502  			-(maxDataBytes - maxBytes),
   503  		))
   504  	}
   505  
   506  	return maxDataBytes
   507  }
   508  
   509  //-----------------------------------------------------------------------------
   510  
   511  // Header defines the structure of a Tendermint block header.
   512  // NOTE: changes to the Header should be duplicated in:
   513  // - header.Hash()
   514  // - abci.Header
   515  // - https://github.com/tendermint/spec/blob/master/spec/blockchain/blockchain.md
   516  type Header struct {
   517  	// basic block info
   518  	Version version.Consensus `json:"version"`
   519  	ChainID string            `json:"chain_id"`
   520  	Height  int64             `json:"height"`
   521  	Time    time.Time         `json:"time"`
   522  
   523  	// prev block info
   524  	LastBlockID BlockID `json:"last_block_id"`
   525  
   526  	// hashes of block data
   527  	LastCommitHash tmbytes.HexBytes `json:"last_commit_hash"` // commit from validators from the last block
   528  	DataHash       tmbytes.HexBytes `json:"data_hash"`        // transactions
   529  
   530  	// hashes from the app output from the prev block
   531  	ValidatorsHash     tmbytes.HexBytes `json:"validators_hash"`      // validators for the current block
   532  	NextValidatorsHash tmbytes.HexBytes `json:"next_validators_hash"` // validators for the next block
   533  	ConsensusHash      tmbytes.HexBytes `json:"consensus_hash"`       // consensus params for current block
   534  	AppHash            tmbytes.HexBytes `json:"app_hash"`             // state after txs from the previous block
   535  	// root hash of all results from the txs from the previous block
   536  	LastResultsHash tmbytes.HexBytes `json:"last_results_hash"`
   537  
   538  	// consensus info
   539  	EvidenceHash    tmbytes.HexBytes `json:"evidence_hash"`    // evidence included in the block
   540  	ProposerAddress Address          `json:"proposer_address"` // original proposer of the block
   541  }
   542  
   543  func (h Header) AminoSize(cdc *amino.Codec) int {
   544  	var size int
   545  
   546  	versionSize := h.Version.AminoSize()
   547  	if versionSize > 0 {
   548  		size += 1 + amino.UvarintSize(uint64(versionSize)) + versionSize
   549  	}
   550  
   551  	if h.ChainID != "" {
   552  		size += 1 + amino.UvarintSize(uint64(len(h.ChainID))) + len(h.ChainID)
   553  	}
   554  
   555  	if h.Height != 0 {
   556  		size += 1 + amino.UvarintSize(uint64(h.Height))
   557  	}
   558  
   559  	timeSize := amino.TimeSize(h.Time)
   560  	if timeSize > 0 {
   561  		size += 1 + amino.UvarintSize(uint64(timeSize)) + timeSize
   562  	}
   563  
   564  	blockIDSize := h.LastBlockID.AminoSize(cdc)
   565  	if blockIDSize > 0 {
   566  		size += 1 + amino.UvarintSize(uint64(blockIDSize)) + blockIDSize
   567  	}
   568  
   569  	if len(h.LastCommitHash) != 0 {
   570  		size += 1 + amino.ByteSliceSize(h.LastCommitHash)
   571  	}
   572  
   573  	if len(h.DataHash) != 0 {
   574  		size += 1 + amino.ByteSliceSize(h.DataHash)
   575  	}
   576  
   577  	if len(h.ValidatorsHash) != 0 {
   578  		size += 1 + amino.ByteSliceSize(h.ValidatorsHash)
   579  	}
   580  
   581  	if len(h.NextValidatorsHash) != 0 {
   582  		size += 1 + amino.ByteSliceSize(h.NextValidatorsHash)
   583  	}
   584  
   585  	if len(h.ConsensusHash) != 0 {
   586  		size += 1 + amino.ByteSliceSize(h.ConsensusHash)
   587  	}
   588  
   589  	if len(h.AppHash) != 0 {
   590  		size += 1 + amino.ByteSliceSize(h.AppHash)
   591  	}
   592  
   593  	if len(h.LastResultsHash) != 0 {
   594  		size += 1 + amino.ByteSliceSize(h.LastResultsHash)
   595  	}
   596  
   597  	if len(h.EvidenceHash) != 0 {
   598  		size += 1 + amino.ByteSliceSize(h.EvidenceHash)
   599  	}
   600  
   601  	if len(h.ProposerAddress) != 0 {
   602  		size += 1 + amino.ByteSliceSize(h.ProposerAddress)
   603  	}
   604  
   605  	return size
   606  }
   607  
   608  func (h *Header) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
   609  	var dataLen uint64 = 0
   610  	var subData []byte
   611  	var timeUpdated = false
   612  
   613  	for {
   614  		data = data[dataLen:]
   615  
   616  		if len(data) == 0 {
   617  			break
   618  		}
   619  
   620  		pos, aminoType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
   621  		if err != nil {
   622  			return err
   623  		}
   624  		data = data[1:]
   625  
   626  		if aminoType == amino.Typ3_ByteLength {
   627  			var n int
   628  			dataLen, n, err = amino.DecodeUvarint(data)
   629  			if err != nil {
   630  				return err
   631  			}
   632  
   633  			data = data[n:]
   634  			if len(data) < int(dataLen) {
   635  				return fmt.Errorf("not enough data for field, need %d, have %d", dataLen, len(data))
   636  			}
   637  			subData = data[:dataLen]
   638  		}
   639  
   640  		switch pos {
   641  		case 1:
   642  			err = h.Version.UnmarshalFromAmino(cdc, subData)
   643  			if err != nil {
   644  				return err
   645  			}
   646  		case 2:
   647  			h.ChainID = string(subData)
   648  		case 3:
   649  			uvint, n, err := amino.DecodeUvarint(data)
   650  			if err != nil {
   651  				return err
   652  			}
   653  			h.Height = int64(uvint)
   654  			dataLen = uint64(n)
   655  		case 4:
   656  			h.Time, _, err = amino.DecodeTime(subData)
   657  			if err != nil {
   658  				return err
   659  			}
   660  			timeUpdated = true
   661  		case 5:
   662  			err = h.LastBlockID.UnmarshalFromAmino(cdc, subData)
   663  			if err != nil {
   664  				return err
   665  			}
   666  		case 6:
   667  			h.LastCommitHash = make([]byte, len(subData))
   668  			copy(h.LastCommitHash, subData)
   669  		case 7:
   670  			h.DataHash = make([]byte, len(subData))
   671  			copy(h.DataHash, subData)
   672  		case 8:
   673  			h.ValidatorsHash = make([]byte, len(subData))
   674  			copy(h.ValidatorsHash, subData)
   675  		case 9:
   676  			h.NextValidatorsHash = make([]byte, len(subData))
   677  			copy(h.NextValidatorsHash, subData)
   678  		case 10:
   679  			h.ConsensusHash = make([]byte, len(subData))
   680  			copy(h.ConsensusHash, subData)
   681  		case 11:
   682  			h.AppHash = make([]byte, len(subData))
   683  			copy(h.AppHash, subData)
   684  		case 12:
   685  			h.LastResultsHash = make([]byte, len(subData))
   686  			copy(h.LastResultsHash, subData)
   687  		case 13:
   688  			h.EvidenceHash = make([]byte, len(subData))
   689  			copy(h.EvidenceHash, subData)
   690  		case 14:
   691  			h.ProposerAddress = make([]byte, len(subData))
   692  			copy(h.ProposerAddress, subData)
   693  		default:
   694  			return fmt.Errorf("unexpect feild num %d", pos)
   695  		}
   696  	}
   697  	if !timeUpdated {
   698  		h.Time = amino.ZeroTime
   699  	}
   700  	return nil
   701  }
   702  
   703  // Populate the Header with state-derived data.
   704  // Call this after MakeBlock to complete the Header.
   705  func (h *Header) Populate(
   706  	version version.Consensus, chainID string,
   707  	timestamp time.Time, lastBlockID BlockID,
   708  	valHash, nextValHash []byte,
   709  	consensusHash, appHash, lastResultsHash []byte,
   710  	proposerAddress Address,
   711  ) {
   712  	h.Version = version
   713  	h.ChainID = chainID
   714  	h.Time = timestamp
   715  	h.LastBlockID = lastBlockID
   716  	h.ValidatorsHash = valHash
   717  	h.NextValidatorsHash = nextValHash
   718  	h.ConsensusHash = consensusHash
   719  	h.AppHash = appHash
   720  	h.LastResultsHash = lastResultsHash
   721  	h.ProposerAddress = proposerAddress
   722  }
   723  
   724  // ValidateBasic performs stateless validation on a Header returning an error
   725  // if any validation fails.
   726  //
   727  // NOTE: Timestamp validation is subtle and handled elsewhere.
   728  func (h Header) ValidateBasic() error {
   729  	if len(h.ChainID) > MaxChainIDLen {
   730  		return fmt.Errorf("chainID is too long; got: %d, max: %d", len(h.ChainID), MaxChainIDLen)
   731  	}
   732  
   733  	if h.Height < 0 {
   734  		return errors.New("negative Height")
   735  	} else if h.Height == 0 {
   736  		return errors.New("zero Height")
   737  	}
   738  
   739  	if err := h.LastBlockID.ValidateBasic(); err != nil {
   740  		return fmt.Errorf("wrong LastBlockID: %w", err)
   741  	}
   742  
   743  	if err := ValidateHash(h.LastCommitHash); err != nil {
   744  		return fmt.Errorf("wrong LastCommitHash: %v", err)
   745  	}
   746  
   747  	if err := ValidateHash(h.DataHash); err != nil {
   748  		return fmt.Errorf("wrong DataHash: %v", err)
   749  	}
   750  
   751  	if err := ValidateHash(h.EvidenceHash); err != nil {
   752  		return fmt.Errorf("wrong EvidenceHash: %v", err)
   753  	}
   754  
   755  	if len(h.ProposerAddress) != crypto.AddressSize {
   756  		return fmt.Errorf(
   757  			"invalid ProposerAddress length; got: %d, expected: %d",
   758  			len(h.ProposerAddress), crypto.AddressSize,
   759  		)
   760  	}
   761  
   762  	// Basic validation of hashes related to application data.
   763  	// Will validate fully against state in state#ValidateBlock.
   764  	if err := ValidateHash(h.ValidatorsHash); err != nil {
   765  		return fmt.Errorf("wrong ValidatorsHash: %v", err)
   766  	}
   767  	if err := ValidateHash(h.NextValidatorsHash); err != nil {
   768  		return fmt.Errorf("wrong NextValidatorsHash: %v", err)
   769  	}
   770  	if err := ValidateHash(h.ConsensusHash); err != nil {
   771  		return fmt.Errorf("wrong ConsensusHash: %v", err)
   772  	}
   773  	// NOTE: AppHash is arbitrary length
   774  	if err := ValidateHash(h.LastResultsHash); err != nil {
   775  		return fmt.Errorf("wrong LastResultsHash: %v", err)
   776  	}
   777  
   778  	return nil
   779  }
   780  
   781  // Hash returns the hash of the header.
   782  // It computes a Merkle tree from the header fields
   783  // ordered as they appear in the Header.
   784  // Returns nil if ValidatorHash is missing,
   785  // since a Header is not valid unless there is
   786  // a ValidatorsHash (corresponding to the validator set).
   787  
   788  func (h *Header) Hash() tmbytes.HexBytes {
   789  	if h == nil || len(h.ValidatorsHash) == 0 {
   790  		return nil
   791  	}
   792  	if HigherThanVenus1(h.Height) {
   793  		return h.IBCHash()
   794  	}
   795  	return h.originHash()
   796  }
   797  func (h *Header) originHash() tmbytes.HexBytes {
   798  	return merkle.SimpleHashFromByteSlices([][]byte{
   799  		cdcEncode(h.Version),
   800  		cdcEncode(h.ChainID),
   801  		cdcEncode(h.Height),
   802  		cdcEncode(h.Time),
   803  		cdcEncode(h.LastBlockID),
   804  		cdcEncode(h.LastCommitHash),
   805  		cdcEncode(h.DataHash),
   806  		cdcEncode(h.ValidatorsHash),
   807  		cdcEncode(h.NextValidatorsHash),
   808  		cdcEncode(h.ConsensusHash),
   809  		cdcEncode(h.AppHash),
   810  		cdcEncode(h.LastResultsHash),
   811  		cdcEncode(h.EvidenceHash),
   812  		cdcEncode(h.ProposerAddress),
   813  	})
   814  }
   815  
   816  func (h *Header) IBCHash() tmbytes.HexBytes {
   817  	if h == nil || len(h.ValidatorsHash) == 0 {
   818  		return nil
   819  	}
   820  	hbz, err := h.Version.Marshal()
   821  	if err != nil {
   822  		return nil
   823  	}
   824  	pbt, err := gogotypes.StdTimeMarshal(h.Time)
   825  	if err != nil {
   826  		return nil
   827  	}
   828  
   829  	pbbi := h.LastBlockID.ToIBCProto()
   830  	bzbi, err := pbbi.Marshal()
   831  	if err != nil {
   832  		return nil
   833  	}
   834  	ret := merkle.HashFromByteSlices([][]byte{
   835  		hbz,
   836  		ibccdcEncode(h.ChainID),
   837  		ibccdcEncode(h.Height),
   838  		pbt,
   839  		bzbi,
   840  		ibccdcEncode(h.LastCommitHash),
   841  		ibccdcEncode(h.DataHash),
   842  		ibccdcEncode(h.ValidatorsHash),
   843  		ibccdcEncode(h.NextValidatorsHash),
   844  		ibccdcEncode(h.ConsensusHash),
   845  		ibccdcEncode(h.AppHash),
   846  		ibccdcEncode(h.LastResultsHash),
   847  		ibccdcEncode(h.EvidenceHash),
   848  		ibccdcEncode(h.ProposerAddress),
   849  	})
   850  	return ret
   851  }
   852  
   853  // StringIndented returns a string representation of the header
   854  func (h *Header) StringIndented(indent string) string {
   855  	if h == nil {
   856  		return "nil-Header"
   857  	}
   858  	return fmt.Sprintf(`Header{
   859  %s  Version:        %v
   860  %s  ChainID:        %v
   861  %s  Height:         %v
   862  %s  Time:           %v
   863  %s  LastBlockID:    %v
   864  %s  LastCommit:     %v
   865  %s  Data:           %v
   866  %s  Validators:     %v
   867  %s  NextValidators: %v
   868  %s  App:            %v
   869  %s  Consensus:      %v
   870  %s  Results:        %v
   871  %s  Evidence:       %v
   872  %s  Proposer:       %v
   873  %s}#%v`,
   874  		indent, h.Version,
   875  		indent, h.ChainID,
   876  		indent, h.Height,
   877  		indent, h.Time,
   878  		indent, h.LastBlockID,
   879  		indent, h.LastCommitHash,
   880  		indent, h.DataHash,
   881  		indent, h.ValidatorsHash,
   882  		indent, h.NextValidatorsHash,
   883  		indent, h.AppHash,
   884  		indent, h.ConsensusHash,
   885  		indent, h.LastResultsHash,
   886  		indent, h.EvidenceHash,
   887  		indent, h.ProposerAddress,
   888  		indent, h.Hash())
   889  }
   890  
   891  // ToProto converts Header to protobuf
   892  func (h *Header) ToProto() *tmproto.Header {
   893  	if h == nil {
   894  		return nil
   895  	}
   896  	return &tmproto.Header{
   897  		Version:            tmversion.Consensus{Block: h.Version.Block.Uint64(), App: h.Version.App.Uint64()},
   898  		ChainID:            h.ChainID,
   899  		Height:             h.Height,
   900  		Time:               h.Time,
   901  		LastBlockID:        h.LastBlockID.ToProto(),
   902  		ValidatorsHash:     h.ValidatorsHash,
   903  		NextValidatorsHash: h.NextValidatorsHash,
   904  		ConsensusHash:      h.ConsensusHash,
   905  		AppHash:            h.AppHash,
   906  		DataHash:           h.DataHash,
   907  		EvidenceHash:       h.EvidenceHash,
   908  		LastResultsHash:    h.LastResultsHash,
   909  		LastCommitHash:     h.LastCommitHash,
   910  		ProposerAddress:    h.ProposerAddress,
   911  	}
   912  }
   913  
   914  // FromProto sets a protobuf Header to the given pointer.
   915  // It returns an error if the header is invalid.
   916  func HeaderFromProto(ph *tmproto.Header) (Header, error) {
   917  	if ph == nil {
   918  		return Header{}, errors.New("nil Header")
   919  	}
   920  
   921  	h := new(Header)
   922  
   923  	bi, err := BlockIDFromProto(&ph.LastBlockID)
   924  	if err != nil {
   925  		return Header{}, err
   926  	}
   927  
   928  	h.Version = version.Consensus{Block: version.Protocol(ph.Version.Block), App: version.Protocol(ph.Version.App)}
   929  	h.ChainID = ph.ChainID
   930  	h.Height = ph.Height
   931  	h.Time = ph.Time
   932  	h.Height = ph.Height
   933  	h.LastBlockID = *bi
   934  	h.ValidatorsHash = ph.ValidatorsHash
   935  	h.NextValidatorsHash = ph.NextValidatorsHash
   936  	h.ConsensusHash = ph.ConsensusHash
   937  	h.AppHash = ph.AppHash
   938  	h.DataHash = ph.DataHash
   939  	h.EvidenceHash = ph.EvidenceHash
   940  	h.LastResultsHash = ph.LastResultsHash
   941  	h.LastCommitHash = ph.LastCommitHash
   942  	h.ProposerAddress = ph.ProposerAddress
   943  
   944  	return *h, h.ValidateBasic()
   945  }
   946  
   947  //-------------------------------------
   948  
   949  // BlockIDFlag indicates which BlockID the signature is for.
   950  type BlockIDFlag byte
   951  
   952  const (
   953  	// BlockIDFlagAbsent - no vote was received from a validator.
   954  	BlockIDFlagAbsent BlockIDFlag = iota + 1
   955  	// BlockIDFlagCommit - voted for the Commit.BlockID.
   956  	BlockIDFlagCommit
   957  	// BlockIDFlagNil - voted for nil.
   958  	BlockIDFlagNil
   959  )
   960  
   961  // CommitSig is a part of the Vote included in a Commit.
   962  type CommitSig struct {
   963  	BlockIDFlag      BlockIDFlag `json:"block_id_flag"`
   964  	ValidatorAddress Address     `json:"validator_address"`
   965  	Timestamp        time.Time   `json:"timestamp"`
   966  	Signature        []byte      `json:"signature"`
   967  }
   968  
   969  func (cs CommitSig) AminoSize(_ *amino.Codec) int {
   970  	var size = 0
   971  
   972  	if cs.BlockIDFlag != 0 {
   973  		size += 1 + amino.UvarintSize(uint64(cs.BlockIDFlag))
   974  	}
   975  
   976  	if len(cs.ValidatorAddress) != 0 {
   977  		size += 1 + amino.ByteSliceSize(cs.ValidatorAddress)
   978  	}
   979  
   980  	timestampSize := amino.TimeSize(cs.Timestamp)
   981  	if timestampSize > 0 {
   982  		size += 1 + amino.UvarintSize(uint64(timestampSize)) + timestampSize
   983  	}
   984  
   985  	if len(cs.Signature) != 0 {
   986  		size += 1 + amino.ByteSliceSize(cs.Signature)
   987  	}
   988  
   989  	return size
   990  }
   991  
   992  func (cs *CommitSig) UnmarshalFromAmino(_ *amino.Codec, data []byte) error {
   993  	var dataLen uint64 = 0
   994  	var subData []byte
   995  	var timestampUpdated bool
   996  
   997  	for {
   998  		data = data[dataLen:]
   999  		if len(data) == 0 {
  1000  			break
  1001  		}
  1002  
  1003  		pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
  1004  		if err != nil {
  1005  			return err
  1006  		}
  1007  		data = data[1:]
  1008  
  1009  		if pbType == amino.Typ3_ByteLength {
  1010  			var n int
  1011  			dataLen, n, err = amino.DecodeUvarint(data)
  1012  			if err != nil {
  1013  				return err
  1014  			}
  1015  			data = data[n:]
  1016  			if len(data) < int(dataLen) {
  1017  				return fmt.Errorf("invalid data len")
  1018  			}
  1019  			subData = data[:dataLen]
  1020  		}
  1021  
  1022  		switch pos {
  1023  		case 1:
  1024  			u64, n, err := amino.DecodeUvarint(data)
  1025  			if err != nil {
  1026  				return err
  1027  			}
  1028  			cs.BlockIDFlag = BlockIDFlag(u64)
  1029  			dataLen = uint64(n)
  1030  		case 2:
  1031  			cs.ValidatorAddress = make([]byte, len(subData))
  1032  			copy(cs.ValidatorAddress, subData)
  1033  		case 3:
  1034  			cs.Timestamp, _, err = amino.DecodeTime(subData)
  1035  			if err != nil {
  1036  				return err
  1037  			}
  1038  			timestampUpdated = true
  1039  		case 4:
  1040  			cs.Signature = make([]byte, len(subData))
  1041  			copy(cs.Signature, subData)
  1042  		default:
  1043  			return fmt.Errorf("unexpect feild num %d", pos)
  1044  		}
  1045  	}
  1046  	if !timestampUpdated {
  1047  		cs.Timestamp = amino.ZeroTime
  1048  	}
  1049  	return nil
  1050  }
  1051  
  1052  // NewCommitSigForBlock returns new CommitSig with BlockIDFlagCommit.
  1053  func NewCommitSigForBlock(signature []byte, valAddr Address, ts time.Time) CommitSig {
  1054  	return CommitSig{
  1055  		BlockIDFlag:      BlockIDFlagCommit,
  1056  		ValidatorAddress: valAddr,
  1057  		Timestamp:        ts,
  1058  		Signature:        signature,
  1059  	}
  1060  }
  1061  
  1062  // ForBlock returns true if CommitSig is for the block.
  1063  func (cs CommitSig) ForBlock() bool {
  1064  	return cs.BlockIDFlag == BlockIDFlagCommit
  1065  }
  1066  
  1067  // NewCommitSigAbsent returns new CommitSig with BlockIDFlagAbsent. Other
  1068  // fields are all empty.
  1069  func NewCommitSigAbsent() CommitSig {
  1070  	return CommitSig{
  1071  		BlockIDFlag: BlockIDFlagAbsent,
  1072  	}
  1073  }
  1074  
  1075  // Absent returns true if CommitSig is absent.
  1076  func (cs CommitSig) Absent() bool {
  1077  	return cs.BlockIDFlag == BlockIDFlagAbsent
  1078  }
  1079  
  1080  func (cs CommitSig) String() string {
  1081  	return fmt.Sprintf("CommitSig{%X by %X on %v @ %s}",
  1082  		tmbytes.Fingerprint(cs.Signature),
  1083  		tmbytes.Fingerprint(cs.ValidatorAddress),
  1084  		cs.BlockIDFlag,
  1085  		CanonicalTime(cs.Timestamp))
  1086  }
  1087  
  1088  // BlockID returns the Commit's BlockID if CommitSig indicates signing,
  1089  // otherwise - empty BlockID.
  1090  func (cs CommitSig) BlockID(commitBlockID BlockID) BlockID {
  1091  	var blockID BlockID
  1092  	switch cs.BlockIDFlag {
  1093  	case BlockIDFlagAbsent:
  1094  		blockID = BlockID{}
  1095  	case BlockIDFlagCommit:
  1096  		blockID = commitBlockID
  1097  	case BlockIDFlagNil:
  1098  		blockID = BlockID{}
  1099  	default:
  1100  		panic(fmt.Sprintf("Unknown BlockIDFlag: %v", cs.BlockIDFlag))
  1101  	}
  1102  	return blockID
  1103  }
  1104  
  1105  // ValidateBasic performs basic validation.
  1106  func (cs CommitSig) ValidateBasic() error {
  1107  	switch cs.BlockIDFlag {
  1108  	case BlockIDFlagAbsent:
  1109  	case BlockIDFlagCommit:
  1110  	case BlockIDFlagNil:
  1111  	default:
  1112  		return fmt.Errorf("unknown BlockIDFlag: %v", cs.BlockIDFlag)
  1113  	}
  1114  
  1115  	switch cs.BlockIDFlag {
  1116  	case BlockIDFlagAbsent:
  1117  		if len(cs.ValidatorAddress) != 0 {
  1118  			return errors.New("validator address is present")
  1119  		}
  1120  		if !cs.Timestamp.IsZero() {
  1121  			return errors.New("time is present")
  1122  		}
  1123  		if len(cs.Signature) != 0 {
  1124  			return errors.New("signature is present")
  1125  		}
  1126  	default:
  1127  		if len(cs.ValidatorAddress) != crypto.AddressSize {
  1128  			return fmt.Errorf("expected ValidatorAddress size to be %d bytes, got %d bytes",
  1129  				crypto.AddressSize,
  1130  				len(cs.ValidatorAddress),
  1131  			)
  1132  		}
  1133  		// NOTE: Timestamp validation is subtle and handled elsewhere.
  1134  		if len(cs.Signature) == 0 {
  1135  			return errors.New("signature is missing")
  1136  		}
  1137  		if len(cs.Signature) > MaxSignatureSize {
  1138  			return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize)
  1139  		}
  1140  	}
  1141  
  1142  	return nil
  1143  }
  1144  
  1145  // ToProto converts CommitSig to protobuf
  1146  func (cs *CommitSig) ToProto() *tmproto.CommitSig {
  1147  	if cs == nil {
  1148  		return nil
  1149  	}
  1150  
  1151  	return &tmproto.CommitSig{
  1152  		BlockIdFlag:      tmproto.BlockIDFlag(cs.BlockIDFlag),
  1153  		ValidatorAddress: cs.ValidatorAddress,
  1154  		Timestamp:        cs.Timestamp,
  1155  		Signature:        cs.Signature,
  1156  	}
  1157  }
  1158  
  1159  // FromProto sets a protobuf CommitSig to the given pointer.
  1160  // It returns an error if the CommitSig is invalid.
  1161  func (cs *CommitSig) FromProto(csp tmproto.CommitSig) error {
  1162  
  1163  	cs.BlockIDFlag = BlockIDFlag(csp.BlockIdFlag)
  1164  	cs.ValidatorAddress = csp.ValidatorAddress
  1165  	cs.Timestamp = csp.Timestamp
  1166  	cs.Signature = csp.Signature
  1167  
  1168  	return cs.ValidateBasic()
  1169  }
  1170  
  1171  //-------------------------------------
  1172  
  1173  // Commit contains the evidence that a block was committed by a set of validators.
  1174  // NOTE: Commit is empty for height 1, but never nil.
  1175  type Commit struct {
  1176  	// NOTE: The signatures are in order of address to preserve the bonded
  1177  	// ValidatorSet order.
  1178  	// Any peer with a block can gossip signatures by index with a peer without
  1179  	// recalculating the active ValidatorSet.
  1180  	Height     int64       `json:"height"`
  1181  	Round      int         `json:"round"`
  1182  	BlockID    BlockID     `json:"block_id"`
  1183  	Signatures []CommitSig `json:"signatures"`
  1184  
  1185  	// Memoized in first call to corresponding method.
  1186  	// NOTE: can't memoize in constructor because constructor isn't used for
  1187  	// unmarshaling.
  1188  	hash     tmbytes.HexBytes
  1189  	bitArray *bits.BitArray
  1190  }
  1191  
  1192  func (commit Commit) AminoSize(cdc *amino.Codec) int {
  1193  	var size int = 0
  1194  
  1195  	if commit.Height != 0 {
  1196  		size += 1 + amino.UvarintSize(uint64(commit.Height))
  1197  	}
  1198  
  1199  	if commit.Round != 0 {
  1200  		size += 1 + amino.UvarintSize(uint64(commit.Round))
  1201  	}
  1202  
  1203  	blockIDSize := commit.BlockID.AminoSize(cdc)
  1204  	if blockIDSize > 0 {
  1205  		size += 1 + amino.UvarintSize(uint64(blockIDSize)) + blockIDSize
  1206  	}
  1207  
  1208  	for _, sig := range commit.Signatures {
  1209  		sigSize := sig.AminoSize(cdc)
  1210  		size += 1 + amino.UvarintSize(uint64(sigSize)) + sigSize
  1211  	}
  1212  
  1213  	return size
  1214  }
  1215  
  1216  func (commit *Commit) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
  1217  	var dataLen uint64 = 0
  1218  	var subData []byte
  1219  
  1220  	for {
  1221  		data = data[dataLen:]
  1222  		if len(data) == 0 {
  1223  			break
  1224  		}
  1225  
  1226  		pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
  1227  		if err != nil {
  1228  			return err
  1229  		}
  1230  		data = data[1:]
  1231  
  1232  		if pbType == amino.Typ3_ByteLength {
  1233  			var n int
  1234  			dataLen, n, err = amino.DecodeUvarint(data)
  1235  			if err != nil {
  1236  				return err
  1237  			}
  1238  			data = data[n:]
  1239  			if len(data) < int(dataLen) {
  1240  				return fmt.Errorf("invalid data len")
  1241  			}
  1242  			subData = data[:dataLen]
  1243  		}
  1244  
  1245  		switch pos {
  1246  		case 1:
  1247  			u64, n, err := amino.DecodeUvarint(data)
  1248  			if err != nil {
  1249  				return err
  1250  			}
  1251  			commit.Height = int64(u64)
  1252  			dataLen = uint64(n)
  1253  		case 2:
  1254  			u64, n, err := amino.DecodeUvarint(data)
  1255  			if err != nil {
  1256  				return err
  1257  			}
  1258  			commit.Round = int(u64)
  1259  			dataLen = uint64(n)
  1260  		case 3:
  1261  			err = commit.BlockID.UnmarshalFromAmino(cdc, subData)
  1262  			if err != nil {
  1263  				return err
  1264  			}
  1265  		case 4:
  1266  			var cs CommitSig
  1267  			err = cs.UnmarshalFromAmino(cdc, subData)
  1268  			if err != nil {
  1269  				return err
  1270  			}
  1271  			commit.Signatures = append(commit.Signatures, cs)
  1272  		default:
  1273  			return fmt.Errorf("unexpect feild num %d", pos)
  1274  		}
  1275  	}
  1276  	return nil
  1277  }
  1278  
  1279  // NewCommit returns a new Commit.
  1280  func NewCommit(height int64, round int, blockID BlockID, commitSigs []CommitSig) *Commit {
  1281  	return &Commit{
  1282  		Height:     height,
  1283  		Round:      round,
  1284  		BlockID:    blockID,
  1285  		Signatures: commitSigs,
  1286  	}
  1287  }
  1288  
  1289  // CommitToVoteSet constructs a VoteSet from the Commit and validator set.
  1290  // Panics if signatures from the commit can't be added to the voteset.
  1291  // Inverse of VoteSet.MakeCommit().
  1292  func CommitToVoteSet(chainID string, commit *Commit, vals *ValidatorSet) *VoteSet {
  1293  	voteSet := NewVoteSet(chainID, commit.Height, commit.Round, PrecommitType, vals)
  1294  	for idx, commitSig := range commit.Signatures {
  1295  		if commitSig.Absent() {
  1296  			continue // OK, some precommits can be missing.
  1297  		}
  1298  		added, err := voteSet.AddVote(commit.GetVote(idx))
  1299  		if !added || err != nil {
  1300  			panic(fmt.Sprintf("Failed to reconstruct LastCommit: %v", err))
  1301  		}
  1302  	}
  1303  	return voteSet
  1304  }
  1305  
  1306  // GetVote converts the CommitSig for the given valIdx to a Vote.
  1307  // Returns nil if the precommit at valIdx is nil.
  1308  // Panics if valIdx >= commit.Size().
  1309  func (commit *Commit) GetVote(valIdx int) *Vote {
  1310  	commitSig := commit.Signatures[valIdx]
  1311  	return &Vote{
  1312  		Type:             PrecommitType,
  1313  		Height:           commit.Height,
  1314  		Round:            commit.Round,
  1315  		BlockID:          commitSig.BlockID(commit.BlockID),
  1316  		Timestamp:        commitSig.Timestamp,
  1317  		ValidatorAddress: commitSig.ValidatorAddress,
  1318  		ValidatorIndex:   valIdx,
  1319  		Signature:        commitSig.Signature,
  1320  	}
  1321  }
  1322  
  1323  // VoteSignBytes constructs the SignBytes for the given CommitSig.
  1324  // The only unique part of the SignBytes is the Timestamp - all other fields
  1325  // signed over are otherwise the same for all validators.
  1326  // Panics if valIdx >= commit.Size().
  1327  func (commit *Commit) VoteSignBytes(chainID string, valIdx int) []byte {
  1328  	return commit.GetVote(valIdx).SignBytes(chainID)
  1329  }
  1330  
  1331  // Type returns the vote type of the commit, which is always VoteTypePrecommit
  1332  // Implements VoteSetReader.
  1333  func (commit *Commit) Type() byte {
  1334  	return byte(PrecommitType)
  1335  }
  1336  
  1337  // GetHeight returns height of the commit.
  1338  // Implements VoteSetReader.
  1339  func (commit *Commit) GetHeight() int64 {
  1340  	return commit.Height
  1341  }
  1342  
  1343  // GetRound returns height of the commit.
  1344  // Implements VoteSetReader.
  1345  func (commit *Commit) GetRound() int {
  1346  	return commit.Round
  1347  }
  1348  
  1349  // Size returns the number of signatures in the commit.
  1350  // Implements VoteSetReader.
  1351  func (commit *Commit) Size() int {
  1352  	if commit == nil {
  1353  		return 0
  1354  	}
  1355  	return len(commit.Signatures)
  1356  }
  1357  
  1358  // BitArray returns a BitArray of which validators voted for BlockID or nil in this commit.
  1359  // Implements VoteSetReader.
  1360  func (commit *Commit) BitArray() *bits.BitArray {
  1361  	if commit.bitArray == nil {
  1362  		commit.bitArray = bits.NewBitArray(len(commit.Signatures))
  1363  		for i, commitSig := range commit.Signatures {
  1364  			// TODO: need to check the BlockID otherwise we could be counting conflicts,
  1365  			// not just the one with +2/3 !
  1366  			commit.bitArray.SetIndex(i, !commitSig.Absent())
  1367  		}
  1368  	}
  1369  	return commit.bitArray
  1370  }
  1371  
  1372  // GetByIndex returns the vote corresponding to a given validator index.
  1373  // Panics if `index >= commit.Size()`.
  1374  // Implements VoteSetReader.
  1375  func (commit *Commit) GetByIndex(valIdx int) *Vote {
  1376  	return commit.GetVote(valIdx)
  1377  }
  1378  
  1379  // IsCommit returns true if there is at least one signature.
  1380  // Implements VoteSetReader.
  1381  func (commit *Commit) IsCommit() bool {
  1382  	return len(commit.Signatures) != 0
  1383  }
  1384  
  1385  // ValidateBasic performs basic validation that doesn't involve state data.
  1386  // Does not actually check the cryptographic signatures.
  1387  func (commit *Commit) ValidateBasic() error {
  1388  	if commit.Height < 0 {
  1389  		return errors.New("negative Height")
  1390  	}
  1391  	if commit.Round < 0 {
  1392  		return errors.New("negative Round")
  1393  	}
  1394  	if commit.Height >= 1 {
  1395  		if commit.BlockID.IsZero() {
  1396  			return errors.New("commit cannot be for nil block")
  1397  		}
  1398  
  1399  		if len(commit.Signatures) == 0 {
  1400  			return errors.New("no signatures in commit")
  1401  		}
  1402  		for i, commitSig := range commit.Signatures {
  1403  			if err := commitSig.ValidateBasic(); err != nil {
  1404  				return fmt.Errorf("wrong CommitSig #%d: %v", i, err)
  1405  			}
  1406  		}
  1407  	}
  1408  
  1409  	return nil
  1410  }
  1411  
  1412  // Hash returns the hash of the commit
  1413  func (commit *Commit) Hash() tmbytes.HexBytes {
  1414  	if commit == nil {
  1415  		return nil
  1416  	}
  1417  	if commit.hash == nil {
  1418  		bs := make([][]byte, len(commit.Signatures))
  1419  		for i, commitSig := range commit.Signatures {
  1420  			bs[i] = cdcEncode(commitSig)
  1421  		}
  1422  		commit.hash = merkle.SimpleHashFromByteSlices(bs)
  1423  	}
  1424  	return commit.hash
  1425  }
  1426  
  1427  // StringIndented returns a string representation of the commit
  1428  func (commit *Commit) StringIndented(indent string) string {
  1429  	if commit == nil {
  1430  		return "nil-Commit"
  1431  	}
  1432  	commitSigStrings := make([]string, len(commit.Signatures))
  1433  	for i, commitSig := range commit.Signatures {
  1434  		commitSigStrings[i] = commitSig.String()
  1435  	}
  1436  	return fmt.Sprintf(`Commit{
  1437  %s  Height:     %d
  1438  %s  Round:      %d
  1439  %s  BlockID:    %v
  1440  %s  Signatures:
  1441  %s    %v
  1442  %s}#%v`,
  1443  		indent, commit.Height,
  1444  		indent, commit.Round,
  1445  		indent, commit.BlockID,
  1446  		indent,
  1447  		indent, strings.Join(commitSigStrings, "\n"+indent+"    "),
  1448  		indent, commit.hash)
  1449  }
  1450  
  1451  // ToProto converts Commit to protobuf
  1452  func (commit *Commit) ToProto() *tmproto.Commit {
  1453  	if commit == nil {
  1454  		return nil
  1455  	}
  1456  
  1457  	c := new(tmproto.Commit)
  1458  	sigs := make([]tmproto.CommitSig, len(commit.Signatures))
  1459  	for i := range commit.Signatures {
  1460  		sigs[i] = *commit.Signatures[i].ToProto()
  1461  	}
  1462  	c.Signatures = sigs
  1463  
  1464  	c.Height = commit.Height
  1465  	c.Round = int32(commit.Round)
  1466  	c.BlockID = commit.BlockID.ToProto()
  1467  	if commit.hash != nil {
  1468  		c.Hash = commit.hash
  1469  	}
  1470  	c.BitArray = commit.bitArray.ToProto()
  1471  	return c
  1472  }
  1473  
  1474  // FromProto sets a protobuf Commit to the given pointer.
  1475  // It returns an error if the commit is invalid.
  1476  func CommitFromProto(cp *tmproto.Commit) (*Commit, error) {
  1477  	if cp == nil {
  1478  		return nil, errors.New("nil Commit")
  1479  	}
  1480  
  1481  	var (
  1482  		commit   = new(Commit)
  1483  		bitArray *bits.BitArray
  1484  	)
  1485  
  1486  	bi, err := BlockIDFromProto(&cp.BlockID)
  1487  	if err != nil {
  1488  		return nil, err
  1489  	}
  1490  
  1491  	bitArray.FromProto(cp.BitArray)
  1492  
  1493  	sigs := make([]CommitSig, len(cp.Signatures))
  1494  	for i := range cp.Signatures {
  1495  		if err := sigs[i].FromProto(cp.Signatures[i]); err != nil {
  1496  			return nil, err
  1497  		}
  1498  	}
  1499  	commit.Signatures = sigs
  1500  
  1501  	commit.Height = cp.Height
  1502  	commit.Round = int(cp.Round)
  1503  	commit.BlockID = *bi
  1504  	commit.hash = cp.Hash
  1505  	commit.bitArray = bitArray
  1506  
  1507  	return commit, commit.ValidateBasic()
  1508  }
  1509  
  1510  //-----------------------------------------------------------------------------
  1511  
  1512  // SignedHeader is a header along with the commits that prove it.
  1513  // It is the basis of the lite client.
  1514  type SignedHeader struct {
  1515  	*Header `json:"header"`
  1516  
  1517  	Commit *Commit `json:"commit"`
  1518  }
  1519  
  1520  // ValidateBasic does basic consistency checks and makes sure the header
  1521  // and commit are consistent.
  1522  // NOTE: This does not actually check the cryptographic signatures.  Make
  1523  // sure to use a Verifier to validate the signatures actually provide a
  1524  // significantly strong proof for this header's validity.
  1525  func (sh SignedHeader) ValidateBasic(chainID string) error {
  1526  	return sh.commonValidateBasic(chainID, false)
  1527  }
  1528  
  1529  func (sh SignedHeader) commonValidateBasic(chainID string, isIbc bool) error {
  1530  	if sh.Header == nil {
  1531  		return errors.New("missing header")
  1532  	}
  1533  	if sh.Commit == nil {
  1534  		return errors.New("missing commit")
  1535  	}
  1536  
  1537  	if err := sh.Header.ValidateBasic(); err != nil {
  1538  		return fmt.Errorf("invalid header: %w", err)
  1539  	}
  1540  	if err := sh.Commit.ValidateBasic(); err != nil {
  1541  		return fmt.Errorf("invalid commit: %w", err)
  1542  	}
  1543  
  1544  	if sh.ChainID != chainID {
  1545  		return fmt.Errorf("header belongs to another chain %q, not %q", sh.ChainID, chainID)
  1546  	}
  1547  
  1548  	// Make sure the header is consistent with the commit.
  1549  	if sh.Commit.Height != sh.Height {
  1550  		return fmt.Errorf("header and commit height mismatch: %d vs %d", sh.Height, sh.Commit.Height)
  1551  	}
  1552  
  1553  	var hhash tmbytes.HexBytes
  1554  	if isIbc {
  1555  		hhash = sh.PureIBCHash()
  1556  	} else {
  1557  		hhash = sh.Hash()
  1558  	}
  1559  	if chash := sh.Commit.BlockID.Hash; !bytes.Equal(hhash, chash) {
  1560  		return fmt.Errorf("commit signs block %X, header is block %X", chash, hhash)
  1561  	}
  1562  	return nil
  1563  }
  1564  
  1565  func (sh SignedHeader) String() string {
  1566  	return sh.StringIndented("")
  1567  }
  1568  
  1569  // StringIndented returns a string representation of the SignedHeader.
  1570  func (sh SignedHeader) StringIndented(indent string) string {
  1571  	return fmt.Sprintf(`SignedHeader{
  1572  %s  %v
  1573  %s  %v
  1574  %s}`,
  1575  		indent, sh.Header.StringIndented(indent+"  "),
  1576  		indent, sh.Commit.StringIndented(indent+"  "),
  1577  		indent)
  1578  }
  1579  
  1580  // ToProto converts SignedHeader to protobuf
  1581  func (sh *SignedHeader) ToProto() *tmproto.SignedHeader {
  1582  	if sh == nil {
  1583  		return nil
  1584  	}
  1585  
  1586  	psh := new(tmproto.SignedHeader)
  1587  	if sh.Header != nil {
  1588  		psh.Header = sh.Header.ToProto()
  1589  	}
  1590  	if sh.Commit != nil {
  1591  		psh.Commit = sh.Commit.ToProto()
  1592  	}
  1593  
  1594  	return psh
  1595  }
  1596  
  1597  // FromProto sets a protobuf SignedHeader to the given pointer.
  1598  // It returns an error if the hader or the commit is invalid.
  1599  func SignedHeaderFromProto(shp *tmproto.SignedHeader) (*SignedHeader, error) {
  1600  	if shp == nil {
  1601  		return nil, errors.New("nil SignedHeader")
  1602  	}
  1603  
  1604  	sh := new(SignedHeader)
  1605  
  1606  	if shp.Header != nil {
  1607  		h, err := HeaderFromProto(shp.Header)
  1608  		if err != nil {
  1609  			return nil, err
  1610  		}
  1611  		sh.Header = &h
  1612  	}
  1613  
  1614  	if shp.Commit != nil {
  1615  		c, err := CommitFromProto(shp.Commit)
  1616  		if err != nil {
  1617  			return nil, err
  1618  		}
  1619  		sh.Commit = c
  1620  	}
  1621  
  1622  	return sh, nil
  1623  }
  1624  
  1625  //-----------------------------------------------------------------------------
  1626  
  1627  // Data contains the set of transactions included in the block
  1628  type Data struct {
  1629  
  1630  	// Txs that will be applied by state @ block.Height+1.
  1631  	// NOTE: not all txs here are valid.  We're just agreeing on the order first.
  1632  	// This means that block.AppHash does not include these txs.
  1633  	Txs Txs `json:"txs"`
  1634  
  1635  	// Volatile
  1636  	hash tmbytes.HexBytes
  1637  }
  1638  
  1639  func (d Data) AminoSize(_ *amino.Codec) int {
  1640  	var size = 0
  1641  
  1642  	for _, tx := range d.Txs {
  1643  		size += 1 + amino.ByteSliceSize(tx)
  1644  	}
  1645  
  1646  	return size
  1647  }
  1648  
  1649  func (d *Data) UnmarshalFromAmino(_ *amino.Codec, data []byte) error {
  1650  	var dataLen uint64 = 0
  1651  	var subData []byte
  1652  
  1653  	for {
  1654  		data = data[dataLen:]
  1655  		if len(data) == 0 {
  1656  			break
  1657  		}
  1658  
  1659  		pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
  1660  		if err != nil {
  1661  			return err
  1662  		}
  1663  		data = data[1:]
  1664  
  1665  		if pbType == amino.Typ3_ByteLength {
  1666  			var n int
  1667  			dataLen, n, err = amino.DecodeUvarint(data)
  1668  			if err != nil {
  1669  				return err
  1670  			}
  1671  			data = data[n:]
  1672  			if len(data) < int(dataLen) {
  1673  				return fmt.Errorf("invalid data len")
  1674  			}
  1675  			subData = data[:dataLen]
  1676  		}
  1677  
  1678  		switch pos {
  1679  		case 1:
  1680  			var tx []byte
  1681  			if dataLen > 0 {
  1682  				tx = make([]byte, len(subData))
  1683  				copy(tx, subData)
  1684  			}
  1685  			d.Txs = append(d.Txs, tx)
  1686  		default:
  1687  			return fmt.Errorf("unexpect feild num %d", pos)
  1688  		}
  1689  	}
  1690  	return nil
  1691  }
  1692  
  1693  // Hash returns the hash of the data
  1694  func (data *Data) Hash(height int64) tmbytes.HexBytes {
  1695  	if data == nil {
  1696  		return (Txs{}).Hash(height)
  1697  	}
  1698  	if data.hash == nil {
  1699  		data.hash = data.Txs.Hash(height) // NOTE: leaves of merkle tree are TxIDs
  1700  	}
  1701  	return data.hash
  1702  }
  1703  
  1704  // StringIndented returns a string representation of the transactions
  1705  func (data *Data) StringIndented(indent string, height int64) string {
  1706  	if data == nil {
  1707  		return "nil-Data"
  1708  	}
  1709  	txStrings := make([]string, tmmath.MinInt(len(data.Txs), 21))
  1710  	for i, tx := range data.Txs {
  1711  		if i == 20 {
  1712  			txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs))
  1713  			break
  1714  		}
  1715  		txStrings[i] = fmt.Sprintf("%X (%d bytes)", tx.Hash(height), len(tx))
  1716  	}
  1717  	return fmt.Sprintf(`Data{
  1718  %s  %v
  1719  %s}#%v`,
  1720  		indent, strings.Join(txStrings, "\n"+indent+"  "),
  1721  		indent, data.hash)
  1722  }
  1723  
  1724  //-----------------------------------------------------------------------------
  1725  
  1726  // EvidenceData contains any evidence of malicious wrong-doing by validators
  1727  type EvidenceData struct {
  1728  	Evidence EvidenceList `json:"evidence"`
  1729  
  1730  	// Volatile
  1731  	hash tmbytes.HexBytes
  1732  }
  1733  
  1734  func (d EvidenceData) AminoSize(cdc *amino.Codec) int {
  1735  	var size = 0
  1736  
  1737  	for _, ev := range d.Evidence {
  1738  		if ev != nil {
  1739  			var evSize int
  1740  			if sizer, ok := ev.(amino.Sizer); ok {
  1741  				evSize = 4 + sizer.AminoSize(cdc)
  1742  			} else {
  1743  				evSize = len(cdc.MustMarshalBinaryBare(ev))
  1744  			}
  1745  			size += 1 + amino.UvarintSize(uint64(evSize)) + evSize
  1746  		} else {
  1747  			size += 1 + amino.UvarintSize(0)
  1748  		}
  1749  	}
  1750  
  1751  	return size
  1752  }
  1753  
  1754  func (d *EvidenceData) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
  1755  	var dataLen uint64 = 0
  1756  	var subData []byte
  1757  
  1758  	for {
  1759  		data = data[dataLen:]
  1760  		if len(data) == 0 {
  1761  			break
  1762  		}
  1763  
  1764  		pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
  1765  		if err != nil {
  1766  			return err
  1767  		}
  1768  		data = data[1:]
  1769  
  1770  		if pbType == amino.Typ3_ByteLength {
  1771  			var n int
  1772  			dataLen, n, err = amino.DecodeUvarint(data)
  1773  			if err != nil {
  1774  				return err
  1775  			}
  1776  			data = data[n:]
  1777  			if len(data) < int(dataLen) {
  1778  				return fmt.Errorf("invalid data len")
  1779  			}
  1780  			subData = data[:dataLen]
  1781  		} else {
  1782  			return fmt.Errorf("unexpect pb type %d", pbType)
  1783  		}
  1784  
  1785  		switch pos {
  1786  		case 1:
  1787  			var evi Evidence
  1788  			if dataLen == 0 {
  1789  				d.Evidence = append(d.Evidence, nil)
  1790  			} else {
  1791  				eviTmp, err := cdc.UnmarshalBinaryBareWithRegisteredUnmarshaller(subData, &evi)
  1792  				if err != nil {
  1793  					err = cdc.UnmarshalBinaryBare(subData, &evi)
  1794  					if err != nil {
  1795  						return err
  1796  					} else {
  1797  						d.Evidence = append(d.Evidence, evi)
  1798  					}
  1799  				} else {
  1800  					d.Evidence = append(d.Evidence, eviTmp.(Evidence))
  1801  				}
  1802  			}
  1803  		default:
  1804  			return fmt.Errorf("unexpect feild num %d", pos)
  1805  		}
  1806  	}
  1807  	return nil
  1808  }
  1809  
  1810  // Hash returns the hash of the data.
  1811  func (data *EvidenceData) Hash() tmbytes.HexBytes {
  1812  	if data.hash == nil {
  1813  		data.hash = data.Evidence.Hash()
  1814  	}
  1815  	return data.hash
  1816  }
  1817  
  1818  // StringIndented returns a string representation of the evidence.
  1819  func (data *EvidenceData) StringIndented(indent string) string {
  1820  	if data == nil {
  1821  		return "nil-Evidence"
  1822  	}
  1823  	evStrings := make([]string, tmmath.MinInt(len(data.Evidence), 21))
  1824  	for i, ev := range data.Evidence {
  1825  		if i == 20 {
  1826  			evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidence))
  1827  			break
  1828  		}
  1829  		evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
  1830  	}
  1831  	return fmt.Sprintf(`EvidenceData{
  1832  %s  %v
  1833  %s}#%v`,
  1834  		indent, strings.Join(evStrings, "\n"+indent+"  "),
  1835  		indent, data.hash)
  1836  }
  1837  
  1838  //--------------------------------------------------------------------------------
  1839  
  1840  // BlockID defines the unique ID of a block as its Hash and its PartSetHeader
  1841  type BlockID struct {
  1842  	Hash        tmbytes.HexBytes `json:"hash"`
  1843  	PartsHeader PartSetHeader    `json:"parts"`
  1844  }
  1845  
  1846  func (blockID BlockID) AminoSize(_ *amino.Codec) int {
  1847  	var size int
  1848  	if len(blockID.Hash) > 0 {
  1849  		size += 1 + amino.UvarintSize(uint64(len(blockID.Hash))) + len(blockID.Hash)
  1850  	}
  1851  	headerSize := blockID.PartsHeader.AminoSize()
  1852  	if headerSize > 0 {
  1853  		size += 1 + amino.UvarintSize(uint64(headerSize)) + headerSize
  1854  	}
  1855  	return size
  1856  }
  1857  
  1858  func (blockID *BlockID) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
  1859  	var dataLen uint64 = 0
  1860  	var subData []byte
  1861  
  1862  	for {
  1863  		data = data[dataLen:]
  1864  
  1865  		if len(data) == 0 {
  1866  			break
  1867  		}
  1868  
  1869  		pos, aminoType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
  1870  		if err != nil {
  1871  			return err
  1872  		}
  1873  		data = data[1:]
  1874  
  1875  		if aminoType == amino.Typ3_ByteLength {
  1876  			var n int
  1877  			dataLen, n, err = amino.DecodeUvarint(data)
  1878  			if err != nil {
  1879  				return err
  1880  			}
  1881  
  1882  			data = data[n:]
  1883  			if len(data) < int(dataLen) {
  1884  				return fmt.Errorf("invalid data len")
  1885  			}
  1886  			subData = data[:dataLen]
  1887  		}
  1888  
  1889  		switch pos {
  1890  		case 1:
  1891  			blockID.Hash = make([]byte, len(subData))
  1892  			copy(blockID.Hash, subData)
  1893  		case 2:
  1894  			err = blockID.PartsHeader.UnmarshalFromAmino(cdc, subData)
  1895  			if err != nil {
  1896  				return err
  1897  			}
  1898  		default:
  1899  			return fmt.Errorf("unexpect feild num %d", pos)
  1900  		}
  1901  	}
  1902  	return nil
  1903  }
  1904  
  1905  // Equals returns true if the BlockID matches the given BlockID
  1906  func (blockID BlockID) Equals(other BlockID) bool {
  1907  	return bytes.Equal(blockID.Hash, other.Hash) &&
  1908  		blockID.PartsHeader.Equals(other.PartsHeader)
  1909  }
  1910  
  1911  // Key returns a machine-readable string representation of the BlockID
  1912  func (blockID BlockID) Key() string {
  1913  	bz, err := cdc.MarshalBinaryBare(blockID.PartsHeader)
  1914  	if err != nil {
  1915  		panic(err)
  1916  	}
  1917  	return string(blockID.Hash) + string(bz)
  1918  }
  1919  
  1920  // ValidateBasic performs basic validation.
  1921  func (blockID BlockID) ValidateBasic() error {
  1922  	// Hash can be empty in case of POLBlockID in Proposal.
  1923  	if err := ValidateHash(blockID.Hash); err != nil {
  1924  		return fmt.Errorf("wrong Hash")
  1925  	}
  1926  	if err := blockID.PartsHeader.ValidateBasic(); err != nil {
  1927  		return fmt.Errorf("wrong PartsHeader: %v", err)
  1928  	}
  1929  	return nil
  1930  }
  1931  
  1932  // IsZero returns true if this is the BlockID of a nil block.
  1933  func (blockID BlockID) IsZero() bool {
  1934  	return len(blockID.Hash) == 0 &&
  1935  		blockID.PartsHeader.IsZero()
  1936  }
  1937  
  1938  // IsComplete returns true if this is a valid BlockID of a non-nil block.
  1939  func (blockID BlockID) IsComplete() bool {
  1940  	return len(blockID.Hash) == tmhash.Size &&
  1941  		blockID.PartsHeader.Total > 0 &&
  1942  		len(blockID.PartsHeader.Hash) == tmhash.Size
  1943  }
  1944  
  1945  // String returns a human readable string representation of the BlockID
  1946  func (blockID BlockID) String() string {
  1947  	return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartsHeader)
  1948  }
  1949  
  1950  // ToProto converts BlockID to protobuf
  1951  func (blockID *BlockID) ToProto() tmproto.BlockID {
  1952  	if blockID == nil {
  1953  		return tmproto.BlockID{}
  1954  	}
  1955  
  1956  	return tmproto.BlockID{
  1957  		Hash:        blockID.Hash,
  1958  		PartsHeader: blockID.PartsHeader.ToProto(),
  1959  	}
  1960  }
  1961  
  1962  func (blockID *BlockID) ToIBCProto() tmproto.BlockID {
  1963  	if blockID == nil {
  1964  		return tmproto.BlockID{}
  1965  	}
  1966  	return tmproto.BlockID{
  1967  		Hash:        blockID.Hash,
  1968  		PartsHeader: blockID.PartsHeader.ToIBCProto(),
  1969  	}
  1970  }
  1971  
  1972  // FromProto sets a protobuf BlockID to the given pointer.
  1973  // It returns an error if the block id is invalid.
  1974  func BlockIDFromProto(bID *tmproto.BlockID) (*BlockID, error) {
  1975  	if bID == nil {
  1976  		return nil, errors.New("nil BlockID")
  1977  	}
  1978  	blockID := new(BlockID)
  1979  	ph, err := PartSetHeaderFromProto(&bID.PartsHeader)
  1980  	if err != nil {
  1981  		return nil, err
  1982  	}
  1983  
  1984  	blockID.PartsHeader = *ph
  1985  	blockID.Hash = bID.Hash
  1986  
  1987  	return blockID, blockID.ValidateBasic()
  1988  }