github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/dbft/types.go (about)

     1  package dbft
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"math/big"
     7  
     8  	"github.com/quickchainproject/quickchain/common"
     9  	"github.com/quickchainproject/quickchain/core/types"
    10  	"github.com/quickchainproject/quickchain/rlp"
    11  )
    12  
    13  // Proposal supports retrieving height and serialized block to be used during BFT consensus.
    14  type Proposal interface {
    15  	// Number retrieves the sequence number of this proposal.
    16  	Number() *big.Int
    17  
    18  	// Hash retrieves the hash of this proposal.
    19  	Hash() common.Hash
    20  
    21  	EncodeRLP(w io.Writer) error
    22  
    23  	DecodeRLP(s *rlp.Stream) error
    24  
    25  	String() string
    26  }
    27  
    28  type Request struct {
    29  	Proposal Proposal
    30  }
    31  
    32  // View includes a round number and a sequence number.
    33  // Sequence is the block number we'd like to commit.
    34  // Each round has a number and is composed by 3 steps: preprepare, prepare and commit.
    35  //
    36  // If the given block is not accepted by validators, a round change will occur
    37  // and the validators start a new round with round+1.
    38  type View struct {
    39  	Round    *big.Int
    40  	Sequence *big.Int
    41  }
    42  
    43  // EncodeRLP serializes b into the Ethereum RLP format.
    44  func (v *View) EncodeRLP(w io.Writer) error {
    45  	return rlp.Encode(w, []interface{}{v.Round, v.Sequence})
    46  }
    47  
    48  // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.
    49  func (v *View) DecodeRLP(s *rlp.Stream) error {
    50  	var view struct {
    51  		Round    *big.Int
    52  		Sequence *big.Int
    53  	}
    54  
    55  	if err := s.Decode(&view); err != nil {
    56  		return err
    57  	}
    58  	v.Round, v.Sequence = view.Round, view.Sequence
    59  	return nil
    60  }
    61  
    62  func (v *View) String() string {
    63  	return fmt.Sprintf("{Round: %d, Sequence: %d}", v.Round.Uint64(), v.Sequence.Uint64())
    64  }
    65  
    66  // Cmp compares v and y and returns:
    67  //   -1 if v <  y
    68  //    0 if v == y
    69  //   +1 if v >  y
    70  func (v *View) Cmp(y *View) int {
    71  	if v.Sequence.Cmp(y.Sequence) != 0 {
    72  		return v.Sequence.Cmp(y.Sequence)
    73  	}
    74  	if v.Round.Cmp(y.Round) != 0 {
    75  		return v.Round.Cmp(y.Round)
    76  	}
    77  	return 0
    78  }
    79  
    80  type Preprepare struct {
    81  	View     *View
    82  	Proposal Proposal
    83  }
    84  
    85  // EncodeRLP serializes b into the Ethereum RLP format.
    86  func (b *Preprepare) EncodeRLP(w io.Writer) error {
    87  	return rlp.Encode(w, []interface{}{b.View, b.Proposal})
    88  }
    89  
    90  // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.
    91  func (b *Preprepare) DecodeRLP(s *rlp.Stream) error {
    92  	var preprepare struct {
    93  		View     *View
    94  		Proposal *types.Block
    95  	}
    96  
    97  	if err := s.Decode(&preprepare); err != nil {
    98  		return err
    99  	}
   100  	b.View, b.Proposal = preprepare.View, preprepare.Proposal
   101  
   102  	return nil
   103  }
   104  
   105  type Subject struct {
   106  	View   *View
   107  	Digest common.Hash
   108  }
   109  
   110  // EncodeRLP serializes b into the Ethereum RLP format.
   111  func (b *Subject) EncodeRLP(w io.Writer) error {
   112  	return rlp.Encode(w, []interface{}{b.View, b.Digest})
   113  }
   114  
   115  // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream.
   116  func (b *Subject) DecodeRLP(s *rlp.Stream) error {
   117  	var subject struct {
   118  		View   *View
   119  		Digest common.Hash
   120  	}
   121  
   122  	if err := s.Decode(&subject); err != nil {
   123  		return err
   124  	}
   125  	b.View, b.Digest = subject.View, subject.Digest
   126  	return nil
   127  }
   128  
   129  func (b *Subject) String() string {
   130  	return fmt.Sprintf("{View: %v, Digest: %v}", b.View, b.Digest.String())
   131  }