Skip to content

Commit

Permalink
Merge branch 'bitcoin' into auxpow
Browse files Browse the repository at this point in the history
  • Loading branch information
domob1812 committed Oct 30, 2023
2 parents 9ad72da + 96ec3b6 commit 46ac33b
Show file tree
Hide file tree
Showing 29 changed files with 393 additions and 151 deletions.
5 changes: 4 additions & 1 deletion ci/test/02_run_container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then

# Still prune everything in case the filtered pruning doesn't work, or if labels were not set
# on a previous run. Belt and suspenders approach, should be fine to remove in the future.
# Prune images used by --external containers (e.g. build containers) when
# using podman.
echo "Prune all dangling images"
docker image prune --force
podman image prune --force --external
fi
echo "Prune all dangling $CI_IMAGE_LABEL images"
# When detecting podman-docker, `--external` should be added.
docker image prune --force --filter "label=$CI_IMAGE_LABEL"

# shellcheck disable=SC2086
Expand Down
2 changes: 1 addition & 1 deletion contrib/devtools/utxo_snapshot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ${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'
${BITCOIN_CLI_CALL} gettxoutsetinfo | grep hash_serialized_3 | sed 's/^.*: "\(.\+\)\+",/\1/g'
else
(>&2 echo "Generating UTXO snapshot...")
${BITCOIN_CLI_CALL} dumptxoutset "${OUTPUT_PATH}"
Expand Down
40 changes: 38 additions & 2 deletions doc/design/assumeutxo.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,44 @@
Assumeutxo is a feature that allows fast bootstrapping of a validating bitcoind
instance.

The RPC commands `dumptxoutset` and `loadtxoutset` are used to
respectively generate and load UTXO snapshots. The utility script
## Loading a snapshot

There is currently no canonical source for snapshots, but any downloaded snapshot
will be checked against a hash that's been hardcoded in source code.

Once you've obtained the snapshot, you can use the RPC command `loadtxoutset` to
load it.

### Pruning

A pruned node can load a snapshot. To save space, it's possible to delete the
snapshot file as soon as `loadtxoutset` finishes.

The minimum `-dbcache` setting is 550 MiB, but this functionality ignores that
minimum and uses at least 1100 MiB.

As the background sync continues there will be temporarily two chainstate
directories, each multiple gigabytes in size (likely growing larger than the
the downloaded snapshot).

### Indexes

Indexes work but don't take advantage of this feature. They always start building
from the genesis block. Once the background validation reaches the snapshot block,
indexes will continue to build all the way to the tip.

For indexes that support pruning, note that no pruning will take place between
the snapshot and the tip, until the background sync has completed - after which
everything is pruned. Depending on how old the snapshot is, this may temporarily
use a significant amount of disk space.

## Generating a snapshot

The RPC command `dumptxoutset` can be used to generate a snapshot. This can be used
to create a snapshot on one node that you wish to load on another node.
It can also be used to verify the hardcoded snapshot hash in the source code.

The utility script
`./contrib/devtools/utxo_snapshot.sh` may be of use.

## General background
Expand Down
4 changes: 4 additions & 0 deletions doc/release-notes-28685.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
RPC
---

The `hash_serialized_2` value has been removed from `gettxoutsetinfo` since the value it calculated contained a bug and did not take all data into account. It is superseded by `hash_serialized_3` which provides the same functionality but serves the correctly calculated hash.
76 changes: 76 additions & 0 deletions doc/release-notes/release-notes-24.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
24.2 Release Notes
==================

Bitcoin Core version 24.2 is now available from:

<https://bitcoincore.org/bin/bitcoin-core-24.2/>

This release includes various bug fixes and performance
improvements, as well as updated translations.

Please report bugs using the issue tracker at GitHub:

<https://github.com/bitcoin/bitcoin/issues>

To receive security and update notifications, please subscribe to:

<https://bitcoincore.org/en/list/announcements/join/>

How to Upgrade
==============

If you are running an older version, shut it down. Wait until it has completely
shut down (which might take a few minutes in some cases), then run the
installer (on Windows) or just copy over `/Applications/Bitcoin-Qt` (on macOS)
or `bitcoind`/`bitcoin-qt` (on Linux).

Upgrading directly from a version of Bitcoin Core that has reached its EOL is
possible, but it might take some time if the data directory needs to be migrated. Old
wallet versions of Bitcoin Core are generally supported.

Compatibility
==============

Bitcoin Core is supported and extensively tested on operating systems
using the Linux kernel, macOS 10.15+, and Windows 7 and newer. Bitcoin
Core should also work on most other Unix-like systems but is not as
frequently tested on them. It is not recommended to use Bitcoin Core on
unsupported systems.

### Fees

- #27622 Fee estimation: avoid serving stale fee estimate

### RPC and other APIs

- #27727 rpc: Fix invalid bech32 address handling

### Build System

- #28097 depends: xcb-proto 1.15.2
- #28543 build, macos: Fix qt package build with new Xcode 15 linker
- #28571 depends: fix unusable memory_resource in macos qt build

### CI

- #27777 ci: Prune dangling images on RESTART_CI_DOCKER_BEFORE_RUN
- #27834 ci: Nuke Android APK task, Use credits for tsan
- #27844 ci: Use podman stop over podman kill
- #27886 ci: Switch to amd64 container in "ARM" task

### Miscellaneous
- #28452 Do not use std::vector = {} to release memory

Credits
=======

Thanks to everyone who directly contributed to this release:

- Abubakar Sadiq Ismail
- Hennadii Stepanov
- Marco Falke
- Michael Ford
- Pieter Wuille

As well as to everyone that helped with translations on
[Transifex](https://www.transifex.com/bitcoin/bitcoin/).
30 changes: 8 additions & 22 deletions src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ static constexpr int64_t MAX_BLOCK_TIME_GAP = 90 * 60;
class CBlockFileInfo
{
public:
unsigned int nBlocks; //!< number of blocks stored in file
unsigned int nSize; //!< number of used bytes of block file
unsigned int nUndoSize; //!< number of used bytes in the undo file
unsigned int nHeightFirst; //!< lowest height of block in file
unsigned int nHeightLast; //!< highest height of block in file
uint64_t nTimeFirst; //!< earliest time of block in file
uint64_t nTimeLast; //!< latest time of block in file
unsigned int nBlocks{}; //!< number of blocks stored in file
unsigned int nSize{}; //!< number of used bytes of block file
unsigned int nUndoSize{}; //!< number of used bytes in the undo file
unsigned int nHeightFirst{}; //!< lowest height of block in file
unsigned int nHeightLast{}; //!< highest height of block in file
uint64_t nTimeFirst{}; //!< earliest time of block in file
uint64_t nTimeLast{}; //!< latest time of block in file

SERIALIZE_METHODS(CBlockFileInfo, obj)
{
Expand All @@ -67,21 +67,7 @@ class CBlockFileInfo
READWRITE(VARINT(obj.nTimeLast));
}

void SetNull()
{
nBlocks = 0;
nSize = 0;
nUndoSize = 0;
nHeightFirst = 0;
nHeightLast = 0;
nTimeFirst = 0;
nTimeLast = 0;
}

CBlockFileInfo()
{
SetNull();
}
CBlockFileInfo() {}

std::string ToString() const;

Expand Down
11 changes: 6 additions & 5 deletions src/index/coinstatsindex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
#include <undo.h>
#include <validation.h>

using kernel::ApplyCoinHash;
using kernel::CCoinsStats;
using kernel::GetBogoSize;
using kernel::TxOutSer;
using kernel::RemoveCoinHash;

static constexpr uint8_t DB_BLOCK_HASH{'s'};
static constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
Expand Down Expand Up @@ -166,7 +167,7 @@ bool CoinStatsIndex::CustomAppend(const interfaces::BlockInfo& block)
continue;
}

m_muhash.Insert(MakeUCharSpan(TxOutSer(outpoint, coin)));
ApplyCoinHash(m_muhash, outpoint, coin);

if (tx->IsCoinBase()) {
m_total_coinbase_amount += coin.out.nValue;
Expand All @@ -187,7 +188,7 @@ bool CoinStatsIndex::CustomAppend(const interfaces::BlockInfo& block)
Coin coin{tx_undo.vprevout[j]};
COutPoint outpoint{tx->vin[j].prevout.hash, tx->vin[j].prevout.n};

m_muhash.Remove(MakeUCharSpan(TxOutSer(outpoint, coin)));
RemoveCoinHash(m_muhash, outpoint, coin);

m_total_prevout_spent_amount += coin.out.nValue;

Expand Down Expand Up @@ -443,7 +444,7 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
continue;
}

m_muhash.Remove(MakeUCharSpan(TxOutSer(outpoint, coin)));
RemoveCoinHash(m_muhash, outpoint, coin);

if (tx->IsCoinBase()) {
m_total_coinbase_amount -= coin.out.nValue;
Expand All @@ -464,7 +465,7 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
Coin coin{tx_undo.vprevout[j]};
COutPoint outpoint{tx->vin[j].prevout.hash, tx->vin[j].prevout.n};

m_muhash.Insert(MakeUCharSpan(TxOutSer(outpoint, coin)));
ApplyCoinHash(m_muhash, outpoint, coin);

m_total_prevout_spent_amount -= coin.out.nValue;

Expand Down
8 changes: 4 additions & 4 deletions src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class CTestNetParams : public CChainParams {
m_assumeutxo_data = {
{
.height = 2'500'000,
.hash_serialized = AssumeutxoHash{uint256S("0x2a8fdefef3bf75fa00540ccaaaba4b5281bea94229327bdb0f7416ef1e7a645c")},
.hash_serialized = AssumeutxoHash{uint256S("0xf841584909f68e47897952345234e37fcd9128cd818f41ee6c3ca68db8071be7")},
.nChainTx = 66484552,
.blockhash = uint256S("0x0000000000000093bcb68c03a9a168ae252572d348a2eaeba2cdf9231d73206f")
}
Expand Down Expand Up @@ -388,7 +388,7 @@ class SigNetParams : public CChainParams {
m_assumeutxo_data = {
{
.height = 160'000,
.hash_serialized = AssumeutxoHash{uint256S("0x5225141cb62dee63ab3be95f9b03d60801f264010b1816d4bd00618b2736e7be")},
.hash_serialized = AssumeutxoHash{uint256S("0xfe0a44309b74d6b5883d246cb419c6221bcccf0b308c9b59b7d70783dbdf928a")},
.nChainTx = 2289496,
.blockhash = uint256S("0x0000003ca3c99aff040f2563c2ad8f8ec88bd0fd6b8f0895cfaf1ef90353a62c")
}
Expand Down Expand Up @@ -509,14 +509,14 @@ class CRegTestParams : public CChainParams
m_assumeutxo_data = {
{
.height = 110,
.hash_serialized = AssumeutxoHash{uint256S("0x162681de9f290aaeb9137f1fd70842cfff8307903fb19660a4e4428581d21d60")},
.hash_serialized = AssumeutxoHash{uint256S("0x6657b736d4fe4db0cbc796789e812d5dba7f5c143764b1b6905612f1830609d1")},
.nChainTx = 111,
.blockhash = uint256S("0x5dd7b94b2c61d979459c9de55113f3edfc7796a70f7a1e301dcb8dd86ceaa654")
},
{
// For use by test/functional/feature_assumeutxo.py
.height = 299,
.hash_serialized = AssumeutxoHash{uint256S("0xdb3b4c29fd2674caf3c163ea3767e67500204cc74c6d9ae396b27005e25f925f")},
.hash_serialized = AssumeutxoHash{uint256S("0x61d9c2b29a2571a5fe285fe2d8554f91f93309666fc9b8223ee96338de25ff53")},
.nChainTx = 300,
.blockhash = uint256S("0x324cc81513e21f2a3297a0a3821183f045a4cc1cac835e073c851c4932d7264d")
},
Expand Down
64 changes: 27 additions & 37 deletions src/kernel/coinstats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,35 @@ uint64_t GetBogoSize(const CScript& script_pub_key)
script_pub_key.size() /* scriptPubKey */;
}

DataStream TxOutSer(const COutPoint& outpoint, const Coin& coin)
template <typename T>
static void TxOutSer(T& ss, const COutPoint& outpoint, const Coin& coin)
{
DataStream ss{};
ss << outpoint;
ss << static_cast<uint32_t>(coin.nHeight * 2 + coin.fCoinBase);
ss << static_cast<uint32_t>((coin.nHeight << 1) + coin.fCoinBase);
ss << coin.out;
return ss;
}

static void ApplyCoinHash(HashWriter& ss, const COutPoint& outpoint, const Coin& coin)
{
TxOutSer(ss, outpoint, coin);
}

void ApplyCoinHash(MuHash3072& muhash, const COutPoint& outpoint, const Coin& coin)
{
DataStream ss{};
TxOutSer(ss, outpoint, coin);
muhash.Insert(MakeUCharSpan(ss));
}

void RemoveCoinHash(MuHash3072& muhash, const COutPoint& outpoint, const Coin& coin)
{
DataStream ss{};
TxOutSer(ss, outpoint, coin);
muhash.Remove(MakeUCharSpan(ss));
}

static void ApplyCoinHash(std::nullptr_t, const COutPoint& outpoint, const Coin& coin) {}

//! Warning: be very careful when changing this! assumeutxo and UTXO snapshot
//! validation commitments are reliant on the hash constructed by this
//! function.
Expand All @@ -69,32 +89,13 @@ DataStream TxOutSer(const COutPoint& outpoint, const Coin& coin)
//! It is also possible, though very unlikely, that a change in this
//! construction could cause a previously invalid (and potentially malicious)
//! UTXO snapshot to be considered valid.
static void ApplyHash(HashWriter& ss, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
{
for (auto it = outputs.begin(); it != outputs.end(); ++it) {
if (it == outputs.begin()) {
ss << hash;
ss << VARINT(it->second.nHeight * 2 + it->second.fCoinBase ? 1u : 0u);
}

ss << VARINT(it->first + 1);
ss << it->second.out.scriptPubKey;
ss << VARINT_MODE(it->second.out.nValue, VarIntMode::NONNEGATIVE_SIGNED);

if (it == std::prev(outputs.end())) {
ss << VARINT(0u);
}
}
}

static void ApplyHash(std::nullptr_t, const uint256& hash, const std::map<uint32_t, Coin>& outputs) {}

static void ApplyHash(MuHash3072& muhash, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
template <typename T>
static void ApplyHash(T& hash_obj, const uint256& hash, const std::map<uint32_t, Coin>& outputs)
{
for (auto it = outputs.begin(); it != outputs.end(); ++it) {
COutPoint outpoint = COutPoint(hash, it->first);
Coin coin = it->second;
muhash.Insert(MakeUCharSpan(TxOutSer(outpoint, coin)));
ApplyCoinHash(hash_obj, outpoint, coin);
}
}

Expand All @@ -118,8 +119,6 @@ static bool ComputeUTXOStats(CCoinsView* view, CCoinsStats& stats, T hash_obj, c
std::unique_ptr<CCoinsViewCursor> pcursor(view->Cursor());
assert(pcursor);

PrepareHash(hash_obj, stats);

uint256 prevkey;
std::map<uint32_t, Coin> outputs;
while (pcursor->Valid()) {
Expand Down Expand Up @@ -180,15 +179,6 @@ std::optional<CCoinsStats> ComputeUTXOStats(CoinStatsHashType hash_type, CCoinsV
return stats;
}

// The legacy hash serializes the hashBlock
static void PrepareHash(HashWriter& ss, const CCoinsStats& stats)
{
ss << stats.hashBlock;
}
// MuHash does not need the prepare step
static void PrepareHash(MuHash3072& muhash, CCoinsStats& stats) {}
static void PrepareHash(std::nullptr_t, CCoinsStats& stats) {}

static void FinalizeHash(HashWriter& ss, CCoinsStats& stats)
{
stats.hashSerialized = ss.GetHash();
Expand Down
4 changes: 3 additions & 1 deletion src/kernel/coinstats.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BITCOIN_KERNEL_COINSTATS_H

#include <consensus/amount.h>
#include <crypto/muhash.h>
#include <streams.h>
#include <uint256.h>

Expand Down Expand Up @@ -72,7 +73,8 @@ struct CCoinsStats {

uint64_t GetBogoSize(const CScript& script_pub_key);

DataStream TxOutSer(const COutPoint& outpoint, const Coin& coin);
void ApplyCoinHash(MuHash3072& muhash, const COutPoint& outpoint, const Coin& coin);
void RemoveCoinHash(MuHash3072& muhash, const COutPoint& outpoint, const Coin& coin);

std::optional<CCoinsStats> ComputeUTXOStats(CoinStatsHashType hash_type, CCoinsView* view, node::BlockManager& blockman, const std::function<void()>& interruption_point = {});
} // namespace kernel
Expand Down
Loading

0 comments on commit 46ac33b

Please sign in to comment.