Page MenuHomePhabricator

D2102.diff
No OneTemporary

D2102.diff

diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1532,7 +1532,7 @@
}
CBlockIndex *pblockindex = mapBlockIndex[hash];
- FinalizeBlock(config, state, pblockindex);
+ FinalizeBlockAndInvalidate(config, state, pblockindex);
}
if (state.IsValid()) {
diff --git a/src/validation.h b/src/validation.h
--- a/src/validation.h
+++ b/src/validation.h
@@ -66,8 +66,9 @@
static const Amount DEFAULT_TRANSACTION_MAXFEE(COIN / 10);
//! Discourage users to set fees higher than this amount (in satoshis) per kB
static const Amount HIGH_TX_FEE_PER_KB(COIN / 100);
-/** -maxtxfee will warn if called with a higher fee than this amount (in
- * satoshis */
+/**
+ * -maxtxfee will warn if called with a higher fee than this amount (in satoshis
+ */
static const Amount HIGH_MAX_TX_FEE(100 * HIGH_TX_FEE_PER_KB);
/** Default for -limitancestorcount, max number of in-mempool ancestors */
static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25;
@@ -93,7 +94,8 @@
static const int MAX_SCRIPTCHECK_THREADS = 16;
/** -par default (number of script-checking threads, 0 = auto) */
static const int DEFAULT_SCRIPTCHECK_THREADS = 0;
-/** Number of blocks that can be requested at any given time from a single peer.
+/**
+ * Number of blocks that can be requested at any given time from a single peer.
*/
static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
/**
@@ -191,6 +193,8 @@
/** Default for -stopatheight */
static const int DEFAULT_STOPATHEIGHT = 0;
+/** Default for -maxreorgdepth */
+static const int DEFAULT_MAX_REORG_DEPTH = 10;
extern CScript COINBASE_FLAGS;
extern CCriticalSection cs_main;
@@ -629,8 +633,8 @@
* Mark a block as finalized.
* A finalized block can not be reorged in any way.
*/
-bool FinalizeBlock(const Config &config, CValidationState &state,
- CBlockIndex *pindex);
+bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state,
+ CBlockIndex *pindex);
/** Mark a block as invalid. */
bool InvalidateBlock(const Config &config, CValidationState &state,
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2289,6 +2289,31 @@
}
};
+static bool FinalizeBlockInternal(const Config &config, CValidationState &state,
+ CBlockIndex *pindex) {
+ AssertLockHeld(cs_main);
+ if (pindex->nStatus.isInvalid()) {
+ // We try to finalize an invalid block.
+ return state.DoS(100,
+ error("%s: Trying to finalize invalid block %s",
+ __func__, pindex->GetBlockHash().ToString()),
+ REJECT_INVALID, "finalize-invalid-block");
+ }
+
+ // Check that the request is consistent with current finalization.
+ if (pindexFinalized && !AreOnTheSameFork(pindex, pindexFinalized)) {
+ return state.DoS(
+ 20, error("%s: Trying to finalize block %s which conflicts "
+ "with already finalized block",
+ __func__, pindex->GetBlockHash().ToString()),
+ REJECT_AGAINST_FINALIZED, "bad-fork-prior-finalized");
+ }
+
+ // Our candidate is valid, finalize it.
+ pindexFinalized = pindex;
+ return true;
+}
+
/**
* Connect a new block to chainActive. pblock is either nullptr or a pointer to
* a CBlock corresponding to pindexNew, to bypass loading it again from disk.
@@ -2338,6 +2363,20 @@
FormatStateMessage(state));
}
+ // Update the finalized block.
+ int32_t nHeightToFinalize =
+ pindexNew->nHeight -
+ gArgs.GetArg("-maxreorgdepth", DEFAULT_MAX_REORG_DEPTH);
+ CBlockIndex *pindexToFinalize =
+ pindexNew->GetAncestor(nHeightToFinalize);
+ if (pindexToFinalize &&
+ !FinalizeBlockInternal(config, state, pindexToFinalize)) {
+ state.SetCorruptionPossible();
+ return error("ConnectTip(): FinalizeBlock %s failed (%s)",
+ pindexNew->GetBlockHash().ToString(),
+ FormatStateMessage(state));
+ }
+
nTime3 = GetTimeMicros();
nTimeConnectTotal += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect total: %.2fms [%.2fs]\n",
@@ -2852,28 +2891,15 @@
return true;
}
-bool FinalizeBlock(const Config &config, CValidationState &state,
- CBlockIndex *pindex) {
+bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state,
+ CBlockIndex *pindex) {
AssertLockHeld(cs_main);
- if (pindex->nStatus.isInvalid()) {
- // We try to finalize an invalid block.
- return state.DoS(100,
- error("%s: Trying to finalize invalid block %s",
- __func__, pindex->GetBlockHash().ToString()),
- REJECT_INVALID, "finalize-invalid-block");
- }
-
- // Check that the request is consistent with current finalization.
- if (pindexFinalized && !AreOnTheSameFork(pindex, pindexFinalized)) {
- return state.DoS(
- 20, error("%s: Trying to finalize block %s which conflicts "
- "with already finalized block",
- __func__, pindex->GetBlockHash().ToString()),
- REJECT_AGAINST_FINALIZED, "bad-fork-prior-finalized");
+ if (!FinalizeBlockInternal(config, state, pindex)) {
+ // state is set by FinalizeBlockInternal.
+ return false;
}
// We have a valid candidate, make sure it is not parked.
- pindexFinalized = pindex;
if (pindex->nStatus.isOnParkedChain()) {
UnparkBlock(pindex);
}
@@ -4669,6 +4695,7 @@
LOCK(cs_main);
setBlockIndexCandidates.clear();
chainActive.SetTip(nullptr);
+ pindexFinalized = nullptr;
pindexBestInvalid = nullptr;
pindexBestParked = nullptr;
pindexBestHeader = nullptr;
diff --git a/test/functional/abc-parkedchain.py b/test/functional/abc-parkedchain.py
--- a/test/functional/abc-parkedchain.py
+++ b/test/functional/abc-parkedchain.py
@@ -12,7 +12,7 @@
class ParkedChainTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.extra_args = [["-noparkdeepreorg"], []]
+ self.extra_args = [["-noparkdeepreorg"], ["-maxreorgdepth=-1"]]
# There should only be one chaintip, which is expected_tip
def only_valid_tip(self, expected_tip, other_tip_status=None):
diff --git a/test/functional/bip68-sequence.py b/test/functional/bip68-sequence.py
--- a/test/functional/bip68-sequence.py
+++ b/test/functional/bip68-sequence.py
@@ -26,8 +26,8 @@
class BIP68Test(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.extra_args = [["-blockprioritypercentage=0", "-noparkdeepreorg"],
- ["-blockprioritypercentage=0", "-acceptnonstdtxn=0"]]
+ self.extra_args = [["-blockprioritypercentage=0", "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-blockprioritypercentage=0", "-acceptnonstdtxn=0", "-maxreorgdepth=-1"]]
def run_test(self):
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
diff --git a/test/functional/p2p-fullblocktest.py b/test/functional/p2p-fullblocktest.py
--- a/test/functional/p2p-fullblocktest.py
+++ b/test/functional/p2p-fullblocktest.py
@@ -61,7 +61,8 @@
# Change the "outcome" variable from each TestInstance object to only do the comparison.
def set_test_params(self):
self.num_nodes = 1
- self.extra_args = [['-whitelist=127.0.0.1', '-noparkdeepreorg']]
+ self.extra_args = [['-whitelist=127.0.0.1',
+ '-noparkdeepreorg', '-maxreorgdepth=-1']]
self.setup_clean_chain = True
self.block_heights = {}
self.coinbase_key = CECKey()
diff --git a/test/functional/pruning.py b/test/functional/pruning.py
--- a/test/functional/pruning.py
+++ b/test/functional/pruning.py
@@ -38,20 +38,20 @@
# Create nodes 0 and 1 to mine.
# Create node 2 to test pruning.
self.full_node_default_args = ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
- "-checkblocks=5", "-noparkdeepreorg",
+ "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1",
"-limitdescendantcount=100", "-limitdescendantsize=5000",
"-limitancestorcount=100", "-limitancestorsize=5000"]
# Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later)
# Create nodes 5 to test wallet in prune mode, but do not connect
self.extra_args = [self.full_node_default_args,
self.full_node_default_args,
- ["-maxreceivebuffer=20000",
- "-prune=550", "-noparkdeepreorg"],
- ["-maxreceivebuffer=20000",
- "-blockmaxsize=999000", "-noparkdeepreorg"],
- ["-maxreceivebuffer=20000",
- "-blockmaxsize=999000", "-noparkdeepreorg"],
- ["-prune=550", "-noparkdeepreorg"]]
+ ["-maxreceivebuffer=20000", "-prune=550",
+ "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
+ "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
+ "-noparkdeepreorg", "-maxreorgdepth=-1"],
+ ["-prune=550"]]
def setup_network(self):
self.setup_nodes()
@@ -152,7 +152,7 @@
self.stop_node(1)
self.start_node(1, extra_args=[
"-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5",
- "-disablesafemode", "-noparkdeepreorg"])
+ "-disablesafemode", "-noparkdeepreorg", "-maxreorgdepth=-1"])
height = self.nodes[1].getblockcount()
self.log.info("Current block height: %d" % height)
@@ -179,7 +179,7 @@
self.stop_node(1)
self.start_node(1, extra_args=[
"-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5",
- "-disablesafemode", "-noparkdeepreorg"])
+ "-disablesafemode", "-noparkdeepreorg", "-maxreorgdepth=-1"])
self.log.info("Generating new longer chain of 300 more blocks")
self.nodes[1].generate(300)
@@ -371,7 +371,8 @@
# check that the pruning node's wallet is still in good shape
self.log.info("Stop and start pruning node to trigger wallet rescan")
self.stop_node(2)
- self.start_node(2, extra_args=["-prune=550", "-noparkdeepreorg"])
+ self.start_node(
+ 2, extra_args=["-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"])
self.log.info("Success")
# check that wallet loads loads successfully when restarting a pruned node after IBD.
@@ -381,7 +382,8 @@
nds = [self.nodes[0], self.nodes[5]]
sync_blocks(nds, wait=5, timeout=300)
self.stop_node(5) # stop and start to trigger rescan
- self.start_node(5, extra_args=["-prune=550", "-noparkdeepreorg"])
+ self.start_node(
+ 5, extra_args=["-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"])
self.log.info("Success")
def run_test(self):
diff --git a/test/functional/timing.json b/test/functional/timing.json
--- a/test/functional/timing.json
+++ b/test/functional/timing.json
@@ -1,7 +1,7 @@
[
{
"name": "abandonconflict.py",
- "time": 16
+ "time": 17
},
{
"name": "abc-checkdatasig-activation.py",
@@ -11,37 +11,41 @@
"name": "abc-cmdline.py",
"time": 8
},
+ {
+ "name": "abc-finalize-block.py",
+ "time": 4
+ },
{
"name": "abc-high_priority_transaction.py",
- "time": 10
+ "time": 37
},
{
"name": "abc-magnetic-anomaly-activation.py",
- "time": 6
+ "time": 14
},
{
"name": "abc-magnetic-anomaly-mining.py",
- "time": 15
+ "time": 13
},
{
"name": "abc-mempool-accept-txn.py",
- "time": 5
+ "time": 3
},
{
"name": "abc-p2p-compactblocks.py",
- "time": 104
+ "time": 273
},
{
"name": "abc-p2p-fullblocktest.py",
- "time": 81
+ "time": 62
},
{
"name": "abc-parkedchain.py",
- "time": 4
+ "time": 17
},
{
"name": "abc-replay-protection.py",
- "time": 5
+ "time": 4
},
{
"name": "abc-rpc.py",
@@ -53,23 +57,23 @@
},
{
"name": "assumevalid.py",
- "time": 20
+ "time": 17
},
{
"name": "bip65-cltv-p2p.py",
- "time": 5
+ "time": 6
},
{
"name": "bip68-112-113-p2p.py",
- "time": 18
+ "time": 15
},
{
"name": "bip68-sequence.py",
- "time": 18
+ "time": 32
},
{
"name": "bipdersig-p2p.py",
- "time": 7
+ "time": 6
},
{
"name": "bitcoin_cli.py",
@@ -77,15 +81,15 @@
},
{
"name": "blockchain.py",
- "time": 11
+ "time": 19
},
{
"name": "dbcrash.py",
- "time": 756
+ "time": 1292
},
{
"name": "decodescript.py",
- "time": 3
+ "time": 2
},
{
"name": "disablewallet.py",
@@ -93,99 +97,99 @@
},
{
"name": "disconnect_ban.py",
- "time": 8
+ "time": 9
},
{
"name": "example_test.py",
- "time": 4
+ "time": 16
},
{
"name": "fundrawtransaction.py",
- "time": 42
+ "time": 40
},
{
"name": "getblocktemplate_longpoll.py",
- "time": 68
+ "time": 69
},
{
"name": "getchaintips.py",
- "time": 4
+ "time": 5
},
{
"name": "httpbasics.py",
- "time": 3
+ "time": 17
},
{
"name": "import-rescan.py",
- "time": 16
+ "time": 18
},
{
"name": "importmulti.py",
- "time": 12
+ "time": 11
},
{
"name": "importprunedfunds.py",
- "time": 4
+ "time": 5
},
{
"name": "invalidateblock.py",
- "time": 9
+ "time": 8
},
{
"name": "invalidblockrequest.py",
- "time": 4
+ "time": 5
},
{
"name": "invalidtxrequest.py",
- "time": 4
+ "time": 15
},
{
"name": "keypool-topup.py",
- "time": 19
+ "time": 34
},
{
"name": "keypool.py",
- "time": 8
+ "time": 9
},
{
"name": "listsinceblock.py",
- "time": 5
+ "time": 24
},
{
"name": "listtransactions.py",
- "time": 11
+ "time": 23
},
{
"name": "maxuploadtarget.py",
- "time": 37
+ "time": 28
},
{
"name": "mempool_limit.py",
- "time": 5
+ "time": 8
},
{
"name": "mempool_packages.py",
- "time": 28
+ "time": 55
},
{
"name": "mempool_persist.py",
- "time": 16
+ "time": 19
},
{
"name": "mempool_reorg.py",
- "time": 4
+ "time": 6
},
{
"name": "mempool_resurrect_test.py",
- "time": 3
+ "time": 18
},
{
"name": "mempool_spendcoinbase.py",
- "time": 3
+ "time": 5
},
{
"name": "merkle_blocks.py",
- "time": 5
+ "time": 32
},
{
"name": "minchainwork.py",
@@ -193,19 +197,19 @@
},
{
"name": "mining.py",
- "time": 3
+ "time": 5
},
{
"name": "multi_rpc.py",
- "time": 4
+ "time": 18
},
{
"name": "multiwallet.py",
- "time": 9
+ "time": 20
},
{
"name": "net.py",
- "time": 4
+ "time": 13
},
{
"name": "notifications.py",
@@ -213,27 +217,27 @@
},
{
"name": "nulldummy.py",
- "time": 4
+ "time": 5
},
{
"name": "p2p-acceptblock.py",
- "time": 7
+ "time": 14
},
{
"name": "p2p-compactblocks.py",
- "time": 23
+ "time": 22
},
{
"name": "p2p-feefilter.py",
- "time": 63
+ "time": 51
},
{
"name": "p2p-fullblocktest.py",
- "time": 184
+ "time": 148
},
{
"name": "p2p-leaktests.py",
- "time": 7
+ "time": 8
},
{
"name": "p2p-mempool.py",
@@ -245,43 +249,43 @@
},
{
"name": "preciousblock.py",
- "time": 4
+ "time": 5
},
{
"name": "prioritise_transaction.py",
- "time": 6
+ "time": 34
},
{
"name": "proxy_test.py",
- "time": 4
+ "time": 5
},
{
"name": "pruning.py",
- "time": 1040
+ "time": 1511
},
{
"name": "rawtransactions.py",
- "time": 17
+ "time": 16
},
{
"name": "receivedby.py",
- "time": 6
+ "time": 37
},
{
"name": "reindex.py",
- "time": 14
+ "time": 18
},
{
"name": "resendwallettransactions.py",
- "time": 6
+ "time": 18
},
{
"name": "rest.py",
- "time": 11
+ "time": 20
},
{
"name": "rpcbind_test.py",
- "time": 29
+ "time": 28
},
{
"name": "rpcnamedargs.py",
@@ -289,7 +293,7 @@
},
{
"name": "sendheaders.py",
- "time": 22
+ "time": 16
},
{
"name": "signmessages.py",
@@ -301,7 +305,7 @@
},
{
"name": "txn_clone.py",
- "time": 5
+ "time": 8
},
{
"name": "txn_clone.py --mineblock",
@@ -309,46 +313,46 @@
},
{
"name": "txn_doublespend.py",
- "time": 5
+ "time": 7
},
{
"name": "txn_doublespend.py --mineblock",
- "time": 6
+ "time": 7
},
{
"name": "uptime.py",
- "time": 2
+ "time": 3
},
{
"name": "wallet-accounts.py",
- "time": 13
+ "time": 26
},
{
"name": "wallet-dump.py",
- "time": 8
+ "time": 35
},
{
"name": "wallet-encryption.py",
- "time": 9
+ "time": 18
},
{
"name": "wallet-hd.py",
- "time": 111
+ "time": 36
},
{
"name": "wallet.py",
- "time": 56
+ "time": 46
},
{
"name": "walletbackup.py",
- "time": 137
+ "time": 119
},
{
"name": "zapwallettxes.py",
- "time": 15
+ "time": 14
},
{
"name": "zmq_test.py",
"time": 9
}
-]
+]
\ No newline at end of file

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 1, 11:41 (6 h, 3 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5183581
Default Alt Text
D2102.diff (17 KB)

Event Timeline