Unverified Commit 7b6003c9 authored by vipwzw's avatar vipwzw Committed by GitHub

Merge pull request #70 from Hugo-Huang/branch_dev_hugo

fix golint problem in tendermint and #67
parents cb7fa786 2e301762
...@@ -27,9 +27,7 @@ const ( ...@@ -27,9 +27,7 @@ const (
proposalHeartbeatIntervalSeconds = 1 proposalHeartbeatIntervalSeconds = 1
) )
//----------------------------------------------------------------------------- // Errors define
// Errors
var ( var (
ErrInvalidProposalSignature = errors.New("Error invalid proposal signature") ErrInvalidProposalSignature = errors.New("Error invalid proposal signature")
ErrInvalidProposalPOLRound = errors.New("Error invalid proposal POL round") ErrInvalidProposalPOLRound = errors.New("Error invalid proposal POL round")
...@@ -61,7 +59,7 @@ func (ti *timeoutInfo) String() string { ...@@ -61,7 +59,7 @@ func (ti *timeoutInfo) String() string {
// The internal state machine receives input from peers, the internal validator, and from a timer. // The internal state machine receives input from peers, the internal validator, and from a timer.
type ConsensusState struct { type ConsensusState struct {
// config details // config details
client *TendermintClient client *Client
privValidator ttypes.PrivValidator // for signing votes privValidator ttypes.PrivValidator // for signing votes
// services for creating and executing blocks // services for creating and executing blocks
...@@ -90,7 +88,7 @@ type ConsensusState struct { ...@@ -90,7 +88,7 @@ type ConsensusState struct {
setProposal func(proposal *tmtypes.Proposal) error setProposal func(proposal *tmtypes.Proposal) error
broadcastChannel chan<- MsgInfo broadcastChannel chan<- MsgInfo
ourId ID ourID ID
started uint32 // atomic started uint32 // atomic
stopped uint32 // atomic stopped uint32 // atomic
Quit chan struct{} Quit chan struct{}
...@@ -101,7 +99,7 @@ type ConsensusState struct { ...@@ -101,7 +99,7 @@ type ConsensusState struct {
} }
// NewConsensusState returns a new ConsensusState. // NewConsensusState returns a new ConsensusState.
func NewConsensusState(client *TendermintClient, state State, blockExec *BlockExecutor, evpool ttypes.EvidencePool) *ConsensusState { func NewConsensusState(client *Client, state State, blockExec *BlockExecutor, evpool ttypes.EvidencePool) *ConsensusState {
cs := &ConsensusState{ cs := &ConsensusState{
client: client, client: client,
blockExec: blockExec, blockExec: blockExec,
...@@ -127,14 +125,17 @@ func NewConsensusState(client *TendermintClient, state State, blockExec *BlockEx ...@@ -127,14 +125,17 @@ func NewConsensusState(client *TendermintClient, state State, blockExec *BlockEx
return cs return cs
} }
// SetOurID method
func (cs *ConsensusState) SetOurID(id ID) { func (cs *ConsensusState) SetOurID(id ID) {
cs.ourId = id cs.ourID = id
} }
// SetBroadcastChannel method
func (cs *ConsensusState) SetBroadcastChannel(broadcastChannel chan<- MsgInfo) { func (cs *ConsensusState) SetBroadcastChannel(broadcastChannel chan<- MsgInfo) {
cs.broadcastChannel = broadcastChannel cs.broadcastChannel = broadcastChannel
} }
// IsRunning method
func (cs *ConsensusState) IsRunning() bool { func (cs *ConsensusState) IsRunning() bool {
return atomic.LoadUint32(&cs.started) == 1 && atomic.LoadUint32(&cs.stopped) == 0 return atomic.LoadUint32(&cs.started) == 1 && atomic.LoadUint32(&cs.stopped) == 0
} }
...@@ -194,8 +195,7 @@ func (cs *ConsensusState) LoadCommit(height int64) *tmtypes.TendermintCommit { ...@@ -194,8 +195,7 @@ func (cs *ConsensusState) LoadCommit(height int64) *tmtypes.TendermintCommit {
return cs.client.LoadBlockCommit(height + 1) return cs.client.LoadBlockCommit(height + 1)
} }
// OnStart implements cmn.Service. // Start It start first time starts the timeout checkTxsAvailable routine and receive routines.
// It loads the latest state via the WAL, and starts the timeout and receive routines.
func (cs *ConsensusState) Start() { func (cs *ConsensusState) Start() {
if atomic.CompareAndSwapUint32(&cs.started, 0, 1) { if atomic.CompareAndSwapUint32(&cs.started, 0, 1) {
if atomic.LoadUint32(&cs.stopped) == 1 { if atomic.LoadUint32(&cs.stopped) == 1 {
...@@ -213,9 +213,10 @@ func (cs *ConsensusState) Start() { ...@@ -213,9 +213,10 @@ func (cs *ConsensusState) Start() {
} }
} }
// OnStop implements cmn.Service. It stops all routines and waits for the WAL to finish. // Stop timer and receive routine
func (cs *ConsensusState) Stop() { func (cs *ConsensusState) Stop() {
cs.timeoutTicker.Stop() cs.timeoutTicker.Stop()
cs.Quit <- struct{}{}
} }
//------------------------------------------------------------ //------------------------------------------------------------
...@@ -348,7 +349,7 @@ func (cs *ConsensusState) updateToState(state State) { ...@@ -348,7 +349,7 @@ func (cs *ConsensusState) updateToState(state State) {
func (cs *ConsensusState) newStep() { func (cs *ConsensusState) newStep() {
if cs.broadcastChannel != nil { if cs.broadcastChannel != nil {
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: cs.ourId, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: cs.ourID, PeerIP: ""}
} }
cs.nSteps++ cs.nSteps++
} }
...@@ -563,7 +564,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) { ...@@ -563,7 +564,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping
//cs.eventBus.PublishEventNewRound(cs.RoundStateEvent()) //cs.eventBus.PublishEventNewRound(cs.RoundStateEvent())
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: cs.ourId, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: cs.RoundStateMessage(), PeerID: cs.ourID, PeerIP: ""}
// Wait for txs to be available in the mempool // Wait for txs to be available in the mempool
// before we enterPropose in round 0. // before we enterPropose in round 0.
...@@ -598,8 +599,8 @@ func (cs *ConsensusState) proposalHeartbeat(height int64, round int) { ...@@ -598,8 +599,8 @@ func (cs *ConsensusState) proposalHeartbeat(height int64, round int) {
} }
heartbeatMsg := &ttypes.Heartbeat{Heartbeat: heartbeat} heartbeatMsg := &ttypes.Heartbeat{Heartbeat: heartbeat}
cs.privValidator.SignHeartbeat(chainID, heartbeatMsg) cs.privValidator.SignHeartbeat(chainID, heartbeatMsg)
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ProposalHeartbeatID, Msg: heartbeat, PeerID: cs.ourId, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.ProposalHeartbeatID, Msg: heartbeat, PeerID: cs.ourID, PeerIP: ""}
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: rs.RoundStateMessage(), PeerID: cs.ourId, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.NewRoundStepID, Msg: rs.RoundStateMessage(), PeerID: cs.ourID, PeerIP: ""}
counter++ counter++
time.Sleep(proposalHeartbeatIntervalSeconds * time.Second) time.Sleep(proposalHeartbeatIntervalSeconds * time.Second)
} }
...@@ -680,8 +681,8 @@ func (cs *ConsensusState) defaultDecideProposal(height int64, round int) { ...@@ -680,8 +681,8 @@ func (cs *ConsensusState) defaultDecideProposal(height int64, round int) {
proposal := ttypes.NewProposal(height, round, block.Hash(), polRound, polBlockID.BlockID) proposal := ttypes.NewProposal(height, round, block.Hash(), polRound, polBlockID.BlockID)
if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal); err == nil { if err := cs.privValidator.SignProposal(cs.state.ChainID, proposal); err == nil {
// send proposal and block on internal msg queue // send proposal and block on internal msg queue
cs.sendInternalMessage(MsgInfo{ttypes.ProposalID, &proposal.Proposal, cs.ourId, ""}) cs.sendInternalMessage(MsgInfo{ttypes.ProposalID, &proposal.Proposal, cs.ourID, ""})
cs.sendInternalMessage(MsgInfo{ttypes.ProposalBlockID, block.TendermintBlock, cs.ourId, ""}) cs.sendInternalMessage(MsgInfo{ttypes.ProposalBlockID, block.TendermintBlock, cs.ourID, ""})
tendermintlog.Info("Signed proposal", "height", height, "round", round, "proposal", proposal) tendermintlog.Info("Signed proposal", "height", height, "round", round, "proposal", proposal)
} else { } else {
tendermintlog.Error("enterPropose: Error signing proposal", "height", height, "round", round, "err", err) tendermintlog.Error("enterPropose: Error signing proposal", "height", height, "round", round, "err", err)
...@@ -1267,14 +1268,14 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1267,14 +1268,14 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
height := cs.Height height := cs.Height
added, err = cs.Votes.AddVote(vote, peerID) added, err = cs.Votes.AddVote(vote, peerID)
if added { if added {
//cs.broadcastChannel <- MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.ourId, PeerIP: ""} //cs.broadcastChannel <- MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.ourID, PeerIP: ""}
hasVoteMsg := &tmtypes.HasVoteMsg{ hasVoteMsg := &tmtypes.HasVoteMsg{
Height: vote.Height, Height: vote.Height,
Round: vote.Round, Round: vote.Round,
Type: int32(vote.Type), Type: int32(vote.Type),
Index: vote.ValidatorIndex, Index: vote.ValidatorIndex,
} }
cs.broadcastChannel <- MsgInfo{TypeID: ttypes.HasVoteID, Msg: hasVoteMsg, PeerID: cs.ourId, PeerIP: ""} cs.broadcastChannel <- MsgInfo{TypeID: ttypes.HasVoteID, Msg: hasVoteMsg, PeerID: cs.ourID, PeerIP: ""}
switch vote.Type { switch vote.Type {
case uint32(ttypes.VoteTypePrevote): case uint32(ttypes.VoteTypePrevote):
...@@ -1358,7 +1359,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin ...@@ -1358,7 +1359,7 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
return return
} }
func (cs *ConsensusState) signVote(type_ byte, hash []byte) (*ttypes.Vote, error) { func (cs *ConsensusState) signVote(voteType byte, hash []byte) (*ttypes.Vote, error) {
addr := cs.privValidator.GetAddress() addr := cs.privValidator.GetAddress()
valIndex, _ := cs.Validators.GetByAddress(addr) valIndex, _ := cs.Validators.GetByAddress(addr)
...@@ -1371,7 +1372,7 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte) (*ttypes.Vote, error ...@@ -1371,7 +1372,7 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte) (*ttypes.Vote, error
Height: cs.Height, Height: cs.Height,
Round: int32(cs.Round), Round: int32(cs.Round),
Timestamp: time.Now().UnixNano(), Timestamp: time.Now().UnixNano(),
Type: uint32(type_), Type: uint32(voteType),
BlockID: &tmtypes.BlockID{Hash: hash}, BlockID: &tmtypes.BlockID{Hash: hash},
Signature: nil, Signature: nil,
}, },
...@@ -1383,14 +1384,14 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte) (*ttypes.Vote, error ...@@ -1383,14 +1384,14 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte) (*ttypes.Vote, error
} }
// sign the vote and publish on internalMsgQueue // sign the vote and publish on internalMsgQueue
func (cs *ConsensusState) signAddVote(type_ byte, hash []byte) *ttypes.Vote { func (cs *ConsensusState) signAddVote(voteType byte, hash []byte) *ttypes.Vote {
// if we don't have a key or we're not in the validator set, do nothing // if we don't have a key or we're not in the validator set, do nothing
if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.GetAddress()) { if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.GetAddress()) {
return nil return nil
} }
vote, err := cs.signVote(type_, hash) vote, err := cs.signVote(voteType, hash)
if err == nil { if err == nil {
cs.sendInternalMessage(MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.ourId, PeerIP: ""}) cs.sendInternalMessage(MsgInfo{TypeID: ttypes.VoteID, Msg: vote.Vote, PeerID: cs.ourID, PeerIP: ""})
tendermintlog.Info("Signed and pushed vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err) tendermintlog.Info("Signed and pushed vote", "height", cs.Height, "round", cs.Round, "vote", vote, "err", err)
return vote return vote
} }
...@@ -1400,8 +1401,7 @@ func (cs *ConsensusState) signAddVote(type_ byte, hash []byte) *ttypes.Vote { ...@@ -1400,8 +1401,7 @@ func (cs *ConsensusState) signAddVote(type_ byte, hash []byte) *ttypes.Vote {
} }
//--------------------------------------------------------- // CompareHRS method
func CompareHRS(h1 int64, r1 int, s1 ttypes.RoundStepType, h2 int64, r2 int, s2 ttypes.RoundStepType) int { func CompareHRS(h1 int64, r1 int, s1 ttypes.RoundStepType, h2 int64, r2 int, s2 ttypes.RoundStepType) int {
if h1 < h2 { if h1 < h2 {
return -1 return -1
...@@ -1446,7 +1446,7 @@ func (cs *ConsensusState) WaitForTxs() bool { ...@@ -1446,7 +1446,7 @@ func (cs *ConsensusState) WaitForTxs() bool {
return !createEmptyBlocks || createEmptyBlocksInterval > 0 return !createEmptyBlocks || createEmptyBlocksInterval > 0
} }
// EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available // EmptyBlocksInterval returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available
func (cs *ConsensusState) EmptyBlocksInterval() time.Duration { func (cs *ConsensusState) EmptyBlocksInterval() time.Duration {
return time.Duration(createEmptyBlocksInterval) * time.Second return time.Duration(createEmptyBlocksInterval) * time.Second
} }
...@@ -1461,10 +1461,12 @@ func (cs *ConsensusState) PeerQueryMaj23Sleep() time.Duration { ...@@ -1461,10 +1461,12 @@ func (cs *ConsensusState) PeerQueryMaj23Sleep() time.Duration {
return time.Duration(peerQueryMaj23SleepDuration) * time.Millisecond return time.Duration(peerQueryMaj23SleepDuration) * time.Millisecond
} }
// IsProposer method
func (cs *ConsensusState) IsProposer() bool { func (cs *ConsensusState) IsProposer() bool {
return cs.isProposer() return cs.isProposer()
} }
// GetPrevotesState method
func (cs *ConsensusState) GetPrevotesState(height int64, round int, blockID *tmtypes.BlockID) *ttypes.BitArray { func (cs *ConsensusState) GetPrevotesState(height int64, round int, blockID *tmtypes.BlockID) *ttypes.BitArray {
if height != cs.Height { if height != cs.Height {
return nil return nil
...@@ -1472,6 +1474,7 @@ func (cs *ConsensusState) GetPrevotesState(height int64, round int, blockID *tmt ...@@ -1472,6 +1474,7 @@ func (cs *ConsensusState) GetPrevotesState(height int64, round int, blockID *tmt
return cs.Votes.Prevotes(round).BitArrayByBlockID(blockID) return cs.Votes.Prevotes(round).BitArrayByBlockID(blockID)
} }
// GetPrecommitsState method
func (cs *ConsensusState) GetPrecommitsState(height int64, round int, blockID *tmtypes.BlockID) *ttypes.BitArray { func (cs *ConsensusState) GetPrecommitsState(height int64, round int, blockID *tmtypes.BlockID) *ttypes.BitArray {
if height != cs.Height { if height != cs.Height {
return nil return nil
...@@ -1479,8 +1482,9 @@ func (cs *ConsensusState) GetPrecommitsState(height int64, round int, blockID *t ...@@ -1479,8 +1482,9 @@ func (cs *ConsensusState) GetPrecommitsState(height int64, round int, blockID *t
return cs.Votes.Precommits(round).BitArrayByBlockID(blockID) return cs.Votes.Precommits(round).BitArrayByBlockID(blockID)
} }
func (cs *ConsensusState) SetPeerMaj23(height int64, round int, type_ byte, peerID ID, blockID *tmtypes.BlockID) { // SetPeerMaj23 when reach maj 2/3
func (cs *ConsensusState) SetPeerMaj23(height int64, round int, voteType byte, peerID ID, blockID *tmtypes.BlockID) {
if height == cs.Height { if height == cs.Height {
cs.Votes.SetPeerMaj23(round, type_, string(peerID), blockID) cs.Votes.SetPeerMaj23(round, voteType, string(peerID), blockID)
} }
} }
...@@ -43,6 +43,7 @@ type envelope struct { ...@@ -43,6 +43,7 @@ type envelope struct {
Data *json.RawMessage `json:"data"` Data *json.RawMessage `json:"data"`
} }
// EvidenceInfo struct
type EvidenceInfo struct { type EvidenceInfo struct {
Committed bool `json:"committed"` Committed bool `json:"committed"`
Priority int64 `json:"priority"` Priority int64 `json:"priority"`
...@@ -77,8 +78,8 @@ func keyPending(evidence ttypes.Evidence) []byte { ...@@ -77,8 +78,8 @@ func keyPending(evidence ttypes.Evidence) []byte {
return _key("%s/%s/%X", baseKeyPending, bE(evidence.Height()), evidence.Hash()) return _key("%s/%s/%X", baseKeyPending, bE(evidence.Height()), evidence.Hash())
} }
func _key(fmt_ string, o ...interface{}) []byte { func _key(s string, o ...interface{}) []byte {
return []byte(fmt.Sprintf(fmt_, o...)) return []byte(fmt.Sprintf(s, o...))
} }
// EvidenceStore is a store of all the evidence we've seen, including // EvidenceStore is a store of all the evidence we've seen, including
...@@ -88,6 +89,7 @@ type EvidenceStore struct { ...@@ -88,6 +89,7 @@ type EvidenceStore struct {
db dbm.DB db dbm.DB
} }
// NewEvidenceStore method
func NewEvidenceStore(db dbm.DB) *EvidenceStore { func NewEvidenceStore(db dbm.DB) *EvidenceStore {
if len(ttypes.EvidenceType2Type) == 0 { if len(ttypes.EvidenceType2Type) == 0 {
ttypes.EvidenceType2Type = map[string]reflect.Type{ ttypes.EvidenceType2Type = map[string]reflect.Type{
...@@ -160,8 +162,8 @@ func (store *EvidenceStore) GetEvidence(height int64, hash []byte) *EvidenceInfo ...@@ -160,8 +162,8 @@ func (store *EvidenceStore) GetEvidence(height int64, hash []byte) *EvidenceInfo
// It returns false if the evidence is already stored. // It returns false if the evidence is already stored.
func (store *EvidenceStore) AddNewEvidence(evidence ttypes.Evidence, priority int64) bool { func (store *EvidenceStore) AddNewEvidence(evidence ttypes.Evidence, priority int64) bool {
// check if we already have seen it // check if we already have seen it
ei_ := store.GetEvidence(evidence.Height(), evidence.Hash()) ei := store.GetEvidence(evidence.Height(), evidence.Hash())
if ei_ != nil && len(ei_.Evidence.Kind) == 0 { if ei != nil && len(ei.Evidence.Kind) == 0 {
return false return false
} }
...@@ -191,7 +193,7 @@ func (store *EvidenceStore) MarkEvidenceAsBroadcasted(evidence ttypes.Evidence) ...@@ -191,7 +193,7 @@ func (store *EvidenceStore) MarkEvidenceAsBroadcasted(evidence ttypes.Evidence)
store.db.Delete(key) store.db.Delete(key)
} }
// MarkEvidenceAsPending removes evidence from pending and outqueue and sets the state to committed. // MarkEvidenceAsCommitted removes evidence from pending and outqueue and sets the state to committed.
func (store *EvidenceStore) MarkEvidenceAsCommitted(evidence ttypes.Evidence) { func (store *EvidenceStore) MarkEvidenceAsCommitted(evidence ttypes.Evidence) {
// if its committed, its been broadcast // if its committed, its been broadcast
store.MarkEvidenceAsBroadcasted(evidence) store.MarkEvidenceAsBroadcasted(evidence)
...@@ -227,6 +229,7 @@ func (store *EvidenceStore) getEvidenceInfo(evidence ttypes.Evidence) EvidenceIn ...@@ -227,6 +229,7 @@ func (store *EvidenceStore) getEvidenceInfo(evidence ttypes.Evidence) EvidenceIn
return ei return ei
} }
// EvidenceToInfoBytes method
func EvidenceToInfoBytes(evidence ttypes.Evidence, priority int64) ([]byte, error) { func EvidenceToInfoBytes(evidence ttypes.Evidence, priority int64) ([]byte, error) {
evi, err := json.Marshal(evidence) evi, err := json.Marshal(evidence)
if err != nil { if err != nil {
...@@ -250,6 +253,7 @@ func EvidenceToInfoBytes(evidence ttypes.Evidence, priority int64) ([]byte, erro ...@@ -250,6 +253,7 @@ func EvidenceToInfoBytes(evidence ttypes.Evidence, priority int64) ([]byte, erro
return eiBytes, nil return eiBytes, nil
} }
// EvidenceFromInfoBytes method
func (store *EvidenceStore) EvidenceFromInfoBytes(data []byte) (ttypes.Evidence, error) { func (store *EvidenceStore) EvidenceFromInfoBytes(data []byte) (ttypes.Evidence, error) {
vote2 := EvidenceInfo{} vote2 := EvidenceInfo{}
err := json.Unmarshal(data, &vote2) err := json.Unmarshal(data, &vote2)
...@@ -268,7 +272,6 @@ func (store *EvidenceStore) EvidenceFromInfoBytes(data []byte) (ttypes.Evidence, ...@@ -268,7 +272,6 @@ func (store *EvidenceStore) EvidenceFromInfoBytes(data []byte) (ttypes.Evidence,
} }
//-------------------------evidence pool----------------------------
// EvidencePool maintains a pool of valid evidence // EvidencePool maintains a pool of valid evidence
// in an EvidenceStore. // in an EvidenceStore.
type EvidencePool struct { type EvidencePool struct {
...@@ -285,6 +288,7 @@ type EvidencePool struct { ...@@ -285,6 +288,7 @@ type EvidencePool struct {
evidenceChan chan ttypes.Evidence evidenceChan chan ttypes.Evidence
} }
// NewEvidencePool method
func NewEvidencePool(stateDB *CSStateDB, state State, evidenceStore *EvidenceStore) *EvidencePool { func NewEvidencePool(stateDB *CSStateDB, state State, evidenceStore *EvidenceStore) *EvidencePool {
evpool := &EvidencePool{ evpool := &EvidencePool{
stateDB: stateDB, stateDB: stateDB,
......
...@@ -22,14 +22,15 @@ import ( ...@@ -22,14 +22,15 @@ import (
) )
const ( const (
numBufferedConnections = 10 numBufferedConnections = 10
MaxNumPeers = 50 maxNumPeers = 50
tryListenSeconds = 5 tryListenSeconds = 5
HandshakeTimeout = 20 // * time.Second, handshakeTimeout = 20 // * time.Second,
maxSendQueueSize = 1024 maxSendQueueSize = 1024
defaultSendTimeout = 60 * time.Second defaultSendTimeout = 60 * time.Second
//MaxMsgPacketPayloadSize define
MaxMsgPacketPayloadSize = 10 * 1024 * 1024 MaxMsgPacketPayloadSize = 10 * 1024 * 1024
DefaultDialTimeout = 3 * time.Second defaultDialTimeout = 3 * time.Second
dialRandomizerIntervalMilliseconds = 3000 dialRandomizerIntervalMilliseconds = 3000
// repeatedly try to reconnect for a few minutes // repeatedly try to reconnect for a few minutes
// ie. 5 * 20 = 100s // ie. 5 * 20 = 100s
...@@ -47,6 +48,7 @@ const ( ...@@ -47,6 +48,7 @@ const (
broadcastEvidenceIntervalS = 60 // broadcast uncommitted evidence this often broadcastEvidenceIntervalS = 60 // broadcast uncommitted evidence this often
) )
// Parallel method
func Parallel(tasks ...func()) { func Parallel(tasks ...func()) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(len(tasks)) wg.Add(len(tasks))
...@@ -59,23 +61,27 @@ func Parallel(tasks ...func()) { ...@@ -59,23 +61,27 @@ func Parallel(tasks ...func()) {
wg.Wait() wg.Wait()
} }
// GenAddressByPubKey method
func GenAddressByPubKey(pubkey crypto.PubKey) []byte { func GenAddressByPubKey(pubkey crypto.PubKey) []byte {
//must add 3 bytes ahead to make compatibly //must add 3 bytes ahead to make compatibly
typeAddr := append([]byte{byte(0x01), byte(0x01), byte(0x20)}, pubkey.Bytes()...) typeAddr := append([]byte{byte(0x01), byte(0x01), byte(0x20)}, pubkey.Bytes()...)
return crypto.Ripemd160(typeAddr) return crypto.Ripemd160(typeAddr)
} }
// IP2IPPort struct
type IP2IPPort struct { type IP2IPPort struct {
mutex sync.RWMutex mutex sync.RWMutex
mapList map[string]string mapList map[string]string
} }
// NewMutexMap method
func NewMutexMap() *IP2IPPort { func NewMutexMap() *IP2IPPort {
return &IP2IPPort{ return &IP2IPPort{
mapList: make(map[string]string), mapList: make(map[string]string),
} }
} }
// Has method
func (ipp *IP2IPPort) Has(ip string) bool { func (ipp *IP2IPPort) Has(ip string) bool {
ipp.mutex.RLock() ipp.mutex.RLock()
defer ipp.mutex.RUnlock() defer ipp.mutex.RUnlock()
...@@ -83,18 +89,21 @@ func (ipp *IP2IPPort) Has(ip string) bool { ...@@ -83,18 +89,21 @@ func (ipp *IP2IPPort) Has(ip string) bool {
return ok return ok
} }
// Set method
func (ipp *IP2IPPort) Set(ip string, ipport string) { func (ipp *IP2IPPort) Set(ip string, ipport string) {
ipp.mutex.Lock() ipp.mutex.Lock()
defer ipp.mutex.Unlock() defer ipp.mutex.Unlock()
ipp.mapList[ip] = ipport ipp.mapList[ip] = ipport
} }
// Delete method
func (ipp *IP2IPPort) Delete(ip string) { func (ipp *IP2IPPort) Delete(ip string) {
ipp.mutex.Lock() ipp.mutex.Lock()
defer ipp.mutex.Unlock() defer ipp.mutex.Unlock()
delete(ipp.mapList, ip) delete(ipp.mapList, ip)
} }
// NodeInfo struct
type NodeInfo struct { type NodeInfo struct {
ID ID `json:"id"` ID ID `json:"id"`
Network string `json:"network"` Network string `json:"network"`
...@@ -102,6 +111,7 @@ type NodeInfo struct { ...@@ -102,6 +111,7 @@ type NodeInfo struct {
IP string `json:"ip,omitempty"` IP string `json:"ip,omitempty"`
} }
// Node struct
type Node struct { type Node struct {
listener net.Listener listener net.Listener
connections chan net.Conn connections chan net.Conn
...@@ -129,6 +139,7 @@ type Node struct { ...@@ -129,6 +139,7 @@ type Node struct {
quit chan struct{} quit chan struct{}
} }
// NewNode method
func NewNode(seeds []string, protocol string, lAddr string, privKey crypto.PrivKey, network string, version string, state *ConsensusState, evpool *EvidencePool) *Node { func NewNode(seeds []string, protocol string, lAddr string, privKey crypto.PrivKey, network string, version string, state *ConsensusState, evpool *EvidencePool) *Node {
address := GenAddressByPubKey(privKey.PubKey()) address := GenAddressByPubKey(privKey.PubKey())
...@@ -163,6 +174,7 @@ func NewNode(seeds []string, protocol string, lAddr string, privKey crypto.PrivK ...@@ -163,6 +174,7 @@ func NewNode(seeds []string, protocol string, lAddr string, privKey crypto.PrivK
return node return node
} }
// Start node
func (node *Node) Start() { func (node *Node) Start() {
if atomic.CompareAndSwapUint32(&node.started, 0, 1) { if atomic.CompareAndSwapUint32(&node.started, 0, 1) {
// Create listener // Create listener
...@@ -211,6 +223,7 @@ func (node *Node) Start() { ...@@ -211,6 +223,7 @@ func (node *Node) Start() {
} }
} }
// DialPeerWithAddress ...
func (node *Node) DialPeerWithAddress(addr string) error { func (node *Node) DialPeerWithAddress(addr string) error {
ip, _ := splitHostPort(addr) ip, _ := splitHostPort(addr)
node.dialing.Set(ip, addr) node.dialing.Set(ip, addr)
...@@ -234,6 +247,7 @@ func (node *Node) addOutboundPeerWithConfig(addr string) error { ...@@ -234,6 +247,7 @@ func (node *Node) addOutboundPeerWithConfig(addr string) error {
return nil return nil
} }
// Stop ...
func (node *Node) Stop() { func (node *Node) Stop() {
atomic.CompareAndSwapUint32(&node.stopped, 0, 1) atomic.CompareAndSwapUint32(&node.stopped, 0, 1)
node.listener.Close() node.listener.Close()
...@@ -245,10 +259,11 @@ func (node *Node) Stop() { ...@@ -245,10 +259,11 @@ func (node *Node) Stop() {
peer.Stop() peer.Stop()
node.peerSet.Remove(peer) node.peerSet.Remove(peer)
} }
// Stop reactors //stop consensus
tendermintlog.Debug("Switch: Stopping reactors") node.state.Stop()
} }
// IsRunning ...
func (node *Node) IsRunning() bool { func (node *Node) IsRunning() bool {
return atomic.LoadUint32(&node.started) == 1 && atomic.LoadUint32(&node.stopped) == 0 return atomic.LoadUint32(&node.started) == 1 && atomic.LoadUint32(&node.stopped) == 0
} }
...@@ -277,8 +292,10 @@ func (node *Node) listenRoutine() { ...@@ -277,8 +292,10 @@ func (node *Node) listenRoutine() {
} }
} }
// StartConsensusRoutine if peers reached the threshold start consensus routine
func (node *Node) StartConsensusRoutine() { func (node *Node) StartConsensusRoutine() {
for { for {
//TODO:the peer count need be optimized
if node.peerSet.Size() >= 0 { if node.peerSet.Size() >= 0 {
node.state.Start() node.state.Start()
break break
...@@ -347,6 +364,7 @@ func (node *Node) evidenceBroadcastRoutine() { ...@@ -347,6 +364,7 @@ func (node *Node) evidenceBroadcastRoutine() {
} }
} }
// BroadcastRoutine receive to broadcast
func (node *Node) BroadcastRoutine() { func (node *Node) BroadcastRoutine() {
for { for {
msg, ok := <-node.broadcastChannel msg, ok := <-node.broadcastChannel
...@@ -359,7 +377,7 @@ func (node *Node) BroadcastRoutine() { ...@@ -359,7 +377,7 @@ func (node *Node) BroadcastRoutine() {
} }
func (node *Node) connectComming(inConn net.Conn) { func (node *Node) connectComming(inConn net.Conn) {
maxPeers := MaxNumPeers maxPeers := maxNumPeers
if maxPeers <= node.peerSet.Size() { if maxPeers <= node.peerSet.Size() {
tendermintlog.Debug("Ignoring inbound connection: already have enough peers", "address", inConn.RemoteAddr().String(), "numPeers", node.peerSet.Size(), "max", maxPeers) tendermintlog.Debug("Ignoring inbound connection: already have enough peers", "address", inConn.RemoteAddr().String(), "numPeers", node.peerSet.Size(), "max", maxPeers)
return return
...@@ -378,6 +396,7 @@ func (node *Node) stopAndRemovePeer(peer Peer, reason interface{}) { ...@@ -378,6 +396,7 @@ func (node *Node) stopAndRemovePeer(peer Peer, reason interface{}) {
peer.Stop() peer.Stop()
} }
// StopPeerForError called if error occured
func (node *Node) StopPeerForError(peer Peer, reason interface{}) { func (node *Node) StopPeerForError(peer Peer, reason interface{}) {
tendermintlog.Error("Stopping peer for error", "peer", peer, "err", reason) tendermintlog.Error("Stopping peer for error", "peer", peer, "err", reason)
addr, err := peer.RemoteAddr() addr, err := peer.RemoteAddr()
...@@ -422,7 +441,7 @@ func (node *Node) addPeer(pc *peerConn) error { ...@@ -422,7 +441,7 @@ func (node *Node) addPeer(pc *peerConn) error {
Version: node.Version, Version: node.Version,
} }
// Exchange NodeInfo on the conn // Exchange NodeInfo on the conn
peerNodeInfo, err := pc.HandshakeTimeout(nodeinfo, HandshakeTimeout*time.Second) peerNodeInfo, err := pc.HandshakeTimeout(nodeinfo, handshakeTimeout*time.Second)
if err != nil { if err != nil {
return err return err
} }
...@@ -489,6 +508,7 @@ func (node *Node) addPeer(pc *peerConn) error { ...@@ -489,6 +508,7 @@ func (node *Node) addPeer(pc *peerConn) error {
return nil return nil
} }
// Broadcast to peers in set
func (node *Node) Broadcast(msg MsgInfo) chan bool { func (node *Node) Broadcast(msg MsgInfo) chan bool {
successChan := make(chan bool, len(node.peerSet.List())) successChan := make(chan bool, len(node.peerSet.List()))
tendermintlog.Debug("Broadcast", "msgtype", msg.TypeID) tendermintlog.Debug("Broadcast", "msgtype", msg.TypeID)
...@@ -519,13 +539,12 @@ func (node *Node) startInitPeer(peer *peerConn) error { ...@@ -519,13 +539,12 @@ func (node *Node) startInitPeer(peer *peerConn) error {
return nil return nil
} }
// FilterConnByAddr TODO:can make fileter by addr
func (node *Node) FilterConnByAddr(addr net.Addr) error { func (node *Node) FilterConnByAddr(addr net.Addr) error {
//if node.filterConnByAddr != nil {
// return node.filterConnByAddr(addr)
//}
return nil return nil
} }
// CompatibleWith one node by nodeInfo
func (node *Node) CompatibleWith(other NodeInfo) error { func (node *Node) CompatibleWith(other NodeInfo) error {
iMajor, iMinor, _, iErr := splitVersion(node.Version) iMajor, iMinor, _, iErr := splitVersion(node.Version)
oMajor, oMinor, _, oErr := splitVersion(other.Version) oMajor, oMinor, _, oErr := splitVersion(other.Version)
...@@ -679,7 +698,7 @@ func splitHostPort(addr string) (host string, port int) { ...@@ -679,7 +698,7 @@ func splitHostPort(addr string) (host string, port int) {
} }
func dial(addr string) (net.Conn, error) { func dial(addr string) (net.Conn, error) {
conn, err := net.DialTimeout("tcp", addr, DefaultDialTimeout) conn, err := net.DialTimeout("tcp", addr, defaultDialTimeout)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -727,7 +746,7 @@ func newPeerConn( ...@@ -727,7 +746,7 @@ func newPeerConn(
conn := rawConn conn := rawConn
// Set deadline for secret handshake // Set deadline for secret handshake
dl := time.Now().Add(HandshakeTimeout * time.Second) dl := time.Now().Add(handshakeTimeout * time.Second)
if err := conn.SetDeadline(dl); err != nil { if err := conn.SetDeadline(dl); err != nil {
return pc, fmt.Errorf("Error setting deadline while encrypting connection:%v", err) return pc, fmt.Errorf("Error setting deadline while encrypting connection:%v", err)
} }
......
...@@ -33,6 +33,7 @@ type msgPacket struct { ...@@ -33,6 +33,7 @@ type msgPacket struct {
Bytes []byte Bytes []byte
} }
// MsgInfo struct
type MsgInfo struct { type MsgInfo struct {
TypeID byte TypeID byte
Msg proto.Message Msg proto.Message
...@@ -40,6 +41,7 @@ type MsgInfo struct { ...@@ -40,6 +41,7 @@ type MsgInfo struct {
PeerIP string PeerIP string
} }
// Peer interface
type Peer interface { type Peer interface {
ID() ID ID() ID
RemoteIP() (net.IP, error) // remote IP of the connection RemoteIP() (net.IP, error) // remote IP of the connection
...@@ -57,6 +59,7 @@ type Peer interface { ...@@ -57,6 +59,7 @@ type Peer interface {
//Get(string) interface{} //Get(string) interface{}
} }
// PeerConnState struct
type PeerConnState struct { type PeerConnState struct {
mtx sync.Mutex mtx sync.Mutex
ip net.IP ip net.IP
...@@ -98,6 +101,7 @@ type peerConn struct { ...@@ -98,6 +101,7 @@ type peerConn struct {
heartbeatQueue chan proto.Message heartbeatQueue chan proto.Message
} }
// PeerSet struct
type PeerSet struct { type PeerSet struct {
mtx sync.Mutex mtx sync.Mutex
lookup map[ID]*peerSetItem lookup map[ID]*peerSetItem
...@@ -109,6 +113,7 @@ type peerSetItem struct { ...@@ -109,6 +113,7 @@ type peerSetItem struct {
index int index int
} }
// NewPeerSet method
func NewPeerSet() *PeerSet { func NewPeerSet() *PeerSet {
return &PeerSet{ return &PeerSet{
lookup: make(map[ID]*peerSetItem), lookup: make(map[ID]*peerSetItem),
...@@ -164,6 +169,7 @@ func (ps *PeerSet) hasIP(peerIP net.IP) bool { ...@@ -164,6 +169,7 @@ func (ps *PeerSet) hasIP(peerIP net.IP) bool {
return false return false
} }
// Size of list
func (ps *PeerSet) Size() int { func (ps *PeerSet) Size() int {
ps.mtx.Lock() ps.mtx.Lock()
defer ps.mtx.Unlock() defer ps.mtx.Unlock()
...@@ -279,14 +285,11 @@ func (pc *peerConn) HandshakeTimeout( ...@@ -279,14 +285,11 @@ func (pc *peerConn) HandshakeTimeout(
if err1 != nil { if err1 != nil {
tendermintlog.Error("Peer handshake peerNodeInfo failed", "err", err1) tendermintlog.Error("Peer handshake peerNodeInfo failed", "err", err1)
return return
} else {
frame := make([]byte, 4)
binary.BigEndian.PutUint32(frame, uint32(len(info)))
_, err1 = pc.conn.Write(frame)
_, err1 = pc.conn.Write(info[:])
} }
//var n int frame := make([]byte, 4)
//wire.WriteBinary(ourNodeInfo, p.conn, &n, &err1) binary.BigEndian.PutUint32(frame, uint32(len(info)))
_, err1 = pc.conn.Write(frame)
_, err1 = pc.conn.Write(info[:])
}, },
func() { func() {
readBuffer := make([]byte, 4) readBuffer := make([]byte, 4)
...@@ -304,9 +307,6 @@ func (pc *peerConn) HandshakeTimeout( ...@@ -304,9 +307,6 @@ func (pc *peerConn) HandshakeTimeout(
if err2 != nil { if err2 != nil {
return return
} }
//var n int
//wire.ReadBinary(peerNodeInfo, p.conn, maxNodeInfoSize, &n, &err2)
tendermintlog.Info("Peer handshake", "peerNodeInfo", peerNodeInfo) tendermintlog.Info("Peer handshake", "peerNodeInfo", peerNodeInfo)
}, },
) )
...@@ -956,6 +956,7 @@ OUTER_LOOP: ...@@ -956,6 +956,7 @@ OUTER_LOOP:
} }
} }
// StackError struct
type StackError struct { type StackError struct {
Err interface{} Err interface{}
Stack []byte Stack []byte
...@@ -969,7 +970,6 @@ func (se StackError) Error() string { ...@@ -969,7 +970,6 @@ func (se StackError) Error() string {
return se.String() return se.String()
} }
//-----------------------------------------------------------------
// GetRoundState returns an atomic snapshot of the PeerRoundState. // GetRoundState returns an atomic snapshot of the PeerRoundState.
// There's no point in mutating it since it won't change PeerState. // There's no point in mutating it since it won't change PeerState.
func (ps *PeerConnState) GetRoundState() *ttypes.PeerRoundState { func (ps *PeerConnState) GetRoundState() *ttypes.PeerRoundState {
...@@ -1034,7 +1034,7 @@ func (ps *PeerConnState) PickVoteToSend(votes ttypes.VoteSetReader) (vote *ttype ...@@ -1034,7 +1034,7 @@ func (ps *PeerConnState) PickVoteToSend(votes ttypes.VoteSetReader) (vote *ttype
return nil, false return nil, false
} }
height, round, type_, size := votes.Height(), votes.Round(), votes.Type(), votes.Size() height, round, voteType, size := votes.Height(), votes.Round(), votes.Type(), votes.Size()
// Lazily set data using 'votes'. // Lazily set data using 'votes'.
if votes.IsCommit() { if votes.IsCommit() {
...@@ -1042,28 +1042,28 @@ func (ps *PeerConnState) PickVoteToSend(votes ttypes.VoteSetReader) (vote *ttype ...@@ -1042,28 +1042,28 @@ func (ps *PeerConnState) PickVoteToSend(votes ttypes.VoteSetReader) (vote *ttype
} }
ps.ensureVoteBitArrays(height, size) ps.ensureVoteBitArrays(height, size)
psVotes := ps.getVoteBitArray(height, round, type_) psVotes := ps.getVoteBitArray(height, round, voteType)
if psVotes == nil { if psVotes == nil {
return nil, false // Not something worth sending return nil, false // Not something worth sending
} }
if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok { if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok {
tendermintlog.Debug("PickVoteToSend", "height", height, "index", index, "type", type_, "selfVotes", votes.BitArray().String(), tendermintlog.Debug("PickVoteToSend", "height", height, "index", index, "type", voteType, "selfVotes", votes.BitArray().String(),
"peerVotes", psVotes.String(), "peerip", ps.ip.String()) "peerVotes", psVotes.String(), "peerip", ps.ip.String())
ps.setHasVote(height, round, type_, index) ps.setHasVote(height, round, voteType, index)
return votes.GetByIndex(index), true return votes.GetByIndex(index), true
} }
return nil, false return nil, false
} }
func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *ttypes.BitArray { func (ps *PeerConnState) getVoteBitArray(height int64, round int, voteType byte) *ttypes.BitArray {
if !ttypes.IsVoteTypeValid(type_) { if !ttypes.IsVoteTypeValid(voteType) {
return nil return nil
} }
if ps.Height == height { if ps.Height == height {
if ps.Round == round { if ps.Round == round {
switch type_ { switch voteType {
case ttypes.VoteTypePrevote: case ttypes.VoteTypePrevote:
return ps.Prevotes return ps.Prevotes
case ttypes.VoteTypePrecommit: case ttypes.VoteTypePrecommit:
...@@ -1071,7 +1071,7 @@ func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *t ...@@ -1071,7 +1071,7 @@ func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *t
} }
} }
if ps.CatchupCommitRound == round { if ps.CatchupCommitRound == round {
switch type_ { switch voteType {
case ttypes.VoteTypePrevote: case ttypes.VoteTypePrevote:
return nil return nil
case ttypes.VoteTypePrecommit: case ttypes.VoteTypePrecommit:
...@@ -1079,7 +1079,7 @@ func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *t ...@@ -1079,7 +1079,7 @@ func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *t
} }
} }
if ps.ProposalPOLRound == round { if ps.ProposalPOLRound == round {
switch type_ { switch voteType {
case ttypes.VoteTypePrevote: case ttypes.VoteTypePrevote:
return ps.ProposalPOL return ps.ProposalPOL
case ttypes.VoteTypePrecommit: case ttypes.VoteTypePrecommit:
...@@ -1090,7 +1090,7 @@ func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *t ...@@ -1090,7 +1090,7 @@ func (ps *PeerConnState) getVoteBitArray(height int64, round int, type_ byte) *t
} }
if ps.Height == height+1 { if ps.Height == height+1 {
if ps.LastCommitRound == round { if ps.LastCommitRound == round {
switch type_ { switch voteType {
case ttypes.VoteTypePrevote: case ttypes.VoteTypePrevote:
return nil return nil
case ttypes.VoteTypePrecommit: case ttypes.VoteTypePrecommit:
...@@ -1127,7 +1127,7 @@ func (ps *PeerConnState) ensureCatchupCommitRound(height int64, round int, numVa ...@@ -1127,7 +1127,7 @@ func (ps *PeerConnState) ensureCatchupCommitRound(height int64, round int, numVa
} }
} }
// EnsureVoteVitArrays ensures the bit-arrays have been allocated for tracking // EnsureVoteBitArrays ensures the bit-arrays have been allocated for tracking
// what votes this peer has received. // what votes this peer has received.
// NOTE: It's important to make sure that numValidators actually matches // NOTE: It's important to make sure that numValidators actually matches
// what the node sees as the number of validators for height. // what the node sees as the number of validators for height.
...@@ -1166,14 +1166,14 @@ func (ps *PeerConnState) SetHasVote(vote *ttypes.Vote) { ...@@ -1166,14 +1166,14 @@ func (ps *PeerConnState) SetHasVote(vote *ttypes.Vote) {
ps.setHasVote(vote.Height, int(vote.Round), byte(vote.Type), int(vote.ValidatorIndex)) ps.setHasVote(vote.Height, int(vote.Round), byte(vote.Type), int(vote.ValidatorIndex))
} }
func (ps *PeerConnState) setHasVote(height int64, round int, type_ byte, index int) { func (ps *PeerConnState) setHasVote(height int64, round int, voteType byte, index int) {
// NOTE: some may be nil BitArrays -> no side effects. // NOTE: some may be nil BitArrays -> no side effects.
psVotes := ps.getVoteBitArray(height, round, type_) psVotes := ps.getVoteBitArray(height, round, voteType)
tendermintlog.Debug("setHasVote before", "height", height, "psVotes", psVotes.String(), "peerip", ps.ip.String()) tendermintlog.Debug("setHasVote before", "height", height, "psVotes", psVotes.String(), "peerip", ps.ip.String())
if psVotes != nil { if psVotes != nil {
psVotes.SetIndex(index, true) psVotes.SetIndex(index, true)
} }
tendermintlog.Debug("setHasVote after", "height", height, "index", index, "type", type_, "peerVotes", psVotes.String(), "peerip", ps.ip.String()) tendermintlog.Debug("setHasVote after", "height", height, "index", index, "type", voteType, "peerVotes", psVotes.String(), "peerip", ps.ip.String())
} }
// ApplyNewRoundStepMessage updates the peer state for the new round. // ApplyNewRoundStepMessage updates the peer state for the new round.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Uses nacl's secret_box to encrypt a net.Conn. // Package tendermint Uses nacl's secret_box to encrypt a net.Conn.
// It is (meant to be) an implementation of the STS protocol. // It is (meant to be) an implementation of the STS protocol.
// Note we do not (yet) assume that a remote peer's pubkey // Note we do not (yet) assume that a remote peer's pubkey
// is known ahead of time, and thus we are technically // is known ahead of time, and thus we are technically
...@@ -36,7 +36,7 @@ const ( ...@@ -36,7 +36,7 @@ const (
authSigMsgSize = (32) + (64) authSigMsgSize = (32) + (64)
) // fixed size (length prefixed) byte arrays ) // fixed size (length prefixed) byte arrays
// Implements net.Conn // SecretConnection Implements net.Conn
type SecretConnection struct { type SecretConnection struct {
conn io.ReadWriteCloser conn io.ReadWriteCloser
recvBuffer []byte recvBuffer []byte
...@@ -46,7 +46,7 @@ type SecretConnection struct { ...@@ -46,7 +46,7 @@ type SecretConnection struct {
shrSecret *[32]byte // shared secret shrSecret *[32]byte // shared secret
} }
// Performs handshake and returns a new authenticated SecretConnection. // MakeSecretConnection Performs handshake and returns a new authenticated SecretConnection.
// Returns nil if error in handshake. // Returns nil if error in handshake.
// Caller should call conn.Close() // Caller should call conn.Close()
// See docs/sts-final.pdf for more information. // See docs/sts-final.pdf for more information.
...@@ -108,7 +108,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (* ...@@ -108,7 +108,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (*
return sc, nil return sc, nil
} }
// Returns authenticated remote pubkey // RemotePubKey Returns authenticated remote pubkey
func (sc *SecretConnection) RemotePubKey() crypto.PubKey { func (sc *SecretConnection) RemotePubKey() crypto.PubKey {
return sc.remPubKey return sc.remPubKey
} }
...@@ -140,9 +140,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) { ...@@ -140,9 +140,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) {
_, err := sc.conn.Write(sealedFrame) _, err := sc.conn.Write(sealedFrame)
if err != nil { if err != nil {
return n, err return n, err
} else {
n += len(chunk)
} }
n += len(chunk)
} }
return return
} }
...@@ -150,8 +149,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) { ...@@ -150,8 +149,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) {
// CONTRACT: data smaller than dataMaxSize is read atomically. // CONTRACT: data smaller than dataMaxSize is read atomically.
func (sc *SecretConnection) Read(data []byte) (n int, err error) { func (sc *SecretConnection) Read(data []byte) (n int, err error) {
if 0 < len(sc.recvBuffer) { if 0 < len(sc.recvBuffer) {
n_ := copy(data, sc.recvBuffer) count := copy(data, sc.recvBuffer)
sc.recvBuffer = sc.recvBuffer[n_:] sc.recvBuffer = sc.recvBuffer[count:]
return return
} }
...@@ -182,14 +181,24 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) { ...@@ -182,14 +181,24 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) {
return return
} }
// Implements net.Conn // Close Implements net.Conn
func (sc *SecretConnection) Close() error { return sc.conn.Close() } func (sc *SecretConnection) Close() error { return sc.conn.Close() }
func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.(net.Conn).LocalAddr() }
func (sc *SecretConnection) RemoteAddr() net.Addr { return sc.conn.(net.Conn).RemoteAddr() } // LocalAddr ...
func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.(net.Conn).LocalAddr() }
// RemoteAddr ...
func (sc *SecretConnection) RemoteAddr() net.Addr { return sc.conn.(net.Conn).RemoteAddr() }
// SetDeadline ...
func (sc *SecretConnection) SetDeadline(t time.Time) error { return sc.conn.(net.Conn).SetDeadline(t) } func (sc *SecretConnection) SetDeadline(t time.Time) error { return sc.conn.(net.Conn).SetDeadline(t) }
// SetReadDeadline ...
func (sc *SecretConnection) SetReadDeadline(t time.Time) error { func (sc *SecretConnection) SetReadDeadline(t time.Time) error {
return sc.conn.(net.Conn).SetReadDeadline(t) return sc.conn.(net.Conn).SetReadDeadline(t)
} }
// SetWriteDeadline ...
func (sc *SecretConnection) SetWriteDeadline(t time.Time) error { func (sc *SecretConnection) SetWriteDeadline(t time.Time) error {
return sc.conn.(net.Conn).SetWriteDeadline(t) return sc.conn.(net.Conn).SetWriteDeadline(t)
} }
...@@ -343,7 +352,7 @@ func incr2Nonce(nonce *[24]byte) { ...@@ -343,7 +352,7 @@ func incr2Nonce(nonce *[24]byte) {
// increment nonce big-endian by 1 with wraparound. // increment nonce big-endian by 1 with wraparound.
func incrNonce(nonce *[24]byte) { func incrNonce(nonce *[24]byte) {
for i := 23; 0 <= i; i-- { for i := 23; 0 <= i; i-- {
nonce[i] += 1 nonce[i]++
if nonce[i] != 0 { if nonce[i] != 0 {
return return
} }
......
...@@ -204,14 +204,15 @@ func MakeGenesisState(genDoc *ttypes.GenesisDoc) (State, error) { ...@@ -204,14 +204,15 @@ func MakeGenesisState(genDoc *ttypes.GenesisDoc) (State, error) {
}, nil }, nil
} }
//-------------------stateDB------------------------ // CSStateDB just for EvidencePool and BlockExecutor
type CSStateDB struct { type CSStateDB struct {
client *TendermintClient client *Client
state State state State
mtx sync.Mutex mtx sync.Mutex
} }
func NewStateDB(client *TendermintClient, state State) *CSStateDB { // NewStateDB make a new one
func NewStateDB(client *Client, state State) *CSStateDB {
r = rand.New(rand.NewSource(time.Now().UnixNano())) r = rand.New(rand.NewSource(time.Now().UnixNano()))
return &CSStateDB{ return &CSStateDB{
client: client, client: client,
...@@ -219,6 +220,7 @@ func NewStateDB(client *TendermintClient, state State) *CSStateDB { ...@@ -219,6 +220,7 @@ func NewStateDB(client *TendermintClient, state State) *CSStateDB {
} }
} }
// LoadState convert external state to internal state
func LoadState(state *tmtypes.State) State { func LoadState(state *tmtypes.State) State {
stateTmp := State{ stateTmp := State{
ChainID: state.GetChainID(), ChainID: state.GetChainID(),
...@@ -286,18 +288,21 @@ func LoadState(state *tmtypes.State) State { ...@@ -286,18 +288,21 @@ func LoadState(state *tmtypes.State) State {
return stateTmp return stateTmp
} }
// SaveState to state cache
func (csdb *CSStateDB) SaveState(state State) { func (csdb *CSStateDB) SaveState(state State) {
csdb.mtx.Lock() csdb.mtx.Lock()
defer csdb.mtx.Unlock() defer csdb.mtx.Unlock()
csdb.state = state.Copy() csdb.state = state.Copy()
} }
// LoadState from state cache
func (csdb *CSStateDB) LoadState() State { func (csdb *CSStateDB) LoadState() State {
csdb.mtx.Lock() csdb.mtx.Lock()
defer csdb.mtx.Unlock() defer csdb.mtx.Unlock()
return csdb.state return csdb.state
} }
// LoadValidators by height
func (csdb *CSStateDB) LoadValidators(height int64) (*ttypes.ValidatorSet, error) { func (csdb *CSStateDB) LoadValidators(height int64) (*ttypes.ValidatorSet, error) {
if height == 0 { if height == 0 {
return nil, nil return nil, nil
...@@ -363,6 +368,7 @@ func saveProposer(dest *tmtypes.Validator, source *ttypes.Validator) { ...@@ -363,6 +368,7 @@ func saveProposer(dest *tmtypes.Validator, source *ttypes.Validator) {
} }
} }
// SaveState convert internal state to external state
func SaveState(state State) *tmtypes.State { func SaveState(state State) *tmtypes.State {
newState := tmtypes.State{ newState := tmtypes.State{
ChainID: state.ChainID, ChainID: state.ChainID,
...@@ -405,6 +411,7 @@ func getprivkey(key string) crypto.PrivKey { ...@@ -405,6 +411,7 @@ func getprivkey(key string) crypto.PrivKey {
return priv return priv
} }
// LoadValidators convert all external validators to internal validators
func LoadValidators(des []*ttypes.Validator, source []*tmtypes.Validator) { func LoadValidators(des []*ttypes.Validator, source []*tmtypes.Validator) {
for i, item := range source { for i, item := range source {
if item.GetAddress() == nil || len(item.GetAddress()) == 0 { if item.GetAddress() == nil || len(item.GetAddress()) == 0 {
...@@ -427,6 +434,7 @@ func LoadValidators(des []*ttypes.Validator, source []*tmtypes.Validator) { ...@@ -427,6 +434,7 @@ func LoadValidators(des []*ttypes.Validator, source []*tmtypes.Validator) {
} }
} }
// LoadProposer convert external proposer to internal proposer
func LoadProposer(source *tmtypes.Validator) (*ttypes.Validator, error) { func LoadProposer(source *tmtypes.Validator) (*ttypes.Validator, error) {
if source.GetAddress() == nil || len(source.GetAddress()) == 0 { if source.GetAddress() == nil || len(source.GetAddress()) == 0 {
tendermintlog.Warn("LoadProposer get address is nil or empty") tendermintlog.Warn("LoadProposer get address is nil or empty")
...@@ -449,6 +457,7 @@ func LoadProposer(source *tmtypes.Validator) (*ttypes.Validator, error) { ...@@ -449,6 +457,7 @@ func LoadProposer(source *tmtypes.Validator) (*ttypes.Validator, error) {
return des, nil return des, nil
} }
// CreateBlockInfoTx make blockInfo to the first transaction of the block and execer is valnode
func CreateBlockInfoTx(pubkey string, lastCommit *tmtypes.TendermintCommit, seenCommit *tmtypes.TendermintCommit, state *tmtypes.State, proposal *tmtypes.Proposal, block *tmtypes.TendermintBlock) *types.Transaction { func CreateBlockInfoTx(pubkey string, lastCommit *tmtypes.TendermintCommit, seenCommit *tmtypes.TendermintCommit, state *tmtypes.State, proposal *tmtypes.Proposal, block *tmtypes.TendermintBlock) *types.Transaction {
blockNoTxs := *block blockNoTxs := *block
blockNoTxs.Txs = make([]*types.Transaction, 0) blockNoTxs.Txs = make([]*types.Transaction, 0)
......
...@@ -22,7 +22,7 @@ import ( ...@@ -22,7 +22,7 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
) )
const tendermint_version = "0.1.0" const tendermintVersion = "0.1.0"
var ( var (
tendermintlog = log15.New("module", "tendermint") tendermintlog = log15.New("module", "tendermint")
...@@ -36,9 +36,9 @@ var ( ...@@ -36,9 +36,9 @@ var (
timeoutPrecommit int32 = 1000 timeoutPrecommit int32 = 1000
timeoutPrecommitDelta int32 = 500 timeoutPrecommitDelta int32 = 500
timeoutCommit int32 = 1000 timeoutCommit int32 = 1000
skipTimeoutCommit bool = false skipTimeoutCommit = false
createEmptyBlocks bool = false createEmptyBlocks = false
createEmptyBlocksInterval int32 = 0 // second createEmptyBlocksInterval int32 // second
validatorNodes = []string{"127.0.0.1:46656"} validatorNodes = []string{"127.0.0.1:46656"}
peerGossipSleepDuration int32 = 100 peerGossipSleepDuration int32 = 100
peerQueryMaj23SleepDuration int32 = 2000 peerQueryMaj23SleepDuration int32 = 2000
...@@ -47,10 +47,11 @@ var ( ...@@ -47,10 +47,11 @@ var (
func init() { func init() {
drivers.Reg("tendermint", New) drivers.Reg("tendermint", New)
drivers.QueryData.Register("tendermint", &TendermintClient{}) drivers.QueryData.Register("tendermint", &Client{})
} }
type TendermintClient struct { // Client Tendermint implementation
type Client struct {
//config //config
*drivers.BaseClient *drivers.BaseClient
genesisDoc *ttypes.GenesisDoc // initial validator set genesisDoc *ttypes.GenesisDoc // initial validator set
...@@ -82,7 +83,7 @@ type subConfig struct { ...@@ -82,7 +83,7 @@ type subConfig struct {
ValidatorNodes []string `json:"validatorNodes"` ValidatorNodes []string `json:"validatorNodes"`
} }
func (client *TendermintClient) applyConfig(sub []byte) { func (client *Client) applyConfig(sub []byte) {
var subcfg subConfig var subcfg subConfig
if sub != nil { if sub != nil {
types.MustDecode(sub, &subcfg) types.MustDecode(sub, &subcfg)
...@@ -133,6 +134,7 @@ func DefaultDBProvider(ID string) (dbm.DB, error) { ...@@ -133,6 +134,7 @@ func DefaultDBProvider(ID string) (dbm.DB, error) {
return dbm.NewDB(ID, "leveldb", "./datadir", 0), nil return dbm.NewDB(ID, "leveldb", "./datadir", 0), nil
} }
// New ...
func New(cfg *types.Consensus, sub []byte) queue.Module { func New(cfg *types.Consensus, sub []byte) queue.Module {
tendermintlog.Info("Start to create tendermint client") tendermintlog.Info("Start to create tendermint client")
//init rand //init rand
...@@ -175,7 +177,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -175,7 +177,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
pubkey := privValidator.GetPubKey().KeyString() pubkey := privValidator.GetPubKey().KeyString()
c := drivers.NewBaseClient(cfg) c := drivers.NewBaseClient(cfg)
client := &TendermintClient{ client := &Client{
BaseClient: c, BaseClient: c,
genesisDoc: genDoc, genesisDoc: genDoc,
privValidator: privValidator, privValidator: privValidator,
...@@ -194,21 +196,24 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -194,21 +196,24 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
// PrivValidator returns the Node's PrivValidator. // PrivValidator returns the Node's PrivValidator.
// XXX: for convenience only! // XXX: for convenience only!
func (client *TendermintClient) PrivValidator() ttypes.PrivValidator { func (client *Client) PrivValidator() ttypes.PrivValidator {
return client.privValidator return client.privValidator
} }
// GenesisDoc returns the Node's GenesisDoc. // GenesisDoc returns the Node's GenesisDoc.
func (client *TendermintClient) GenesisDoc() *ttypes.GenesisDoc { func (client *Client) GenesisDoc() *ttypes.GenesisDoc {
return client.genesisDoc return client.genesisDoc
} }
func (client *TendermintClient) Close() { // Close TODO:may need optimize
func (client *Client) Close() {
client.node.Stop()
client.stopC <- struct{}{} client.stopC <- struct{}{}
tendermintlog.Info("consensus tendermint closed") tendermintlog.Info("consensus tendermint closed")
} }
func (client *TendermintClient) SetQueueClient(q queue.Client) { // SetQueueClient ...
func (client *Client) SetQueueClient(q queue.Client) {
client.InitClient(q, func() { client.InitClient(q, func() {
//call init block //call init block
client.InitBlock() client.InitBlock()
...@@ -218,14 +223,16 @@ func (client *TendermintClient) SetQueueClient(q queue.Client) { ...@@ -218,14 +223,16 @@ func (client *TendermintClient) SetQueueClient(q queue.Client) {
go client.StartConsensus() go client.StartConsensus()
} }
const DEBUG_CATCHUP = false // DebugCatchup define whether catch up now
const DebugCatchup = false
func (client *TendermintClient) StartConsensus() { // StartConsensus a routine that make the consensus start
func (client *Client) StartConsensus() {
//进入共识前先同步到最大高度 //进入共识前先同步到最大高度
hint := time.NewTicker(5 * time.Second) hint := time.NewTicker(5 * time.Second)
beg := time.Now() beg := time.Now()
OuterLoop: OuterLoop:
for !DEBUG_CATCHUP { for !DebugCatchup {
select { select {
case <-hint.C: case <-hint.C:
tendermintlog.Info("Still catching up max height......", "Height", client.GetCurrentHeight(), "cost", time.Since(beg)) tendermintlog.Info("Still catching up max height......", "Height", client.GetCurrentHeight(), "cost", time.Since(beg))
...@@ -320,7 +327,7 @@ OuterLoop: ...@@ -320,7 +327,7 @@ OuterLoop:
// Create & add listener // Create & add listener
protocol, listeningAddress := "tcp", "0.0.0.0:46656" protocol, listeningAddress := "tcp", "0.0.0.0:46656"
node := NewNode(validatorNodes, protocol, listeningAddress, client.privKey, state.ChainID, tendermint_version, csState, evidencePool) node := NewNode(validatorNodes, protocol, listeningAddress, client.privKey, state.ChainID, tendermintVersion, csState, evidencePool)
client.node = node client.node = node
node.Start() node.Start()
...@@ -328,11 +335,13 @@ OuterLoop: ...@@ -328,11 +335,13 @@ OuterLoop:
go client.CreateBlock() go client.CreateBlock()
} }
func (client *TendermintClient) GetGenesisBlockTime() int64 { // GetGenesisBlockTime ...
func (client *Client) GetGenesisBlockTime() int64 {
return genesisBlockTime return genesisBlockTime
} }
func (client *TendermintClient) CreateGenesisTx() (ret []*types.Transaction) { // CreateGenesisTx ...
func (client *Client) CreateGenesisTx() (ret []*types.Transaction) {
var tx types.Transaction var tx types.Transaction
tx.Execer = []byte("coins") tx.Execer = []byte("coins")
tx.To = genesis tx.To = genesis
...@@ -345,16 +354,18 @@ func (client *TendermintClient) CreateGenesisTx() (ret []*types.Transaction) { ...@@ -345,16 +354,18 @@ func (client *TendermintClient) CreateGenesisTx() (ret []*types.Transaction) {
return return
} }
//暂不检查任何的交易 // CheckBlock 暂不检查任何的交易
func (client *TendermintClient) CheckBlock(parent *types.Block, current *types.BlockDetail) error { func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
return nil return nil
} }
func (client *TendermintClient) ProcEvent(msg queue.Message) bool { // ProcEvent ...
func (client *Client) ProcEvent(msg queue.Message) bool {
return false return false
} }
func (client *TendermintClient) CreateBlock() { // CreateBlock a routine monitor whether some transactions available and tell client by available channel
func (client *Client) CreateBlock() {
issleep := true issleep := true
for { for {
...@@ -378,21 +389,25 @@ func (client *TendermintClient) CreateBlock() { ...@@ -378,21 +389,25 @@ func (client *TendermintClient) CreateBlock() {
} }
} }
func (client *TendermintClient) TxsAvailable() <-chan int64 { // TxsAvailable check available channel
func (client *Client) TxsAvailable() <-chan int64 {
return client.txsAvailable return client.txsAvailable
} }
func (client *TendermintClient) StopC() <-chan struct{} { // StopC stop client
func (client *Client) StopC() <-chan struct{} {
return client.stopC return client.stopC
} }
func (client *TendermintClient) CheckTxsAvailable() bool { // CheckTxsAvailable check whether some new transactions arriving
func (client *Client) CheckTxsAvailable() bool {
txs := client.RequestTx(10, nil) txs := client.RequestTx(10, nil)
txs = client.CheckTxDup(txs, client.GetCurrentHeight()) txs = client.CheckTxDup(txs, client.GetCurrentHeight())
return len(txs) != 0 return len(txs) != 0
} }
func (client *TendermintClient) CheckTxDup(txs []*types.Transaction, height int64) (transactions []*types.Transaction) { // CheckTxDup check transactions that duplicate
func (client *Client) CheckTxDup(txs []*types.Transaction, height int64) (transactions []*types.Transaction) {
cacheTxs := types.TxsToCache(txs) cacheTxs := types.TxsToCache(txs)
var err error var err error
cacheTxs, err = util.CheckTxDup(client.GetQueueClient(), cacheTxs, height) cacheTxs, err = util.CheckTxDup(client.GetQueueClient(), cacheTxs, height)
...@@ -402,7 +417,8 @@ func (client *TendermintClient) CheckTxDup(txs []*types.Transaction, height int6 ...@@ -402,7 +417,8 @@ func (client *TendermintClient) CheckTxDup(txs []*types.Transaction, height int6
return types.CacheToTxs(cacheTxs) return types.CacheToTxs(cacheTxs)
} }
func (client *TendermintClient) BuildBlock() *types.Block { // BuildBlock build a new block contains some transactions
func (client *Client) BuildBlock() *types.Block {
lastHeight := client.GetCurrentHeight() lastHeight := client.GetCurrentHeight()
txs := client.RequestTx(int(types.GetP(lastHeight+1).MaxTxNumber)-1, nil) txs := client.RequestTx(int(types.GetP(lastHeight+1).MaxTxNumber)-1, nil)
newblock := &types.Block{} newblock := &types.Block{}
...@@ -411,7 +427,8 @@ func (client *TendermintClient) BuildBlock() *types.Block { ...@@ -411,7 +427,8 @@ func (client *TendermintClient) BuildBlock() *types.Block {
return newblock return newblock
} }
func (client *TendermintClient) CommitBlock(propBlock *types.Block) error { // CommitBlock call WriteBlock to real commit to chain
func (client *Client) CommitBlock(propBlock *types.Block) error {
newblock := *propBlock newblock := *propBlock
lastBlock, err := client.RequestBlock(newblock.Height - 1) lastBlock, err := client.RequestBlock(newblock.Height - 1)
if err != nil { if err != nil {
...@@ -438,7 +455,8 @@ func (client *TendermintClient) CommitBlock(propBlock *types.Block) error { ...@@ -438,7 +455,8 @@ func (client *TendermintClient) CommitBlock(propBlock *types.Block) error {
return nil return nil
} }
func (client *TendermintClient) CheckCommit(height int64) bool { // CheckCommit by height
func (client *Client) CheckCommit(height int64) bool {
retry := 0 retry := 0
newHeight := int64(1) newHeight := int64(1)
for { for {
...@@ -456,7 +474,8 @@ func (client *TendermintClient) CheckCommit(height int64) bool { ...@@ -456,7 +474,8 @@ func (client *TendermintClient) CheckCommit(height int64) bool {
} }
} }
func (client *TendermintClient) QueryValidatorsByHeight(height int64) (*tmtypes.ValNodes, error) { // QueryValidatorsByHeight ...
func (client *Client) QueryValidatorsByHeight(height int64) (*tmtypes.ValNodes, error) {
if height <= 0 { if height <= 0 {
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
...@@ -476,7 +495,8 @@ func (client *TendermintClient) QueryValidatorsByHeight(height int64) (*tmtypes. ...@@ -476,7 +495,8 @@ func (client *TendermintClient) QueryValidatorsByHeight(height int64) (*tmtypes.
return msg.GetData().(types.Message).(*tmtypes.ValNodes), nil return msg.GetData().(types.Message).(*tmtypes.ValNodes), nil
} }
func (client *TendermintClient) QueryBlockInfoByHeight(height int64) (*tmtypes.TendermintBlockInfo, error) { // QueryBlockInfoByHeight ...
func (client *Client) QueryBlockInfoByHeight(height int64) (*tmtypes.TendermintBlockInfo, error) {
if height <= 0 { if height <= 0 {
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
...@@ -496,7 +516,8 @@ func (client *TendermintClient) QueryBlockInfoByHeight(height int64) (*tmtypes.T ...@@ -496,7 +516,8 @@ func (client *TendermintClient) QueryBlockInfoByHeight(height int64) (*tmtypes.T
return msg.GetData().(types.Message).(*tmtypes.TendermintBlockInfo), nil return msg.GetData().(types.Message).(*tmtypes.TendermintBlockInfo), nil
} }
func (client *TendermintClient) LoadSeenCommit(height int64) *tmtypes.TendermintCommit { // LoadSeenCommit by height
func (client *Client) LoadSeenCommit(height int64) *tmtypes.TendermintCommit {
blockInfo, err := client.QueryBlockInfoByHeight(height) blockInfo, err := client.QueryBlockInfoByHeight(height)
if err != nil { if err != nil {
panic(fmt.Sprintf("LoadSeenCommit GetBlockInfo failed:%v", err)) panic(fmt.Sprintf("LoadSeenCommit GetBlockInfo failed:%v", err))
...@@ -508,7 +529,8 @@ func (client *TendermintClient) LoadSeenCommit(height int64) *tmtypes.Tendermint ...@@ -508,7 +529,8 @@ func (client *TendermintClient) LoadSeenCommit(height int64) *tmtypes.Tendermint
return blockInfo.GetSeenCommit() return blockInfo.GetSeenCommit()
} }
func (client *TendermintClient) LoadBlockCommit(height int64) *tmtypes.TendermintCommit { // LoadBlockCommit by height
func (client *Client) LoadBlockCommit(height int64) *tmtypes.TendermintCommit {
blockInfo, err := client.QueryBlockInfoByHeight(height) blockInfo, err := client.QueryBlockInfoByHeight(height)
if err != nil { if err != nil {
panic(fmt.Sprintf("LoadBlockCommit GetBlockInfo failed:%v", err)) panic(fmt.Sprintf("LoadBlockCommit GetBlockInfo failed:%v", err))
...@@ -520,7 +542,8 @@ func (client *TendermintClient) LoadBlockCommit(height int64) *tmtypes.Tendermin ...@@ -520,7 +542,8 @@ func (client *TendermintClient) LoadBlockCommit(height int64) *tmtypes.Tendermin
return blockInfo.GetLastCommit() return blockInfo.GetLastCommit()
} }
func (client *TendermintClient) LoadProposalBlock(height int64) *tmtypes.TendermintBlock { // LoadProposalBlock by height
func (client *Client) LoadProposalBlock(height int64) *tmtypes.TendermintBlock {
block, err := client.RequestBlock(height) block, err := client.RequestBlock(height)
if err != nil { if err != nil {
tendermintlog.Error("LoadProposal by height failed", "curHeight", client.GetCurrentHeight(), "requestHeight", height, "error", err) tendermintlog.Error("LoadProposal by height failed", "curHeight", client.GetCurrentHeight(), "requestHeight", height, "error", err)
......
...@@ -36,7 +36,7 @@ import ( ...@@ -36,7 +36,7 @@ import (
var ( var (
random *rand.Rand random *rand.Rand
loopCount int = 10 loopCount = 10
conn *grpc.ClientConn conn *grpc.ClientConn
c types.Chain33Client c types.Chain33Client
) )
......
...@@ -29,7 +29,9 @@ const fee = 1e6 ...@@ -29,7 +29,9 @@ const fee = 1e6
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var r *rand.Rand var r *rand.Rand
var TxHeightOffset int64 = 0
// TxHeightOffset needed
var TxHeightOffset int64
func main() { func main() {
if len(os.Args) == 1 || os.Args[1] == "-h" { if len(os.Args) == 1 || os.Args[1] == "-h" {
...@@ -69,6 +71,7 @@ func main() { ...@@ -69,6 +71,7 @@ func main() {
} }
} }
// LoadHelp ...
func LoadHelp() { func LoadHelp() {
fmt.Println("Available Commands:") fmt.Println("Available Commands:")
fmt.Println("perf [ip, size, num, interval, duration] {offset} : 写数据性能测试") fmt.Println("perf [ip, size, num, interval, duration] {offset} : 写数据性能测试")
...@@ -77,6 +80,7 @@ func LoadHelp() { ...@@ -77,6 +80,7 @@ func LoadHelp() {
fmt.Println("valnode [ip, pubkey, power] : 增加/删除/修改tendermint节点") fmt.Println("valnode [ip, pubkey, power] : 增加/删除/修改tendermint节点")
} }
// Perf ...
func Perf(ip, size, num, interval, duration string) { func Perf(ip, size, num, interval, duration string) {
var numThread int var numThread int
numInt, err := strconv.Atoi(num) numInt, err := strconv.Atoi(num)
...@@ -128,6 +132,7 @@ func Perf(ip, size, num, interval, duration string) { ...@@ -128,6 +132,7 @@ func Perf(ip, size, num, interval, duration string) {
} }
} }
// Put ...
func Put(ip string, size string, privkey string) { func Put(ip string, size string, privkey string) {
sizeInt, err := strconv.Atoi(size) sizeInt, err := strconv.Atoi(size)
if err != nil { if err != nil {
...@@ -164,6 +169,7 @@ func Put(ip string, size string, privkey string) { ...@@ -164,6 +169,7 @@ func Put(ip string, size string, privkey string) {
fmt.Printf("returned JSON: %s\n", string(b)) fmt.Printf("returned JSON: %s\n", string(b))
} }
// Get ...
func Get(ip string, hash string) { func Get(ip string, hash string) {
url := "http://" + ip + ":8801" url := "http://" + ip + ":8801"
fmt.Println("transaction hash:", hash) fmt.Println("transaction hash:", hash)
...@@ -209,8 +215,9 @@ func setTxHeight(ip string) { ...@@ -209,8 +215,9 @@ func setTxHeight(ip string) {
fmt.Println("TxHeightOffset:", TxHeightOffset) fmt.Println("TxHeightOffset:", TxHeightOffset)
} }
// RespMsg ...
type RespMsg struct { type RespMsg struct {
Id int64 `json:"id"` ID int64 `json:"id"`
Result rpctypes.Header `json:"result"` Result rpctypes.Header `json:"result"`
Err string `json:"error"` Err string `json:"error"`
} }
...@@ -245,6 +252,7 @@ func genaddress() (string, crypto.PrivKey) { ...@@ -245,6 +252,7 @@ func genaddress() (string, crypto.PrivKey) {
return addrto.String(), privto return addrto.String(), privto
} }
// RandStringBytes ...
func RandStringBytes(n int) string { func RandStringBytes(n int) string {
b := make([]byte, n) b := make([]byte, n)
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
...@@ -254,6 +262,7 @@ func RandStringBytes(n int) string { ...@@ -254,6 +262,7 @@ func RandStringBytes(n int) string {
return string(b) return string(b)
} }
// ValNode ...
func ValNode(ip, pubkey, power string) { func ValNode(ip, pubkey, power string) {
url := "http://" + ip + ":8801" url := "http://" + ip + ":8801"
......
...@@ -21,12 +21,12 @@ import ( ...@@ -21,12 +21,12 @@ import (
) )
var ( var (
blocklog = log15.New("module", "tendermint-block") blocklog = log15.New("module", "tendermint-block")
// ConsensusCrypto define
ConsensusCrypto crypto.Crypto ConsensusCrypto crypto.Crypto
) )
//----------------------------------------------------------------------------- // BlockID struct
//BlockID
type BlockID struct { type BlockID struct {
tmtypes.BlockID tmtypes.BlockID
} }
...@@ -51,8 +51,7 @@ func (blockID BlockID) String() string { ...@@ -51,8 +51,7 @@ func (blockID BlockID) String() string {
return Fmt(`%v`, blockID.Hash) return Fmt(`%v`, blockID.Hash)
} }
//----------------------------------------------------------------------------- //TendermintBlock struct
//TendermintBlock
type TendermintBlock struct { type TendermintBlock struct {
*tmtypes.TendermintBlock *tmtypes.TendermintBlock
} }
...@@ -186,12 +185,10 @@ func (b *TendermintBlock) StringIndented(indent string) string { ...@@ -186,12 +185,10 @@ func (b *TendermintBlock) StringIndented(indent string) string {
func (b *TendermintBlock) StringShort() string { func (b *TendermintBlock) StringShort() string {
if b == nil { if b == nil {
return "nil-Block" return "nil-Block"
} else {
return Fmt("Block#%v", b.Hash())
} }
return Fmt("Block#%v", b.Hash())
} }
//-----------------------------------------------------------------------------
// Header defines the structure of a Tendermint block header // Header defines the structure of a Tendermint block header
// TODO: limit header size // TODO: limit header size
// NOTE: changes to the Header should be duplicated in the abci Header // NOTE: changes to the Header should be duplicated in the abci Header
...@@ -247,8 +244,7 @@ func (h *Header) StringIndented(indent string) string { ...@@ -247,8 +244,7 @@ func (h *Header) StringIndented(indent string) string {
indent, h.Hash()) indent, h.Hash())
} }
//----------------------------------------------------------------------------- // Commit struct
//Commit
type Commit struct { type Commit struct {
*tmtypes.TendermintCommit *tmtypes.TendermintCommit
...@@ -393,21 +389,21 @@ func (commit *Commit) StringIndented(indent string) string { ...@@ -393,21 +389,21 @@ func (commit *Commit) StringIndented(indent string) string {
indent, commit.hash) indent, commit.hash)
} }
//-----------------------------------------------------------------------------
// SignedHeader is a header along with the commits that prove it // SignedHeader is a header along with the commits that prove it
type SignedHeader struct { type SignedHeader struct {
Header *Header `json:"header"` Header *Header `json:"header"`
Commit *Commit `json:"commit"` Commit *Commit `json:"commit"`
} }
//----------------------------------------------------------------------------- // EvidenceEnvelope ...
type EvidenceEnvelope struct { type EvidenceEnvelope struct {
*tmtypes.EvidenceEnvelope *tmtypes.EvidenceEnvelope
} }
// EvidenceData contains any evidence of malicious wrong-doing by validators // EvidenceEnvelopeList contains any evidence of malicious wrong-doing by validators
type EvidenceEnvelopeList []EvidenceEnvelope type EvidenceEnvelopeList []EvidenceEnvelope
// Hash ...
func (env EvidenceEnvelope) Hash() []byte { func (env EvidenceEnvelope) Hash() []byte {
penv := env.EvidenceEnvelope penv := env.EvidenceEnvelope
evidence := EvidenceEnvelope2Evidence(penv) evidence := EvidenceEnvelope2Evidence(penv)
...@@ -464,6 +460,7 @@ func (evl EvidenceEnvelopeList) Has(evidence Evidence) bool { ...@@ -464,6 +460,7 @@ func (evl EvidenceEnvelopeList) Has(evidence Evidence) bool {
return false return false
} }
// EvidenceData ...
type EvidenceData struct { type EvidenceData struct {
*tmtypes.EvidenceData *tmtypes.EvidenceData
hash []byte hash []byte
......
...@@ -23,6 +23,7 @@ type ErrEvidenceInvalid struct { ...@@ -23,6 +23,7 @@ type ErrEvidenceInvalid struct {
ErrorValue error ErrorValue error
} }
// NewEvidenceInvalidErr ...
func NewEvidenceInvalidErr(ev Evidence, err error) *ErrEvidenceInvalid { func NewEvidenceInvalidErr(ev Evidence, err error) *ErrEvidenceInvalid {
return &ErrEvidenceInvalid{ev, err} return &ErrEvidenceInvalid{ev, err}
} }
...@@ -39,8 +40,11 @@ const ( ...@@ -39,8 +40,11 @@ const (
MockBad = "MockBad" MockBad = "MockBad"
) )
var EvidenceType2Type map[string]reflect.Type // EvidenceType map define
var EvidenceType2Obj map[string]Evidence var (
EvidenceType2Type map[string]reflect.Type
EvidenceType2Obj map[string]Evidence
)
// Evidence represents any provable malicious activity by a validator // Evidence represents any provable malicious activity by a validator
type Evidence interface { type Evidence interface {
...@@ -205,22 +209,27 @@ func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool { ...@@ -205,22 +209,27 @@ func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool {
return bytes.Equal(SimpleHashFromBinary(dve), SimpleHashFromBinary(ev.(*DuplicateVoteEvidence))) return bytes.Equal(SimpleHashFromBinary(dve), SimpleHashFromBinary(ev.(*DuplicateVoteEvidence)))
} }
// TypeName ...
func (dve *DuplicateVoteEvidence) TypeName() string { func (dve *DuplicateVoteEvidence) TypeName() string {
return DuplicateVote return DuplicateVote
} }
// Copy ...
func (dve *DuplicateVoteEvidence) Copy() Evidence { func (dve *DuplicateVoteEvidence) Copy() Evidence {
return &DuplicateVoteEvidence{} return &DuplicateVoteEvidence{}
} }
// SetChild ...
func (dve *DuplicateVoteEvidence) SetChild(child proto.Message) { func (dve *DuplicateVoteEvidence) SetChild(child proto.Message) {
dve.DuplicateVoteEvidence = child.(*tmtypes.DuplicateVoteEvidence) dve.DuplicateVoteEvidence = child.(*tmtypes.DuplicateVoteEvidence)
} }
// Child ...
func (dve *DuplicateVoteEvidence) Child() proto.Message { func (dve *DuplicateVoteEvidence) Child() proto.Message {
return dve.DuplicateVoteEvidence return dve.DuplicateVoteEvidence
} }
// SimpleHashFromBinary ...
func SimpleHashFromBinary(item *DuplicateVoteEvidence) []byte { func SimpleHashFromBinary(item *DuplicateVoteEvidence) []byte {
bytes, e := json.Marshal(item) bytes, e := json.Marshal(item)
if e != nil { if e != nil {
...@@ -231,6 +240,7 @@ func SimpleHashFromBinary(item *DuplicateVoteEvidence) []byte { ...@@ -231,6 +240,7 @@ func SimpleHashFromBinary(item *DuplicateVoteEvidence) []byte {
} }
// EvidenceEnvelope2Evidence ...
func EvidenceEnvelope2Evidence(envelope *tmtypes.EvidenceEnvelope) Evidence { func EvidenceEnvelope2Evidence(envelope *tmtypes.EvidenceEnvelope) Evidence {
if v, ok := EvidenceType2Type[envelope.TypeName]; ok { if v, ok := EvidenceType2Type[envelope.TypeName]; ok {
realMsg2 := reflect.New(v).Interface() realMsg2 := reflect.New(v).Interface()
...@@ -247,69 +257,98 @@ func EvidenceEnvelope2Evidence(envelope *tmtypes.EvidenceEnvelope) Evidence { ...@@ -247,69 +257,98 @@ func EvidenceEnvelope2Evidence(envelope *tmtypes.EvidenceEnvelope) Evidence {
return nil return nil
} }
//----------------------------------------------------------------- // MockGoodEvidence UNSTABLE
// UNSTABLE
type MockGoodEvidence struct { type MockGoodEvidence struct {
Height_ int64 MGHeight int64
Address_ []byte MGAddress []byte
Index_ int MGIndex int
} }
// UNSTABLE // NewMockGoodEvidence UNSTABLE
func NewMockGoodEvidence(height int64, index int, address []byte) MockGoodEvidence { func NewMockGoodEvidence(height int64, index int, address []byte) MockGoodEvidence {
return MockGoodEvidence{height, address, index} return MockGoodEvidence{height, address, index}
} }
func (e MockGoodEvidence) Height() int64 { return e.Height_ } // Height ...
func (e MockGoodEvidence) Address() []byte { return e.Address_ } func (e MockGoodEvidence) Height() int64 { return e.MGHeight }
func (e MockGoodEvidence) Index() int { return e.Index_ }
// Address ...
func (e MockGoodEvidence) Address() []byte { return e.MGAddress }
// Index ...
func (e MockGoodEvidence) Index() int { return e.MGIndex }
// Hash ...
func (e MockGoodEvidence) Hash() []byte { func (e MockGoodEvidence) Hash() []byte {
return []byte(Fmt("%d-%d", e.Height_, e.Index_)) return []byte(Fmt("%d-%d", e.MGHeight, e.MGIndex))
} }
// Verify ...
func (e MockGoodEvidence) Verify(chainID string) error { return nil } func (e MockGoodEvidence) Verify(chainID string) error { return nil }
// Equal ...
func (e MockGoodEvidence) Equal(ev Evidence) bool { func (e MockGoodEvidence) Equal(ev Evidence) bool {
e2 := ev.(MockGoodEvidence) e2 := ev.(MockGoodEvidence)
return e.Height_ == e2.Height_ && return e.MGHeight == e2.MGHeight &&
bytes.Equal(e.Address_, e2.Address_) && bytes.Equal(e.MGAddress, e2.MGAddress) &&
e.Index_ == e2.Index_ e.MGIndex == e2.MGIndex
} }
func (e MockGoodEvidence) String() string { func (e MockGoodEvidence) String() string {
return Fmt("GoodEvidence: %d/%s/%d", e.Height_, e.Address_, e.Index_) return Fmt("GoodEvidence: %d/%s/%d", e.MGHeight, e.MGAddress, e.MGIndex)
} }
// TypeName ...
func (e MockGoodEvidence) TypeName() string { func (e MockGoodEvidence) TypeName() string {
return MockGood return MockGood
} }
// Copy ...
func (e MockGoodEvidence) Copy() Evidence { func (e MockGoodEvidence) Copy() Evidence {
return &MockGoodEvidence{} return &MockGoodEvidence{}
} }
// SetChild ...
func (e MockGoodEvidence) SetChild(proto.Message) {} func (e MockGoodEvidence) SetChild(proto.Message) {}
// Child ...
func (e MockGoodEvidence) Child() proto.Message { func (e MockGoodEvidence) Child() proto.Message {
return nil return nil
} }
// UNSTABLE // MockBadEvidence UNSTABLE
type MockBadEvidence struct { type MockBadEvidence struct {
MockGoodEvidence MockGoodEvidence
} }
// Verify ...
func (e MockBadEvidence) Verify(chainID string) error { return fmt.Errorf("MockBadEvidence") } func (e MockBadEvidence) Verify(chainID string) error { return fmt.Errorf("MockBadEvidence") }
// Equal ...
func (e MockBadEvidence) Equal(ev Evidence) bool { func (e MockBadEvidence) Equal(ev Evidence) bool {
e2 := ev.(MockBadEvidence) e2 := ev.(MockBadEvidence)
return e.Height_ == e2.Height_ && return e.MGHeight == e2.MGHeight &&
bytes.Equal(e.Address_, e2.Address_) && bytes.Equal(e.MGAddress, e2.MGAddress) &&
e.Index_ == e2.Index_ e.MGIndex == e2.MGIndex
} }
func (e MockBadEvidence) String() string { func (e MockBadEvidence) String() string {
return Fmt("BadEvidence: %d/%s/%d", e.Height_, e.Address_, e.Index_) return Fmt("BadEvidence: %d/%s/%d", e.MGHeight, e.MGAddress, e.MGIndex)
} }
// TypeName ...
func (e MockBadEvidence) TypeName() string { func (e MockBadEvidence) TypeName() string {
return MockBad return MockBad
} }
// Copy ...
func (e MockBadEvidence) Copy() Evidence { func (e MockBadEvidence) Copy() Evidence {
return &MockBadEvidence{} return &MockBadEvidence{}
} }
// SetChild ...
func (e MockBadEvidence) SetChild(proto.Message) {} func (e MockBadEvidence) SetChild(proto.Message) {}
// Child ...
func (e MockBadEvidence) Child() proto.Message { func (e MockBadEvidence) Child() proto.Message {
return nil return nil
} }
...@@ -325,11 +364,16 @@ type EvidencePool interface { ...@@ -325,11 +364,16 @@ type EvidencePool interface {
Update(*TendermintBlock) Update(*TendermintBlock)
} }
// MockMempool is an empty implementation of a Mempool, useful for testing. // MockEvidencePool is an empty implementation of a Mempool, useful for testing.
// UNSTABLE // UNSTABLE
type MockEvidencePool struct { type MockEvidencePool struct {
} }
// PendingEvidence ...
func (m MockEvidencePool) PendingEvidence() []Evidence { return nil } func (m MockEvidencePool) PendingEvidence() []Evidence { return nil }
func (m MockEvidencePool) AddEvidence(Evidence) error { return nil }
func (m MockEvidencePool) Update(*TendermintBlock) {} // AddEvidence ...
func (m MockEvidencePool) AddEvidence(Evidence) error { return nil }
// Update ...
func (m MockEvidencePool) Update(*TendermintBlock) {}
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types" tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
// RoundVoteSet ...
type RoundVoteSet struct { type RoundVoteSet struct {
Prevotes *VoteSet Prevotes *VoteSet
Precommits *VoteSet Precommits *VoteSet
...@@ -31,6 +32,8 @@ peer to prevent abuse. ...@@ -31,6 +32,8 @@ peer to prevent abuse.
We let each peer provide us with up to 2 unexpected "catchup" rounds. We let each peer provide us with up to 2 unexpected "catchup" rounds.
One for their LastCommit round, and another for the official commit round. One for their LastCommit round, and another for the official commit round.
*/ */
// HeightVoteSet ...
type HeightVoteSet struct { type HeightVoteSet struct {
chainID string chainID string
height int64 height int64
...@@ -42,6 +45,7 @@ type HeightVoteSet struct { ...@@ -42,6 +45,7 @@ type HeightVoteSet struct {
peerCatchupRounds map[string][]int // keys: peer.Key; values: at most 2 rounds peerCatchupRounds map[string][]int // keys: peer.Key; values: at most 2 rounds
} }
// NewHeightVoteSet ...
func NewHeightVoteSet(chainID string, height int64, valSet *ValidatorSet) *HeightVoteSet { func NewHeightVoteSet(chainID string, height int64, valSet *ValidatorSet) *HeightVoteSet {
hvs := &HeightVoteSet{ hvs := &HeightVoteSet{
chainID: chainID, chainID: chainID,
...@@ -50,6 +54,7 @@ func NewHeightVoteSet(chainID string, height int64, valSet *ValidatorSet) *Heigh ...@@ -50,6 +54,7 @@ func NewHeightVoteSet(chainID string, height int64, valSet *ValidatorSet) *Heigh
return hvs return hvs
} }
// Reset ...
func (hvs *HeightVoteSet) Reset(height int64, valSet *ValidatorSet) { func (hvs *HeightVoteSet) Reset(height int64, valSet *ValidatorSet) {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
...@@ -63,19 +68,21 @@ func (hvs *HeightVoteSet) Reset(height int64, valSet *ValidatorSet) { ...@@ -63,19 +68,21 @@ func (hvs *HeightVoteSet) Reset(height int64, valSet *ValidatorSet) {
hvs.round = 0 hvs.round = 0
} }
// Height ...
func (hvs *HeightVoteSet) Height() int64 { func (hvs *HeightVoteSet) Height() int64 {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
return hvs.height return hvs.height
} }
// Round ...
func (hvs *HeightVoteSet) Round() int { func (hvs *HeightVoteSet) Round() int {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
return hvs.round return hvs.round
} }
// Create more RoundVoteSets up to round. // SetRound Create more RoundVoteSets up to round.
func (hvs *HeightVoteSet) SetRound(round int) { func (hvs *HeightVoteSet) SetRound(round int) {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
...@@ -104,7 +111,7 @@ func (hvs *HeightVoteSet) addRound(round int) { ...@@ -104,7 +111,7 @@ func (hvs *HeightVoteSet) addRound(round int) {
} }
} }
// Duplicate votes return added=false, err=nil. // AddVote Duplicate votes return added=false, err=nil.
// By convention, peerKey is "" if origin is self. // By convention, peerKey is "" if origin is self.
func (hvs *HeightVoteSet) AddVote(vote *Vote, peerID string) (added bool, err error) { func (hvs *HeightVoteSet) AddVote(vote *Vote, peerID string) (added bool, err error) {
hvs.mtx.Lock() hvs.mtx.Lock()
...@@ -132,19 +139,21 @@ func (hvs *HeightVoteSet) AddVote(vote *Vote, peerID string) (added bool, err er ...@@ -132,19 +139,21 @@ func (hvs *HeightVoteSet) AddVote(vote *Vote, peerID string) (added bool, err er
return return
} }
// Prevotes ...
func (hvs *HeightVoteSet) Prevotes(round int) *VoteSet { func (hvs *HeightVoteSet) Prevotes(round int) *VoteSet {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
return hvs.getVoteSet(round, VoteTypePrevote) return hvs.getVoteSet(round, VoteTypePrevote)
} }
// Precommits ...
func (hvs *HeightVoteSet) Precommits(round int) *VoteSet { func (hvs *HeightVoteSet) Precommits(round int) *VoteSet {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
return hvs.getVoteSet(round, VoteTypePrecommit) return hvs.getVoteSet(round, VoteTypePrecommit)
} }
// Last round and blockID that has +2/3 prevotes for a particular block or nil. // POLInfo Last round and blockID that has +2/3 prevotes for a particular block or nil.
// Returns -1 if no such round exists. // Returns -1 if no such round exists.
func (hvs *HeightVoteSet) POLInfo() (polRound int, polBlockID BlockID) { func (hvs *HeightVoteSet) POLInfo() (polRound int, polBlockID BlockID) {
hvs.mtx.Lock() hvs.mtx.Lock()
...@@ -159,18 +168,18 @@ func (hvs *HeightVoteSet) POLInfo() (polRound int, polBlockID BlockID) { ...@@ -159,18 +168,18 @@ func (hvs *HeightVoteSet) POLInfo() (polRound int, polBlockID BlockID) {
return -1, BlockID{} return -1, BlockID{}
} }
func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *VoteSet { func (hvs *HeightVoteSet) getVoteSet(round int, voteType byte) *VoteSet {
rvs, ok := hvs.roundVoteSets[round] rvs, ok := hvs.roundVoteSets[round]
if !ok { if !ok {
return nil return nil
} }
switch type_ { switch voteType {
case VoteTypePrevote: case VoteTypePrevote:
return rvs.Prevotes return rvs.Prevotes
case VoteTypePrecommit: case VoteTypePrecommit:
return rvs.Precommits return rvs.Precommits
default: default:
panic(Fmt("Panicked on a Sanity Check: %v", Fmt("Unexpected vote type %X", type_))) panic(Fmt("Panicked on a Sanity Check: %v", Fmt("Unexpected vote type %X", voteType)))
} }
} }
...@@ -178,6 +187,7 @@ func (hvs *HeightVoteSet) String() string { ...@@ -178,6 +187,7 @@ func (hvs *HeightVoteSet) String() string {
return hvs.StringIndented("") return hvs.StringIndented("")
} }
// StringIndented ...
func (hvs *HeightVoteSet) StringIndented(indent string) string { func (hvs *HeightVoteSet) StringIndented(indent string) string {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
...@@ -207,17 +217,17 @@ func (hvs *HeightVoteSet) StringIndented(indent string) string { ...@@ -207,17 +217,17 @@ func (hvs *HeightVoteSet) StringIndented(indent string) string {
indent) indent)
} }
// If a peer claims that it has 2/3 majority for given blockKey, call this. // SetPeerMaj23 If a peer claims that it has 2/3 majority for given blockKey, call this.
// NOTE: if there are too many peers, or too much peer churn, // NOTE: if there are too many peers, or too much peer churn,
// this can cause memory issues. // this can cause memory issues.
// TODO: implement ability to remove peers too // TODO: implement ability to remove peers too
func (hvs *HeightVoteSet) SetPeerMaj23(round int, type_ byte, peerID string, blockID *tmtypes.BlockID) { func (hvs *HeightVoteSet) SetPeerMaj23(round int, voteType byte, peerID string, blockID *tmtypes.BlockID) {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
if !IsVoteTypeValid(type_) { if !IsVoteTypeValid(voteType) {
return return
} }
voteSet := hvs.getVoteSet(round, type_) voteSet := hvs.getVoteSet(round, voteType)
if voteSet == nil { if voteSet == nil {
return return
} }
......
...@@ -82,7 +82,7 @@ func DefaultBlockGossip() BlockGossip { ...@@ -82,7 +82,7 @@ func DefaultBlockGossip() BlockGossip {
} }
} }
// DefaultEvidence Params returns a default EvidenceParams. // DefaultEvidenceParams returns a default EvidenceParams.
func DefaultEvidenceParams() EvidenceParams { func DefaultEvidenceParams() EvidenceParams {
return EvidenceParams{ return EvidenceParams{
MaxAge: 100000, // 27.8 hrs at 1block/s MaxAge: 100000, // 27.8 hrs at 1block/s
......
...@@ -27,6 +27,7 @@ const ( ...@@ -27,6 +27,7 @@ const (
stepPrecommit = 3 stepPrecommit = 3
) )
// KeyText ...
type KeyText struct { type KeyText struct {
Kind string `json:"type"` Kind string `json:"type"`
Data string `json:"data"` Data string `json:"data"`
...@@ -78,6 +79,7 @@ type PrivValidatorFS struct { ...@@ -78,6 +79,7 @@ type PrivValidatorFS struct {
PrivKey KeyText `json:"priv_key"` PrivKey KeyText `json:"priv_key"`
} }
// PrivValidatorImp ...
type PrivValidatorImp struct { type PrivValidatorImp struct {
Address []byte Address []byte
PubKey crypto.PubKey PubKey crypto.PubKey
...@@ -135,12 +137,14 @@ func (pv *PrivValidatorImp) GetPubKey() crypto.PubKey { ...@@ -135,12 +137,14 @@ func (pv *PrivValidatorImp) GetPubKey() crypto.PubKey {
return pv.PubKey return pv.PubKey
} }
// GenAddressByPubKey ...
func GenAddressByPubKey(pubkey crypto.PubKey) []byte { func GenAddressByPubKey(pubkey crypto.PubKey) []byte {
//must add 3 bytes ahead to make compatibly //must add 3 bytes ahead to make compatibly
typeAddr := append([]byte{byte(0x01), byte(0x01), byte(0x20)}, pubkey.Bytes()...) typeAddr := append([]byte{byte(0x01), byte(0x01), byte(0x20)}, pubkey.Bytes()...)
return crypto.Ripemd160(typeAddr) return crypto.Ripemd160(typeAddr)
} }
// PubKeyFromString ...
func PubKeyFromString(pubkeystring string) (crypto.PubKey, error) { func PubKeyFromString(pubkeystring string) (crypto.PubKey, error) {
pub, err := hex.DecodeString(pubkeystring) pub, err := hex.DecodeString(pubkeystring)
if err != nil { if err != nil {
...@@ -154,6 +158,7 @@ func PubKeyFromString(pubkeystring string) (crypto.PubKey, error) { ...@@ -154,6 +158,7 @@ func PubKeyFromString(pubkeystring string) (crypto.PubKey, error) {
return pubkey, nil return pubkey, nil
} }
// SignatureFromString ...
func SignatureFromString(sigString string) (crypto.Signature, error) { func SignatureFromString(sigString string) (crypto.Signature, error) {
sigbyte, err := hex.DecodeString(sigString) sigbyte, err := hex.DecodeString(sigString)
if err != nil { if err != nil {
...@@ -203,7 +208,7 @@ func LoadOrGenPrivValidatorFS(filePath string) *PrivValidatorImp { ...@@ -203,7 +208,7 @@ func LoadOrGenPrivValidatorFS(filePath string) *PrivValidatorImp {
return privVal return privVal
} }
// LoadPrivValidatorWithSigner loads a PrivValidatorFS with a custom // LoadPrivValidatorFSWithSigner loads a PrivValidatorFS with a custom
// signer object. The PrivValidatorFS handles double signing prevention by persisting // signer object. The PrivValidatorFS handles double signing prevention by persisting
// data to the filePath, while the Signer handles the signing. // data to the filePath, while the Signer handles the signing.
// If the filePath does not exist, the PrivValidatorFS must be created manually and saved. // If the filePath does not exist, the PrivValidatorFS must be created manually and saved.
...@@ -272,33 +277,33 @@ func LoadPrivValidatorFSWithSigner(filePath string, signerFunc func(PrivValidato ...@@ -272,33 +277,33 @@ func LoadPrivValidatorFSWithSigner(filePath string, signerFunc func(PrivValidato
} }
// Save persists the PrivValidatorFS to disk. // Save persists the PrivValidatorFS to disk.
func (privVal *PrivValidatorImp) Save() { func (pv *PrivValidatorImp) Save() {
privVal.mtx.Lock() pv.mtx.Lock()
defer privVal.mtx.Unlock() defer pv.mtx.Unlock()
privVal.save() pv.save()
} }
func (privVal *PrivValidatorImp) save() { func (pv *PrivValidatorImp) save() {
if privVal.filePath == "" { if pv.filePath == "" {
PanicSanity("Cannot save PrivValidator: filePath not set") PanicSanity("Cannot save PrivValidator: filePath not set")
} }
addr := Fmt("%X", privVal.Address[:]) addr := Fmt("%X", pv.Address[:])
privValFS := &PrivValidatorFS{ privValFS := &PrivValidatorFS{
Address: addr, Address: addr,
LastHeight: privVal.LastHeight, LastHeight: pv.LastHeight,
LastRound: privVal.LastRound, LastRound: pv.LastRound,
LastStep: privVal.LastStep, LastStep: pv.LastStep,
LastSignature: nil, LastSignature: nil,
} }
privValFS.PrivKey = KeyText{Kind: "ed25519", Data: Fmt("%X", privVal.PrivKey.Bytes()[:])} privValFS.PrivKey = KeyText{Kind: "ed25519", Data: Fmt("%X", pv.PrivKey.Bytes()[:])}
privValFS.PubKey = KeyText{Kind: "ed25519", Data: privVal.PubKey.KeyString()} privValFS.PubKey = KeyText{Kind: "ed25519", Data: pv.PubKey.KeyString()}
if len(privVal.LastSignBytes) != 0 { if len(pv.LastSignBytes) != 0 {
tmp := Fmt("%X", privVal.LastSignBytes[:]) tmp := Fmt("%X", pv.LastSignBytes[:])
privValFS.LastSignBytes = tmp privValFS.LastSignBytes = tmp
} }
if privVal.LastSignature != nil { if pv.LastSignature != nil {
sig := Fmt("%X", privVal.LastSignature.Bytes()[:]) sig := Fmt("%X", pv.LastSignature.Bytes()[:])
privValFS.LastSignature = &KeyText{Kind: "ed25519", Data: sig} privValFS.LastSignature = &KeyText{Kind: "ed25519", Data: sig}
} }
jsonBytes, err := json.Marshal(privValFS) jsonBytes, err := json.Marshal(privValFS)
...@@ -306,7 +311,7 @@ func (privVal *PrivValidatorImp) save() { ...@@ -306,7 +311,7 @@ func (privVal *PrivValidatorImp) save() {
// `@; BOOM!!! // `@; BOOM!!!
PanicCrisis(err) PanicCrisis(err)
} }
err = WriteFileAtomic(privVal.filePath, jsonBytes, 0600) err = WriteFileAtomic(pv.filePath, jsonBytes, 0600)
if err != nil { if err != nil {
// `@; BOOM!!! // `@; BOOM!!!
PanicCrisis(err) PanicCrisis(err)
...@@ -315,21 +320,21 @@ func (privVal *PrivValidatorImp) save() { ...@@ -315,21 +320,21 @@ func (privVal *PrivValidatorImp) save() {
// Reset resets all fields in the PrivValidatorFS. // Reset resets all fields in the PrivValidatorFS.
// NOTE: Unsafe! // NOTE: Unsafe!
func (privVal *PrivValidatorImp) Reset() { func (pv *PrivValidatorImp) Reset() {
privVal.LastHeight = 0 pv.LastHeight = 0
privVal.LastRound = 0 pv.LastRound = 0
privVal.LastStep = 0 pv.LastStep = 0
privVal.LastSignature = nil pv.LastSignature = nil
privVal.LastSignBytes = nil pv.LastSignBytes = nil
privVal.Save() pv.Save()
} }
// SignVote signs a canonical representation of the vote, along with the // SignVote signs a canonical representation of the vote, along with the
// chainID. Implements PrivValidator. // chainID. Implements PrivValidator.
func (privVal *PrivValidatorImp) SignVote(chainID string, vote *Vote) error { func (pv *PrivValidatorImp) SignVote(chainID string, vote *Vote) error {
privVal.mtx.Lock() pv.mtx.Lock()
defer privVal.mtx.Unlock() defer pv.mtx.Unlock()
signature, err := privVal.signBytesHRS(vote.Height, int(vote.Round), voteToStep(vote), signature, err := pv.signBytesHRS(vote.Height, int(vote.Round), voteToStep(vote),
SignBytes(chainID, vote), checkVotesOnlyDifferByTimestamp) SignBytes(chainID, vote), checkVotesOnlyDifferByTimestamp)
if err != nil { if err != nil {
return errors.New(Fmt("Error signing vote: %v", err)) return errors.New(Fmt("Error signing vote: %v", err))
...@@ -340,10 +345,10 @@ func (privVal *PrivValidatorImp) SignVote(chainID string, vote *Vote) error { ...@@ -340,10 +345,10 @@ func (privVal *PrivValidatorImp) SignVote(chainID string, vote *Vote) error {
// SignProposal signs a canonical representation of the proposal, along with // SignProposal signs a canonical representation of the proposal, along with
// the chainID. Implements PrivValidator. // the chainID. Implements PrivValidator.
func (privVal *PrivValidatorImp) SignProposal(chainID string, proposal *Proposal) error { func (pv *PrivValidatorImp) SignProposal(chainID string, proposal *Proposal) error {
privVal.mtx.Lock() pv.mtx.Lock()
defer privVal.mtx.Unlock() defer pv.mtx.Unlock()
signature, err := privVal.signBytesHRS(proposal.Height, int(proposal.Round), stepPropose, signature, err := pv.signBytesHRS(proposal.Height, int(proposal.Round), stepPropose,
SignBytes(chainID, proposal), checkProposalsOnlyDifferByTimestamp) SignBytes(chainID, proposal), checkProposalsOnlyDifferByTimestamp)
if err != nil { if err != nil {
return fmt.Errorf("Error signing proposal: %v", err) return fmt.Errorf("Error signing proposal: %v", err)
...@@ -353,23 +358,23 @@ func (privVal *PrivValidatorImp) SignProposal(chainID string, proposal *Proposal ...@@ -353,23 +358,23 @@ func (privVal *PrivValidatorImp) SignProposal(chainID string, proposal *Proposal
} }
// returns error if HRS regression or no LastSignBytes. returns true if HRS is unchanged // returns error if HRS regression or no LastSignBytes. returns true if HRS is unchanged
func (privVal *PrivValidatorImp) checkHRS(height int64, round int, step int8) (bool, error) { func (pv *PrivValidatorImp) checkHRS(height int64, round int, step int8) (bool, error) {
if privVal.LastHeight > height { if pv.LastHeight > height {
return false, errors.New("Height regression") return false, errors.New("Height regression")
} }
if privVal.LastHeight == height { if pv.LastHeight == height {
if privVal.LastRound > round { if pv.LastRound > round {
return false, errors.New("Round regression") return false, errors.New("Round regression")
} }
if privVal.LastRound == round { if pv.LastRound == round {
if privVal.LastStep > step { if pv.LastStep > step {
return false, errors.New("Step regression") return false, errors.New("Step regression")
} else if privVal.LastStep == step { } else if pv.LastStep == step {
if privVal.LastSignBytes != nil { if pv.LastSignBytes != nil {
if privVal.LastSignature == nil { if pv.LastSignature == nil {
panic("privVal: LastSignature is nil but LastSignBytes is not!") panic("pv: LastSignature is nil but LastSignBytes is not!")
} }
return true, nil return true, nil
} }
...@@ -383,10 +388,10 @@ func (privVal *PrivValidatorImp) checkHRS(height int64, round int, step int8) (b ...@@ -383,10 +388,10 @@ func (privVal *PrivValidatorImp) checkHRS(height int64, round int, step int8) (b
// signBytesHRS signs the given signBytes if the height/round/step (HRS) are // signBytesHRS signs the given signBytes if the height/round/step (HRS) are
// greater than the latest state. If the HRS are equal and the only thing changed is the timestamp, // greater than the latest state. If the HRS are equal and the only thing changed is the timestamp,
// it returns the privValidator.LastSignature. Else it returns an error. // it returns the privValidator.LastSignature. Else it returns an error.
func (privVal *PrivValidatorImp) signBytesHRS(height int64, round int, step int8, func (pv *PrivValidatorImp) signBytesHRS(height int64, round int, step int8,
signBytes []byte, checkFn checkOnlyDifferByTimestamp) (crypto.Signature, error) { signBytes []byte, checkFn checkOnlyDifferByTimestamp) (crypto.Signature, error) {
sameHRS, err := privVal.checkHRS(height, round, step) sameHRS, err := pv.checkHRS(height, round, step)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -396,68 +401,71 @@ func (privVal *PrivValidatorImp) signBytesHRS(height int64, round int, step int8 ...@@ -396,68 +401,71 @@ func (privVal *PrivValidatorImp) signBytesHRS(height int64, round int, step int8
if sameHRS { if sameHRS {
// if they're the same or only differ by timestamp, // if they're the same or only differ by timestamp,
// return the LastSignature. Otherwise, error // return the LastSignature. Otherwise, error
if bytes.Equal(signBytes, privVal.LastSignBytes) || if bytes.Equal(signBytes, pv.LastSignBytes) ||
checkFn(privVal.LastSignBytes, signBytes) { checkFn(pv.LastSignBytes, signBytes) {
return privVal.LastSignature, nil return pv.LastSignature, nil
} }
return nil, fmt.Errorf("Conflicting data") return nil, fmt.Errorf("Conflicting data")
} }
sig, err := privVal.Sign(signBytes) sig, err := pv.Sign(signBytes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
//privVal.saveSigned(height, round, step, signBytes, sig) //pv.saveSigned(height, round, step, signBytes, sig)
return sig, nil return sig, nil
} }
// Persist height/round/step and signature // Persist height/round/step and signature
func (privVal *PrivValidatorImp) saveSigned(height int64, round int, step int8, func (pv *PrivValidatorImp) saveSigned(height int64, round int, step int8,
signBytes []byte, sig crypto.Signature) { signBytes []byte, sig crypto.Signature) {
privVal.LastHeight = height pv.LastHeight = height
privVal.LastRound = round pv.LastRound = round
privVal.LastStep = step pv.LastStep = step
privVal.LastSignature = sig pv.LastSignature = sig
privVal.LastSignBytes = signBytes pv.LastSignBytes = signBytes
privVal.save() pv.save()
} }
// SignHeartbeat signs a canonical representation of the heartbeat, along with the chainID. // SignHeartbeat signs a canonical representation of the heartbeat, along with the chainID.
// Implements PrivValidator. // Implements PrivValidator.
func (privVal *PrivValidatorImp) SignHeartbeat(chainID string, heartbeat *Heartbeat) error { func (pv *PrivValidatorImp) SignHeartbeat(chainID string, heartbeat *Heartbeat) error {
privVal.mtx.Lock() pv.mtx.Lock()
defer privVal.mtx.Unlock() defer pv.mtx.Unlock()
sig, err := privVal.Sign(SignBytes(chainID, heartbeat)) sig, err := pv.Sign(SignBytes(chainID, heartbeat))
heartbeat.Signature = sig.Bytes() heartbeat.Signature = sig.Bytes()
return err return err
} }
// String returns a string representation of the PrivValidatorImp. // String returns a string representation of the PrivValidatorImp.
func (privVal *PrivValidatorImp) String() string { func (pv *PrivValidatorImp) String() string {
return Fmt("PrivValidator{%v LH:%v, LR:%v, LS:%v}", privVal.GetAddress(), privVal.LastHeight, privVal.LastRound, privVal.LastStep) return Fmt("PrivValidator{%v LH:%v, LR:%v, LS:%v}", pv.GetAddress(), pv.LastHeight, pv.LastRound, pv.LastStep)
} }
func (privVal *PrivValidatorImp) GetLastHeight() int64 { // GetLastHeight ...
return privVal.LastHeight func (pv *PrivValidatorImp) GetLastHeight() int64 {
return pv.LastHeight
} }
func (privVal *PrivValidatorImp) GetLastRound() int { // GetLastRound ...
return privVal.LastRound func (pv *PrivValidatorImp) GetLastRound() int {
return pv.LastRound
} }
func (privVal *PrivValidatorImp) GetLastStep() int8 { // GetLastStep ...
return privVal.LastStep func (pv *PrivValidatorImp) GetLastStep() int8 {
return pv.LastStep
} }
func (privVal *PrivValidatorImp) ResetLastHeight(height int64) { // ResetLastHeight ...
privVal.LastHeight = height func (pv *PrivValidatorImp) ResetLastHeight(height int64) {
privVal.LastRound = 0 pv.LastHeight = height
privVal.LastStep = 0 pv.LastRound = 0
pv.LastStep = 0
} }
//------------------------------------- // PrivValidatorsByAddress ...
type PrivValidatorsByAddress []*PrivValidatorImp type PrivValidatorsByAddress []*PrivValidatorImp
func (pvs PrivValidatorsByAddress) Len() int { func (pvs PrivValidatorsByAddress) Len() int {
......
...@@ -22,6 +22,7 @@ var ( ...@@ -22,6 +22,7 @@ var (
pvFile = "priv_validator_" pvFile = "priv_validator_"
) )
// KeyFileCmd ...
func KeyFileCmd() *cobra.Command { func KeyFileCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "keyfile", Use: "keyfile",
...@@ -34,6 +35,7 @@ func KeyFileCmd() *cobra.Command { ...@@ -34,6 +35,7 @@ func KeyFileCmd() *cobra.Command {
return cmd return cmd
} }
// CreateCmd ...
func CreateCmd() *cobra.Command { func CreateCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "create", Use: "create",
...@@ -49,6 +51,7 @@ func addCreateCmdFlags(cmd *cobra.Command) { ...@@ -49,6 +51,7 @@ func addCreateCmdFlags(cmd *cobra.Command) {
cmd.MarkFlagRequired("num") cmd.MarkFlagRequired("num")
} }
// RandStr ...
func RandStr(length int) string { func RandStr(length int) string {
chars := []byte{} chars := []byte{}
MAIN_LOOP: MAIN_LOOP:
......
...@@ -12,16 +12,15 @@ import ( ...@@ -12,16 +12,15 @@ import (
tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types" tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
//-----------------------------------------------------------------------------
// RoundStepType enum type
// RoundStepType enumerates the state of the consensus state machine // RoundStepType enumerates the state of the consensus state machine
type RoundStepType uint8 // These must be numeric, ordered. type RoundStepType uint8 // These must be numeric, ordered.
var ( var (
// MsgMap define
MsgMap map[byte]reflect.Type MsgMap map[byte]reflect.Type
) )
// step and message id define
const ( const (
RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit RoundStepNewHeight = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit
RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose RoundStepNewRound = RoundStepType(0x02) // Setup new round and go to RoundStepPropose
...@@ -49,6 +48,7 @@ const ( ...@@ -49,6 +48,7 @@ const (
PacketTypePong = byte(0xfe) PacketTypePong = byte(0xfe)
) )
// InitMessageMap ...
func InitMessageMap() { func InitMessageMap() {
MsgMap = map[byte]reflect.Type{ MsgMap = map[byte]reflect.Type{
EvidenceListID: reflect.TypeOf(tmtypes.EvidenceData{}), EvidenceListID: reflect.TypeOf(tmtypes.EvidenceData{}),
...@@ -114,6 +114,7 @@ type RoundState struct { ...@@ -114,6 +114,7 @@ type RoundState struct {
LastValidators *ValidatorSet LastValidators *ValidatorSet
} }
// RoundStateMessage ...
func (rs *RoundState) RoundStateMessage() *tmtypes.NewRoundStepMsg { func (rs *RoundState) RoundStateMessage() *tmtypes.NewRoundStepMsg {
return &tmtypes.NewRoundStepMsg{ return &tmtypes.NewRoundStepMsg{
Height: rs.Height, Height: rs.Height,
...@@ -164,7 +165,7 @@ func (rs *RoundState) StringShort() string { ...@@ -164,7 +165,7 @@ func (rs *RoundState) StringShort() string {
rs.Height, rs.Round, rs.Step, rs.StartTime) rs.Height, rs.Round, rs.Step, rs.StartTime)
} }
//---------------------PeerRoundState---------------------------- // PeerRoundState ...
type PeerRoundState struct { type PeerRoundState struct {
Height int64 // Height peer is at Height int64 // Height peer is at
Round int // Round peer is at, -1 if unknown. Round int // Round peer is at, -1 if unknown.
...@@ -211,16 +212,20 @@ func (prs PeerRoundState) StringIndented(indent string) string { ...@@ -211,16 +212,20 @@ func (prs PeerRoundState) StringIndented(indent string) string {
} }
//---------------------Canonical json----------------------------------- //---------------------Canonical json-----------------------------------
// CanonicalJSONBlockID ...
type CanonicalJSONBlockID struct { type CanonicalJSONBlockID struct {
Hash []byte `json:"hash,omitempty"` Hash []byte `json:"hash,omitempty"`
PartsHeader CanonicalJSONPartSetHeader `json:"parts,omitempty"` PartsHeader CanonicalJSONPartSetHeader `json:"parts,omitempty"`
} }
// CanonicalJSONPartSetHeader ...
type CanonicalJSONPartSetHeader struct { type CanonicalJSONPartSetHeader struct {
Hash []byte `json:"hash"` Hash []byte `json:"hash"`
Total int `json:"total"` Total int `json:"total"`
} }
// CanonicalJSONProposal ...
type CanonicalJSONProposal struct { type CanonicalJSONProposal struct {
BlockBytes []byte `json:"block_parts_header"` BlockBytes []byte `json:"block_parts_header"`
Height int64 `json:"height"` Height int64 `json:"height"`
...@@ -230,6 +235,7 @@ type CanonicalJSONProposal struct { ...@@ -230,6 +235,7 @@ type CanonicalJSONProposal struct {
Timestamp string `json:"timestamp"` Timestamp string `json:"timestamp"`
} }
// CanonicalJSONVote ...
type CanonicalJSONVote struct { type CanonicalJSONVote struct {
BlockID CanonicalJSONBlockID `json:"block_id"` BlockID CanonicalJSONBlockID `json:"block_id"`
Height int64 `json:"height"` Height int64 `json:"height"`
...@@ -238,6 +244,7 @@ type CanonicalJSONVote struct { ...@@ -238,6 +244,7 @@ type CanonicalJSONVote struct {
Type byte `json:"type"` Type byte `json:"type"`
} }
// CanonicalJSONHeartbeat ...
type CanonicalJSONHeartbeat struct { type CanonicalJSONHeartbeat struct {
Height int64 `json:"height"` Height int64 `json:"height"`
Round int `json:"round"` Round int `json:"round"`
...@@ -246,33 +253,36 @@ type CanonicalJSONHeartbeat struct { ...@@ -246,33 +253,36 @@ type CanonicalJSONHeartbeat struct {
ValidatorIndex int `json:"validator_index"` ValidatorIndex int `json:"validator_index"`
} }
//------------------------------------
// Messages including a "chain id" can only be applied to one chain, hence "Once" // Messages including a "chain id" can only be applied to one chain, hence "Once"
// CanonicalJSONOnceProposal ...
type CanonicalJSONOnceProposal struct { type CanonicalJSONOnceProposal struct {
ChainID string `json:"chain_id"` ChainID string `json:"chain_id"`
Proposal CanonicalJSONProposal `json:"proposal"` Proposal CanonicalJSONProposal `json:"proposal"`
} }
// CanonicalJSONOnceVote ...
type CanonicalJSONOnceVote struct { type CanonicalJSONOnceVote struct {
ChainID string `json:"chain_id"` ChainID string `json:"chain_id"`
Vote CanonicalJSONVote `json:"vote"` Vote CanonicalJSONVote `json:"vote"`
} }
// CanonicalJSONOnceHeartbeat ...
type CanonicalJSONOnceHeartbeat struct { type CanonicalJSONOnceHeartbeat struct {
ChainID string `json:"chain_id"` ChainID string `json:"chain_id"`
Heartbeat CanonicalJSONHeartbeat `json:"heartbeat"` Heartbeat CanonicalJSONHeartbeat `json:"heartbeat"`
} }
//-----------------------------------
// Canonicalize the structs // Canonicalize the structs
// CanonicalBlockID ...
func CanonicalBlockID(blockID BlockID) CanonicalJSONBlockID { func CanonicalBlockID(blockID BlockID) CanonicalJSONBlockID {
return CanonicalJSONBlockID{ return CanonicalJSONBlockID{
Hash: blockID.Hash, Hash: blockID.Hash,
} }
} }
// CanonicalProposal ...
func CanonicalProposal(proposal *Proposal) CanonicalJSONProposal { func CanonicalProposal(proposal *Proposal) CanonicalJSONProposal {
return CanonicalJSONProposal{ return CanonicalJSONProposal{
//BlockBytes: proposal.BlockBytes, //BlockBytes: proposal.BlockBytes,
...@@ -286,6 +296,7 @@ func CanonicalProposal(proposal *Proposal) CanonicalJSONProposal { ...@@ -286,6 +296,7 @@ func CanonicalProposal(proposal *Proposal) CanonicalJSONProposal {
} }
} }
// CanonicalVote ...
func CanonicalVote(vote *Vote) CanonicalJSONVote { func CanonicalVote(vote *Vote) CanonicalJSONVote {
return CanonicalJSONVote{ return CanonicalJSONVote{
BlockID: CanonicalJSONBlockID{Hash: vote.BlockID.Hash}, BlockID: CanonicalJSONBlockID{Hash: vote.BlockID.Hash},
...@@ -296,6 +307,7 @@ func CanonicalVote(vote *Vote) CanonicalJSONVote { ...@@ -296,6 +307,7 @@ func CanonicalVote(vote *Vote) CanonicalJSONVote {
} }
} }
// CanonicalHeartbeat ...
func CanonicalHeartbeat(heartbeat *Heartbeat) CanonicalJSONHeartbeat { func CanonicalHeartbeat(heartbeat *Heartbeat) CanonicalJSONHeartbeat {
return CanonicalJSONHeartbeat{ return CanonicalJSONHeartbeat{
heartbeat.Height, heartbeat.Height,
...@@ -306,6 +318,7 @@ func CanonicalHeartbeat(heartbeat *Heartbeat) CanonicalJSONHeartbeat { ...@@ -306,6 +318,7 @@ func CanonicalHeartbeat(heartbeat *Heartbeat) CanonicalJSONHeartbeat {
} }
} }
// CanonicalTime ...
func CanonicalTime(t time.Time) string { func CanonicalTime(t time.Time) string {
// note that sending time over go-wire resets it to // note that sending time over go-wire resets it to
// local time, we need to force UTC here, so the // local time, we need to force UTC here, so the
......
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types" tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
// error defines
var ( var (
ErrVoteUnexpectedStep = errors.New("Unexpected step") ErrVoteUnexpectedStep = errors.New("Unexpected step")
ErrVoteInvalidValidatorIndex = errors.New("Invalid validator index") ErrVoteInvalidValidatorIndex = errors.New("Invalid validator index")
...@@ -44,7 +45,6 @@ func SignBytes(chainID string, o Signable) []byte { ...@@ -44,7 +45,6 @@ func SignBytes(chainID string, o Signable) []byte {
return buf.Bytes() return buf.Bytes()
} }
//----------------------Proposal----------------------
// Proposal defines a block proposal for the consensus. // Proposal defines a block proposal for the consensus.
// It refers to the block only by its PartSetHeader. // It refers to the block only by its PartSetHeader.
// It must be signed by the correct proposer for the given Height/Round // It must be signed by the correct proposer for the given Height/Round
...@@ -89,12 +89,12 @@ func (p *Proposal) WriteSignBytes(chainID string, w io.Writer, n *int, err *erro ...@@ -89,12 +89,12 @@ func (p *Proposal) WriteSignBytes(chainID string, w io.Writer, n *int, err *erro
*err = e *err = e
return return
} }
n_, err_ := w.Write(byteOnceProposal) number, writeErr := w.Write(byteOnceProposal)
*n = n_ *n = number
*err = err_ *err = writeErr
} }
//-------------------heartbeat------------------------- // Heartbeat ...
type Heartbeat struct { type Heartbeat struct {
*tmtypes.Heartbeat *tmtypes.Heartbeat
} }
...@@ -114,12 +114,12 @@ func (heartbeat *Heartbeat) WriteSignBytes(chainID string, w io.Writer, n *int, ...@@ -114,12 +114,12 @@ func (heartbeat *Heartbeat) WriteSignBytes(chainID string, w io.Writer, n *int,
*err = e *err = e
return return
} }
n_, err_ := w.Write(byteHeartbeat) number, writeErr := w.Write(byteHeartbeat)
*n = n_ *n = number
*err = err_ *err = writeErr
} }
//----------------------vote----------------------------- // ErrVoteConflictingVotes ...
type ErrVoteConflictingVotes struct { type ErrVoteConflictingVotes struct {
*DuplicateVoteEvidence *DuplicateVoteEvidence
} }
...@@ -133,6 +133,7 @@ func (err *ErrVoteConflictingVotes) Error() string { ...@@ -133,6 +133,7 @@ func (err *ErrVoteConflictingVotes) Error() string {
return fmt.Sprintf("Conflicting votes from validator %v", addr) return fmt.Sprintf("Conflicting votes from validator %v", addr)
} }
// NewConflictingVoteError ...
func NewConflictingVoteError(val *Validator, voteA, voteB *tmtypes.Vote) *ErrVoteConflictingVotes { func NewConflictingVoteError(val *Validator, voteA, voteB *tmtypes.Vote) *ErrVoteConflictingVotes {
keyString := fmt.Sprintf("%X", val.PubKey) keyString := fmt.Sprintf("%X", val.PubKey)
return &ErrVoteConflictingVotes{ return &ErrVoteConflictingVotes{
...@@ -153,8 +154,9 @@ const ( ...@@ -153,8 +154,9 @@ const (
VoteTypePrecommit = byte(0x02) VoteTypePrecommit = byte(0x02)
) )
func IsVoteTypeValid(type_ byte) bool { // IsVoteTypeValid ...
switch type_ { func IsVoteTypeValid(voteType byte) bool {
switch voteType {
case VoteTypePrevote: case VoteTypePrevote:
return true return true
case VoteTypePrecommit: case VoteTypePrecommit:
...@@ -164,11 +166,12 @@ func IsVoteTypeValid(type_ byte) bool { ...@@ -164,11 +166,12 @@ func IsVoteTypeValid(type_ byte) bool {
} }
} }
// Represents a prevote, precommit, or commit vote from validators for consensus. // Vote Represents a prevote, precommit, or commit vote from validators for consensus.
type Vote struct { type Vote struct {
*tmtypes.Vote *tmtypes.Vote
} }
// WriteSignBytes ...
func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) { func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error) {
if *err != nil { if *err != nil {
return return
...@@ -183,11 +186,12 @@ func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error ...@@ -183,11 +186,12 @@ func (vote *Vote) WriteSignBytes(chainID string, w io.Writer, n *int, err *error
votelog.Error("vote WriteSignBytes marshal failed", "err", e) votelog.Error("vote WriteSignBytes marshal failed", "err", e)
return return
} }
n_, err_ := w.Write(byteVote) number, writeErr := w.Write(byteVote)
*n = n_ *n = number
*err = err_ *err = writeErr
} }
// Copy ...
func (vote *Vote) Copy() *Vote { func (vote *Vote) Copy() *Vote {
voteCopy := *vote voteCopy := *vote
return &voteCopy return &voteCopy
...@@ -214,6 +218,7 @@ func (vote *Vote) String() string { ...@@ -214,6 +218,7 @@ func (vote *Vote) String() string {
CanonicalTime(time.Unix(0, vote.Timestamp))) CanonicalTime(time.Unix(0, vote.Timestamp)))
} }
// Verify ...
func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error { func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
addr := GenAddressByPubKey(pubKey) addr := GenAddressByPubKey(pubKey)
if !bytes.Equal(addr, vote.ValidatorAddress) { if !bytes.Equal(addr, vote.ValidatorAddress) {
...@@ -232,6 +237,7 @@ func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error { ...@@ -232,6 +237,7 @@ func (vote *Vote) Verify(chainID string, pubKey crypto.PubKey) error {
return nil return nil
} }
// Hash ...
func (vote *Vote) Hash() []byte { func (vote *Vote) Hash() []byte {
if vote == nil { if vote == nil {
//votelog.Error("vote hash is nil") //votelog.Error("vote hash is nil")
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
) )
const ( const (
// RFC3339Millis ...
RFC3339Millis = "2006-01-02T15:04:05.000Z" // forced microseconds RFC3339Millis = "2006-01-02T15:04:05.000Z" // forced microseconds
timeFormat = RFC3339Millis timeFormat = RFC3339Millis
) )
...@@ -29,9 +30,11 @@ const ( ...@@ -29,9 +30,11 @@ const (
var ( var (
randgen *rand.Rand randgen *rand.Rand
randMux sync.Mutex randMux sync.Mutex
Fmt = fmt.Sprintf // Fmt ...
Fmt = fmt.Sprintf
) )
// Init ...
func Init() { func Init() {
if randgen == nil { if randgen == nil {
randMux.Lock() randMux.Lock()
...@@ -40,10 +43,12 @@ func Init() { ...@@ -40,10 +43,12 @@ func Init() {
} }
} }
// WriteFile ...
func WriteFile(filePath string, contents []byte, mode os.FileMode) error { func WriteFile(filePath string, contents []byte, mode os.FileMode) error {
return ioutil.WriteFile(filePath, contents, mode) return ioutil.WriteFile(filePath, contents, mode)
} }
// WriteFileAtomic ...
func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error { func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error {
dir := filepath.Dir(filePath) dir := filepath.Dir(filePath)
f, err := ioutil.TempFile(dir, "") f, err := ioutil.TempFile(dir, "")
...@@ -70,7 +75,7 @@ func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error { ...@@ -70,7 +75,7 @@ func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error {
return err return err
} }
//---------------------------------------------------------- // Tempfile ...
func Tempfile(prefix string) (*os.File, string) { func Tempfile(prefix string) (*os.File, string) {
file, err := ioutil.TempFile("", prefix) file, err := ioutil.TempFile("", prefix)
if err != nil { if err != nil {
...@@ -79,12 +84,14 @@ func Tempfile(prefix string) (*os.File, string) { ...@@ -79,12 +84,14 @@ func Tempfile(prefix string) (*os.File, string) {
return file, file.Name() return file, file.Name()
} }
// Fingerprint ...
func Fingerprint(slice []byte) []byte { func Fingerprint(slice []byte) []byte {
fingerprint := make([]byte, 6) fingerprint := make([]byte, 6)
copy(fingerprint, slice) copy(fingerprint, slice)
return fingerprint return fingerprint
} }
// Kill ...
func Kill() error { func Kill() error {
p, err := os.FindProcess(os.Getpid()) p, err := os.FindProcess(os.Getpid())
if err != nil { if err != nil {
...@@ -93,12 +100,13 @@ func Kill() error { ...@@ -93,12 +100,13 @@ func Kill() error {
return p.Signal(syscall.SIGTERM) return p.Signal(syscall.SIGTERM)
} }
// Exit ...
func Exit(s string) { func Exit(s string) {
fmt.Printf(s + "\n") fmt.Printf(s + "\n")
os.Exit(1) os.Exit(1)
} }
//----------------------------------------------------------- // Parallel ...
func Parallel(tasks ...func()) { func Parallel(tasks ...func()) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(len(tasks)) wg.Add(len(tasks))
...@@ -114,6 +122,7 @@ func Parallel(tasks ...func()) { ...@@ -114,6 +122,7 @@ func Parallel(tasks ...func()) {
// Percent represents a percentage in increments of 1/1000th of a percent. // Percent represents a percentage in increments of 1/1000th of a percent.
type Percent uint32 type Percent uint32
// Float ...
func (p Percent) Float() float64 { func (p Percent) Float() float64 {
return float64(p) * 1e-3 return float64(p) * 1e-3
} }
...@@ -127,7 +136,7 @@ func (p Percent) String() string { ...@@ -127,7 +136,7 @@ func (p Percent) String() string {
return string(append(b, '%')) return string(append(b, '%'))
} }
//------------------------------------------------------------------- // MinInt ...
func MinInt(a, b int) int { func MinInt(a, b int) int {
if a < b { if a < b {
return a return a
...@@ -135,6 +144,7 @@ func MinInt(a, b int) int { ...@@ -135,6 +144,7 @@ func MinInt(a, b int) int {
return b return b
} }
// MaxInt ...
func MaxInt(a, b int) int { func MaxInt(a, b int) int {
if a > b { if a > b {
return a return a
...@@ -142,7 +152,7 @@ func MaxInt(a, b int) int { ...@@ -142,7 +152,7 @@ func MaxInt(a, b int) int {
return b return b
} }
//-------------------------------------------------------------- // RandIntn ...
func RandIntn(n int) int { func RandIntn(n int) int {
if n <= 0 { if n <= 0 {
panic("invalid argument to Intn") panic("invalid argument to Intn")
...@@ -159,6 +169,7 @@ func RandIntn(n int) int { ...@@ -159,6 +169,7 @@ func RandIntn(n int) int {
return int(i64) return int(i64)
} }
// RandUint32 ...
func RandUint32() uint32 { func RandUint32() uint32 {
randMux.Lock() randMux.Lock()
u32 := randgen.Uint32() u32 := randgen.Uint32()
...@@ -166,6 +177,7 @@ func RandUint32() uint32 { ...@@ -166,6 +177,7 @@ func RandUint32() uint32 {
return u32 return u32
} }
// RandInt63n ...
func RandInt63n(n int64) int64 { func RandInt63n(n int64) int64 {
randMux.Lock() randMux.Lock()
i64 := randgen.Int63n(n) i64 := randgen.Int63n(n)
...@@ -173,26 +185,28 @@ func RandInt63n(n int64) int64 { ...@@ -173,26 +185,28 @@ func RandInt63n(n int64) int64 {
return i64 return i64
} }
//------------------------------------------------------------- // PanicSanity ...
func PanicSanity(v interface{}) { func PanicSanity(v interface{}) {
panic(Fmt("Panicked on a Sanity Check: %v", v)) panic(Fmt("Panicked on a Sanity Check: %v", v))
} }
// PanicCrisis ...
func PanicCrisis(v interface{}) { func PanicCrisis(v interface{}) {
panic(Fmt("Panicked on a Crisis: %v", v)) panic(Fmt("Panicked on a Crisis: %v", v))
} }
// PanicQ ...
func PanicQ(v interface{}) { func PanicQ(v interface{}) {
panic(Fmt("Panicked questionably: %v", v)) panic(Fmt("Panicked questionably: %v", v))
} }
//--------------------BitArray------------------------ // BitArray ...
type BitArray struct { type BitArray struct {
*tmtypes.TendermintBitArray *tmtypes.TendermintBitArray
mtx sync.Mutex mtx sync.Mutex
} }
// There is no BitArray whose Size is 0. Use nil instead. // NewBitArray There is no BitArray whose Size is 0. Use nil instead.
func NewBitArray(bits int) *BitArray { func NewBitArray(bits int) *BitArray {
if bits <= 0 { if bits <= 0 {
return nil return nil
...@@ -205,6 +219,7 @@ func NewBitArray(bits int) *BitArray { ...@@ -205,6 +219,7 @@ func NewBitArray(bits int) *BitArray {
} }
} }
// Size ...
func (bA *BitArray) Size() int { func (bA *BitArray) Size() int {
if bA == nil { if bA == nil {
return 0 return 0
...@@ -212,7 +227,7 @@ func (bA *BitArray) Size() int { ...@@ -212,7 +227,7 @@ func (bA *BitArray) Size() int {
return int(bA.Bits) return int(bA.Bits)
} }
// NOTE: behavior is undefined if i >= bA.Bits // GetIndex NOTE: behavior is undefined if i >= bA.Bits
func (bA *BitArray) GetIndex(i int) bool { func (bA *BitArray) GetIndex(i int) bool {
if bA == nil { if bA == nil {
return false return false
...@@ -229,7 +244,7 @@ func (bA *BitArray) getIndex(i int) bool { ...@@ -229,7 +244,7 @@ func (bA *BitArray) getIndex(i int) bool {
return bA.Elems[i/64]&(uint64(1)<<uint(i%64)) > 0 return bA.Elems[i/64]&(uint64(1)<<uint(i%64)) > 0
} }
// NOTE: behavior is undefined if i >= bA.Bits // SetIndex NOTE: behavior is undefined if i >= bA.Bits
func (bA *BitArray) SetIndex(i int, v bool) bool { func (bA *BitArray) SetIndex(i int, v bool) bool {
if bA == nil { if bA == nil {
return false return false
...@@ -251,6 +266,7 @@ func (bA *BitArray) setIndex(i int, v bool) bool { ...@@ -251,6 +266,7 @@ func (bA *BitArray) setIndex(i int, v bool) bool {
return true return true
} }
// Copy ...
func (bA *BitArray) Copy() *BitArray { func (bA *BitArray) Copy() *BitArray {
if bA == nil { if bA == nil {
return nil return nil
...@@ -280,7 +296,7 @@ func (bA *BitArray) copyBits(bits int) *BitArray { ...@@ -280,7 +296,7 @@ func (bA *BitArray) copyBits(bits int) *BitArray {
} }
} }
// Returns a BitArray of larger bits size. // Or Returns a BitArray of larger bits size.
func (bA *BitArray) Or(o *BitArray) *BitArray { func (bA *BitArray) Or(o *BitArray) *BitArray {
if bA == nil && o.TendermintBitArray == nil { if bA == nil && o.TendermintBitArray == nil {
return nil return nil
...@@ -300,7 +316,7 @@ func (bA *BitArray) Or(o *BitArray) *BitArray { ...@@ -300,7 +316,7 @@ func (bA *BitArray) Or(o *BitArray) *BitArray {
return c return c
} }
// Returns a BitArray of smaller bit size. // And Returns a BitArray of smaller bit size.
func (bA *BitArray) And(o *BitArray) *BitArray { func (bA *BitArray) And(o *BitArray) *BitArray {
if bA == nil || o.TendermintBitArray == nil { if bA == nil || o.TendermintBitArray == nil {
return nil return nil
...@@ -318,6 +334,7 @@ func (bA *BitArray) and(o *BitArray) *BitArray { ...@@ -318,6 +334,7 @@ func (bA *BitArray) and(o *BitArray) *BitArray {
return c return c
} }
// Not ...
func (bA *BitArray) Not() *BitArray { func (bA *BitArray) Not() *BitArray {
if bA == nil { if bA == nil {
return nil // Degenerate return nil // Degenerate
...@@ -331,6 +348,7 @@ func (bA *BitArray) Not() *BitArray { ...@@ -331,6 +348,7 @@ func (bA *BitArray) Not() *BitArray {
return c return c
} }
// Sub ...
func (bA *BitArray) Sub(o *BitArray) *BitArray { func (bA *BitArray) Sub(o *BitArray) *BitArray {
if bA == nil || o.TendermintBitArray == nil { if bA == nil || o.TendermintBitArray == nil {
return nil return nil
...@@ -354,6 +372,7 @@ func (bA *BitArray) Sub(o *BitArray) *BitArray { ...@@ -354,6 +372,7 @@ func (bA *BitArray) Sub(o *BitArray) *BitArray {
return bA.and(o.Not()) // Note degenerate case where o == nil return bA.and(o.Not()) // Note degenerate case where o == nil
} }
// IsEmpty ...
func (bA *BitArray) IsEmpty() bool { func (bA *BitArray) IsEmpty() bool {
if bA == nil { if bA == nil {
return true // should this be opposite? return true // should this be opposite?
...@@ -368,6 +387,7 @@ func (bA *BitArray) IsEmpty() bool { ...@@ -368,6 +387,7 @@ func (bA *BitArray) IsEmpty() bool {
return true return true
} }
// IsFull ...
func (bA *BitArray) IsFull() bool { func (bA *BitArray) IsFull() bool {
if bA == nil { if bA == nil {
return true return true
...@@ -388,6 +408,7 @@ func (bA *BitArray) IsFull() bool { ...@@ -388,6 +408,7 @@ func (bA *BitArray) IsFull() bool {
return (lastElem+1)&((uint64(1)<<uint(lastElemBits))-1) == 0 return (lastElem+1)&((uint64(1)<<uint(lastElemBits))-1) == 0
} }
// PickRandom ...
func (bA *BitArray) PickRandom() (int, bool) { func (bA *BitArray) PickRandom() (int, bool) {
if bA == nil { if bA == nil {
return 0, false return 0, false
...@@ -440,6 +461,7 @@ func (bA *BitArray) String() string { ...@@ -440,6 +461,7 @@ func (bA *BitArray) String() string {
return bA.stringIndented("") return bA.stringIndented("")
} }
// StringIndented ...
func (bA *BitArray) StringIndented(indent string) string { func (bA *BitArray) StringIndented(indent string) string {
if bA == nil { if bA == nil {
return "nil-BitArray" return "nil-BitArray"
...@@ -476,6 +498,7 @@ func (bA *BitArray) stringIndented(indent string) string { ...@@ -476,6 +498,7 @@ func (bA *BitArray) stringIndented(indent string) string {
return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent)) return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent))
} }
// Bytes ...
func (bA *BitArray) Bytes() []byte { func (bA *BitArray) Bytes() []byte {
bA.mtx.Lock() bA.mtx.Lock()
defer bA.mtx.Unlock() defer bA.mtx.Unlock()
...@@ -490,7 +513,7 @@ func (bA *BitArray) Bytes() []byte { ...@@ -490,7 +513,7 @@ func (bA *BitArray) Bytes() []byte {
return bytes return bytes
} }
// NOTE: other bitarray o is not locked when reading, // Update NOTE: other bitarray o is not locked when reading,
// so if necessary, caller must copy or lock o prior to calling Update. // so if necessary, caller must copy or lock o prior to calling Update.
// If bA is nil, does nothing. // If bA is nil, does nothing.
func (bA *BitArray) Update(o *BitArray) { func (bA *BitArray) Update(o *BitArray) {
...@@ -503,12 +526,12 @@ func (bA *BitArray) Update(o *BitArray) { ...@@ -503,12 +526,12 @@ func (bA *BitArray) Update(o *BitArray) {
} }
//------------------Heap---------------------- //------------------Heap----------------------
// Comparable ...
type Comparable interface { type Comparable interface {
Less(o interface{}) bool Less(o interface{}) bool
} }
//-----------------------------------------------------------------------------
/* /*
Example usage: Example usage:
h := NewHeap() h := NewHeap()
...@@ -522,22 +545,27 @@ Example usage: ...@@ -522,22 +545,27 @@ Example usage:
fmt.Println(h.Pop()) fmt.Println(h.Pop())
*/ */
// Heap ...
type Heap struct { type Heap struct {
pq priorityQueue pq priorityQueue
} }
// NewHeap ...
func NewHeap() *Heap { func NewHeap() *Heap {
return &Heap{pq: make([]*pqItem, 0)} return &Heap{pq: make([]*pqItem, 0)}
} }
// Len ...
func (h *Heap) Len() int64 { func (h *Heap) Len() int64 {
return int64(len(h.pq)) return int64(len(h.pq))
} }
// Push ...
func (h *Heap) Push(value interface{}, priority Comparable) { func (h *Heap) Push(value interface{}, priority Comparable) {
heap.Push(&h.pq, &pqItem{value: value, priority: priority}) heap.Push(&h.pq, &pqItem{value: value, priority: priority})
} }
// Peek ...
func (h *Heap) Peek() interface{} { func (h *Heap) Peek() interface{} {
if len(h.pq) == 0 { if len(h.pq) == 0 {
return nil return nil
...@@ -545,10 +573,12 @@ func (h *Heap) Peek() interface{} { ...@@ -545,10 +573,12 @@ func (h *Heap) Peek() interface{} {
return h.pq[0].value return h.pq[0].value
} }
// Update ...
func (h *Heap) Update(value interface{}, priority Comparable) { func (h *Heap) Update(value interface{}, priority Comparable) {
h.pq.Update(h.pq[0], value, priority) h.pq.Update(h.pq[0], value, priority)
} }
// Pop ...
func (h *Heap) Pop() interface{} { func (h *Heap) Pop() interface{} {
item := heap.Pop(&h.pq).(*pqItem) item := heap.Pop(&h.pq).(*pqItem)
return item.value return item.value
......
...@@ -19,6 +19,7 @@ import ( ...@@ -19,6 +19,7 @@ import (
var validatorsetlog = log15.New("module", "tendermint-val") var validatorsetlog = log15.New("module", "tendermint-val")
// Validator ...
type Validator struct { type Validator struct {
Address []byte `json:"address"` Address []byte `json:"address"`
PubKey []byte `json:"pub_key"` PubKey []byte `json:"pub_key"`
...@@ -27,6 +28,7 @@ type Validator struct { ...@@ -27,6 +28,7 @@ type Validator struct {
Accum int64 `json:"accum"` Accum int64 `json:"accum"`
} }
// NewValidator ...
func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator {
return &Validator{ return &Validator{
Address: GenAddressByPubKey(pubKey), Address: GenAddressByPubKey(pubKey),
...@@ -36,14 +38,14 @@ func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { ...@@ -36,14 +38,14 @@ func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator {
} }
} }
// Creates a new copy of the validator so we can mutate accum. // Copy Creates a new copy of the validator so we can mutate accum.
// Panics if the validator is nil. // Panics if the validator is nil.
func (v *Validator) Copy() *Validator { func (v *Validator) Copy() *Validator {
vCopy := *v vCopy := *v
return &vCopy return &vCopy
} }
// Returns the one with higher Accum. // CompareAccum Returns the one with higher Accum.
func (v *Validator) CompareAccum(other *Validator) *Validator { func (v *Validator) CompareAccum(other *Validator) *Validator {
if v == nil { if v == nil {
return other return other
...@@ -105,6 +107,7 @@ type ValidatorSet struct { ...@@ -105,6 +107,7 @@ type ValidatorSet struct {
totalVotingPower int64 totalVotingPower int64
} }
// NewValidatorSet ...
func NewValidatorSet(vals []*Validator) *ValidatorSet { func NewValidatorSet(vals []*Validator) *ValidatorSet {
validators := make([]*Validator, len(vals)) validators := make([]*Validator, len(vals))
for i, val := range vals { for i, val := range vals {
...@@ -122,7 +125,7 @@ func NewValidatorSet(vals []*Validator) *ValidatorSet { ...@@ -122,7 +125,7 @@ func NewValidatorSet(vals []*Validator) *ValidatorSet {
return vs return vs
} }
// incrementAccum and update the proposer // IncrementAccum incrementAccum and update the proposer
// TODO: mind the overflow when times and votingPower shares too large. // TODO: mind the overflow when times and votingPower shares too large.
func (valSet *ValidatorSet) IncrementAccum(times int) { func (valSet *ValidatorSet) IncrementAccum(times int) {
// Add VotingPower * times to each validator and order into heap. // Add VotingPower * times to each validator and order into heap.
...@@ -143,6 +146,7 @@ func (valSet *ValidatorSet) IncrementAccum(times int) { ...@@ -143,6 +146,7 @@ func (valSet *ValidatorSet) IncrementAccum(times int) {
} }
} }
// Copy ...
func (valSet *ValidatorSet) Copy() *ValidatorSet { func (valSet *ValidatorSet) Copy() *ValidatorSet {
validators := make([]*Validator, len(valSet.Validators)) validators := make([]*Validator, len(valSet.Validators))
for i, val := range valSet.Validators { for i, val := range valSet.Validators {
...@@ -156,6 +160,7 @@ func (valSet *ValidatorSet) Copy() *ValidatorSet { ...@@ -156,6 +160,7 @@ func (valSet *ValidatorSet) Copy() *ValidatorSet {
} }
} }
// HasAddress ...
func (valSet *ValidatorSet) HasAddress(address []byte) bool { func (valSet *ValidatorSet) HasAddress(address []byte) bool {
idx := sort.Search(len(valSet.Validators), func(i int) bool { idx := sort.Search(len(valSet.Validators), func(i int) bool {
return bytes.Compare(address, valSet.Validators[i].Address) <= 0 return bytes.Compare(address, valSet.Validators[i].Address) <= 0
...@@ -163,15 +168,15 @@ func (valSet *ValidatorSet) HasAddress(address []byte) bool { ...@@ -163,15 +168,15 @@ func (valSet *ValidatorSet) HasAddress(address []byte) bool {
return idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) return idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address)
} }
// GetByAddress ...
func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) { func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) {
idx := sort.Search(len(valSet.Validators), func(i int) bool { idx := sort.Search(len(valSet.Validators), func(i int) bool {
return bytes.Compare(address, valSet.Validators[i].Address) <= 0 return bytes.Compare(address, valSet.Validators[i].Address) <= 0
}) })
if idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) { if idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) {
return idx, valSet.Validators[idx].Copy() return idx, valSet.Validators[idx].Copy()
} else {
return -1, nil
} }
return -1, nil
} }
// GetByIndex returns the validator by index. // GetByIndex returns the validator by index.
...@@ -185,10 +190,12 @@ func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validato ...@@ -185,10 +190,12 @@ func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validato
return val.Address, val.Copy() return val.Address, val.Copy()
} }
// Size ...
func (valSet *ValidatorSet) Size() int { func (valSet *ValidatorSet) Size() int {
return len(valSet.Validators) return len(valSet.Validators)
} }
// TotalVotingPower ...
func (valSet *ValidatorSet) TotalVotingPower() int64 { func (valSet *ValidatorSet) TotalVotingPower() int64 {
if valSet.totalVotingPower == 0 { if valSet.totalVotingPower == 0 {
for _, val := range valSet.Validators { for _, val := range valSet.Validators {
...@@ -198,6 +205,7 @@ func (valSet *ValidatorSet) TotalVotingPower() int64 { ...@@ -198,6 +205,7 @@ func (valSet *ValidatorSet) TotalVotingPower() int64 {
return valSet.totalVotingPower return valSet.totalVotingPower
} }
// GetProposer ...
func (valSet *ValidatorSet) GetProposer() (proposer *Validator) { func (valSet *ValidatorSet) GetProposer() (proposer *Validator) {
if len(valSet.Validators) == 0 { if len(valSet.Validators) == 0 {
return nil return nil
...@@ -218,6 +226,7 @@ func (valSet *ValidatorSet) findProposer() *Validator { ...@@ -218,6 +226,7 @@ func (valSet *ValidatorSet) findProposer() *Validator {
return proposer return proposer
} }
// Hash ...
func (valSet *ValidatorSet) Hash() []byte { func (valSet *ValidatorSet) Hash() []byte {
if len(valSet.Validators) == 0 { if len(valSet.Validators) == 0 {
return nil return nil
...@@ -229,6 +238,7 @@ func (valSet *ValidatorSet) Hash() []byte { ...@@ -229,6 +238,7 @@ func (valSet *ValidatorSet) Hash() []byte {
return merkle.GetMerkleRoot(hashables) return merkle.GetMerkleRoot(hashables)
} }
// Add ...
func (valSet *ValidatorSet) Add(val *Validator) (added bool) { func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
val = val.Copy() val = val.Copy()
idx := sort.Search(len(valSet.Validators), func(i int) bool { idx := sort.Search(len(valSet.Validators), func(i int) bool {
...@@ -255,39 +265,40 @@ func (valSet *ValidatorSet) Add(val *Validator) (added bool) { ...@@ -255,39 +265,40 @@ func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
} }
} }
// Update ...
func (valSet *ValidatorSet) Update(val *Validator) (updated bool) { func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
index, sameVal := valSet.GetByAddress(val.Address) index, sameVal := valSet.GetByAddress(val.Address)
if sameVal == nil { if sameVal == nil {
return false return false
} else {
valSet.Validators[index] = val.Copy()
// Invalidate cache
valSet.Proposer = nil
valSet.totalVotingPower = 0
return true
} }
valSet.Validators[index] = val.Copy()
// Invalidate cache
valSet.Proposer = nil
valSet.totalVotingPower = 0
return true
} }
// Remove ...
func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) { func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
idx := sort.Search(len(valSet.Validators), func(i int) bool { idx := sort.Search(len(valSet.Validators), func(i int) bool {
return bytes.Compare(address, valSet.Validators[i].Address) <= 0 return bytes.Compare(address, valSet.Validators[i].Address) <= 0
}) })
if idx == len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) { if idx == len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) {
return nil, false return nil, false
} else {
removedVal := valSet.Validators[idx]
newValidators := valSet.Validators[:idx]
if idx+1 < len(valSet.Validators) {
newValidators = append(newValidators, valSet.Validators[idx+1:]...)
}
valSet.Validators = newValidators
// Invalidate cache
valSet.Proposer = nil
valSet.totalVotingPower = 0
return removedVal, true
} }
removedVal := valSet.Validators[idx]
newValidators := valSet.Validators[:idx]
if idx+1 < len(valSet.Validators) {
newValidators = append(newValidators, valSet.Validators[idx+1:]...)
}
valSet.Validators = newValidators
// Invalidate cache
valSet.Proposer = nil
valSet.totalVotingPower = 0
return removedVal, true
} }
// Iterate ...
func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
for i, val := range valSet.Validators { for i, val := range valSet.Validators {
stop := fn(i, val.Copy()) stop := fn(i, val.Copy())
...@@ -297,7 +308,7 @@ func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { ...@@ -297,7 +308,7 @@ func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
} }
} }
// Verify that +2/3 of the set had signed the given signBytes // VerifyCommit Verify that +2/3 of the set had signed the given signBytes
func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height int64, commit *Commit) error { func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height int64, commit *Commit) error {
if valSet.Size() != len(commit.Precommits) { if valSet.Size() != len(commit.Precommits) {
return fmt.Errorf("Invalid commit -- wrong set size: %v vs %v", valSet.Size(), len(commit.Precommits)) return fmt.Errorf("Invalid commit -- wrong set size: %v vs %v", valSet.Size(), len(commit.Precommits))
...@@ -350,10 +361,9 @@ func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height ...@@ -350,10 +361,9 @@ func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height
if talliedVotingPower > valSet.TotalVotingPower()*2/3 { if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
return nil return nil
} else {
return fmt.Errorf("Invalid commit -- insufficient voting power: got %v, needed %v",
talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
} }
return fmt.Errorf("Invalid commit -- insufficient voting power: got %v, needed %v",
talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
} }
// VerifyCommitAny will check to see if the set would // VerifyCommitAny will check to see if the set would
...@@ -453,6 +463,7 @@ func (valSet *ValidatorSet) String() string { ...@@ -453,6 +463,7 @@ func (valSet *ValidatorSet) String() string {
return valSet.StringIndented("") return valSet.StringIndented("")
} }
// StringIndented ...
func (valSet *ValidatorSet) StringIndented(indent string) string { func (valSet *ValidatorSet) StringIndented(indent string) string {
if valSet == nil { if valSet == nil {
return "nil-ValidatorSet" return "nil-ValidatorSet"
...@@ -474,9 +485,9 @@ func (valSet *ValidatorSet) StringIndented(indent string) string { ...@@ -474,9 +485,9 @@ func (valSet *ValidatorSet) StringIndented(indent string) string {
} }
//-------------------------------------
// Implements sort for sorting validators by address. // Implements sort for sorting validators by address.
// ValidatorsByAddress ...
type ValidatorsByAddress []*Validator type ValidatorsByAddress []*Validator
func (vs ValidatorsByAddress) Len() int { func (vs ValidatorsByAddress) Len() int {
......
...@@ -47,11 +47,13 @@ import ( ...@@ -47,11 +47,13 @@ import (
NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64. NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64.
*/ */
// VoteSet ...
type VoteSet struct { type VoteSet struct {
chainID string chainID string
height int64 height int64
round int round int
type_ byte voteType byte
mtx sync.Mutex mtx sync.Mutex
valSet *ValidatorSet valSet *ValidatorSet
...@@ -63,8 +65,8 @@ type VoteSet struct { ...@@ -63,8 +65,8 @@ type VoteSet struct {
peerMaj23s map[string]*tmtypes.BlockID // Maj23 for each peer peerMaj23s map[string]*tmtypes.BlockID // Maj23 for each peer
} }
// Constructs a new VoteSet struct used to accumulate votes for given height/round. // NewVoteSet Constructs a new VoteSet struct used to accumulate votes for given height/round.
func NewVoteSet(chainID string, height int64, round int, type_ byte, valSet *ValidatorSet) *VoteSet { func NewVoteSet(chainID string, height int64, round int, voteType byte, valSet *ValidatorSet) *VoteSet {
if height == 0 { if height == 0 {
PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.") PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.")
} }
...@@ -72,7 +74,7 @@ func NewVoteSet(chainID string, height int64, round int, type_ byte, valSet *Val ...@@ -72,7 +74,7 @@ func NewVoteSet(chainID string, height int64, round int, type_ byte, valSet *Val
chainID: chainID, chainID: chainID,
height: height, height: height,
round: round, round: round,
type_: type_, voteType: voteType,
valSet: valSet, valSet: valSet,
votesBitArray: NewBitArray(valSet.Size()), votesBitArray: NewBitArray(valSet.Size()),
votes: make([]*Vote, valSet.Size()), votes: make([]*Vote, valSet.Size()),
...@@ -83,46 +85,47 @@ func NewVoteSet(chainID string, height int64, round int, type_ byte, valSet *Val ...@@ -83,46 +85,47 @@ func NewVoteSet(chainID string, height int64, round int, type_ byte, valSet *Val
} }
} }
// ChainID ...
func (voteSet *VoteSet) ChainID() string { func (voteSet *VoteSet) ChainID() string {
return voteSet.chainID return voteSet.chainID
} }
// Height ...
func (voteSet *VoteSet) Height() int64 { func (voteSet *VoteSet) Height() int64 {
if voteSet == nil { if voteSet == nil {
return 0 return 0
} else {
return voteSet.height
} }
return voteSet.height
} }
// Round ...
func (voteSet *VoteSet) Round() int { func (voteSet *VoteSet) Round() int {
if voteSet == nil { if voteSet == nil {
return -1 return -1
} else {
return voteSet.round
} }
return voteSet.round
} }
// Type ...
func (voteSet *VoteSet) Type() byte { func (voteSet *VoteSet) Type() byte {
if voteSet == nil { if voteSet == nil {
return 0x00 return 0x00
} else {
return voteSet.type_
} }
return voteSet.voteType
} }
// Size ...
func (voteSet *VoteSet) Size() int { func (voteSet *VoteSet) Size() int {
if voteSet == nil { if voteSet == nil {
return 0 return 0
} else {
return voteSet.valSet.Size()
} }
return voteSet.valSet.Size()
} }
// Returns added=true if vote is valid and new. // AddVote Returns added=true if vote is valid and new.
// Otherwise returns err=ErrVote[ // Otherwise returns err=ErrVote[
// UnexpectedStep | InvalidIndex | InvalidAddress | // UnexpectedStep | InvalidIndex | InvalidAddress |
// InvalidSignature | InvalidBlockHash | ConflictingVotes ] // InvalidSignature | InvalidBlockHash | ConflictingVotes ]
// Duplicate votes return added=false, err=nil. // Duplicate votes return added=false, err=nil.
// Conflicting votes return added=*, err=ErrVoteConflictingVotes. // Conflicting votes return added=*, err=ErrVoteConflictingVotes.
// NOTE: vote should not be mutated after adding. // NOTE: vote should not be mutated after adding.
...@@ -157,9 +160,9 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { ...@@ -157,9 +160,9 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
// Make sure the step matches. // Make sure the step matches.
if (vote.Height != voteSet.height) || if (vote.Height != voteSet.height) ||
(int(vote.Round) != voteSet.round) || (int(vote.Round) != voteSet.round) ||
(vote.Type != uint32(voteSet.type_)) { (vote.Type != uint32(voteSet.voteType)) {
return false, errors.Wrapf(ErrVoteUnexpectedStep, "Got %d/%d/%d, expected %d/%d/%d", return false, errors.Wrapf(ErrVoteUnexpectedStep, "Got %d/%d/%d, expected %d/%d/%d",
voteSet.height, voteSet.round, voteSet.type_, voteSet.height, voteSet.round, voteSet.voteType,
vote.Height, vote.Round, vote.Type) vote.Height, vote.Round, vote.Type)
} }
...@@ -181,9 +184,8 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { ...@@ -181,9 +184,8 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
if existing, ok := voteSet.getVote(valIndex, blockKey); ok { if existing, ok := voteSet.getVote(valIndex, blockKey); ok {
if bytes.Equal(existing.Signature[:], vote.Signature[:]) { if bytes.Equal(existing.Signature[:], vote.Signature[:]) {
return false, nil // duplicate return false, nil // duplicate
} else {
return false, errors.Wrapf(ErrVoteNonDeterministicSignature, "Existing vote: %v; New vote: %v", existing, vote)
} }
return false, errors.Wrapf(ErrVoteNonDeterministicSignature, "Existing vote: %v; New vote: %v", existing, vote)
} }
// Check signature. // Check signature.
...@@ -199,13 +201,11 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { ...@@ -199,13 +201,11 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
added, conflicting := voteSet.addVerifiedVote(vote, blockKey, val.VotingPower) added, conflicting := voteSet.addVerifiedVote(vote, blockKey, val.VotingPower)
if conflicting != nil { if conflicting != nil {
return added, NewConflictingVoteError(val, conflicting.Vote, vote.Vote) return added, NewConflictingVoteError(val, conflicting.Vote, vote.Vote)
} else {
if !added {
PanicSanity("Expected to add non-conflicting vote")
}
return added, nil
} }
if !added {
PanicSanity("Expected to add non-conflicting vote")
}
return added, nil
} }
// Returns (vote, true) if vote exists for valIndex and blockKey // Returns (vote, true) if vote exists for valIndex and blockKey
...@@ -258,13 +258,12 @@ func (voteSet *VoteSet) addVerifiedVote(vote *Vote, blockKey string, votingPower ...@@ -258,13 +258,12 @@ func (voteSet *VoteSet) addVerifiedVote(vote *Vote, blockKey string, votingPower
// ... and there's a conflicting vote. // ... and there's a conflicting vote.
// We're not even tracking this blockKey, so just forget it. // We're not even tracking this blockKey, so just forget it.
return false, conflicting return false, conflicting
} else {
// ... and there's no conflicting vote.
// Start tracking this blockKey
votesByBlock = newBlockVotes(false, voteSet.valSet.Size())
voteSet.votesByBlock[blockKey] = votesByBlock
// We'll add the vote in a bit.
} }
// ... and there's no conflicting vote.
// Start tracking this blockKey
votesByBlock = newBlockVotes(false, voteSet.valSet.Size())
voteSet.votesByBlock[blockKey] = votesByBlock
// We'll add the vote in a bit.
} }
// Before adding to votesByBlock, see if we'll exceed quorum // Before adding to votesByBlock, see if we'll exceed quorum
...@@ -292,7 +291,7 @@ func (voteSet *VoteSet) addVerifiedVote(vote *Vote, blockKey string, votingPower ...@@ -292,7 +291,7 @@ func (voteSet *VoteSet) addVerifiedVote(vote *Vote, blockKey string, votingPower
return true, conflicting return true, conflicting
} }
// If a peer claims that it has 2/3 majority for given blockKey, call this. // SetPeerMaj23 If a peer claims that it has 2/3 majority for given blockKey, call this.
// NOTE: if there are too many peers, or too much peer churn, // NOTE: if there are too many peers, or too much peer churn,
// this can cause memory issues. // this can cause memory issues.
// TODO: implement ability to remove peers too // TODO: implement ability to remove peers too
...@@ -310,9 +309,8 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID *tmtypes.BlockID) { ...@@ -310,9 +309,8 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID *tmtypes.BlockID) {
if existing, ok := voteSet.peerMaj23s[peerID]; ok { if existing, ok := voteSet.peerMaj23s[peerID]; ok {
if bytes.Equal(existing.Hash, blockID.Hash) { if bytes.Equal(existing.Hash, blockID.Hash) {
return // Nothing to do return // Nothing to do
} else {
return // TODO bad peer!
} }
return // TODO bad peer!
} }
voteSet.peerMaj23s[peerID] = blockID voteSet.peerMaj23s[peerID] = blockID
...@@ -321,10 +319,8 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID *tmtypes.BlockID) { ...@@ -321,10 +319,8 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID *tmtypes.BlockID) {
if ok { if ok {
if votesByBlock.peerMaj23 { if votesByBlock.peerMaj23 {
return // Nothing to do return // Nothing to do
} else {
votesByBlock.peerMaj23 = true
// No need to copy votes, already there.
} }
votesByBlock.peerMaj23 = true // No need to copy votes, already there.
} else { } else {
votesByBlock = newBlockVotes(true, voteSet.valSet.Size()) votesByBlock = newBlockVotes(true, voteSet.valSet.Size())
voteSet.votesByBlock[blockKey] = votesByBlock voteSet.votesByBlock[blockKey] = votesByBlock
...@@ -332,6 +328,7 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID *tmtypes.BlockID) { ...@@ -332,6 +328,7 @@ func (voteSet *VoteSet) SetPeerMaj23(peerID string, blockID *tmtypes.BlockID) {
} }
} }
// BitArray ...
func (voteSet *VoteSet) BitArray() *BitArray { func (voteSet *VoteSet) BitArray() *BitArray {
if voteSet == nil { if voteSet == nil {
return nil return nil
...@@ -341,6 +338,7 @@ func (voteSet *VoteSet) BitArray() *BitArray { ...@@ -341,6 +338,7 @@ func (voteSet *VoteSet) BitArray() *BitArray {
return voteSet.votesBitArray.Copy() return voteSet.votesBitArray.Copy()
} }
// BitArrayByBlockID ...
func (voteSet *VoteSet) BitArrayByBlockID(blockID *tmtypes.BlockID) *BitArray { func (voteSet *VoteSet) BitArrayByBlockID(blockID *tmtypes.BlockID) *BitArray {
if voteSet == nil { if voteSet == nil {
return nil return nil
...@@ -354,7 +352,7 @@ func (voteSet *VoteSet) BitArrayByBlockID(blockID *tmtypes.BlockID) *BitArray { ...@@ -354,7 +352,7 @@ func (voteSet *VoteSet) BitArrayByBlockID(blockID *tmtypes.BlockID) *BitArray {
return nil return nil
} }
// NOTE: if validator has conflicting votes, returns "canonical" vote // GetByIndex if validator has conflicting votes, returns "canonical" vote
func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote { func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote {
if voteSet == nil { if voteSet == nil {
return nil return nil
...@@ -364,6 +362,7 @@ func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote { ...@@ -364,6 +362,7 @@ func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote {
return voteSet.votes[valIndex] return voteSet.votes[valIndex]
} }
// GetByAddress ...
func (voteSet *VoteSet) GetByAddress(address []byte) *Vote { func (voteSet *VoteSet) GetByAddress(address []byte) *Vote {
if voteSet == nil { if voteSet == nil {
return nil return nil
...@@ -377,6 +376,7 @@ func (voteSet *VoteSet) GetByAddress(address []byte) *Vote { ...@@ -377,6 +376,7 @@ func (voteSet *VoteSet) GetByAddress(address []byte) *Vote {
return voteSet.votes[valIndex] return voteSet.votes[valIndex]
} }
// HasTwoThirdsMajority ...
func (voteSet *VoteSet) HasTwoThirdsMajority() bool { func (voteSet *VoteSet) HasTwoThirdsMajority() bool {
if voteSet == nil { if voteSet == nil {
return false return false
...@@ -386,11 +386,12 @@ func (voteSet *VoteSet) HasTwoThirdsMajority() bool { ...@@ -386,11 +386,12 @@ func (voteSet *VoteSet) HasTwoThirdsMajority() bool {
return voteSet.maj23 != nil return voteSet.maj23 != nil
} }
// IsCommit ...
func (voteSet *VoteSet) IsCommit() bool { func (voteSet *VoteSet) IsCommit() bool {
if voteSet == nil { if voteSet == nil {
return false return false
} }
if voteSet.type_ != VoteTypePrecommit { if voteSet.voteType != VoteTypePrecommit {
return false return false
} }
voteSet.mtx.Lock() voteSet.mtx.Lock()
...@@ -398,6 +399,7 @@ func (voteSet *VoteSet) IsCommit() bool { ...@@ -398,6 +399,7 @@ func (voteSet *VoteSet) IsCommit() bool {
return voteSet.maj23 != nil return voteSet.maj23 != nil
} }
// HasTwoThirdsAny ...
func (voteSet *VoteSet) HasTwoThirdsAny() bool { func (voteSet *VoteSet) HasTwoThirdsAny() bool {
if voteSet == nil { if voteSet == nil {
return false return false
...@@ -407,11 +409,12 @@ func (voteSet *VoteSet) HasTwoThirdsAny() bool { ...@@ -407,11 +409,12 @@ func (voteSet *VoteSet) HasTwoThirdsAny() bool {
return voteSet.sum > voteSet.valSet.TotalVotingPower()*2/3 return voteSet.sum > voteSet.valSet.TotalVotingPower()*2/3
} }
// HasAll ...
func (voteSet *VoteSet) HasAll() bool { func (voteSet *VoteSet) HasAll() bool {
return voteSet.sum == voteSet.valSet.TotalVotingPower() return voteSet.sum == voteSet.valSet.TotalVotingPower()
} }
// Returns either a blockhash (or nil) that received +2/3 majority. // TwoThirdsMajority Returns either a blockhash (or nil) that received +2/3 majority.
// If there exists no such majority, returns (nil, PartSetHeader{}, false). // If there exists no such majority, returns (nil, PartSetHeader{}, false).
func (voteSet *VoteSet) TwoThirdsMajority() (blockID tmtypes.BlockID, ok bool) { func (voteSet *VoteSet) TwoThirdsMajority() (blockID tmtypes.BlockID, ok bool) {
if voteSet == nil { if voteSet == nil {
...@@ -421,9 +424,8 @@ func (voteSet *VoteSet) TwoThirdsMajority() (blockID tmtypes.BlockID, ok bool) { ...@@ -421,9 +424,8 @@ func (voteSet *VoteSet) TwoThirdsMajority() (blockID tmtypes.BlockID, ok bool) {
defer voteSet.mtx.Unlock() defer voteSet.mtx.Unlock()
if voteSet.maj23 != nil { if voteSet.maj23 != nil {
return *voteSet.maj23, true return *voteSet.maj23, true
} else {
return tmtypes.BlockID{}, false
} }
return tmtypes.BlockID{}, false
} }
func (voteSet *VoteSet) String() string { func (voteSet *VoteSet) String() string {
...@@ -433,6 +435,7 @@ func (voteSet *VoteSet) String() string { ...@@ -433,6 +435,7 @@ func (voteSet *VoteSet) String() string {
return voteSet.StringIndented("") return voteSet.StringIndented("")
} }
// StringIndented ...
func (voteSet *VoteSet) StringIndented(indent string) string { func (voteSet *VoteSet) StringIndented(indent string) string {
voteStrings := make([]string, len(voteSet.votes)) voteStrings := make([]string, len(voteSet.votes))
for i, vote := range voteSet.votes { for i, vote := range voteSet.votes {
...@@ -448,13 +451,14 @@ func (voteSet *VoteSet) StringIndented(indent string) string { ...@@ -448,13 +451,14 @@ func (voteSet *VoteSet) StringIndented(indent string) string {
%s %v %s %v
%s %v %s %v
%s}`, %s}`,
indent, voteSet.height, voteSet.round, voteSet.type_, indent, voteSet.height, voteSet.round, voteSet.voteType,
indent, strings.Join(voteStrings, "\n"+indent+" "), indent, strings.Join(voteStrings, "\n"+indent+" "),
indent, voteSet.votesBitArray, indent, voteSet.votesBitArray,
indent, voteSet.peerMaj23s, indent, voteSet.peerMaj23s,
indent) indent)
} }
// StringShort ...
func (voteSet *VoteSet) StringShort() string { func (voteSet *VoteSet) StringShort() string {
if voteSet == nil { if voteSet == nil {
return "nil-VoteSet" return "nil-VoteSet"
...@@ -462,14 +466,12 @@ func (voteSet *VoteSet) StringShort() string { ...@@ -462,14 +466,12 @@ func (voteSet *VoteSet) StringShort() string {
voteSet.mtx.Lock() voteSet.mtx.Lock()
defer voteSet.mtx.Unlock() defer voteSet.mtx.Unlock()
return Fmt(`VoteSet{H:%v R:%v T:%v +2/3:%v %v %v}`, return Fmt(`VoteSet{H:%v R:%v T:%v +2/3:%v %v %v}`,
voteSet.height, voteSet.round, voteSet.type_, voteSet.maj23, voteSet.votesBitArray, voteSet.peerMaj23s) voteSet.height, voteSet.round, voteSet.voteType, voteSet.maj23, voteSet.votesBitArray, voteSet.peerMaj23s)
} }
//-------------------------------------------------------------------------------- // MakeCommit ...
// Commit
func (voteSet *VoteSet) MakeCommit() *tmtypes.TendermintCommit { func (voteSet *VoteSet) MakeCommit() *tmtypes.TendermintCommit {
if voteSet.type_ != VoteTypePrecommit { if voteSet.voteType != VoteTypePrecommit {
PanicSanity("Cannot MakeCommit() unless VoteSet.Type is VoteTypePrecommit") PanicSanity("Cannot MakeCommit() unless VoteSet.Type is VoteTypePrecommit")
} }
voteSet.mtx.Lock() voteSet.mtx.Lock()
...@@ -538,7 +540,7 @@ func (vs *blockVotes) getByIndex(index int) *Vote { ...@@ -538,7 +540,7 @@ func (vs *blockVotes) getByIndex(index int) *Vote {
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Common interface between *consensus.VoteSet and types.Commit // VoteSetReader Common interface between *consensus.VoteSet and types.Commit
type VoteSetReader interface { type VoteSetReader interface {
Height() int64 Height() int64
Round() int Round() int
......
...@@ -17,7 +17,7 @@ func calcCertHeightKey(height int64) []byte { ...@@ -17,7 +17,7 @@ func calcCertHeightKey(height int64) []byte {
} }
// ExecLocal_New 启用证书交易执行 // ExecLocal_New 启用证书交易执行
func (c *Cert) ExecLocal_New(payload *ct.CertNew, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Cert) ExecLocal_New(payload *ct.CertNew, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if !authority.IsAuthEnable { if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.") clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
return nil, ct.ErrInitializeAuthority return nil, ct.ErrInitializeAuthority
...@@ -49,7 +49,7 @@ func (c *Cert) ExecLocal_New(payload *ct.CertNew, tx *types.Transaction, receipt ...@@ -49,7 +49,7 @@ func (c *Cert) ExecLocal_New(payload *ct.CertNew, tx *types.Transaction, receipt
} }
// ExecLocal_Update 更新证书交易执行 // ExecLocal_Update 更新证书交易执行
func (c *Cert) ExecLocal_Update(payload *ct.CertUpdate, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Cert) ExecLocal_Update(payload *ct.CertUpdate, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if !authority.IsAuthEnable { if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.") clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
return nil, ct.ErrInitializeAuthority return nil, ct.ErrInitializeAuthority
...@@ -82,7 +82,7 @@ func (c *Cert) ExecLocal_Update(payload *ct.CertUpdate, tx *types.Transaction, r ...@@ -82,7 +82,7 @@ func (c *Cert) ExecLocal_Update(payload *ct.CertUpdate, tx *types.Transaction, r
} }
// ExecLocal_Normal 非证书变更交易执行 // ExecLocal_Normal 非证书变更交易执行
func (c *Cert) ExecLocal_Normal(payload *ct.CertNormal, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Cert) ExecLocal_Normal(payload *ct.CertNormal, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if !authority.IsAuthEnable { if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.") clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
return nil, ct.ErrInitializeAuthority return nil, ct.ErrInitializeAuthority
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
) )
// ExecDelLocal_Hlock Action // ExecDelLocal_Hlock Action
func (h *Hashlock) ExecDelLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, receipt types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (h *Hashlock) ExecDelLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receipt.GetTy() != types.ExecOk { if receipt.GetTy() != types.ExecOk {
return &types.LocalDBSet{}, nil return &types.LocalDBSet{}, nil
} }
...@@ -24,7 +24,7 @@ func (h *Hashlock) ExecDelLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transac ...@@ -24,7 +24,7 @@ func (h *Hashlock) ExecDelLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transac
} }
// ExecDelLocal_Hsend Action // ExecDelLocal_Hsend Action
func (h *Hashlock) ExecDelLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transaction, receipt types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (h *Hashlock) ExecDelLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receipt.GetTy() != types.ExecOk { if receipt.GetTy() != types.ExecOk {
return &types.LocalDBSet{}, nil return &types.LocalDBSet{}, nil
} }
...@@ -37,7 +37,7 @@ func (h *Hashlock) ExecDelLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transac ...@@ -37,7 +37,7 @@ func (h *Hashlock) ExecDelLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transac
} }
// ExecDelLocal_Hunlock Action // ExecDelLocal_Hunlock Action
func (h *Hashlock) ExecDelLocal_Hunlock(hunlock *pty.HashlockUnlock, tx *types.Transaction, receipt types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (h *Hashlock) ExecDelLocal_Hunlock(hunlock *pty.HashlockUnlock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receipt.GetTy() != types.ExecOk { if receipt.GetTy() != types.ExecOk {
return &types.LocalDBSet{}, nil return &types.LocalDBSet{}, nil
} }
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
) )
// ExecLocal_Hlock Action // ExecLocal_Hlock Action
func (h *Hashlock) ExecLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, receipt types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (h *Hashlock) ExecLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receipt.GetTy() != types.ExecOk { if receipt.GetTy() != types.ExecOk {
return &types.LocalDBSet{}, nil return &types.LocalDBSet{}, nil
} }
...@@ -25,7 +25,7 @@ func (h *Hashlock) ExecLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transactio ...@@ -25,7 +25,7 @@ func (h *Hashlock) ExecLocal_Hlock(hlock *pty.HashlockLock, tx *types.Transactio
} }
// ExecLocal_Hsend Action // ExecLocal_Hsend Action
func (h *Hashlock) ExecLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transaction, receipt types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (h *Hashlock) ExecLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receipt.GetTy() != types.ExecOk { if receipt.GetTy() != types.ExecOk {
return &types.LocalDBSet{}, nil return &types.LocalDBSet{}, nil
} }
...@@ -39,7 +39,7 @@ func (h *Hashlock) ExecLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transactio ...@@ -39,7 +39,7 @@ func (h *Hashlock) ExecLocal_Hsend(hsend *pty.HashlockSend, tx *types.Transactio
} }
// ExecLocal_Hunlock Action // ExecLocal_Hunlock Action
func (h *Hashlock) ExecLocal_Hunlock(hunlock *pty.HashlockUnlock, tx *types.Transaction, receipt types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (h *Hashlock) ExecLocal_Hunlock(hunlock *pty.HashlockUnlock, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receipt.GetTy() != types.ExecOk { if receipt.GetTy() != types.ExecOk {
return &types.LocalDBSet{}, nil return &types.LocalDBSet{}, nil
} }
......
...@@ -49,7 +49,7 @@ func DelRetrieveInfo(info *rt.RetrieveQuery, Status int64, db dbm.KVDB) (*types. ...@@ -49,7 +49,7 @@ func DelRetrieveInfo(info *rt.RetrieveQuery, Status int64, db dbm.KVDB) (*types.
} }
// ExecDelLocal_Backup Action // ExecDelLocal_Backup Action
func (c *Retrieve) ExecDelLocal_Backup(backup *rt.BackupRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecDelLocal_Backup(backup *rt.BackupRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
...@@ -70,7 +70,7 @@ func (c *Retrieve) ExecDelLocal_Backup(backup *rt.BackupRetrieve, tx *types.Tran ...@@ -70,7 +70,7 @@ func (c *Retrieve) ExecDelLocal_Backup(backup *rt.BackupRetrieve, tx *types.Tran
} }
// ExecDelLocal_Prepare Action // ExecDelLocal_Prepare Action
func (c *Retrieve) ExecDelLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecDelLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
...@@ -91,7 +91,7 @@ func (c *Retrieve) ExecDelLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Trans ...@@ -91,7 +91,7 @@ func (c *Retrieve) ExecDelLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Trans
} }
// ExecDelLocal_Perform Action // ExecDelLocal_Perform Action
func (c *Retrieve) ExecDelLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecDelLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
...@@ -112,7 +112,7 @@ func (c *Retrieve) ExecDelLocal_Perform(perf *rt.PerformRetrieve, tx *types.Tran ...@@ -112,7 +112,7 @@ func (c *Retrieve) ExecDelLocal_Perform(perf *rt.PerformRetrieve, tx *types.Tran
} }
// ExecDelLocal_Cancel Action // ExecDelLocal_Cancel Action
func (c *Retrieve) ExecDelLocal_Cancel(cancel *rt.CancelRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecDelLocal_Cancel(cancel *rt.CancelRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
......
...@@ -52,7 +52,7 @@ func SaveRetrieveInfo(info *rt.RetrieveQuery, Status int64, db dbm.KVDB) (*types ...@@ -52,7 +52,7 @@ func SaveRetrieveInfo(info *rt.RetrieveQuery, Status int64, db dbm.KVDB) (*types
} }
// ExecLocal_Backup Action // ExecLocal_Backup Action
func (c *Retrieve) ExecLocal_Backup(backup *rt.BackupRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecLocal_Backup(backup *rt.BackupRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
...@@ -72,7 +72,7 @@ func (c *Retrieve) ExecLocal_Backup(backup *rt.BackupRetrieve, tx *types.Transac ...@@ -72,7 +72,7 @@ func (c *Retrieve) ExecLocal_Backup(backup *rt.BackupRetrieve, tx *types.Transac
} }
// ExecLocal_Prepare Action // ExecLocal_Prepare Action
func (c *Retrieve) ExecLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
...@@ -93,7 +93,7 @@ func (c *Retrieve) ExecLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Transact ...@@ -93,7 +93,7 @@ func (c *Retrieve) ExecLocal_Prepare(pre *rt.PrepareRetrieve, tx *types.Transact
} }
// ExecLocal_Perform Action // ExecLocal_Perform Action
func (c *Retrieve) ExecLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
...@@ -114,7 +114,7 @@ func (c *Retrieve) ExecLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transac ...@@ -114,7 +114,7 @@ func (c *Retrieve) ExecLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transac
} }
// ExecLocal_Cancel Action // ExecLocal_Cancel Action
func (c *Retrieve) ExecLocal_Cancel(cancel *rt.CancelRetrieve, tx *types.Transaction, receiptData types.ExecTypeGet, index int) (*types.LocalDBSet, error) { func (c *Retrieve) ExecLocal_Cancel(cancel *rt.CancelRetrieve, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receiptData.GetTy() != types.ExecOk { if receiptData.GetTy() != types.ExecOk {
return set, nil return set, nil
......
...@@ -9,11 +9,13 @@ import ( ...@@ -9,11 +9,13 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/valnode/types" pty "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
// Exec_Node method
func (val *ValNode) Exec_Node(node *pty.ValNode, tx *types.Transaction, index int) (*types.Receipt, error) { func (val *ValNode) Exec_Node(node *pty.ValNode, tx *types.Transaction, index int) (*types.Receipt, error) {
receipt := &types.Receipt{Ty: types.ExecOk, KV: nil, Logs: nil} receipt := &types.Receipt{Ty: types.ExecOk, KV: nil, Logs: nil}
return receipt, nil return receipt, nil
} }
// Exec_BlockInfo method
func (val *ValNode) Exec_BlockInfo(blockInfo *pty.TendermintBlockInfo, tx *types.Transaction, index int) (*types.Receipt, error) { func (val *ValNode) Exec_BlockInfo(blockInfo *pty.TendermintBlockInfo, tx *types.Transaction, index int) (*types.Receipt, error) {
receipt := &types.Receipt{Ty: types.ExecOk, KV: nil, Logs: nil} receipt := &types.Receipt{Ty: types.ExecOk, KV: nil, Logs: nil}
return receipt, nil return receipt, nil
......
...@@ -9,15 +9,23 @@ import ( ...@@ -9,15 +9,23 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/valnode/types" pty "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
// ExecDelLocal_Node method
func (val *ValNode) ExecDelLocal_Node(node *pty.ValNode, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (val *ValNode) ExecDelLocal_Node(node *pty.ValNode, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return set, nil
}
key := CalcValNodeUpdateHeightIndexKey(val.GetHeight(), index) key := CalcValNodeUpdateHeightIndexKey(val.GetHeight(), index)
set.KV = append(set.KV, &types.KeyValue{Key: key, Value: nil}) set.KV = append(set.KV, &types.KeyValue{Key: key, Value: nil})
return set, nil return set, nil
} }
// ExecDelLocal_BlockInfo method
func (val *ValNode) ExecDelLocal_BlockInfo(blockInfo *pty.TendermintBlockInfo, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (val *ValNode) ExecDelLocal_BlockInfo(blockInfo *pty.TendermintBlockInfo, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return set, nil
}
key := CalcValNodeBlockInfoHeightKey(val.GetHeight()) key := CalcValNodeBlockInfoHeightKey(val.GetHeight())
set.KV = append(set.KV, &types.KeyValue{Key: key, Value: nil}) set.KV = append(set.KV, &types.KeyValue{Key: key, Value: nil})
return set, nil return set, nil
......
...@@ -11,8 +11,12 @@ import ( ...@@ -11,8 +11,12 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/valnode/types" pty "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
// ExecLocal_Node method
func (val *ValNode) ExecLocal_Node(node *pty.ValNode, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (val *ValNode) ExecLocal_Node(node *pty.ValNode, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return set, nil
}
if len(node.GetPubKey()) == 0 { if len(node.GetPubKey()) == 0 {
return nil, errors.New("validator pubkey is empty") return nil, errors.New("validator pubkey is empty")
} }
...@@ -25,8 +29,12 @@ func (val *ValNode) ExecLocal_Node(node *pty.ValNode, tx *types.Transaction, rec ...@@ -25,8 +29,12 @@ func (val *ValNode) ExecLocal_Node(node *pty.ValNode, tx *types.Transaction, rec
return set, nil return set, nil
} }
// ExecLocal_BlockInfo method
func (val *ValNode) ExecLocal_BlockInfo(blockInfo *pty.TendermintBlockInfo, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (val *ValNode) ExecLocal_BlockInfo(blockInfo *pty.TendermintBlockInfo, tx *types.Transaction, receipt *types.ReceiptData, index int) (*types.LocalDBSet, error) {
set := &types.LocalDBSet{} set := &types.LocalDBSet{}
if receipt.GetTy() != types.ExecOk {
return set, nil
}
key := CalcValNodeBlockInfoHeightKey(val.GetHeight()) key := CalcValNodeBlockInfoHeightKey(val.GetHeight())
set.KV = append(set.KV, &types.KeyValue{Key: key, Value: types.Encode(blockInfo)}) set.KV = append(set.KV, &types.KeyValue{Key: key, Value: types.Encode(blockInfo)})
return set, nil return set, nil
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
pty "github.com/33cn/plugin/plugin/dapp/valnode/types" pty "github.com/33cn/plugin/plugin/dapp/valnode/types"
) )
// Query_GetValNodeByHeight method
func (val *ValNode) Query_GetValNodeByHeight(in *pty.ReqNodeInfo) (types.Message, error) { func (val *ValNode) Query_GetValNodeByHeight(in *pty.ReqNodeInfo) (types.Message, error) {
height := in.GetHeight() height := in.GetHeight()
...@@ -36,6 +37,7 @@ func (val *ValNode) Query_GetValNodeByHeight(in *pty.ReqNodeInfo) (types.Message ...@@ -36,6 +37,7 @@ func (val *ValNode) Query_GetValNodeByHeight(in *pty.ReqNodeInfo) (types.Message
return reply, nil return reply, nil
} }
// Query_GetBlockInfoByHeight method
func (val *ValNode) Query_GetBlockInfoByHeight(in *pty.ReqBlockInfo) (types.Message, error) { func (val *ValNode) Query_GetBlockInfoByHeight(in *pty.ReqBlockInfo) (types.Message, error) {
height := in.GetHeight() height := in.GetHeight()
......
...@@ -20,15 +20,18 @@ func init() { ...@@ -20,15 +20,18 @@ func init() {
ety.InitFuncList(types.ListMethod(&ValNode{})) ety.InitFuncList(types.ListMethod(&ValNode{}))
} }
// Init method
func Init(name string, sub []byte) { func Init(name string, sub []byte) {
clog.Debug("register valnode execer") clog.Debug("register valnode execer")
drivers.Register(GetName(), newValNode, 0) drivers.Register(GetName(), newValNode, 0)
} }
// GetName method
func GetName() string { func GetName() string {
return newValNode().GetName() return newValNode().GetName()
} }
// ValNode strucyt
type ValNode struct { type ValNode struct {
drivers.DriverBase drivers.DriverBase
} }
...@@ -41,22 +44,27 @@ func newValNode() drivers.Driver { ...@@ -41,22 +44,27 @@ func newValNode() drivers.Driver {
return n return n
} }
// GetDriverName method
func (val *ValNode) GetDriverName() string { func (val *ValNode) GetDriverName() string {
return driverName return driverName
} }
// CheckTx method
func (val *ValNode) CheckTx(tx *types.Transaction, index int) error { func (val *ValNode) CheckTx(tx *types.Transaction, index int) error {
return nil return nil
} }
// CalcValNodeUpdateHeightIndexKey method
func CalcValNodeUpdateHeightIndexKey(height int64, index int) []byte { func CalcValNodeUpdateHeightIndexKey(height int64, index int) []byte {
return []byte(fmt.Sprintf("LODB-valnode-Update:%18d:%18d", height, int64(index))) return []byte(fmt.Sprintf("LODB-valnode-Update:%18d:%18d", height, int64(index)))
} }
// CalcValNodeUpdateHeightKey method
func CalcValNodeUpdateHeightKey(height int64) []byte { func CalcValNodeUpdateHeightKey(height int64) []byte {
return []byte(fmt.Sprintf("LODB-valnode-Update:%18d:", height)) return []byte(fmt.Sprintf("LODB-valnode-Update:%18d:", height))
} }
// CalcValNodeBlockInfoHeightKey method
func CalcValNodeBlockInfoHeightKey(height int64) []byte { func CalcValNodeBlockInfoHeightKey(height int64) []byte {
return []byte(fmt.Sprintf("LODB-valnode-BlockInfo:%18d:", height)) return []byte(fmt.Sprintf("LODB-valnode-BlockInfo:%18d:", height))
} }
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
// ValNodeX define
var ValNodeX = "valnode" var ValNodeX = "valnode"
func init() { func init() {
...@@ -16,21 +17,24 @@ func init() { ...@@ -16,21 +17,24 @@ func init() {
types.RegisterDappFork(ValNodeX, "Enable", 0) types.RegisterDappFork(ValNodeX, "Enable", 0)
} }
// exec // ValNodeType stuct
type ValNodeType struct { type ValNodeType struct {
types.ExecTypeBase types.ExecTypeBase
} }
// NewType method
func NewType() *ValNodeType { func NewType() *ValNodeType {
c := &ValNodeType{} c := &ValNodeType{}
c.SetChild(c) c.SetChild(c)
return c return c
} }
// GetPayload method
func (t *ValNodeType) GetPayload() types.Message { func (t *ValNodeType) GetPayload() types.Message {
return &ValNodeAction{} return &ValNodeAction{}
} }
// GetTypeMap method
func (t *ValNodeType) GetTypeMap() map[string]int32 { func (t *ValNodeType) GetTypeMap() map[string]int32 {
return map[string]int32{ return map[string]int32{
"Node": ValNodeActionUpdate, "Node": ValNodeActionUpdate,
...@@ -38,6 +42,7 @@ func (t *ValNodeType) GetTypeMap() map[string]int32 { ...@@ -38,6 +42,7 @@ func (t *ValNodeType) GetTypeMap() map[string]int32 {
} }
} }
// GetLogMap method
func (t *ValNodeType) GetLogMap() map[int64]*types.LogInfo { func (t *ValNodeType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{} return map[int64]*types.LogInfo{}
} }
...@@ -251,7 +251,7 @@ type ExecutorType interface { ...@@ -251,7 +251,7 @@ type ExecutorType interface {
GetAssets(tx *Transaction) ([]*Asset, error) GetAssets(tx *Transaction) ([]*Asset, error)
} }
type ExecTypeGet interface { type execTypeGet interface {
GetTy() int32 GetTy() int32
} }
...@@ -466,7 +466,7 @@ func (base *ExecTypeBase) ActionName(tx *Transaction) string { ...@@ -466,7 +466,7 @@ func (base *ExecTypeBase) ActionName(tx *Transaction) string {
return "unknown-err" return "unknown-err"
} }
tm := base.child.GetTypeMap() tm := base.child.GetTypeMap()
if get, ok := payload.(ExecTypeGet); ok { if get, ok := payload.(execTypeGet); ok {
ty := get.GetTy() ty := get.GetTy()
for k, v := range tm { for k, v := range tm {
if v == ty { if v == ty {
......
...@@ -87,15 +87,11 @@ func ListMethodByType(typ reflect.Type) map[string]reflect.Method { ...@@ -87,15 +87,11 @@ func ListMethodByType(typ reflect.Type) map[string]reflect.Method {
return methods return methods
} }
type ExecutorAction interface {
GetTy() int32
}
var nilValue = reflect.ValueOf(nil) var nilValue = reflect.ValueOf(nil)
func GetActionValue(action interface{}, funclist map[string]reflect.Method) (string, int32, reflect.Value) { func GetActionValue(action interface{}, funclist map[string]reflect.Method) (string, int32, reflect.Value) {
var ty int32 var ty int32
if a, ok := action.(ExecutorAction); ok { if a, ok := action.(execTypeGet); ok {
ty = a.GetTy() ty = a.GetTy()
} }
value := reflect.ValueOf(action) value := reflect.ValueOf(action)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment