github.com/annchain/OG@v0.0.9/consensus/bft/bft_model.go (about)

     1  package bft
     2  
     3  import (
     4  	"encoding/json"
     5  	"github.com/annchain/OG/common"
     6  	"github.com/annchain/OG/common/crypto"
     7  	"github.com/annchain/OG/common/hexutil"
     8  	"time"
     9  )
    10  
    11  const (
    12  	TimeoutPropose   = time.Duration(8) * time.Second
    13  	TimeoutPreVote   = time.Duration(8) * time.Second
    14  	TimeoutPreCommit = time.Duration(8) * time.Second
    15  	TimeoutDelta     = time.Duration(1) * time.Second
    16  )
    17  
    18  type ValueIdMatchType int
    19  
    20  const (
    21  	MatchTypeAny ValueIdMatchType = iota
    22  	MatchTypeByValue
    23  	MatchTypeNil
    24  )
    25  
    26  type StepType int
    27  
    28  const (
    29  	StepTypePropose StepType = iota
    30  	StepTypePreVote
    31  	StepTypePreCommit
    32  )
    33  
    34  func (m StepType) String() string {
    35  	switch m {
    36  	case StepTypePropose:
    37  		return "Proposal"
    38  	case StepTypePreVote:
    39  		return "PreVote"
    40  	case StepTypePreCommit:
    41  		return "PreCommit"
    42  	default:
    43  		return "Unknown"
    44  	}
    45  }
    46  
    47  func (m *StepType) MarshalJSON() ([]byte, error) {
    48  	s := m.String()
    49  	return json.Marshal(&s)
    50  }
    51  
    52  func (m StepType) IsAfter(o StepType) bool {
    53  	return m > o
    54  }
    55  
    56  type ChangeStateEvent struct {
    57  	NewStepType StepType
    58  	HeightRound HeightRound
    59  }
    60  
    61  type TendermintContext struct {
    62  	HeightRound HeightRound
    63  	StepType    StepType
    64  }
    65  
    66  func (t *TendermintContext) Equal(w WaiterContext) bool {
    67  	v, ok := w.(*TendermintContext)
    68  	if !ok {
    69  		return false
    70  	}
    71  	return t.HeightRound == v.HeightRound && t.StepType == v.StepType
    72  }
    73  
    74  func (t *TendermintContext) IsAfter(w WaiterContext) bool {
    75  	v, ok := w.(*TendermintContext)
    76  	if !ok {
    77  		return false
    78  	}
    79  	return t.HeightRound.IsAfter(v.HeightRound) || (t.HeightRound == v.HeightRound && t.StepType.IsAfter(v.StepType))
    80  }
    81  
    82  type BftPeer struct {
    83  	Id             int
    84  	PublicKey      crypto.PublicKey `json:"-"`
    85  	Address        common.Address   `json:"address"`
    86  	PublicKeyBytes hexutil.Bytes    `json:"public_key"`
    87  }
    88  
    89  // HeightRoundState is the structure for each Height/Round
    90  // Always keep this state that is higher than current in Partner.States map in order not to miss future things
    91  type HeightRoundState struct {
    92  	MessageProposal                       *BftMessageProposal // the proposal received in this round
    93  	LockedValue                           Proposal
    94  	LockedRound                           int
    95  	ValidValue                            Proposal
    96  	ValidRound                            int
    97  	Decision                              ConsensusDecision      // final decision of mine in this round
    98  	PreVotes                              []*BftMessagePreVote   // other peers' PreVotes
    99  	PreCommits                            []*BftMessagePreCommit // other peers' PreCommits
   100  	Sources                               map[uint16]bool        // for line 55, who send future round so that I may advance?
   101  	StepTypeEqualPreVoteTriggered         bool                   // for line 34, FIRST time trigger
   102  	StepTypeEqualOrLargerPreVoteTriggered bool                   // for line 36, FIRST time trigger
   103  	StepTypeEqualPreCommitTriggered       bool                   // for line 47, FIRST time trigger
   104  	Step                                  StepType               // current step in this round
   105  	StartAt                               time.Time
   106  }
   107  
   108  func NewHeightRoundState(total int) *HeightRoundState {
   109  	return &HeightRoundState{
   110  		LockedRound: -1,
   111  		ValidRound:  -1,
   112  		PreVotes:    make([]*BftMessagePreVote, total),
   113  		PreCommits:  make([]*BftMessagePreCommit, total),
   114  		Sources:     make(map[uint16]bool),
   115  		StartAt:     time.Now(),
   116  	}
   117  }
   118  
   119  type HeightRoundStateMap map[HeightRound]*HeightRoundState
   120  
   121  func (h *HeightRoundStateMap) MarshalJSON() ([]byte, error) {
   122  	if h == nil {
   123  		return nil, nil
   124  	}
   125  	m := make(map[string]*HeightRoundState, len(*h))
   126  	for k, v := range *h {
   127  		m[k.String()] = v
   128  	}
   129  	return json.Marshal(&m)
   130  }
   131  
   132  // BftStatus records all states of BFT
   133  // consider updating resetStatus() if you want to add things here
   134  type BftStatus struct {
   135  	CurrentHR HeightRound
   136  	N         int // total number of participants
   137  	F         int // max number of Byzantines
   138  	Maj23     int
   139  	Peers     []BftPeer
   140  	States    HeightRoundStateMap // for line 55, round number -> count
   141  }
   142  type BftMessageEvent struct {
   143  	Message BftMessage
   144  	Peer    BftPeer
   145  }
   146