Skip to content

Commit 868570b

Browse files
authored
Merge pull request #146 from getamis/feature/avoid_bad_block
avoid bad block
2 parents 88d667b + cd0c67d commit 868570b

File tree

15 files changed

+69
-18
lines changed

15 files changed

+69
-18
lines changed

consensus/consensus.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ type Istanbul interface {
121121
Engine
122122

123123
// Start starts the engine
124-
Start(chain ChainReader, currentBlock func() *types.Block) error
124+
Start(chain ChainReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error
125125

126126
// Stop stops the engine
127127
Stop() error

consensus/istanbul/backend.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,7 @@ type Backend interface {
6767

6868
// ParentValidators returns the validator set of the given proposal's parent block
6969
ParentValidators(proposal Proposal) ValidatorSet
70+
71+
// HasBadBlock returns whether the block with the hash is a bad block
72+
HasBadProposal(hash common.Hash) bool
7073
}

consensus/istanbul/backend/backend.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/ethereum/go-ethereum/consensus/istanbul"
2828
istanbulCore "github.com/ethereum/go-ethereum/consensus/istanbul/core"
2929
"github.com/ethereum/go-ethereum/consensus/istanbul/validator"
30+
"github.com/ethereum/go-ethereum/core"
3031
"github.com/ethereum/go-ethereum/core/types"
3132
"github.com/ethereum/go-ethereum/crypto"
3233
"github.com/ethereum/go-ethereum/ethdb"
@@ -76,6 +77,7 @@ type backend struct {
7677
db ethdb.Database
7778
chain consensus.ChainReader
7879
currentBlock func() *types.Block
80+
hasBadBlock func(hash common.Hash) bool
7981

8082
// the channels for istanbul engine notifications
8183
commitCh chan *types.Block
@@ -208,6 +210,22 @@ func (sb *backend) Verify(proposal istanbul.Proposal) (time.Duration, error) {
208210
sb.logger.Error("Invalid proposal, %v", proposal)
209211
return 0, errInvalidProposal
210212
}
213+
214+
// check bad block
215+
if sb.HasBadProposal(block.Hash()) {
216+
return 0, core.ErrBlacklistedHash
217+
}
218+
219+
// check block body
220+
txnHash := types.DeriveSha(block.Transactions())
221+
uncleHash := types.CalcUncleHash(block.Uncles())
222+
if txnHash != block.Header().TxHash {
223+
return 0, errMismatchTxhashes
224+
}
225+
if uncleHash != nilUncleHash {
226+
return 0, errInvalidUncleHash
227+
}
228+
211229
// verify the header of proposed block
212230
err := sb.VerifyHeader(sb.chain, block.Header(), false)
213231
// ignore errEmptyCommittedSeals error because we don't have the committed seals yet
@@ -285,3 +303,10 @@ func (sb *backend) LastProposal() (istanbul.Proposal, common.Address) {
285303
// Return header only block here since we don't need block body
286304
return block, proposer
287305
}
306+
307+
func (sb *backend) HasBadProposal(hash common.Hash) bool {
308+
if sb.hasBadBlock == nil {
309+
return false
310+
}
311+
return sb.hasBadBlock(hash)
312+
}

consensus/istanbul/backend/engine.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ var (
8080
errInvalidCommittedSeals = errors.New("invalid committed seals")
8181
// errEmptyCommittedSeals is returned if the field of committed seals is zero.
8282
errEmptyCommittedSeals = errors.New("zero committed seals")
83+
// errMismatchTxhashes is returned if the TxHash in header is mismatch.
84+
errMismatchTxhashes = errors.New("mismatch transcations hashes")
8385
)
8486
var (
8587
defaultDifficulty = big.NewInt(1)
@@ -485,7 +487,7 @@ func (sb *backend) APIs(chain consensus.ChainReader) []rpc.API {
485487
}
486488

487489
// Start implements consensus.Istanbul.Start
488-
func (sb *backend) Start(chain consensus.ChainReader, currentBlock func() *types.Block) error {
490+
func (sb *backend) Start(chain consensus.ChainReader, currentBlock func() *types.Block, hasBadBlock func(hash common.Hash) bool) error {
489491
sb.coreMu.Lock()
490492
defer sb.coreMu.Unlock()
491493
if sb.coreStarted {
@@ -501,6 +503,7 @@ func (sb *backend) Start(chain consensus.ChainReader, currentBlock func() *types
501503

502504
sb.chain = chain
503505
sb.currentBlock = currentBlock
506+
sb.hasBadBlock = hasBadBlock
504507

505508
if err := sb.core.Start(); err != nil {
506509
return err

consensus/istanbul/backend/engine_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func newBlockChain(n int) (*core.BlockChain, *backend) {
5151
if err != nil {
5252
panic(err)
5353
}
54-
b.Start(blockchain, blockchain.CurrentBlock)
54+
b.Start(blockchain, blockchain.CurrentBlock, blockchain.HasBadBlock)
5555
snap, err := b.snapshot(blockchain, 0, common.Hash{}, nil)
5656
if err != nil {
5757
panic(err)

consensus/istanbul/core/backlog_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestCheckMessage(t *testing.T) {
3737
current: newRoundState(&istanbul.View{
3838
Sequence: big.NewInt(1),
3939
Round: big.NewInt(0),
40-
}, newTestValidatorSet(4), common.Hash{}, nil, nil),
40+
}, newTestValidatorSet(4), common.Hash{}, nil, nil, nil),
4141
}
4242

4343
// invalid view format
@@ -209,7 +209,7 @@ func TestProcessFutureBacklog(t *testing.T) {
209209
current: newRoundState(&istanbul.View{
210210
Sequence: big.NewInt(1),
211211
Round: big.NewInt(0),
212-
}, newTestValidatorSet(4), common.Hash{}, nil, nil),
212+
}, newTestValidatorSet(4), common.Hash{}, nil, nil, nil),
213213
state: StateAcceptRequest,
214214
}
215215
c.subscribeEvents()
@@ -297,7 +297,7 @@ func testProcessBacklog(t *testing.T, msg *message) {
297297
current: newRoundState(&istanbul.View{
298298
Sequence: big.NewInt(1),
299299
Round: big.NewInt(0),
300-
}, newTestValidatorSet(4), common.Hash{}, nil, nil),
300+
}, newTestValidatorSet(4), common.Hash{}, nil, nil, nil),
301301
}
302302
c.subscribeEvents()
303303
defer c.unsubscribeEvents()

consensus/istanbul/core/core.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,12 @@ func (c *core) updateRoundState(view *istanbul.View, validatorSet istanbul.Valid
276276
// Lock only if both roundChange is true and it is locked
277277
if roundChange && c.current != nil {
278278
if c.current.IsHashLocked() {
279-
c.current = newRoundState(view, validatorSet, c.current.GetLockedHash(), c.current.Preprepare, c.current.pendingRequest)
279+
c.current = newRoundState(view, validatorSet, c.current.GetLockedHash(), c.current.Preprepare, c.current.pendingRequest, c.backend.HasBadProposal)
280280
} else {
281-
c.current = newRoundState(view, validatorSet, common.Hash{}, nil, c.current.pendingRequest)
281+
c.current = newRoundState(view, validatorSet, common.Hash{}, nil, c.current.pendingRequest, c.backend.HasBadProposal)
282282
}
283283
} else {
284-
c.current = newRoundState(view, validatorSet, common.Hash{}, nil, nil)
284+
c.current = newRoundState(view, validatorSet, common.Hash{}, nil, nil, c.backend.HasBadProposal)
285285
}
286286
}
287287

consensus/istanbul/core/final_committed.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package core
1919
import "github.com/ethereum/go-ethereum/common"
2020

2121
func (c *core) handleFinalCommitted() error {
22-
logger := c.logger.New("state", c.state, "number")
22+
logger := c.logger.New("state", c.state)
2323
logger.Trace("Received a final committed proposal")
2424
c.startNewRound(common.Big0)
2525
return nil

consensus/istanbul/core/prepare.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ func (c *core) handlePrepare(msg *message, src istanbul.Validator) error {
5959

6060
// Change to Prepared state if we've received enough PREPARE messages or it is locked
6161
// and we are in earlier state before Prepared state.
62-
if (c.current.IsHashLocked() || c.current.GetPrepareOrCommitSize() > 2*c.valSet.F()) && c.state.Cmp(StatePrepared) < 0 {
62+
if ((c.current.IsHashLocked() && prepare.Digest == c.current.GetLockedHash()) || c.current.Prepares.Size() > 2*c.valSet.F()) &&
63+
c.state.Cmp(StatePrepared) < 0 {
6364
c.current.LockHash()
6465
c.setState(StatePrepared)
6566
c.sendCommit()

consensus/istanbul/core/request_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestCheckRequestMsg(t *testing.T) {
3636
current: newRoundState(&istanbul.View{
3737
Sequence: big.NewInt(1),
3838
Round: big.NewInt(0),
39-
}, newTestValidatorSet(4), common.Hash{}, nil, nil),
39+
}, newTestValidatorSet(4), common.Hash{}, nil, nil, nil),
4040
}
4141

4242
// invalid request
@@ -91,7 +91,7 @@ func TestStoreRequestMsg(t *testing.T) {
9191
current: newRoundState(&istanbul.View{
9292
Sequence: big.NewInt(0),
9393
Round: big.NewInt(0),
94-
}, newTestValidatorSet(4), common.Hash{}, nil, nil),
94+
}, newTestValidatorSet(4), common.Hash{}, nil, nil, nil),
9595
pendingRequests: prque.New(),
9696
pendingRequestsMu: new(sync.Mutex),
9797
}

0 commit comments

Comments
 (0)