Commit fceee563 authored by caopingcp's avatar caopingcp

tendermint remove evidence part

parent 7915e316
......@@ -65,8 +65,6 @@ type ConsensusState struct {
// TODO: encapsulate all of this in one "BlockManager"
blockExec *BlockExecutor
evpool ttypes.EvidencePool
// internal state
mtx sync.Mutex
ttypes.RoundState
......@@ -97,14 +95,13 @@ type ConsensusState struct {
}
// NewConsensusState returns a new ConsensusState.
func NewConsensusState(client *Client, state State, blockExec *BlockExecutor, evpool ttypes.EvidencePool) *ConsensusState {
func NewConsensusState(client *Client, state State, blockExec *BlockExecutor) *ConsensusState {
cs := &ConsensusState{
client: client,
blockExec: blockExec,
peerMsgQueue: make(chan MsgInfo, msgQueueSize),
internalMsgQueue: make(chan MsgInfo, msgQueueSize),
timeoutTicker: NewTimeoutTicker(),
evpool: evpool,
Quit: make(chan struct{}),
txsAvailable: make(chan int64, 1),
......@@ -554,9 +551,6 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
// We've already reset these upon new height,
// and meanwhile we might have received a proposal
// for round 0.
if cs.begCons.IsZero() {
cs.begCons = time.Now()
}
} else {
tendermintlog.Info("Resetting Proposal info")
cs.Proposal = nil
......@@ -756,9 +750,6 @@ func (cs *ConsensusState) createProposalBlock() (block *ttypes.TendermintBlock)
return nil
}
block.Data = pblockNew
evidence := cs.evpool.PendingEvidence()
block.AddEvidence(evidence)
return block
}
......@@ -1277,13 +1268,11 @@ func (cs *ConsensusState) tryAddVote(voteRaw *tmtypes.Vote, peerID string, peerI
// If it's otherwise invalid, punish peer.
if err == ErrVoteHeightMismatch {
return err
} else if voteErr, ok := err.(*ttypes.ErrVoteConflictingVotes); ok {
} else if err == ttypes.ErrVoteConflict {
if bytes.Equal(vote.ValidatorAddress, cs.privValidator.GetAddress()) {
tendermintlog.Error("Found conflicting vote from ourselves. Did you unsafe_reset a validator?", "height", vote.Height, "round", vote.Round, "type", vote.Type)
return err
}
err = cs.evpool.AddEvidence(voteErr.DuplicateVoteEvidence)
return err
} else {
// Probably an invalid signature / Bad peer.
// Seems this can also err sometimes with "Unexpected step" - perhaps not from a bad peer ?
......@@ -1339,6 +1328,10 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
return
}
if cs.begCons.IsZero() {
cs.begCons = time.Now()
}
height := cs.Height
added, err = cs.Votes.AddVote(vote, peerID)
if !added {
......
This diff is collapsed.
......@@ -21,16 +21,14 @@ import (
// BlockExecutor provides the context and accessories for properly executing a block.
type BlockExecutor struct {
// save state, validators, consensus params, abci responses here
db *CSStateDB
evpool ttypes.EvidencePool
db *CSStateDB
}
// NewBlockExecutor returns a new BlockExecutor with a NopEventBus.
// Call SetEventBus to provide one.
func NewBlockExecutor(db *CSStateDB, evpool ttypes.EvidencePool) *BlockExecutor {
func NewBlockExecutor(db *CSStateDB) *BlockExecutor {
return &BlockExecutor{
db: db,
evpool: evpool,
db: db,
}
}
......@@ -59,12 +57,6 @@ func (blockExec *BlockExecutor) ApplyBlock(s State, blockID ttypes.BlockID, bloc
}
blockExec.db.SaveState(s)
// Update evpool now that state is saved
// TODO: handle the crash/recover scenario
// ie. (may need to call Update for last block)
blockExec.evpool.Update(block)
return s, nil
}
......@@ -246,13 +238,5 @@ func validateBlock(stateDB *CSStateDB, s State, b *ttypes.TendermintBlock) error
}
}
for _, ev := range b.Evidence.Evidence {
evidence := ttypes.EvidenceEnvelope2Evidence(ev)
if evidence != nil {
if err := VerifyEvidence(stateDB, s, evidence); err != nil {
return ttypes.NewEvidenceInvalidErr(evidence, err)
}
}
}
return nil
}
......@@ -17,8 +17,6 @@ import (
"github.com/33cn/chain33/common/crypto"
ttypes "github.com/33cn/plugin/plugin/consensus/tendermint/types"
tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types"
"github.com/golang/protobuf/proto"
)
const (
......@@ -132,7 +130,6 @@ type Node struct {
lAddr string
state *ConsensusState
evpool *EvidencePool
broadcastChannel chan MsgInfo
started uint32 // atomic
stopped uint32 // atomic
......@@ -140,7 +137,7 @@ type Node 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) *Node {
address := GenAddressByPubKey(privKey.PubKey())
node := &Node{
......@@ -158,7 +155,6 @@ func NewNode(seeds []string, protocol string, lAddr string, privKey crypto.PrivK
reconnecting: NewMutexMap(),
broadcastChannel: make(chan MsgInfo, maxSendQueueSize),
state: state,
evpool: evpool,
localIPs: make(map[string]net.IP),
}
......@@ -219,7 +215,6 @@ func (node *Node) Start() {
go node.StartConsensusRoutine()
go node.BroadcastRoutine()
go node.evidenceBroadcastRoutine()
}
}
......@@ -234,7 +229,7 @@ func (node *Node) DialPeerWithAddress(addr string) error {
func (node *Node) addOutboundPeerWithConfig(addr string) error {
tendermintlog.Info("Dialing peer", "address", addr)
peerConn, err := newOutboundPeerConn(addr, node.privKey, node.StopPeerForError, node.state, node.evpool)
peerConn, err := newOutboundPeerConn(addr, node.privKey, node.StopPeerForError, node.state)
if err != nil {
go node.reconnectToPeer(addr)
return err
......@@ -307,66 +302,6 @@ func (node *Node) StartConsensusRoutine() {
}
}
func (node *Node) evidenceBroadcastRoutine() {
ticker := time.NewTicker(time.Second * broadcastEvidenceIntervalS)
for {
select {
case evidence := <-node.evpool.EvidenceChan():
// broadcast some new evidence
data, err := proto.Marshal(evidence.Child())
if err != nil {
msg := MsgInfo{TypeID: ttypes.EvidenceListID,
Msg: &tmtypes.EvidenceData{
Evidence: []*tmtypes.EvidenceEnvelope{
{
TypeName: evidence.TypeName(),
Data: data,
},
},
},
PeerID: node.ID, PeerIP: node.IP,
}
node.Broadcast(msg)
// TODO: Broadcast runs asynchronously, so this should wait on the successChan
// in another routine before marking to be proper.
node.evpool.evidenceStore.MarkEvidenceAsBroadcasted(evidence)
}
case <-ticker.C:
// broadcast all pending evidence
var eData tmtypes.EvidenceData
evidence := node.evpool.PendingEvidence()
for _, item := range evidence {
ev := item.Child()
if ev != nil {
data, err := proto.Marshal(ev)
if err != nil {
panic("AddEvidence marshal failed")
}
env := &tmtypes.EvidenceEnvelope{
TypeName: item.TypeName(),
Data: data,
}
eData.Evidence = append(eData.Evidence, env)
}
}
msg := MsgInfo{TypeID: ttypes.EvidenceListID,
Msg: &eData,
PeerID: node.ID,
PeerIP: node.IP,
}
node.Broadcast(msg)
case _, ok := <-node.quit:
if !ok {
node.quit = nil
tendermintlog.Info("evidenceBroadcastRoutine quit")
return
}
}
}
}
// BroadcastRoutine receive to broadcast
func (node *Node) BroadcastRoutine() {
for {
......@@ -413,7 +348,7 @@ func (node *Node) StopPeerForError(peer Peer, reason interface{}) {
}
func (node *Node) addInboundPeer(conn net.Conn) error {
peerConn, err := newInboundPeerConn(conn, node.privKey, node.StopPeerForError, node.state, node.evpool)
peerConn, err := newInboundPeerConn(conn, node.privKey, node.StopPeerForError, node.state)
if err != nil {
if er := conn.Close(); er != nil {
tendermintlog.Error("addInboundPeer close conn failed", "er", er)
......@@ -710,13 +645,13 @@ func dial(addr string) (net.Conn, error) {
return conn, nil
}
func newOutboundPeerConn(addr string, ourNodePrivKey crypto.PrivKey, onPeerError func(Peer, interface{}), state *ConsensusState, evpool *EvidencePool) (*peerConn, error) {
func newOutboundPeerConn(addr string, ourNodePrivKey crypto.PrivKey, onPeerError func(Peer, interface{}), state *ConsensusState) (*peerConn, error) {
conn, err := dial(addr)
if err != nil {
return &peerConn{}, fmt.Errorf("Error creating peer:%v", err)
}
pc, err := newPeerConn(conn, true, true, ourNodePrivKey, onPeerError, state, evpool)
pc, err := newPeerConn(conn, true, true, ourNodePrivKey, onPeerError, state)
if err != nil {
if cerr := conn.Close(); cerr != nil {
return &peerConn{}, fmt.Errorf("newPeerConn failed:%v, connection close failed:%v", err, cerr)
......@@ -732,12 +667,11 @@ func newInboundPeerConn(
ourNodePrivKey crypto.PrivKey,
onPeerError func(Peer, interface{}),
state *ConsensusState,
evpool *EvidencePool,
) (*peerConn, error) {
// TODO: issue PoW challenge
return newPeerConn(conn, false, false, ourNodePrivKey, onPeerError, state, evpool)
return newPeerConn(conn, false, false, ourNodePrivKey, onPeerError, state)
}
func newPeerConn(
......@@ -746,7 +680,6 @@ func newPeerConn(
ourNodePrivKey crypto.PrivKey,
onPeerError func(Peer, interface{}),
state *ConsensusState,
evpool *EvidencePool,
) (pc *peerConn, err error) {
conn := rawConn
......@@ -769,6 +702,5 @@ func newPeerConn(
conn: conn,
onPeerError: onPeerError,
myState: state,
myevpool: evpool,
}, nil
}
......@@ -94,8 +94,7 @@ type peerConn struct {
onPeerError func(Peer, interface{})
myState *ConsensusState
myevpool *EvidencePool
myState *ConsensusState
state *PeerConnState
updateStateQueue chan MsgInfo
......@@ -579,19 +578,6 @@ FOR_LOOP:
}
} else if pkt.TypeID == ttypes.ProposalHeartbeatID {
pc.heartbeatQueue <- realMsg.(*tmtypes.Heartbeat)
} else if pkt.TypeID == ttypes.EvidenceListID {
go func() {
for _, ev := range realMsg.(*tmtypes.EvidenceData).Evidence {
evidence := ttypes.EvidenceEnvelope2Evidence(ev)
if evidence != nil {
err := pc.myevpool.AddEvidence(evidence.(ttypes.Evidence))
if err != nil {
tendermintlog.Error("Evidence is not valid", "evidence", ev, "err", err)
// TODO: punish peer
}
}
}
}()
} else {
pc.updateStateQueue <- MsgInfo{pkt.TypeID, realMsg.(proto.Message), pc.ID(), pc.ip.String()}
}
......
......@@ -295,15 +295,11 @@ OuterLoop:
stateDB := NewStateDB(client, state)
//make evidenceReactor
evidenceStore := NewEvidenceStore(client.evidenceDB)
evidencePool := NewEvidencePool(stateDB, state, evidenceStore)
// make block executor for consensus and blockchain reactors to execute blocks
blockExec := NewBlockExecutor(stateDB, evidencePool)
blockExec := NewBlockExecutor(stateDB)
// Make ConsensusReactor
csState := NewConsensusState(client, state, blockExec, evidencePool)
csState := NewConsensusState(client, state, blockExec)
// reset height, round, state begin at newheigt,0,0
client.privValidator.ResetLastHeight(state.LastBlockHeight)
csState.SetPrivValidator(client.privValidator)
......@@ -312,7 +308,7 @@ OuterLoop:
// Create & add listener
protocol, listeningAddress := "tcp", "0.0.0.0:46656"
node := NewNode(validatorNodes, protocol, listeningAddress, client.privKey, state.ChainID, tendermintVersion, csState, evidencePool)
node := NewNode(validatorNodes, protocol, listeningAddress, client.privKey, state.ChainID, tendermintVersion, csState)
client.node = node
node.Start()
......
......@@ -17,7 +17,6 @@ import (
"github.com/33cn/chain33/common/merkle"
"github.com/33cn/chain33/types"
tmtypes "github.com/33cn/plugin/plugin/dapp/valnode/types"
"github.com/golang/protobuf/proto"
)
var (
......@@ -69,32 +68,12 @@ func MakeBlock(height int64, round int64, pblock *types.Block, commit *tmtypes.T
},
Data: pblock,
LastCommit: commit,
Evidence: &tmtypes.EvidenceData{Evidence: make([]*tmtypes.EvidenceEnvelope, 0)},
},
}
block.FillHeader()
return block
}
// AddEvidence appends the given evidence to the block
func (b *TendermintBlock) AddEvidence(evidence []Evidence) {
for _, item := range evidence {
ev := item.Child()
if ev != nil {
data, err := proto.Marshal(ev)
if err != nil {
blocklog.Error("AddEvidence marshal failed", "error", err)
panic("AddEvidence marshal failed")
}
env := &tmtypes.EvidenceEnvelope{
TypeName: item.TypeName(),
Data: data,
}
b.Evidence.Evidence = append(b.Evidence.Evidence, env)
}
}
}
// ValidateBasic performs basic validation that doesn't involve state data.
// It checks the internal consistency of the block.
// Further validation is done using state#ValidateBlock.
......@@ -133,10 +112,6 @@ func (b *TendermintBlock) ValidateBasic() error {
return fmt.Errorf("Wrong Header.LastCommitHash. Expected %v, got %v", b.Header.LastCommitHash, lastCommit.Hash())
}
evidence := &EvidenceData{EvidenceData: b.Evidence}
if !bytes.Equal(b.Header.EvidenceHash, evidence.Hash()) {
return errors.New(Fmt("Wrong Header.EvidenceHash. Expected %v, got %v", b.Header.EvidenceHash, evidence.Hash()))
}
return nil
}
......@@ -148,10 +123,6 @@ func (b *TendermintBlock) FillHeader() {
}
b.Header.LastCommitHash = lastCommit.Hash()
}
if b.Header.EvidenceHash == nil {
evidence := &EvidenceData{EvidenceData: b.Evidence}
b.Header.EvidenceHash = evidence.Hash()
}
}
// Hash computes and returns the block hash.
......@@ -246,7 +217,6 @@ func (h *Header) StringIndented(indent string) string {
%s App: %v
%s Conensus: %v
%s Results: %v
%s Evidence: %v
%s}#%v`,
indent, h.ChainID,
indent, h.Height,
......@@ -259,7 +229,6 @@ func (h *Header) StringIndented(indent string) string {
indent, h.AppHash,
indent, h.ConsensusHash,
indent, h.LastResultsHash,
indent, h.EvidenceHash,
indent, h.Hash())
}
......@@ -410,113 +379,3 @@ type SignedHeader struct {
Header *Header `json:"header"`
Commit *Commit `json:"commit"`
}
// EvidenceEnvelope ...
type EvidenceEnvelope struct {
*tmtypes.EvidenceEnvelope
}
// EvidenceEnvelopeList contains any evidence of malicious wrong-doing by validators
type EvidenceEnvelopeList []EvidenceEnvelope
// Hash ...
func (env EvidenceEnvelope) Hash() []byte {
penv := env.EvidenceEnvelope
evidence := EvidenceEnvelope2Evidence(penv)
if evidence != nil {
return evidence.Hash()
}
return nil
}
func (env EvidenceEnvelope) String() string {
penv := env.EvidenceEnvelope
evidence := EvidenceEnvelope2Evidence(penv)
if evidence != nil {
return evidence.String()
}
return ""
}
// Hash returns the simple merkle root hash of the EvidenceList.
func (evl EvidenceEnvelopeList) Hash() []byte {
// Recursive impl.
// Copied from tmlibs/merkle to avoid allocations
switch len(evl) {
case 0:
return nil
case 1:
return evl[0].Hash()
default:
left := evl[:(len(evl)+1)/2].Hash()
right := evl[(len(evl)+1)/2:].Hash()
cache := make([]byte, len(left)+len(right))
return merkle.GetHashFromTwoHash(cache, left, right)
}
}
func (evl EvidenceEnvelopeList) String() string {
s := ""
for _, e := range evl {
s += Fmt("%s\t\t", e)
}
return s
}
// Has returns true if the evidence is in the EvidenceList.
func (evl EvidenceEnvelopeList) Has(evidence Evidence) bool {
for _, ev := range evl {
penv := ev.EvidenceEnvelope
tmp := EvidenceEnvelope2Evidence(penv)
if tmp != nil {
if tmp.Equal(evidence) {
return true
}
}
}
return false
}
// EvidenceData ...
type EvidenceData struct {
*tmtypes.EvidenceData
hash []byte
}
// Hash returns the hash of the data.
func (data *EvidenceData) Hash() []byte {
if data.hash == nil {
if data.EvidenceData == nil {
return nil
}
var evidence EvidenceEnvelopeList
for _, item := range data.Evidence {
elem := EvidenceEnvelope{
EvidenceEnvelope: item,
}
evidence = append(evidence, elem)
}
data.hash = evidence.Hash()
}
return data.hash
}
// StringIndented returns a string representation of the evidence.
func (data *EvidenceData) StringIndented(indent string) string {
if data == nil {
return "nil-Evidence"
}
evStrings := make([]string, MinInt(len(data.Evidence), 21))
for i, ev := range data.Evidence {
if i == 20 {
evStrings[i] = Fmt("... (%v total)", len(data.Evidence))
break
}
evStrings[i] = Fmt("Evidence:%v", ev)
}
return Fmt(`Data{
%s %v
%s}#%v`,
indent, strings.Join(evStrings, "\n"+indent+" "),
indent, data.hash)
}
This diff is collapsed.
......@@ -32,7 +32,6 @@ const (
RoundStepCommit = RoundStepType(0x08) // Entered commit state machine
// NOTE: RoundStepNewHeight acts as RoundStepCommitWait.
EvidenceListID = byte(0x01)
NewRoundStepID = byte(0x02)
CommitStepID = byte(0x03)
ProposalID = byte(0x04)
......@@ -52,7 +51,6 @@ const (
// InitMessageMap ...
func InitMessageMap() {
MsgMap = map[byte]reflect.Type{
EvidenceListID: reflect.TypeOf(tmtypes.EvidenceData{}),
NewRoundStepID: reflect.TypeOf(tmtypes.NewRoundStepMsg{}),
CommitStepID: reflect.TypeOf(tmtypes.CommitStepMsg{}),
ProposalID: reflect.TypeOf(tmtypes.Proposal{}),
......@@ -121,9 +119,9 @@ type RoundState struct {
// RoundStateMessage ...
func (rs *RoundState) RoundStateMessage() *tmtypes.NewRoundStepMsg {
return &tmtypes.NewRoundStepMsg{
Height: rs.Height,
Round: int32(rs.Round),
Step: int32(rs.Step),
Height: rs.Height,
Round: int32(rs.Round),
Step: int32(rs.Step),
SecondsSinceStartTime: int32(time.Since(rs.StartTime).Seconds()),
LastCommitRound: int32(rs.LastCommit.Round()),
}
......
......@@ -25,6 +25,7 @@ var (
ErrVoteInvalidSignature = errors.New("Invalid signature")
ErrVoteInvalidBlockHash = errors.New("Invalid block hash")
ErrVoteNonDeterministicSignature = errors.New("Non-deterministic signature")
ErrVoteConflict = errors.New("Conflicting vote")
ErrVoteNil = errors.New("Nil vote")
votelog = log15.New("module", "tendermint-vote")
)
......@@ -119,34 +120,6 @@ func (heartbeat *Heartbeat) WriteSignBytes(chainID string, w io.Writer, n *int,
*err = writeErr
}
// ErrVoteConflictingVotes ...
type ErrVoteConflictingVotes struct {
*DuplicateVoteEvidence
}
func (err *ErrVoteConflictingVotes) Error() string {
pubkey, error := PubKeyFromString(err.PubKey)
if error != nil {
return fmt.Sprintf("Conflicting votes from validator PubKey:%v,error:%v", err.PubKey, error)
}
addr := GenAddressByPubKey(pubkey)
return fmt.Sprintf("Conflicting votes from validator %v", addr)
}
// NewConflictingVoteError ...
func NewConflictingVoteError(val *Validator, voteA, voteB *tmtypes.Vote) *ErrVoteConflictingVotes {
keyString := fmt.Sprintf("%X", val.PubKey)
return &ErrVoteConflictingVotes{
&DuplicateVoteEvidence{
&tmtypes.DuplicateVoteEvidence{
PubKey: keyString,
VoteA: voteA,
VoteB: voteB,
},
},
}
}
// Types of votes
// TODO Make a new type "VoteType"
const (
......
......@@ -200,7 +200,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
// Add vote and get conflicting vote if any
added, conflicting := voteSet.addVerifiedVote(vote, blockKey, val.VotingPower)
if conflicting != nil {
return added, NewConflictingVoteError(val, conflicting.Vote, vote.Vote)
return added, errors.Wrapf(ErrVoteConflict, "Conflicting vote: %v; New vote: %v", conflicting, vote)
}
if !added {
PanicSanity("Expected to add non-conflicting vote")
......
......@@ -87,20 +87,6 @@ message State {
bytes AppHash = 12;
}
message DuplicateVoteEvidence {
string pubKey = 1;
Vote voteA = 2;
Vote voteB = 3;
}
message EvidenceEnvelope {
string typeName = 1;
bytes data = 2;
}
message EvidenceData {
repeated EvidenceEnvelope evidence = 1;
}
message TendermintBlockHeader {
string chainID = 1;
......@@ -115,14 +101,12 @@ message TendermintBlockHeader {
bytes consensusHash = 10;
bytes appHash = 11;
bytes lastResultsHash = 12;
bytes evidenceHash = 13;
bytes proposerAddr = 14;
bytes proposerAddr = 13;
}
message TendermintBlock {
TendermintBlockHeader header = 1;
Block data = 2;
EvidenceData evidence = 3;
TendermintCommit lastCommit = 4;
}
......
This diff is collapsed.
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