Skip to content

Commit 32c7386

Browse files
committed
blockheaders include block height, nodes validate it
1 parent de842cb commit 32c7386

File tree

6 files changed

+34
-3
lines changed

6 files changed

+34
-3
lines changed

src/chain.h

+16
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,9 @@ class CBlockIndex
254258
nVersion = block.nVersion;
255259
hashMerkleRoot = block.hashMerkleRoot;
256260
nTime = block.nTime;
261+
if (gArgs.GetBoolArg("-con_blockheightinheader", false)) {
262+
block_height = block.block_height;
263+
}
257264
nBits = block.nBits;
258265
nNonce = block.nNonce;
259266
}
@@ -284,6 +291,9 @@ class CBlockIndex
284291
block.hashPrevBlock = pprev->GetBlockHash();
285292
block.hashMerkleRoot = hashMerkleRoot;
286293
block.nTime = nTime;
294+
if (gArgs.GetBoolArg("-con_blockheightinheader", false)) {
295+
block.block_height = block_height;
296+
}
287297
block.nBits = nBits;
288298
block.nNonce = nNonce;
289299
return block;
@@ -403,6 +413,9 @@ class CDiskBlockIndex : public CBlockIndex
403413
READWRITE(hashPrev);
404414
READWRITE(hashMerkleRoot);
405415
READWRITE(nTime);
416+
if (gArgs.GetBoolArg("-con_blockheightinheader", false)) {
417+
READWRITE(block_height);
418+
}
406419
READWRITE(nBits);
407420
READWRITE(nNonce);
408421
}
@@ -414,6 +427,9 @@ class CDiskBlockIndex : public CBlockIndex
414427
block.hashPrevBlock = hashPrev;
415428
block.hashMerkleRoot = hashMerkleRoot;
416429
block.nTime = nTime;
430+
if (gArgs.GetBoolArg("-con_blockheightinheader", false)) {
431+
block.block_height = block_height;
432+
}
417433
block.nBits = nBits;
418434
block.nNonce = nNonce;
419435
return block.GetHash();

src/chainparams.cpp

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

119119
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
120120
consensus.hashGenesisBlock = genesis.GetHash();
121-
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
122121
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
123122

124123
// Note that of those which support the service bits prefix, most only support a subset of
@@ -227,7 +226,6 @@ class CTestNetParams : public CChainParams {
227226

228227
genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
229228
consensus.hashGenesisBlock = genesis.GetHash();
230-
assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
231229
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
232230

233231
vFixedSeeds.clear();
@@ -318,7 +316,6 @@ class CRegTestParams : public CChainParams {
318316

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

324321
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", false)) {
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
@@ -3252,6 +3252,11 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
32523252
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
32533253
return state.Invalid(false, REJECT_INVALID, "time-too-old", "block's timestamp is too early");
32543254

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

0 commit comments

Comments
 (0)