aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2023-10-02 17:00:28 -0400
committerAndrew Chow <github@achow101.com>2023-10-02 17:09:44 -0400
commite7b0004b375be25096fbaf3d5f6980095a90fc0c (patch)
tree93db27979c413ea295e5c9e1578b99f406195b5f /src/kernel
parentfd8ab08558ccfb62f2d0a64d2d0d4dcefba977bc (diff)
parentedbed31066e3674ba52b8c093ab235625527f383 (diff)
Merge bitcoin/bitcoin#27596: assumeutxo (2)
edbed31066e3674ba52b8c093ab235625527f383 chainparams: add signet assumeutxo param at height 160_000 (Sjors Provoost) b8cafe38713cbf10d15459042f7f911bcc1b1e4e chainparams: add testnet assumeutxo param at height 2_500_000 (Sjors Provoost) 99839bbfa7110c7abf22e587ae2f72c9c57d3c85 doc: add note about confusing HaveTxsDownloaded name (James O'Beirne) 7ee46a755f1d57ce9d51975d3b54dc9ac3d08d52 contrib: add script to demo/test assumeutxo (James O'Beirne) 42cae39356fd20d521aaf99aff1ed85856f3c9f3 test: add feature_assumeutxo functional test (James O'Beirne) 0f64bac6030334d798ae205cd7af4bf248feddd9 rpc: add getchainstates (James O'Beirne) bb0585779472962f40d9cdd9c6532132850d371c refuse to activate a UTXO snapshot if mempool not empty (James O'Beirne) ce585a9a158476b0ad3296477b922e79f308e795 rpc: add loadtxoutset (James O'Beirne) 62ac519e718eb7a31dca1102a96ba219fbc7f95d validation: do not activate snapshot if behind active chain (James O'Beirne) 9511fb3616b7bbe1d0d2f54a45ea0a650ba0367b validation: assumeutxo: swap m_mempool on snapshot activation (James O'Beirne) 7fcd21544a333ffdf1910b65c573579860be6a36 blockstorage: segment normal/assumedvalid blockfiles (James O'Beirne) 4c3b8ca35c2e4a441264749bb312df2bd054b5b8 validation: populate nChainTx value for assumedvalid chainstates (James O'Beirne) 49ef778158c43859946a592e11ec34fe1b93a5b6 test: adjust chainstate tests to use recognized snapshot base (James O'Beirne) 1019c399825b0d512c1fd751c376d46fed4992b9 validation: pruning for multiple chainstates (James O'Beirne) 373cf91531b84bfdd06fdf8abf4dca228029ce6b validation: indexing changes for assumeutxo (James O'Beirne) 1fffdd76a1bca908f55d73b64983655b14cf7432 net_processing: validationinterface: ignore some events for bg chain (James O'Beirne) fbe0a7d7ca680358237b6c2369b3fd2b43221113 wallet: validationinterface: only handle active chain notifications (James O'Beirne) f073917a9e7ba423643dcae0339776470b628f65 validationinterface: only send zmq notifications for active (James O'Beirne) 4d8f4dcb450d31e4847804e62bf91545b949fa14 validation: pass ChainstateRole for validationinterface calls (James O'Beirne) 1e59acdf17309f567c370885f0cf02605e2baa58 validation: only call UpdatedBlockTip for active chainstate (James O'Beirne) c6af23c5179cc383f8e6c275373af8d11e6a989f validation: add ChainstateRole (James O'Beirne) 9f2318c76cc6986d48e13831cf5bd8dab194fdf4 validation: MaybeRebalanceCaches when chain leaves IBD (James O'Beirne) 434495a8c1496ca23fe35b84499f3daf668d76b8 chainparams: add blockhash to AssumeutxoData (James O'Beirne) c711ca186f8d8a28810be0beedcb615ddcf93163 assumeutxo: remove snapshot during -reindex{-chainstate} (James O'Beirne) c93ef43e4fd4fbc1263cdc9e98ae5856830fe89e bugfix: correct is_snapshot_cs in VerifyDB (James O'Beirne) b73d3bbd23220857bf17cbb6401275bf58013b72 net_processing: Request assumeutxo background chain blocks (Suhas Daftuar) Pull request description: - Background and FAQ: https://github.com/jamesob/assumeutxo-docs/tree/2019-04-proposal/proposal - Prior progress/project: https://github.com/bitcoin/bitcoin/projects/11 - Replaces https://github.com/bitcoin/bitcoin/pull/15606, which was closed due to Github slowness. Original description and commentary can be found there. --- This changeset finishes the first phase of the assumeutxo project. It makes UTXO snapshots loadable via RPC (`loadtxoutset`) and adds `assumeutxo` parameters to chainparams. It contains all the remaining changes necessary to both use an assumedvalid snapshot chainstate and do a full validation sync in the background. This may look like a lot to review, but note that - ~200 lines are a (non-essential) demo shell script - Many lines are functional test, documentation, and relatively dilute RPC code. So it shouldn't be as burdensome to review as the linecount might suggest. - **P2P**: minor changes are made to `init.cpp` and `net_processing.cpp` to make simultaneous IBD across multiple chainstates work. - **Pruning**: implement correct pruning behavior when using a background chainstate - **Blockfile separation**: to prevent "fragmentation" in blockfile storage, have background chainstates use separate blockfiles from active snapshot chainstates to avoid interleaving heights and impairing pruning. - **Indexing**: some `CValidationInterface` events are given with an additional parameter, ChainstateRole, and all indexers ignore events from ChainstateRole::ASSUMEDVALID so that indexation only happens sequentially. - Have `-reindex` properly wipe snapshot chainstates. - **RPC**: introduce RPC commands `loadtxoutset` and (hidden) `getchainstates`. - **Release docs & first assumeutxo commitment**: add notes and a particular assumeutxo hash value for first AU-enabled release. - This will complete the project and allow use of UTXO snapshots for faster node bootstrap. The next phase, if it were to be pursued, would be coming up with a way to distribute the UTXO snapshots over the P2P network. --- ### UTXO snapshots Create your own with `./contrib/devtools/utxo_snapshot.sh`, e.g. ```shell ./contrib/devtools/utxo_snapshot.sh 788000 utxo.dat ./src/bitcoin-cli -datadir=$(pwd)/testdata`) ``` or use the pre-generated ones listed below. - Testnet: **2'500'000** (Sjors): - torrent: `magnet:?xt=urn:btih:511e09f4bf853aefab00de5c070b1e031f0ecbe9&dn=utxo-testnet-2500000.dat&tr=udp%3A%2F%2Ftracker.bitcoin.sprovoost.nl%3A6969` - sha256: `79db4b025448cc0ac388d8589a28eab02de53055d181e34eb47391717aa16388` - Signet: **160'000** (Sjors): - torrent: `magnet:?xt=urn:btih:9da986cb27b3980ea7fd06b21e199b148d486880&dn=utxo-signet-160000.dat&tr=udp%3A%2F%2Ftracker.bitcoin.sprovoost.nl%3A6969` - sha256: `eeeca845385ba91e84ef58c09d38f98f246a24feadaad57fe1e5874f3f92ef8c` - Mainnet: **800'000** (Sjors): - Note: this needs the following commit cherry-picked in: https://github.com/Sjors/bitcoin/commit/24deb2022b822f22fba9fcbee201e37a83225eb2 - torrent: `magnet:?xt=urn:btih:50ee955bef37f5ec3e5b0df4cf0288af3d715a2e&dn=utxo-800000.dat&tr=udp%3A%2F%2Ftracker.bitcoin.sprovoost.nl%3A6969` ### Testing #### For fun (~5min) If you want to do a quick test, you can run `./contrib/devtools/test_utxo_snapshots.sh` and follow the instructions. This is mostly obviated by the functional tests, though. #### For real (longer) If you'd like to experience a real usage of assumeutxo, you can do that too. I've cut a new snapshot at height 788'000 (http://img.jameso.be/utxo-788000.dat - but you can do it yourself with `./contrib/devtools/utxo_snapshot.sh` if you want). Download that, and then create a datadir for testing: ```sh $ cd ~/src/bitcoin # or whatever # get the snapshot $ curl http://img.jameso.be/utxo-788000.dat > utxo-788000.dat # you'll want to do this if you like copy/pasting $ export AU_DATADIR=/home/${USER}/au-test # or wherever $ mkdir ${AU_DATADIR} $ vim ${AU_DATADIR}/bitcoin.conf dbcache=8000 # or, you know, something high blockfilterindex=1 coinstatsindex=1 prune=3000 logthreadnames=1 ``` Obtain this branch, build it, and then start bitcoind: ```sh $ git remote add jamesob https://github.com/jamesob/bitcoin $ git fetch jamesob assumeutxo $ git checkout jamesob/assumeutxo $ ./configure $conf_args && make # (whatever you like to do here) # start 'er up and watch the logs $ ./src/bitcoind -datadir=${AU_DATADIR} ``` Then, in some other window, load the snapshot ```sh $ ./src/bitcoin-cli -datadir=${AU_DATADIR} loadtxoutset $(pwd)/utxo-788000.dat ``` You'll see some log messages about headers retrieval and waiting to see the snapshot in the headers chain. Once you get the full headers chain, you'll spend a decent amount of time (~10min) loading the snapshot, checking it, and flushing it to disk. After all that happens, you should be syncing to tip in pretty short order, and you'll see the occasional `[background validation]` log message go by. In yet another window, you can check out chainstate status with ```sh $ ./src/bitcoin-cli -datadir=${AU_DATADIR} getchainstates ``` as well as usual favorites like `getblockchaininfo`. ACKs for top commit: achow101: ACK edbed31066e3674ba52b8c093ab235625527f383 Tree-SHA512: 6086fb9a38dc7df85fedc76b30084dd8154617a2a91e89a84fb41326d34ef8e7d7ea593107afba01369093bf8cc91770621d98f0ea42a5b3b99db868d2f14dc2
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/chain.cpp11
-rw-r--r--src/kernel/chain.h20
-rw-r--r--src/kernel/chainparams.cpp37
-rw-r--r--src/kernel/chainparams.h26
4 files changed, 77 insertions, 17 deletions
diff --git a/src/kernel/chain.cpp b/src/kernel/chain.cpp
index 1c877866d0..318c956b38 100644
--- a/src/kernel/chain.cpp
+++ b/src/kernel/chain.cpp
@@ -4,6 +4,7 @@
#include <chain.h>
#include <interfaces/chain.h>
+#include <kernel/chain.h>
#include <sync.h>
#include <uint256.h>
@@ -25,3 +26,13 @@ interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* index, const CBlock* data
return info;
}
} // namespace kernel
+
+std::ostream& operator<<(std::ostream& os, const ChainstateRole& role) {
+ switch(role) {
+ case ChainstateRole::NORMAL: os << "normal"; break;
+ case ChainstateRole::ASSUMEDVALID: os << "assumedvalid"; break;
+ case ChainstateRole::BACKGROUND: os << "background"; break;
+ default: os.setstate(std::ios_base::failbit);
+ }
+ return os;
+}
diff --git a/src/kernel/chain.h b/src/kernel/chain.h
index f0750f8266..feba24a557 100644
--- a/src/kernel/chain.h
+++ b/src/kernel/chain.h
@@ -5,6 +5,8 @@
#ifndef BITCOIN_KERNEL_CHAIN_H
#define BITCOIN_KERNEL_CHAIN_H
+#include<iostream>
+
class CBlock;
class CBlockIndex;
namespace interfaces {
@@ -14,6 +16,24 @@ struct BlockInfo;
namespace kernel {
//! Return data from block index.
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* block_index, const CBlock* data = nullptr);
+
} // namespace kernel
+//! This enum describes the various roles a specific Chainstate instance can take.
+//! Other parts of the system sometimes need to vary in behavior depending on the
+//! existence of a background validation chainstate, e.g. when building indexes.
+enum class ChainstateRole {
+ // Single chainstate in use, "normal" IBD mode.
+ NORMAL,
+
+ // Doing IBD-style validation in the background. Implies use of an assumed-valid
+ // chainstate.
+ BACKGROUND,
+
+ // Active assumed-valid chainstate. Implies use of a background IBD chainstate.
+ ASSUMEDVALID,
+};
+
+std::ostream& operator<<(std::ostream& os, const ChainstateRole& role);
+
#endif // BITCOIN_KERNEL_CHAIN_H
diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp
index 7e69c097a6..5e893a3f58 100644
--- a/src/kernel/chainparams.cpp
+++ b/src/kernel/chainparams.cpp
@@ -172,8 +172,8 @@ public:
}
};
- m_assumeutxo_data = MapAssumeutxo{
- // TODO to be specified in a future patch.
+ m_assumeutxo_data = {
+ // TODO to be specified in a future patch.
};
chainTxData = ChainTxData{
@@ -266,8 +266,13 @@ public:
}
};
- m_assumeutxo_data = MapAssumeutxo{
- // TODO to be specified in a future patch.
+ m_assumeutxo_data = {
+ {
+ .height = 2'500'000,
+ .hash_serialized = AssumeutxoHash{uint256S("0x2a8fdefef3bf75fa00540ccaaaba4b5281bea94229327bdb0f7416ef1e7a645c")},
+ .nChainTx = 66484552,
+ .blockhash = uint256S("0x0000000000000093bcb68c03a9a168ae252572d348a2eaeba2cdf9231d73206f")
+ }
};
chainTxData = ChainTxData{
@@ -370,6 +375,15 @@ public:
vFixedSeeds.clear();
+ m_assumeutxo_data = {
+ {
+ .height = 160'000,
+ .hash_serialized = AssumeutxoHash{uint256S("0x5225141cb62dee63ab3be95f9b03d60801f264010b1816d4bd00618b2736e7be")},
+ .nChainTx = 2289496,
+ .blockhash = uint256S("0x0000003ca3c99aff040f2563c2ad8f8ec88bd0fd6b8f0895cfaf1ef90353a62c")
+ }
+ };
+
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
@@ -477,14 +491,19 @@ public:
}
};
- m_assumeutxo_data = MapAssumeutxo{
+ m_assumeutxo_data = {
{
- 110,
- {AssumeutxoHash{uint256S("0x1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618")}, 110},
+ .height = 110,
+ .hash_serialized = AssumeutxoHash{uint256S("0x1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618")},
+ .nChainTx = 110,
+ .blockhash = uint256S("0x696e92821f65549c7ee134edceeeeaaa4105647a3c4fd9f298c0aec0ab50425c")
},
{
- 200,
- {AssumeutxoHash{uint256S("0x51c8d11d8b5c1de51543c579736e786aa2736206d1e11e627568029ce092cf62")}, 200},
+ // For use by test/functional/feature_assumeutxo.py
+ .height = 299,
+ .hash_serialized = AssumeutxoHash{uint256S("0xef45ccdca5898b6c2145e4581d2b88c56564dd389e4bd75a1aaf6961d3edd3c0")},
+ .nChainTx = 300,
+ .blockhash = uint256S("0x7e0517ef3ea6ecbed9117858e42eedc8eb39e8698a38dcbd1b3962a283233f4c")
},
};
diff --git a/src/kernel/chainparams.h b/src/kernel/chainparams.h
index ec1697493c..7a5539bc71 100644
--- a/src/kernel/chainparams.h
+++ b/src/kernel/chainparams.h
@@ -12,6 +12,7 @@
#include <uint256.h>
#include <util/chaintype.h>
#include <util/hash_type.h>
+#include <util/vector.h>
#include <cstdint>
#include <iterator>
@@ -44,17 +45,21 @@ struct AssumeutxoHash : public BaseHash<uint256> {
* as valid.
*/
struct AssumeutxoData {
+ int height;
+
//! The expected hash of the deserialized UTXO set.
- const AssumeutxoHash hash_serialized;
+ AssumeutxoHash hash_serialized;
//! Used to populate the nChainTx value, which is used during BlockManager::LoadBlockIndex().
//!
//! We need to hardcode the value here because this is computed cumulatively using block data,
//! which we do not necessarily have at the time of snapshot load.
- const unsigned int nChainTx;
-};
+ unsigned int nChainTx;
-using MapAssumeutxo = std::map<int, const AssumeutxoData>;
+ //! The hash of the base block for this snapshot. Used to refer to assumeutxo data
+ //! prior to having a loaded blockindex.
+ uint256 blockhash;
+};
/**
* Holds various statistics on transactions within a chain. Used to estimate
@@ -114,9 +119,14 @@ public:
const std::vector<uint8_t>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
- //! Get allowed assumeutxo configuration.
- //! @see ChainstateManager
- const MapAssumeutxo& Assumeutxo() const { return m_assumeutxo_data; }
+ std::optional<AssumeutxoData> AssumeutxoForHeight(int height) const
+ {
+ return FindFirst(m_assumeutxo_data, [&](const auto& d) { return d.height == height; });
+ }
+ std::optional<AssumeutxoData> AssumeutxoForBlockhash(const uint256& blockhash) const
+ {
+ return FindFirst(m_assumeutxo_data, [&](const auto& d) { return d.blockhash == blockhash; });
+ }
const ChainTxData& TxData() const { return chainTxData; }
@@ -169,7 +179,7 @@ protected:
bool fDefaultConsistencyChecks;
bool m_is_mockable_chain;
CCheckpointData checkpointData;
- MapAssumeutxo m_assumeutxo_data;
+ std::vector<AssumeutxoData> m_assumeutxo_data;
ChainTxData chainTxData;
};