Commit 77b9e508 authored by Hugo's avatar Hugo

fix golint problem in tendermint and #67

parent f495782e
...@@ -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,
......
...@@ -23,13 +23,14 @@ import ( ...@@ -23,13 +23,14 @@ 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,9 +292,11 @@ func (node *Node) listenRoutine() { ...@@ -277,9 +292,11 @@ func (node *Node) listenRoutine() {
} }
} }
// StartConsensusRoutine if peers reached the threshold start consensus routine
func (node *Node) StartConsensusRoutine() { func (node *Node) StartConsensusRoutine() {
for { for {
if node.peerSet.Size() >= 0 { //TODO:the peer count need be optimized
if node.peerSet.Size() >= 1 {
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() }
// LocalAddr ...
func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.(net.Conn).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() } 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
} }
...@@ -475,7 +494,8 @@ func (client *TendermintClient) QueryValidatorsByHeight(height int64) (*tmtypes. ...@@ -475,7 +494,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
} }
...@@ -494,7 +514,8 @@ func (client *TendermintClient) QueryBlockInfoByHeight(height int64) (*tmtypes.T ...@@ -494,7 +514,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))
...@@ -506,7 +527,8 @@ func (client *TendermintClient) LoadSeenCommit(height int64) *tmtypes.Tendermint ...@@ -506,7 +527,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))
...@@ -518,7 +540,8 @@ func (client *TendermintClient) LoadBlockCommit(height int64) *tmtypes.Tendermin ...@@ -518,7 +540,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,8 @@ const fee = 1e6 ...@@ -29,7 +29,8 @@ 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 +70,7 @@ func main() { ...@@ -69,6 +70,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 +79,7 @@ func LoadHelp() { ...@@ -77,6 +79,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 +131,7 @@ func Perf(ip, size, num, interval, duration string) { ...@@ -128,6 +131,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 +168,7 @@ func Put(ip string, size string, privkey string) { ...@@ -164,6 +168,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 +214,9 @@ func setTxHeight(ip string) { ...@@ -209,8 +214,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 +251,7 @@ func genaddress() (string, crypto.PrivKey) { ...@@ -245,6 +251,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 +261,7 @@ func RandStringBytes(n int) string { ...@@ -254,6 +261,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"
......
...@@ -22,11 +22,11 @@ import ( ...@@ -22,11 +22,11 @@ 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 }
// AddEvidence ...
func (m MockEvidencePool) AddEvidence(Evidence) error { return nil } func (m MockEvidencePool) AddEvidence(Evidence) error { return nil }
// Update ...
func (m MockEvidencePool) Update(*TendermintBlock) {} 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
......
...@@ -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 = fmt.Sprintf 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,14 +136,14 @@ func (p Percent) String() string { ...@@ -127,14 +136,14 @@ 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
} }
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 +151,7 @@ func MaxInt(a, b int) int { ...@@ -142,7 +151,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 +168,7 @@ func RandIntn(n int) int { ...@@ -159,6 +168,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 +176,7 @@ func RandUint32() uint32 { ...@@ -166,6 +176,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 +184,28 @@ func RandInt63n(n int64) int64 { ...@@ -173,26 +184,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 +218,7 @@ func NewBitArray(bits int) *BitArray { ...@@ -205,6 +218,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 +226,7 @@ func (bA *BitArray) Size() int { ...@@ -212,7 +226,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 +243,7 @@ func (bA *BitArray) getIndex(i int) bool { ...@@ -229,7 +243,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 +265,7 @@ func (bA *BitArray) setIndex(i int, v bool) bool { ...@@ -251,6 +265,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 +295,7 @@ func (bA *BitArray) copyBits(bits int) *BitArray { ...@@ -280,7 +295,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 +315,7 @@ func (bA *BitArray) Or(o *BitArray) *BitArray { ...@@ -300,7 +315,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 +333,7 @@ func (bA *BitArray) and(o *BitArray) *BitArray { ...@@ -318,6 +333,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 +347,7 @@ func (bA *BitArray) Not() *BitArray { ...@@ -331,6 +347,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 +371,7 @@ func (bA *BitArray) Sub(o *BitArray) *BitArray { ...@@ -354,6 +371,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 +386,7 @@ func (bA *BitArray) IsEmpty() bool { ...@@ -368,6 +386,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 +407,7 @@ func (bA *BitArray) IsFull() bool { ...@@ -388,6 +407,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 +460,7 @@ func (bA *BitArray) String() string { ...@@ -440,6 +460,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 +497,7 @@ func (bA *BitArray) stringIndented(indent string) string { ...@@ -476,6 +497,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 +512,7 @@ func (bA *BitArray) Bytes() []byte { ...@@ -490,7 +512,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 +525,12 @@ func (bA *BitArray) Update(o *BitArray) { ...@@ -503,12 +525,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 +544,27 @@ Example usage: ...@@ -522,22 +544,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 +572,12 @@ func (h *Heap) Peek() interface{} { ...@@ -545,10 +572,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 {
......
...@@ -11,6 +11,9 @@ import ( ...@@ -11,6 +11,9 @@ import (
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
...@@ -18,6 +21,9 @@ func (val *ValNode) ExecDelLocal_Node(node *pty.ValNode, tx *types.Transaction, ...@@ -18,6 +21,9 @@ func (val *ValNode) ExecDelLocal_Node(node *pty.ValNode, tx *types.Transaction,
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
......
...@@ -13,6 +13,9 @@ import ( ...@@ -13,6 +13,9 @@ import (
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")
} }
...@@ -27,6 +30,9 @@ func (val *ValNode) ExecLocal_Node(node *pty.ValNode, tx *types.Transaction, rec ...@@ -27,6 +30,9 @@ func (val *ValNode) ExecLocal_Node(node *pty.ValNode, tx *types.Transaction, rec
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
......
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