Compare commits

...

9 Commits

Author SHA1 Message Date
Christopher Goes
73de99ecab Set evidence.Type 2018-05-31 06:35:26 +02:00
Christopher Goes
2046b346a1 Merge pull request #1652 from tendermint/cwgoes/abci-evidence-type-constants
Constants for evidence types
2018-05-31 05:24:47 +02:00
Christopher Goes
c9514f077b DUPLICATE_VOTE evidence type 2018-05-31 05:24:15 +02:00
Christopher Goes
3bf9a7dc50 Validator public key, not address (somehow this was lost in cherry-pick) 2018-05-29 07:51:28 +02:00
Christopher Goes
53b0c67f75 Switch to tagged ABCI version 2018-05-29 05:49:33 +02:00
Christopher Goes
3b8c1ae119 Pin to an ABCI version 2018-05-29 04:59:18 +02:00
Christopher Goes
849ffaf43d Cherry-pick 2018-05-29 01:02:44 +02:00
Christopher Goes
058867669e Pass validator set to ExecCommitBlock, update testcases 2018-05-29 00:50:44 +02:00
Christopher Goes
923e0b02bf Retarget 2018-05-29 00:49:57 +02:00
6 changed files with 37 additions and 28 deletions

6
Gopkg.lock generated
View File

@@ -238,8 +238,8 @@
"server", "server",
"types" "types"
] ]
revision = "78a8905690ef54f9d57e3b2b0ee7ad3a04ef3f1f" revision = "f9dce537281ffba5d1e047e6729429f7e5fb90c9"
version = "v0.10.3" version = "v0.11.0-rc0"
[[projects]] [[projects]]
branch = "master" branch = "master"
@@ -382,6 +382,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "d85c98dcac32cc1fe05d006aa75e8985f6447a150a041b972a673a65e7681da9" inputs-digest = "90dc14750c1499107a3e6728ae696f9977f56bee2855c2f1c0a14831a165cc0e"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@@ -71,7 +71,7 @@
[[constraint]] [[constraint]]
name = "github.com/tendermint/abci" name = "github.com/tendermint/abci"
version = "~0.10.3" version = "0.11.0-rc0"
[[constraint]] [[constraint]]
name = "github.com/tendermint/go-crypto" name = "github.com/tendermint/go-crypto"

View File

