Permalink
Browse files

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.
  • Loading branch information...
zander committed Jan 31, 2017
1 parent dd52ec0 commit f31829e1a7c4163d99149d5def431efc4a0851f4
Showing with 10 additions and 4 deletions.
  1. +2 −0 src/consensus/validation.h
  2. +8 −4 src/main.cpp
@@ -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.
@@ -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;
View
@@ -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

0 comments on commit f31829e

Please sign in to comment.