From 1273cd00d195588ad2cdf006e71ec0f301b0caed Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 1 Feb 2018 15:39:14 -0600 Subject: [PATCH] blockchain: Validate num votes in header sanity. This moves the test for validating the number of votes specified by the header is at least the required minimum into the checkBlockHeaderSanity function where it more naturally belongs since it is solely dependent on information the header. Also, remove the redundant check for the same condition from checkBlockSanity since it has now already been checked according to the value the header commits to and therefore validating the header commitment for the number of votes implies correctness. --- blockchain/validate.go | 41 +++++++++++-------------------------- blockchain/validate_test.go | 1 + 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/blockchain/validate.go b/blockchain/validate.go index 3648a31d..89dfbca7 100644 --- a/blockchain/validate.go +++ b/blockchain/validate.go @@ -400,6 +400,18 @@ func checkBlockHeaderSanity(header *wire.BlockHeader, timeSource MedianTimeSourc return ruleError(ErrTimeTooNew, str) } + // A block must not contain more votes than the minimum required to + // reach majority once stake validation height has been reached. + if header.Height >= uint32(chainParams.StakeValidationHeight) { + majority := (chainParams.TicketsPerBlock / 2) + 1 + if header.Voters < majority { + errStr := fmt.Sprintf("block does not commit to enough "+ + "votes (min: %d, got %d)", majority, + header.Voters) + return ruleError(ErrNotEnoughVotes, errStr) + } + } + return nil } @@ -520,15 +532,6 @@ func checkBlockSanity(block *dcrutil.Block, timeSource MedianTimeSource, flags B return ruleError(ErrFreshStakeMismatch, errStr) } - // Not enough voters on this block. - if block.Height() >= chainParams.StakeValidationHeight && - totalVotes <= int(chainParams.TicketsPerBlock)/2 { - errStr := fmt.Sprintf("block contained too few votes! %v "+ - "votes but %v or more required", totalVotes, - (int(chainParams.TicketsPerBlock)/2)+1) - return ruleError(ErrNotEnoughVotes, errStr) - } - if totalVotes > int(chainParams.TicketsPerBlock) { errStr := fmt.Sprintf("the number of SSGen tx in block %v "+ "was %v, overflowing the maximum allowed (%v)", @@ -989,26 +992,6 @@ func (b *BlockChain) CheckBlockStakeSanity(stakeValidationHeight int64, node *bl return nil } - // ------------------------------------------------------------------- - // General Purpose Checks - // ------------------------------------------------------------------- - // 1. Check that we have a majority vote of potential voters. - - // 1. Check to make sure we have a majority of the potential voters voting. - if msgBlock.Header.Voters == 0 { - errStr := fmt.Sprintf("Error: no voters in block %v", - blockHash) - return ruleError(ErrNotEnoughVotes, errStr) - } - - majority := (chainParams.TicketsPerBlock / 2) + 1 - if msgBlock.Header.Voters < majority { - errStr := fmt.Sprintf("Error in stake consensus: the number "+ - "of voters is not in the majority as compared to "+ - "potential votes for block %v", blockHash) - return ruleError(ErrNotEnoughVotes, errStr) - } - // ------------------------------------------------------------------- // SSGen Tx Handling // ------------------------------------------------------------------- diff --git a/blockchain/validate_test.go b/blockchain/validate_test.go index c1ccb3a1..cb8080fa 100644 --- a/blockchain/validate_test.go +++ b/blockchain/validate_test.go @@ -795,6 +795,7 @@ func TestBlockValidationRules(t *testing.T) { notEnoughVotes154.FromBytes(block154Bytes) notEnoughVotes154.STransactions = notEnoughVotes154.STransactions[0:2] notEnoughVotes154.Header.FreshStake = 0 + notEnoughVotes154.Header.Voters = 2 recalculateMsgBlockMerkleRootsSize(notEnoughVotes154) b154test = dcrutil.NewBlock(notEnoughVotes154)