github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/consensus/istanbul/qbft/types/roundchange.go (about)

     1  package qbfttypes
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"math/big"
     8  
     9  	"github.com/kisexp/xdchain/common"
    10  	"github.com/kisexp/xdchain/consensus/istanbul"
    11  	istanbulcommon "github.com/kisexp/xdchain/consensus/istanbul/common"
    12  	"github.com/kisexp/xdchain/core/types"
    13  	"github.com/kisexp/xdchain/log"
    14  	"github.com/kisexp/xdchain/rlp"
    15  )
    16  
    17  // ROUND-CHANGE
    18  type RoundChange struct {
    19  	SignedRoundChangePayload
    20  	PreparedBlock *types.Block
    21  	Justification []*Prepare
    22  }
    23  
    24  func NewRoundChange(sequence *big.Int, round *big.Int, preparedRound *big.Int, preparedBlock istanbul.Proposal) *RoundChange {
    25  	roundChange := &RoundChange{
    26  		SignedRoundChangePayload: SignedRoundChangePayload{
    27  			CommonPayload: CommonPayload{
    28  				code:     RoundChangeCode,
    29  				Sequence: sequence,
    30  				Round:    round,
    31  			},
    32  			PreparedRound:  preparedRound,
    33  			PreparedDigest: common.Hash{},
    34  		},
    35  	}
    36  
    37  	if preparedBlock != nil {
    38  		roundChange.PreparedBlock = preparedBlock.(*types.Block)
    39  		roundChange.PreparedDigest = preparedBlock.Hash()
    40  	}
    41  
    42  	return roundChange
    43  }
    44  
    45  type SignedRoundChangePayload struct {
    46  	CommonPayload
    47  	PreparedRound  *big.Int
    48  	PreparedDigest common.Hash
    49  }
    50  
    51  func (p *SignedRoundChangePayload) String() string {
    52  	return fmt.Sprintf("RoundChange {seq=%v, round=%v, pr=%v, pv=%v}",
    53  		p.Sequence, p.Round, p.PreparedRound, p.PreparedDigest.Hex())
    54  }
    55  
    56  func (p *SignedRoundChangePayload) EncodeRLP(w io.Writer) error {
    57  	var encodedPayload rlp.RawValue
    58  	encodedPayload, err := p.encodePayloadInternal()
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	return rlp.Encode(
    64  		w,
    65  		[]interface{}{encodedPayload, p.signature})
    66  
    67  }
    68  
    69  func (p *SignedRoundChangePayload) DecodeRLP(stream *rlp.Stream) error {
    70  	// Signed Payload
    71  	if _, err := stream.List(); err != nil {
    72  		log.Error("QBFT: Error List() Signed Payload", "err", err)
    73  		return err
    74  	}
    75  
    76  	// Payload
    77  	encodedPayload, err := stream.Raw()
    78  	if err != nil {
    79  		log.Error("QBFT: Error Raw()", "err", err)
    80  		return err
    81  	}
    82  
    83  	payloadStream := rlp.NewStream(bytes.NewReader(encodedPayload), 0)
    84  
    85  	if _, err = payloadStream.List(); err != nil {
    86  		log.Error("QBFT: Error List() Payload", "err", err)
    87  		return err
    88  	}
    89  
    90  	if err = payloadStream.Decode(&p.Sequence); err != nil {
    91  		log.Error("QBFT: Error Decode(&m.Sequence)", "err", err)
    92  		return err
    93  	}
    94  	if err = payloadStream.Decode(&p.Round); err != nil {
    95  		log.Error("QBFT: Error Decode(&m.Round)", "err", err)
    96  		return err
    97  	}
    98  
    99  	// Prepared
   100  	var size uint64
   101  	if size, err = payloadStream.List(); err != nil {
   102  		log.Error("QBFT: Error List() Prepared", "err", err)
   103  		return err
   104  	}
   105  	if size > 0 {
   106  		if err = payloadStream.Decode(&p.PreparedRound); err != nil {
   107  			log.Error("QBFT: Error Decode(&m.PreparedRound)", "err", err)
   108  			return err
   109  		}
   110  		if err = payloadStream.Decode(&p.PreparedDigest); err != nil {
   111  			log.Error("QBFT: Error Decode(&p.PreparedDigest)", "err", err)
   112  			return err
   113  		}
   114  	}
   115  	// End Prepared
   116  	if err = payloadStream.ListEnd(); err != nil {
   117  		return err
   118  	}
   119  
   120  	// End Payload
   121  	if err = payloadStream.ListEnd(); err != nil {
   122  		return err
   123  	}
   124  
   125  	if err = stream.Decode(&p.signature); err != nil {
   126  		return err
   127  	}
   128  	// End SignedPayload
   129  	if err = stream.ListEnd(); err != nil {
   130  		return err
   131  	}
   132  
   133  	p.code = RoundChangeCode
   134  
   135  	log.Info("QBFT: Correctly decoded SignedRoundChangePayload", "p", p)
   136  
   137  	return nil
   138  }
   139  
   140  func (p *SignedRoundChangePayload) encodePayloadInternal() ([]byte, error) {
   141  	var prepared = []interface{}{}
   142  	if p.PreparedRound != nil && !common.EmptyHash(p.PreparedDigest) {
   143  		prepared = []interface{}{p.PreparedRound, p.PreparedDigest}
   144  	}
   145  	return rlp.EncodeToBytes(
   146  		[]interface{}{
   147  			p.Sequence,
   148  			p.Round,
   149  			prepared})
   150  }
   151  
   152  func (p *SignedRoundChangePayload) EncodePayloadForSigning() ([]byte, error) {
   153  	var encodedPayload rlp.RawValue
   154  	encodedPayload, err := p.encodePayloadInternal()
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  
   159  	return rlp.EncodeToBytes(
   160  		[]interface{}{
   161  			p.Code(),
   162  			encodedPayload,
   163  		})
   164  }
   165  
   166  func (m *RoundChange) EncodeRLP(w io.Writer) error {
   167  	var encodedPayload rlp.RawValue
   168  	encodedPayload, err := m.encodePayloadInternal()
   169  	if err != nil {
   170  		return err
   171  	}
   172  
   173  	return rlp.Encode(
   174  		w,
   175  		[]interface{}{
   176  			[]interface{}{
   177  				encodedPayload,
   178  				m.signature,
   179  			},
   180  			m.PreparedBlock, m.Justification,
   181  		})
   182  }
   183  
   184  func (m *RoundChange) DecodeRLP(stream *rlp.Stream) error {
   185  	var err error
   186  
   187  	// RoundChange Message
   188  	if _, err = stream.List(); err != nil {
   189  		return err
   190  	}
   191  
   192  	// Signed Payload
   193  	if _, err = stream.List(); err != nil {
   194  		log.Error("QBFT: Error List() Signed Payload", "err", err)
   195  		return err
   196  	}
   197  
   198  	// Payload
   199  	encodedPayload, err := stream.Raw()
   200  	if err != nil {
   201  		log.Error("QBFT: Error Raw()", "err", err)
   202  		return err
   203  	}
   204  
   205  	payloadStream := rlp.NewStream(bytes.NewReader(encodedPayload), 0)
   206  
   207  	if _, err = payloadStream.List(); err != nil {
   208  		log.Error("QBFT: Error List() Payload", "err", err)
   209  		return err
   210  	}
   211  
   212  	if err = payloadStream.Decode(&m.Sequence); err != nil {
   213  		log.Error("QBFT: Error Decode(&m.Sequence)", "err", err)
   214  		return err
   215  	}
   216  	if err = payloadStream.Decode(&m.Round); err != nil {
   217  		log.Error("QBFT: Error Decode(&m.Round)", "err", err)
   218  		return err
   219  	}
   220  
   221  	// Prepared
   222  	var size uint64
   223  	if size, err = payloadStream.List(); err != nil {
   224  		log.Error("QBFT: Error List() Prepared", "err", err)
   225  		return err
   226  	}
   227  	if size > 0 {
   228  		if err = payloadStream.Decode(&m.PreparedRound); err != nil {
   229  			log.Error("QBFT: Error Decode(&m.PreparedRound)", "err", err)
   230  			return err
   231  		}
   232  		if err = payloadStream.Decode(&m.PreparedDigest); err != nil {
   233  			log.Error("QBFT: Error Decode(&m.PreparedDigest)", "err", err)
   234  			return err
   235  		}
   236  	}
   237  	// End Prepared
   238  	if err = payloadStream.ListEnd(); err != nil {
   239  		return err
   240  	}
   241  
   242  	// End Payload
   243  	if err = payloadStream.ListEnd(); err != nil {
   244  		return err
   245  	}
   246  
   247  	if err = stream.Decode(&m.signature); err != nil {
   248  		return err
   249  	}
   250  	// End SignedPayload
   251  	if err = stream.ListEnd(); err != nil {
   252  		return err
   253  	}
   254  
   255  	if _, size, err = stream.Kind(); err != nil {
   256  		log.Error("QBFT: Error Kind()", "err", err)
   257  		return err
   258  	}
   259  	if size == 0 {
   260  		if _, err = stream.Raw(); err != nil {
   261  			log.Error("QBFT: Error Raw()", "err", err)
   262  			return err
   263  		}
   264  	} else {
   265  		if err = stream.Decode(&m.PreparedBlock); err != nil {
   266  			log.Error("QBFT: Error Decode(&m.PreparedDigest)", "err", err)
   267  			return err
   268  		}
   269  		if m.PreparedBlock.Hash() != m.PreparedDigest {
   270  			log.Error("QBFT: Error m.PreparedDigest.Hash() != digest")
   271  			return istanbulcommon.ErrFailedDecodePreprepare
   272  		}
   273  	}
   274  
   275  	if _, size, err = stream.Kind(); err != nil {
   276  		log.Error("QBFT: Error Kind()", "err", err)
   277  		return err
   278  	}
   279  	if size == 0 {
   280  		if _, err = stream.Raw(); err != nil {
   281  			log.Error("QBFT: Error Raw()", "err", err)
   282  			return err
   283  		}
   284  	} else {
   285  		if err = stream.Decode(&m.Justification); err != nil {
   286  			log.Error("QBFT: Error Decode(&m.Justification)", "err", err)
   287  			return err
   288  		}
   289  	}
   290  
   291  	// End RoundChange Message
   292  	if err = stream.ListEnd(); err != nil {
   293  		return err
   294  	}
   295  
   296  	m.code = RoundChangeCode
   297  
   298  	return nil
   299  }