Skip to content

Commit

Permalink
Punish nodes relatively for oversize blocks
Browse files Browse the repository at this point in the history
In the case we receive a block that is over our size limit we don't
immediately disconnect. Instead we punish the node based on the amount
of bytes that it was over our limit. (100 points is immediate
disconnect)
This avoids us receiving a block 1 byte over the limit and immediately
banning that node for 24 hours. Instead only ban nodes that have
substantially different ideas about block sizes than we do.
  • Loading branch information
zander committed Feb 2, 2017
1 parent dd52ec0 commit f31829e
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Copyright (c) 2017 Tom Zander <tomz@freedommail.ch>
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand All @@ -13,6 +14,7 @@ static const unsigned char REJECT_MALFORMED = 0x01;
static const unsigned char REJECT_INVALID = 0x10;
static const unsigned char REJECT_OBSOLETE = 0x11;
static const unsigned char REJECT_DUPLICATE = 0x12;
static const unsigned char REJECT_EXCEEDSLIMIT = 0x13;
static const unsigned char REJECT_NONSTANDARD = 0x40;
static const unsigned char REJECT_DUST = 0x41;
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;
Expand Down
12 changes: 8 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3091,10 +3091,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
}

// Size limits
std::int32_t nSizeLimit = Policy::blockSizeAcceptLimit();
if (block.vtx.empty() || block.vtx.size() > (uint32_t) nSizeLimit || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > (uint32_t) nSizeLimit)
return state.DoS(100, error("CheckBlock(): size limits failed"),
REJECT_INVALID, "bad-blk-length");
if (block.vtx.empty())
return state.DoS(100, error("CheckBlock(): Missing coinbase tx"), REJECT_INVALID, "bad-blk-length");
const std::uint32_t blockSizeAcceptLimit = Policy::blockSizeAcceptLimit();
const std::uint32_t blockSize = ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION);
if (block.vtx.size() > blockSizeAcceptLimit || blockSize > blockSizeAcceptLimit) {
const float punishment = (blockSize - blockSizeAcceptLimit) / (float) blockSizeAcceptLimit;
return state.DoS(10 * punishment + 0.5, error("CheckBlock(): block larger than user-limit"), REJECT_EXCEEDSLIMIT, "bad-blk-length");
}

// All potential-corruption validation must be done before we do any
// transaction validation, as otherwise we may mark the header as invalid
Expand Down

0 comments on commit f31829e

Please sign in to comment.