Skip to content

Commit f31829e

Browse files
committed
Punish nodes relatively for oversize blocks
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.
1 parent dd52ec0 commit f31829e

2 files changed

Lines changed: 10 additions & 4 deletions

File tree

‎src/consensus/validation.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright (c) 2009-2010 Satoshi Nakamoto
22
// Copyright (c) 2009-2015 The Bitcoin Core developers
3+
// Copyright (c) 2017 Tom Zander <tomz@freedommail.ch>
34
// Distributed under the MIT software license, see the accompanying
45
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
56

@@ -13,6 +14,7 @@ static const unsigned char REJECT_MALFORMED = 0x01;
1314
static const unsigned char REJECT_INVALID = 0x10;
1415
static const unsigned char REJECT_OBSOLETE = 0x11;
1516
static const unsigned char REJECT_DUPLICATE = 0x12;
17+
static const unsigned char REJECT_EXCEEDSLIMIT = 0x13;
1618
static const unsigned char REJECT_NONSTANDARD = 0x40;
1719
static const unsigned char REJECT_DUST = 0x41;
1820
static const unsigned char REJECT_INSUFFICIENTFEE = 0x42;

‎src/main.cpp‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,10 +3091,14 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
30913091
}
30923092

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

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

0 commit comments

Comments
 (0)