Skip to content

Commit a89d0eb

Browse files
committed
blockheaders include block height, nodes validate it
1 parent e1ed37e commit a89d0eb

File tree

8 files changed

+31
-4
lines changed

8 files changed

+31
-4
lines changed

src/chain.h

+10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#include <vector>
1616

17+
#include <util.h>
18+
1719
/**
1820
* Maximum amount of time that a block timestamp is allowed to exceed the
1921
* current network-adjusted time before the block will be accepted.
@@ -210,6 +212,7 @@ class CBlockIndex
210212
int32_t nVersion;
211213
uint256 hashMerkleRoot;
212214
uint32_t nTime;
215+
uint32_t block_height;
213216
uint32_t nBits;
214217
uint32_t nNonce;
215218

@@ -238,6 +241,7 @@ class CBlockIndex
238241
nVersion = 0;
239242
hashMerkleRoot = uint256();
240243
nTime = 0;
244+
block_height = 0;
241245
nBits = 0;
242246
nNonce = 0;
243247
}
@@ -254,6 +258,7 @@ class CBlockIndex
254258
nVersion = block.nVersion;
255259
hashMerkleRoot = block.hashMerkleRoot;
256260
nTime = block.nTime;
261+
block_height = block.block_height;
257262
nBits = block.nBits;
258263
nNonce = block.nNonce;
259264
}
@@ -284,6 +289,9 @@ class CBlockIndex
284289
block.hashPrevBlock = pprev->GetBlockHash();
285290
block.hashMerkleRoot = hashMerkleRoot;
286291
block.nTime = nTime;
292+
if (gArgs.GetBoolArg("-con_blockheightinheader", false)) {
293+
block.block_height = block_height;
294+
}
287295
block.nBits = nBits;
288296
block.nNonce = nNonce;
289297
return block;
@@ -403,6 +411,7 @@ class CDiskBlockIndex : public CBlockIndex
403411
READWRITE(hashPrev);
404412
READWRITE(hashMerkleRoot);
405413
READWRITE(nTime);
414+
READWRITE(block_height);
406415
READWRITE(nBits);
407416
READWRITE(nNonce);
408417
}
@@ -414,6 +423,7 @@ class CDiskBlockIndex : public CBlockIndex
414423
block.hashPrevBlock = hashPrev;
415424
block.hashMerkleRoot = hashMerkleRoot;
416425
block.nTime = nTime;
426+
block.block_height = block_height;
417427
block.nBits = nBits;
418428
block.nNonce = nNonce;
419429
return block.GetHash();

src/chainparams.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ class CMainParams : public CChainParams {
121121

122122
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
123123
consensus.hashGenesisBlock = genesis.GetHash();
124-
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
125124
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
126125

127126
// Note that of those which support the service bits prefix, most only support a subset of
@@ -230,7 +229,6 @@ class CTestNetParams : public CChainParams {
230229

231230
genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
232231
consensus.hashGenesisBlock = genesis.GetHash();
233-
assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
234232
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
235233

236234
vFixedSeeds.clear();
@@ -319,7 +317,6 @@ class CRegTestParams : public CChainParams {
319317

320318
genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
321319
consensus.hashGenesisBlock = genesis.GetHash();
322-
assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
323320
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
324321

325322
vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.

src/init.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ void SetupServerArgs()
514514
gArgs.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", false, OptionsCategory::RPC);
515515
gArgs.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), true, OptionsCategory::RPC);
516516
gArgs.AddArg("-server", "Accept command line and JSON-RPC commands", false, OptionsCategory::RPC);
517+
gArgs.AddArg("-con_blockheightinheader", "Block headers have height serialized inside them.", false, OptionsCategory::CHAINPARAMS);
517518

518519
#if HAVE_DECL_DAEMON
519520
gArgs.AddArg("-daemon", "Run in the background as a daemon and accept commands", false, OptionsCategory::OPTIONS);

src/miner.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
168168
// Fill in header
169169
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
170170
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
171+
if (gArgs.GetBoolArg("-con_blockheightinheader", false)) {
172+
pblock->block_height = nHeight;
173+
}
171174
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
172175
pblock->nNonce = 0;
173176
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);

src/primitives/block.h

+9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <primitives/transaction.h>
1010
#include <serialize.h>
1111
#include <uint256.h>
12+
#include <util.h>
1213

1314
/** Nodes collect new transactions into a block, hash them into a hash tree,
1415
* and scan through nonce values to make the block's hash satisfy proof-of-work
@@ -25,6 +26,9 @@ class CBlockHeader
2526
uint256 hashPrevBlock;
2627
uint256 hashMerkleRoot;
2728
uint32_t nTime;
29+
// Height in header as well as in coinbase for easier hsm validation
30+
// Is set for serialization with `-con_blockheightinheader=1`
31+
uint32_t block_height;
2832
uint32_t nBits;
2933
uint32_t nNonce;
3034

@@ -41,6 +45,9 @@ class CBlockHeader
4145
READWRITE(hashPrevBlock);
4246
READWRITE(hashMerkleRoot);
4347
READWRITE(nTime);
48+
if (gArgs.GetBoolArg("-con_blockheightinheader", true)) {
49+
READWRITE(block_height);
50+
}
4451
READWRITE(nBits);
4552
READWRITE(nNonce);
4653
}
@@ -51,6 +58,7 @@ class CBlockHeader
5158
hashPrevBlock.SetNull();
5259
hashMerkleRoot.SetNull();
5360
nTime = 0;
61+
block_height = 0;
5462
nBits = 0;
5563
nNonce = 0;
5664
}
@@ -111,6 +119,7 @@ class CBlock : public CBlockHeader
111119
block.hashPrevBlock = hashPrevBlock;
112120
block.hashMerkleRoot = hashMerkleRoot;
113121
block.nTime = nTime;
122+
block.block_height = block_height;
114123
block.nBits = nBits;
115124
block.nNonce = nNonce;
116125
return block;

src/validation.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -3249,6 +3249,11 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
32493249
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
32503250
return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early");
32513251

3252+
// Check height in header against prev
3253+
if (gArgs.GetBoolArg("-con_blockheightinheader", false) && (uint32_t)nHeight != block.block_height)
3254+
return state.Invalid(error("%s: block height in header is incorrect", __func__),
3255+
REJECT_INVALID, "bad-header-height");
3256+
32523257
// Check timestamp
32533258
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
32543259
return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future");

test/functional/rpc_getchaintips.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
class GetChainTipsTest (BitcoinTestFramework):
1717
def set_test_params(self):
1818
self.num_nodes = 4
19+
self.extended_args = [["-con_blockheightinheader=1"], ["-con_blockheightinheader=1"], ["-con_blockheightinheader=1"], ["-con_blockheightinheader=1"]]
1920

2021
def run_test (self):
2122
tips = self.nodes[0].getchaintips ()

test/functional/test_framework/test_framework.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import sys
1515
import tempfile
1616
import time
17-
17+
from pdb import set_trace
1818
from .authproxy import JSONRPCException
1919
from . import coverage
2020
from .test_node import TestNode
@@ -237,6 +237,7 @@ def setup_network(self):
237237
# two halves that can work on competing chains.
238238
for i in range(self.num_nodes - 1):
239239
connect_nodes_bi(self.nodes, i, i + 1)
240+
set_trace()
240241
self.sync_all()
241242

242243
def setup_nodes(self):

0 commit comments

Comments
 (0)