@@ -269,8 +269,8 @@ func (h *Handshaker) ReplayBlocks(state sm.State, appHash []byte, appBlockHeight
if appBlockHeight == 0 { if appBlockHeight == 0 {
validators := types.TM2PB.Validators(state.Validators) validators := types.TM2PB.Validators(state.Validators)
req := abci.RequestInitChain{ req := abci.RequestInitChain{
Validators: validators, Validators: validators,
AppStateBytes: h.appState, GenesisBytes: h.appState,
} }
_, err := proxyApp.Consensus().InitChainSync(req) _, err := proxyApp.Consensus().InitChainSync(req)
if err != nil { if err != nil {
@@ -365,7 +365,8 @@ func (h *Handshaker) replayBlocks(state sm.State, proxyApp proxy.AppConns, appBl
for i := appBlockHeight + 1; i <= finalBlock; i++ { for i := appBlockHeight + 1; i <= finalBlock; i++ {
h.logger.Info("Applying block", "height", i) h.logger.Info("Applying block", "height", i)
block := h.store.LoadBlock(i) block := h.store.LoadBlock(i)
appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger) appHash, err = sm.ExecCommitBlock(proxyApp.Consensus(), block, h.logger, new(types.ValidatorSet))
// TODO: Temporary, see above comment.
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -74,7 +74,7 @@ func (blockExec *BlockExecutor) ApplyBlock(s State, blockID types.BlockID, block
return s, ErrInvalidBlock(err) return s, ErrInvalidBlock(err)
} }
abciResponses, err := execBlockOnProxyApp(blockExec.logger, blockExec.proxyApp, block) abciResponses, err := execBlockOnProxyApp(blockExec.logger, blockExec.proxyApp, block, s.Validators)
if err != nil { if err != nil {
return s, ErrProxyAppConn(err) return s, ErrProxyAppConn(err)
} }
@@ -160,7 +160,7 @@ func (blockExec *BlockExecutor) Commit(block *types.Block) ([]byte, error) {
// Executes block's transactions on proxyAppConn. // Executes block's transactions on proxyAppConn.
// Returns a list of transaction results and updates to the validator set // Returns a list of transaction results and updates to the validator set
func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus, block *types.Block) (*ABCIResponses, error) { func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus, block *types.Block, vs *types.ValidatorSet) (*ABCIResponses, error) {
var validTxs, invalidTxs = 0, 0 var validTxs, invalidTxs = 0, 0
txIndex := 0 txIndex := 0
@@ -187,10 +187,11 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus,
proxyAppConn.SetResponseCallback(proxyCb) proxyAppConn.SetResponseCallback(proxyCb)
// determine which validators did not sign last block // determine which validators did not sign last block
absentVals := make([]int32, 0) absentVals := make([][]byte, 0)
for valI, vote := range block.LastCommit.Precommits { for valI, vote := range block.LastCommit.Precommits {
if vote == nil { if vote == nil {
absentVals = append(absentVals, int32(valI)) _, val := vs.GetByIndex(valI)
absentVals = append(absentVals, val.PubKey.Bytes())
} }
} }
@@ -198,6 +199,7 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus,
byzantineVals := make([]abci.Evidence, len(block.Evidence.Evidence)) byzantineVals := make([]abci.Evidence, len(block.Evidence.Evidence))
for i, ev := range block.Evidence.Evidence { for i, ev := range block.Evidence.Evidence {
byzantineVals[i] = abci.Evidence{ byzantineVals[i] = abci.Evidence{
Type: []byte(ev.String()),
PubKey: ev.Address(), // XXX PubKey: ev.Address(), // XXX
Height: ev.Height(), Height: ev.Height(),
} }
@@ -359,8 +361,8 @@ func fireEvents(logger log.Logger, eventBus types.BlockEventPublisher, block *ty
// ExecCommitBlock executes and commits a block on the proxyApp without validating or mutating the state. // ExecCommitBlock executes and commits a block on the proxyApp without validating or mutating the state.
// It returns the application root hash (result of abci.Commit). // It returns the application root hash (result of abci.Commit).
func ExecCommitBlock(appConnConsensus proxy.AppConnConsensus, block *types.Block, logger log.Logger) ([]byte, error) { func ExecCommitBlock(appConnConsensus proxy.AppConnConsensus, block *types.Block, logger log.Logger, vs *types.ValidatorSet) ([]byte, error) {
_, err := execBlockOnProxyApp(logger, appConnConsensus, block) _, err := execBlockOnProxyApp(logger, appConnConsensus, block, vs)
if err != nil { if err != nil {
logger.Error("Error executing block on proxy app", "height", block.Height, "err", err) logger.Error("Error executing block on proxy app", "height", block.Height, "err", err)
return nil, err return nil, err

View File

@@ -18,7 +18,8 @@ import (
) )
var ( var (
privKey = crypto.GenPrivKeyEd25519FromSecret([]byte("execution_test")) privKey = crypto.GenPrivKeyEd25519FromSecret([]byte("execution_test_1"))
privKey2 = crypto.GenPrivKeyEd25519FromSecret([]byte("execution_test_2"))
chainID = "execution_chain" chainID = "execution_chain"
testPartSize = 65536 testPartSize = 65536
nTxsPerBlock = 10 nTxsPerBlock = 10
@@ -64,18 +65,18 @@ func TestBeginBlockAbsentValidators(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
lastCommitPrecommits []*types.Vote lastCommitPrecommits []*types.Vote
expectedAbsentValidators []int32 expectedAbsentValidators [][]byte
}{ }{
{"none absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit}, {ValidatorIndex: 1, Timestamp: now}}, []int32{}}, {"none absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit}, {ValidatorIndex: 1, Timestamp: now}}, [][]byte{}},
{"one absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit}, nil}, []int32{1}}, {"one absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit}, nil}, [][]byte{privKey2.PubKey().Bytes()}},
{"multiple absent", []*types.Vote{nil, nil}, []int32{0, 1}}, {"multiple absent", []*types.Vote{nil, nil}, [][]byte{privKey.PubKey().Bytes(), privKey2.PubKey().Bytes()}},
} }
for _, tc := range testCases { for _, tc := range testCases {
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits} lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit) block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger()) _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators)
require.Nil(t, err, tc.desc) require.Nil(t, err, tc.desc)
// -> app must receive an index of the absent validator // -> app must receive an index of the absent validator
@@ -109,10 +110,10 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
expectedByzantineValidators []abci.Evidence expectedByzantineValidators []abci.Evidence
}{ }{
{"none byzantine", []types.Evidence{}, []abci.Evidence{}}, {"none byzantine", []types.Evidence{}, []abci.Evidence{}},
{"one byzantine", []types.Evidence{ev1}, []abci.Evidence{{ev1.Address(), ev1.Height()}}}, {"one byzantine", []types.Evidence{ev1}, []abci.Evidence{{[]byte(ev1.String()), ev1.Address(), ev1.Height(), int64(0)}}},
{"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{ {"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{
{ev1.Address(), ev1.Height()}, {[]byte(ev1.String()), ev1.Address(), ev1.Height(), int64(0)},
{ev2.Address(), ev2.Height()}}}, {[]byte(ev2.String()), ev2.Address(), ev2.Height(), int64(0)}}},
} }
for _, tc := range testCases { for _, tc := range testCases {
@@ -120,7 +121,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit) block, _ := state.MakeBlock(10, makeTxs(2), lastCommit)
block.Evidence.Evidence = tc.evidence block.Evidence.Evidence = tc.evidence
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger()) _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators)
require.Nil(t, err, tc.desc) require.Nil(t, err, tc.desc)
// -> app must receive an index of the byzantine validator // -> app must receive an index of the byzantine validator
@@ -142,7 +143,8 @@ func state() State {
s, _ := MakeGenesisState(&types.GenesisDoc{ s, _ := MakeGenesisState(&types.GenesisDoc{
ChainID: chainID, ChainID: chainID,
Validators: []types.GenesisValidator{ Validators: []types.GenesisValidator{
{privKey.PubKey(), 10000, "test"}, {privKey.PubKey(), 10000, "test1"},
{privKey2.PubKey(), 10000, "test2"},
}, },
AppHash: nil, AppHash: nil,
}) })
@@ -161,7 +163,7 @@ var _ abci.Application = (*testApp)(nil)
type testApp struct { type testApp struct {
abci.BaseApplication abci.BaseApplication
AbsentValidators []int32 AbsentValidators [][]byte
ByzantineValidators []abci.Evidence ByzantineValidators []abci.Evidence
} }

View File

@@ -9,6 +9,11 @@ import (
"github.com/tendermint/tmlibs/merkle" "github.com/tendermint/tmlibs/merkle"
) )
const (
// Evidence type for duplicate vote
DUPLICATE_VOTE = "DUPLICATE_VOTE"
)
// ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid. // ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid.
type ErrEvidenceInvalid struct { type ErrEvidenceInvalid struct {
Evidence Evidence Evidence Evidence
@@ -35,7 +40,7 @@ type Evidence interface {
Verify(chainID string) error // verify the evidence Verify(chainID string) error // verify the evidence
Equal(Evidence) bool // check equality of evidence Equal(Evidence) bool // check equality of evidence
String() string String() string // used as type in abci.Evidence
} }
func RegisterEvidences(cdc *amino.Codec) { func RegisterEvidences(cdc *amino.Codec) {
@@ -54,8 +59,7 @@ type DuplicateVoteEvidence struct {
// String returns a string representation of the evidence. // String returns a string representation of the evidence.
func (dve *DuplicateVoteEvidence) String() string { func (dve *DuplicateVoteEvidence) String() string {
return fmt.Sprintf("VoteA: %v; VoteB: %v", dve.VoteA, dve.VoteB) return DUPLICATE_VOTE
} }
// Height returns the height this evidence refers to. // Height returns the height this evidence refers to.