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

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/tendermint/go-amino"
     7  
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // BlockMeta contains meta information.
    12  type BlockMeta struct {
    13  	BlockID   BlockID `json:"block_id"`
    14  	BlockSize int     `json:"block_size"`
    15  	Header    Header  `json:"header"`
    16  	NumTxs    int     `json:"num_txs"`
    17  }
    18  
    19  // NewBlockMeta returns a new BlockMeta.
    20  func NewBlockMeta(block *Block, blockParts *PartSet) *BlockMeta {
    21  	return &BlockMeta{
    22  		BlockID:   BlockID{block.Hash(), blockParts.Header()},
    23  		BlockSize: block.Size(),
    24  		Header:    block.Header,
    25  		NumTxs:    len(block.Data.Txs),
    26  	}
    27  }
    28  
    29  func (bm *BlockMeta) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error {
    30  	const fieldCount = 4
    31  	var currentField int
    32  	var currentType amino.Typ3
    33  	var err error
    34  
    35  	for cur := 1; cur <= fieldCount; cur++ {
    36  		if len(data) != 0 && (currentField == 0 || currentField < cur) {
    37  			var nextField int
    38  			if nextField, currentType, err = amino.ParseProtoPosAndTypeMustOneByte(data[0]); err != nil {
    39  				return err
    40  			}
    41  			if nextField < currentField {
    42  				return errors.Errorf("next field should greater than %d, got %d", currentField, nextField)
    43  			} else {
    44  				currentField = nextField
    45  			}
    46  		}
    47  
    48  		if len(data) == 0 || currentField != cur {
    49  			switch cur {
    50  			case 1:
    51  				bm.BlockID = BlockID{}
    52  			case 2:
    53  				bm.BlockSize = 0
    54  			case 3:
    55  				bm.Header = Header{}
    56  			case 4:
    57  				bm.NumTxs = 0
    58  			default:
    59  				return fmt.Errorf("unexpect feild num %d", cur)
    60  			}
    61  		} else {
    62  			pbk := data[0]
    63  			data = data[1:]
    64  			var subData []byte
    65  			if currentType == amino.Typ3_ByteLength {
    66  				if subData, err = amino.DecodeByteSliceWithoutCopy(&data); err != nil {
    67  					return err
    68  				}
    69  			}
    70  			switch pbk {
    71  			case 1<<3 | byte(amino.Typ3_ByteLength):
    72  				if err = bm.BlockID.UnmarshalFromAmino(cdc, subData); err != nil {
    73  					return err
    74  				}
    75  			case 2<<3 | byte(amino.Typ3_Varint):
    76  				if bm.BlockSize, err = amino.DecodeIntUpdateBytes(&data); err != nil {
    77  					return err
    78  				}
    79  			case 3<<3 | byte(amino.Typ3_ByteLength):
    80  				if err = bm.Header.UnmarshalFromAmino(cdc, subData); err != nil {
    81  					return err
    82  				}
    83  			case 4<<3 | byte(amino.Typ3_Varint):
    84  				if bm.NumTxs, err = amino.DecodeIntUpdateBytes(&data); err != nil {
    85  					return err
    86  				}
    87  			default:
    88  				return fmt.Errorf("unexpect pb key %d", pbk)
    89  			}
    90  		}
    91  	}
    92  
    93  	if len(data) != 0 {
    94  		return errors.Errorf("unexpect data remain %X", data)
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  //-----------------------------------------------------------
   101  // These methods are for Protobuf Compatibility
   102  
   103  // Size returns the size of the amino encoding, in bytes.
   104  func (bm *BlockMeta) Size() int {
   105  	bs, _ := bm.Marshal()
   106  	return len(bs)
   107  }
   108  
   109  // Marshal returns the amino encoding.
   110  func (bm *BlockMeta) Marshal() ([]byte, error) {
   111  	return cdc.MarshalBinaryBare(bm)
   112  }
   113  
   114  // MarshalTo calls Marshal and copies to the given buffer.
   115  func (bm *BlockMeta) MarshalTo(data []byte) (int, error) {
   116  	bs, err := bm.Marshal()
   117  	if err != nil {
   118  		return -1, err
   119  	}
   120  	return copy(data, bs), nil
   121  }
   122  
   123  // Unmarshal deserializes from amino encoded form.
   124  func (bm *BlockMeta) Unmarshal(bs []byte) error {
   125  	return cdc.UnmarshalBinaryBare(bs, bm)
   126  }
   127  
   128  // ValidateBasic performs basic validation.
   129  func (bm *BlockMeta) ValidateBasic() error {
   130  	if err := bm.BlockID.ValidateBasic(); err != nil {
   131  		return err
   132  	}
   133  	if !bytes.Equal(bm.BlockID.Hash, bm.Header.Hash()) {
   134  		return errors.Errorf("expected BlockID#Hash and Header#Hash to be the same, got %X != %X",
   135  			bm.BlockID.Hash, bm.Header.Hash())
   136  	}
   137  	return nil
   138  }