forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge bitcoin#16899: UTXO snapshot creation (dumptxoutset)
95c7f5e test: add dumptxoutset RPC test (James O'Beirne) ddc90a8 devtools: add utxo_snapshot.sh (James O'Beirne) 49f281b rpc: add dumptxoutset (James O'Beirne) 644c7e7 coinstats: add coins_count (James O'Beirne) 707fde7 add unused SnapshotMetadata class (James O'Beirne) Pull request description: This is part of the [assumeutxo project](https://github.com/bitcoin/bitcoin/projects/11): Parent PR: bitcoin#15606 Issue: bitcoin#15605 Specification: https://github.com/jamesob/assumeutxo-docs/tree/master/proposal --- This changeset defines the serialization format for UTXO snapshots and adds an RPC command for creating them, `dumptxoutset`. It also adds a convenience script for generating and verifying snapshots at a certain height, since that requires doing a hacky rewind of the chain via `invalidateblock`. All of this is unused at the moment.
- Loading branch information
Showing
9 changed files
with
267 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Copyright (c) 2019 The Bitcoin Core developers | ||
# Distributed under the MIT software license, see the accompanying | ||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
# | ||
export LC_ALL=C | ||
|
||
set -ueo pipefail | ||
|
||
if (( $# < 3 )); then | ||
echo 'Usage: utxo_snapshot.sh <generate-at-height> <snapshot-out-path> <bitcoin-cli-call ...>' | ||
echo | ||
echo " if <snapshot-out-path> is '-', don't produce a snapshot file but instead print the " | ||
echo " expected assumeutxo hash" | ||
echo | ||
echo 'Examples:' | ||
echo | ||
echo " ./contrib/devtools/utxo_snapshot.sh 570000 utxo.dat ./src/bitcoin-cli -datadir=\$(pwd)/testdata" | ||
echo ' ./contrib/devtools/utxo_snapshot.sh 570000 - ./src/bitcoin-cli' | ||
exit 1 | ||
fi | ||
|
||
GENERATE_AT_HEIGHT="${1}"; shift; | ||
OUTPUT_PATH="${1}"; shift; | ||
# Most of the calls we make take a while to run, so pad with a lengthy timeout. | ||
BITCOIN_CLI_CALL="${*} -rpcclienttimeout=9999999" | ||
|
||
# Block we'll invalidate/reconsider to rewind/fast-forward the chain. | ||
PIVOT_BLOCKHASH=$($BITCOIN_CLI_CALL getblockhash $(( GENERATE_AT_HEIGHT + 1 )) ) | ||
|
||
(>&2 echo "Rewinding chain back to height ${GENERATE_AT_HEIGHT} (by invalidating ${PIVOT_BLOCKHASH}); this may take a while") | ||
${BITCOIN_CLI_CALL} invalidateblock "${PIVOT_BLOCKHASH}" | ||
|
||
if [[ "${OUTPUT_PATH}" = "-" ]]; then | ||
(>&2 echo "Generating txoutset info...") | ||
${BITCOIN_CLI_CALL} gettxoutsetinfo | grep hash_serialized_2 | sed 's/^.*: "\(.\+\)\+",/\1/g' | ||
else | ||
(>&2 echo "Generating UTXO snapshot...") | ||
${BITCOIN_CLI_CALL} dumptxoutset "${OUTPUT_PATH}" | ||
fi | ||
|
||
(>&2 echo "Restoring chain to original height; this may take a while") | ||
${BITCOIN_CLI_CALL} reconsiderblock "${PIVOT_BLOCKHASH}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) 2009-2010 Satoshi Nakamoto | ||
// Copyright (c) 2009-2019 The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#ifndef BITCOIN_NODE_UTXO_SNAPSHOT_H | ||
#define BITCOIN_NODE_UTXO_SNAPSHOT_H | ||
|
||
#include <uint256.h> | ||
#include <serialize.h> | ||
|
||
//! Metadata describing a serialized version of a UTXO set from which an | ||
//! assumeutxo CChainState can be constructed. | ||
class SnapshotMetadata | ||
{ | ||
public: | ||
//! The hash of the block that reflects the tip of the chain for the | ||
//! UTXO set contained in this snapshot. | ||
uint256 m_base_blockhash; | ||
|
||
//! The number of coins in the UTXO set contained in this snapshot. Used | ||
//! during snapshot load to estimate progress of UTXO set reconstruction. | ||
uint64_t m_coins_count = 0; | ||
|
||
//! Necessary to "fake" the base nChainTx so that we can estimate progress during | ||
//! initial block download for the assumeutxo chainstate. | ||
unsigned int m_nchaintx = 0; | ||
|
||
SnapshotMetadata() { } | ||
SnapshotMetadata( | ||
const uint256& base_blockhash, | ||
uint64_t coins_count, | ||
unsigned int nchaintx) : | ||
m_base_blockhash(base_blockhash), | ||
m_coins_count(coins_count), | ||
m_nchaintx(nchaintx) { } | ||
|
||
ADD_SERIALIZE_METHODS; | ||
|
||
template <typename Stream, typename Operation> | ||
inline void SerializationOp(Stream& s, Operation ser_action) | ||
{ | ||
READWRITE(m_base_blockhash); | ||
READWRITE(m_coins_count); | ||
READWRITE(m_nchaintx); | ||
} | ||
|
||
}; | ||
|
||
#endif // BITCOIN_NODE_UTXO_SNAPSHOT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (c) 2019 The Bitcoin Core developers | ||
# Distributed under the MIT software license, see the accompanying | ||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
"""Test the generation of UTXO snapshots using `dumptxoutset`. | ||
""" | ||
from test_framework.test_framework import BitcoinTestFramework | ||
from test_framework.util import assert_equal, assert_raises_rpc_error | ||
|
||
import hashlib | ||
from pathlib import Path | ||
|
||
|
||
class DumptxoutsetTest(BitcoinTestFramework): | ||
def set_test_params(self): | ||
self.setup_clean_chain = True | ||
self.num_nodes = 1 | ||
|
||
def run_test(self): | ||
"""Test a trivial usage of the dumptxoutset RPC command.""" | ||
node = self.nodes[0] | ||
mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1 | ||
node.setmocktime(mocktime) | ||
node.generate(100) | ||
|
||
FILENAME = 'txoutset.dat' | ||
out = node.dumptxoutset(FILENAME) | ||
expected_path = Path(node.datadir) / 'regtest' / FILENAME | ||
|
||
assert expected_path.is_file() | ||
|
||
assert_equal(out['coins_written'], 100) | ||
assert_equal(out['base_height'], 100) | ||
assert_equal(out['path'], str(expected_path)) | ||
# Blockhash should be deterministic based on mocked time. | ||
assert_equal( | ||
out['base_hash'], | ||
'6fd417acba2a8738b06fee43330c50d58e6a725046c3d843c8dd7e51d46d1ed6') | ||
|
||
with open(str(expected_path), 'rb') as f: | ||
digest = hashlib.sha256(f.read()).hexdigest() | ||
# UTXO snapshot hash should be deterministic based on mocked time. | ||
assert_equal( | ||
digest, 'be032e5f248264ba08e11099ac09dbd001f6f87ffc68bf0f87043d8146d50664') | ||
|
||
# Specifying a path to an existing file will fail. | ||
assert_raises_rpc_error( | ||
-8, '{} already exists'.format(FILENAME), node.dumptxoutset, FILENAME) | ||
|
||
if __name__ == '__main__': | ||
DumptxoutsetTest().main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters