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