github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/consensus/ipbft/types/tendermint.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/intfoundation/intchain/common/hexutil"
     6  	ethTypes "github.com/intfoundation/intchain/core/types"
     7  	"github.com/intfoundation/go-merkle"
     8  	"github.com/intfoundation/go-wire"
     9  	"time"
    10  )
    11  
    12  type TendermintExtra struct {
    13  	ChainID         string    `json:"chain_id"`
    14  	Height          uint64    `json:"height"`
    15  	Time            time.Time `json:"time"`
    16  	NeedToSave      bool      `json:"need_to_save"`
    17  	NeedToBroadcast bool      `json:"need_to_broadcast"`
    18  	EpochNumber     uint64    `json:"epoch_number"`
    19  	SeenCommitHash  []byte    `json:"last_commit_hash"` // commit from validators from the last block
    20  	ValidatorsHash  []byte    `json:"validators_hash"`  // validators for the current block
    21  	SeenCommit      *Commit   `json:"seen_commit"`
    22  	EpochBytes      []byte    `json:"epoch_bytes"`
    23  }
    24  
    25  /*
    26  // EncodeRLP serializes ist into the Ethereum RLP format.
    27  func (te *TendermintExtra) EncodeRLP(w io.Writer) error {
    28  	return rlp.Encode(w, []interface{}{
    29  		te.ChainID, te.Height, te.Time, te.LastBlockID,
    30  		te.SeenCommitHash, te.ValidatorsHash,
    31  		te.SeenCommit,
    32  	})
    33  }
    34  
    35  // DecodeRLP implements rlp.Decoder, and load the istanbul fields from a RLP stream.
    36  func (te *TendermintExtra) DecodeRLP(s *rlp.Stream) error {
    37  	var tdmExtra TendermintExtra
    38  	if err := s.Decode(&tdmExtra); err != nil {
    39  		return err
    40  	}
    41  	te.ChainID, te.Height, te.Time, te.LastBlockID,
    42  		te.SeenCommitHash, te.ValidatorsHash,
    43  		te.SeenCommit = tdmExtra.ChainID, tdmExtra.Height, tdmExtra.Time, tdmExtra.LastBlockID,
    44  		tdmExtra.SeenCommitHash, tdmExtra.ValidatorsHash,
    45  		tdmExtra.SeenCommit
    46  	return nil
    47  }
    48  */
    49  
    50  //be careful, here not deep copy because just reference to SeenCommit
    51  func (te *TendermintExtra) Copy() *TendermintExtra {
    52  	//fmt.Printf("State.Copy(), s.LastValidators are %v\n",s.LastValidators)
    53  	//debug.PrintStack()
    54  
    55  	return &TendermintExtra{
    56  		ChainID:         te.ChainID,
    57  		Height:          te.Height,
    58  		Time:            te.Time,
    59  		NeedToSave:      te.NeedToSave,
    60  		NeedToBroadcast: te.NeedToBroadcast,
    61  		EpochNumber:     te.EpochNumber,
    62  		SeenCommitHash:  te.SeenCommitHash,
    63  		ValidatorsHash:  te.ValidatorsHash,
    64  		SeenCommit:      te.SeenCommit,
    65  		EpochBytes:      te.EpochBytes,
    66  	}
    67  }
    68  
    69  // NOTE: hash is nil if required fields are missing.
    70  func (te *TendermintExtra) Hash() []byte {
    71  	if len(te.ValidatorsHash) == 0 {
    72  		return nil
    73  	}
    74  	return merkle.SimpleHashFromMap(map[string]interface{}{
    75  		"ChainID":         te.ChainID,
    76  		"Height":          te.Height,
    77  		"Time":            te.Time,
    78  		"NeedToSave":      te.NeedToSave,
    79  		"NeedToBroadcast": te.NeedToBroadcast,
    80  		"EpochNumber":     te.EpochNumber,
    81  		"Validators":      te.ValidatorsHash,
    82  		"EpochBytes":      te.EpochBytes,
    83  	})
    84  }
    85  
    86  // ExtractTendermintExtra extracts all values of the TendermintExtra from the header. It returns an
    87  // error if the length of the given extra-data is less than 32 bytes or the extra-data can not
    88  // be decoded.
    89  func ExtractTendermintExtra(h *ethTypes.Header) (*TendermintExtra, error) {
    90  
    91  	if len(h.Extra) == 0 {
    92  		return &TendermintExtra{}, nil
    93  	}
    94  
    95  	var tdmExtra = TendermintExtra{}
    96  	err := wire.ReadBinaryBytes(h.Extra[:], &tdmExtra)
    97  	//err := rlp.DecodeBytes(h.Extra[:], &tdmExtra)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	return &tdmExtra, nil
   102  }
   103  
   104  func (te *TendermintExtra) String() string {
   105  	str := fmt.Sprintf(`TendermintExtra: {
   106  ChainID:     %s
   107  EpochNumber: %v
   108  Height:      %v
   109  Time:        %v
   110  
   111  EpochBytes: length %v
   112  }
   113  `, te.ChainID, te.EpochNumber, te.Height, te.Time, len(te.EpochBytes))
   114  	return str
   115  }
   116  
   117  func DecodeExtraData(extra string) (tdmExtra *TendermintExtra, err error) {
   118  	tdmExtra = &TendermintExtra{}
   119  	extraByte, err := hexutil.Decode(extra)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	err = wire.ReadBinaryBytes(extraByte, tdmExtra)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	return tdmExtra, nil
   129  }