Skip to content

Commit 00a3917

Browse files
committed
Squashed 'libbitcoinkernel-sys/bitcoin/' changes from 5b8c204275aa..d07a42ca43ed
d07a42ca43ed Add sans utxo set block validation 00da3f047017 doc: Add docstrings for ConnectBlock and SpendBlock 1c16831a2fc2 validation: Move coin existence and spend check to SpendBlock 023ad3f66158 validation: Move SetBestBlock out of ConnectBlock d49b24250048 validation: Add SpendBlock function 702df0169535 validation: Use vector of outputs instead of CCoinsViewCache in CheckInputScripts 2f907b9e230f consensus: Use Coin span in CheckTxInputs 1b78755de266 consensus: Use Coin span in GetTransactionSigOpCost ccdcbd82ae3e consensus: Use Coin span in GetP2SHSigOpCount 27aeeff63014 Merge bitcoin/bitcoin#34328: rpc: make `uptime` monotonic across NTP jumps f970cb39fb64 Merge bitcoin/bitcoin#34267: net: avoid unconditional `privatebroadcast` logging (+ warn for debug logs) 8593d965191e Merge bitcoin/bitcoin#33067: test: refactor ValidWitnessMalleatedTx class to helper function 34a5ecadd720 Merge bitcoin/bitcoin#34397: doc: fix arg name hints so bugprone can validate them 1cc58d3a0c65 Merge bitcoin/bitcoin#34281: build: Temporarily remove confusing and brittle `-fdebug-prefix-map` 2778eb46647a Merge bitcoin/bitcoin#34337: fuzz: Return chrono point from ConsumeTime(), Add ConsumeDuration() d70fb8a5754f Merge bitcoin/bitcoin#34351: util: Remove `FilterHeaderHasher` 6472ba06c36a Merge bitcoin/bitcoin#34388: doc: Explain that low-effort pull requests may be closed 5f66fca633c8 Merge bitcoin-core/gui#920: Set peer version and subversion to N/A when not available or detecting 02240a7698e3 Merge bitcoin/bitcoin#34390: test: allow overriding `tar` in `get_previous_releases.py` a73a3ec5532d doc: fix invalid arg name hints for bugprone validation eeee3755f8c4 fuzz: Return chrono point from ConsumeTime(), Add ConsumeDuration() fa15a8d2d03b doc: Explain that low-effort pull requests may be closed be2b48b9f3e5 test: allow overriding tar in get_previous_releases 3f5211cba8e7 test: remove child_one/child_two (w)txid variables 7cfe790820cf test: replace ValidWitnessMalleatedTx class with function ccf9172ab3bb util: Remove `FilterHeaderHasher` 81675a781f3a test: use pre-generated chain 14f99cfe53f0 rpc: make `uptime` monotonic across NTP jumps a9440b1595be util: add `TicksSeconds` faa5a9ebad15 fuzz: Use min option in ConsumeTime fa37928536e0 build: Temporarily remove confusing and brittle -fdebug-prefix-map b39291f4cde0 doc: fix `-logips` description to clarify that non-debug logs can also contain IP addresses c7028d3368e9 init: log that additional logs may contain privacy-sensitive information 31b771a9425d net: move `privatebroadcast` logs to debug category b261100e7169 [qt] Set peer version and subversion to N/A when not available or detecting git-subtree-dir: libbitcoinkernel-sys/bitcoin git-subtree-split: d07a42ca43edd620bcfee8108b440b0cdf867bec
1 parent 319b3a3 commit 00a3917

56 files changed

Lines changed: 836 additions & 403 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,8 @@ try_append_cxx_flags("-fno-extended-identifiers" TARGET core_interface SKIP_LINK
488488
# which can cause issues with coverage builds, particularly when using
489489
# Clang in the OSS-Fuzz environment due to its use of other options
490490
# and a third party script, or with GCC.
491-
try_append_cxx_flags("-fdebug-prefix-map=A=B" TARGET core_interface SKIP_LINK
492-
IF_CHECK_PASSED "-fdebug-prefix-map=${PROJECT_SOURCE_DIR}/src=."
493-
)
491+
# Set `-fmacro-prefix-map`, so that source file names are expanded without the
492+
# src prefix.
494493
try_append_cxx_flags("-fmacro-prefix-map=A=B" TARGET core_interface SKIP_LINK
495494
IF_CHECK_PASSED "-fmacro-prefix-map=${PROJECT_SOURCE_DIR}/src=."
496495
)

CONTRIBUTING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ The codebase is maintained using the "contributor workflow" where everyone
7878
without exception contributes patch proposals using "pull requests" (PRs). This
7979
facilitates social contribution, easy testing and peer review.
8080

81+
Pull request authors must fully and confidently understand their own changes
82+
and must have tested them. Contributors should mention which tests cover their
83+
changes, or include the manual steps they used to confirm the change.
84+
Contributors are expected to be prepared to clearly motivate and explain their
85+
changes. If there is doubt, the pull request may be closed.
86+
Please refer to the [peer review](#peer-review) section below for more details.
87+
8188
To contribute a patch, the workflow is as follows:
8289

8390
1. Fork repository ([only for the first time](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo))
@@ -338,6 +345,11 @@ reviewers that the changes warrant the review effort, and if reviewers are
338345
"Concept NACK'ing" the PR, the author may need to present arguments and/or do
339346
research backing their suggested changes.
340347

348+
Moreover, if there is reasonable doubt that the pull request author does not
349+
fully understand the changes they are submitting themselves, or if it becomes
350+
clear that they have not tested the changes on a basic level themselves, the
351+
pull request may be closed immediately.
352+
341353
#### Conceptual Review
342354

343355
A review can be a conceptual review, where the reviewer leaves a comment

contrib/guix/libexec/build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ CONFIGFLAGS="-DREDUCE_EXPORTS=ON -DBUILD_BENCH=OFF -DBUILD_GUI_TESTS=OFF -DBUILD
211211
# CFLAGS
212212
HOST_CFLAGS="-O2 -g"
213213
HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;)
214+
HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=."
214215
case "$HOST" in
215216
*mingw*) HOST_CFLAGS+=" -fno-ident" ;;
216217
*darwin*) unset HOST_CFLAGS ;;

src/bench/connectblock.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <script/interpreter.h>
1010
#include <sync.h>
1111
#include <test/util/setup_common.h>
12+
#include <undo.h>
1213
#include <validation.h>
1314

1415
#include <cassert>
@@ -100,7 +101,9 @@ void BenchmarkConnectBlock(benchmark::Bench& bench, std::vector<CKey>& keys, std
100101
auto* pindex{chainman->m_blockman.AddToBlockIndex(test_block, chainman->m_best_header)}; // Doing this here doesn't impact the benchmark
101102
CCoinsViewCache viewNew{&chainstate.CoinsTip()};
102103

103-
assert(chainstate.ConnectBlock(test_block, test_block_state, pindex, viewNew));
104+
CBlockUndo blockundo;
105+
assert(chainstate.SpendBlock(test_block, pindex, viewNew, test_block_state, blockundo));
106+
assert(chainstate.ConnectBlock(test_block, blockundo, test_block_state, pindex));
104107
});
105108
}
106109

src/bench/mempool_stress.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static void MemPoolAddTransactions(benchmark::Bench& bench)
106106
std::vector<CTransactionRef> transactions;
107107
// Create 1000 clusters of 100 transactions each
108108
for (int i=0; i<100; i++) {
109-
auto new_txs = CreateCoinCluster(det_rand, childTxs, /*min_ancestors*/ 1);
109+
auto new_txs = CreateCoinCluster(det_rand, childTxs, /*min_ancestors=*/ 1);
110110
transactions.insert(transactions.end(), new_txs.begin(), new_txs.end());
111111
}
112112

@@ -156,7 +156,7 @@ static void ComplexMemPool(benchmark::Bench& bench)
156156
// in the same state at the end of the function, so we benchmark both
157157
// mining a block and reorging the block's contents back into the mempool.
158158
bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
159-
pool.removeForBlock(tx_remove_for_block, /*nBlockHeight*/100);
159+
pool.removeForBlock(tx_remove_for_block, /*nBlockHeight=*/100);
160160
for (auto& tx: tx_remove_for_block) {
161161
AddTx(tx, pool, det_rand);
162162
}

src/coins.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,29 @@ const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
167167
}
168168
}
169169

170+
std::vector<std::reference_wrapper<const Coin>> CCoinsViewCache::AccessCoins(const CTransaction& tx) const
171+
{
172+
std::vector<std::reference_wrapper<const Coin>> coins;
173+
coins.reserve(tx.vin.size());
174+
for (const CTxIn& input : tx.vin) {
175+
coins.emplace_back(AccessCoin(input.prevout));
176+
}
177+
return coins;
178+
}
179+
180+
std::vector<CTxOut> CCoinsViewCache::GetUnspentOutputs(const CTransaction& tx) const
181+
{
182+
std::vector<CTxOut> spent_outputs;
183+
spent_outputs.reserve(tx.vin.size());
184+
for (const auto& txin : tx.vin) {
185+
const COutPoint& prevout = txin.prevout;
186+
const Coin& coin = AccessCoin(prevout);
187+
assert(!coin.IsSpent());
188+
spent_outputs.emplace_back(coin.out);
189+
}
190+
return spent_outputs;
191+
}
192+
170193
bool CCoinsViewCache::HaveCoin(const COutPoint &outpoint) const {
171194
CCoinsMap::const_iterator it = FetchCoin(outpoint);
172195
return (it != cacheCoins.end() && !it->second.coin.IsSpent());

src/coins.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,23 @@ class CCoinsViewCache : public CCoinsViewBacked
413413
*/
414414
const Coin& AccessCoin(const COutPoint &output) const;
415415

416+
/**
417+
* Return a vector of references to Coins in the cache in order they get
418+
* consumed by the tx's inputs, or coinEmpty if the Coin is not
419+
* found.
420+
*
421+
* Generally, this should only be held for a short scope. The coins should
422+
* generally not be held through any other calls to this cache.
423+
*/
424+
std::vector<std::reference_wrapper<const Coin>> AccessCoins(const CTransaction& tx) const;
425+
426+
/**
427+
* Return a vector of unspent outputs of coins in the cache that are spent
428+
* by the provided transaction. The coins they belong to must be unspent in
429+
* the cache.
430+
*/
431+
std::vector<CTxOut> GetUnspentOutputs(const CTransaction& tx) const;
432+
416433
/**
417434
* Add a coin. Set possible_overwrite to true if an unspent version may
418435
* already exist in the cache.

src/common/system.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@
3737

3838
using util::ReplaceAll;
3939

40-
// Application startup time (used for uptime calculation)
41-
const int64_t nStartupTime = GetTime();
42-
4340
#ifndef WIN32
4441
std::string ShellEscape(const std::string& arg)
4542
{
@@ -130,8 +127,8 @@ std::optional<size_t> GetTotalRAM()
130127
return std::nullopt;
131128
}
132129

133-
// Obtain the application startup time (used for uptime calculation)
134-
int64_t GetStartupTime()
130+
SteadyClock::duration GetUptime()
135131
{
136-
return nStartupTime;
132+
static const auto g_startup_time{SteadyClock::now()};
133+
return SteadyClock::now() - g_startup_time;
137134
}

src/common/system.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
#define BITCOIN_COMMON_SYSTEM_H
88

99
#include <bitcoin-build-config.h> // IWYU pragma: keep
10+
#include <util/time.h>
1011

12+
#include <chrono>
1113
#include <cstdint>
1214
#include <optional>
1315
#include <string>
1416

15-
// Application startup time (used for uptime calculation)
16-
int64_t GetStartupTime();
17+
/// Monotonic uptime (not affected by system time changes).
18+
SteadyClock::duration GetUptime();
1719

1820
void SetupEnvironment();
1921
[[nodiscard]] bool SetupNetworking();

src/consensus/tx_verify.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <util/check.h>
1515
#include <util/moneystr.h>
1616

17+
#include <span>
18+
1719
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
1820
{
1921
if (tx.nLockTime == 0)
@@ -123,62 +125,73 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx)
123125
return nSigOps;
124126
}
125127

126-
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
128+
template <Consensus::CoinRef T>
129+
unsigned int GetP2SHSigOpCount(const CTransaction& tx, const std::span<T> coins)
127130
{
128131
if (tx.IsCoinBase())
129132
return 0;
130133

131134
unsigned int nSigOps = 0;
132-
for (unsigned int i = 0; i < tx.vin.size(); i++)
133-
{
134-
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
135+
Assert(coins.size() == tx.vin.size());
136+
auto input_it = tx.vin.begin();
137+
for (auto it = coins.begin(); it != coins.end(); ++it, ++input_it) {
138+
const Coin& coin = *it;
135139
assert(!coin.IsSpent());
136140
const CTxOut &prevout = coin.out;
137141
if (prevout.scriptPubKey.IsPayToScriptHash())
138-
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
142+
nSigOps += prevout.scriptPubKey.GetSigOpCount(input_it->scriptSig);
139143
}
140144
return nSigOps;
141145
}
142146

143-
int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, script_verify_flags flags)
147+
template unsigned int GetP2SHSigOpCount<const Coin>(
148+
const CTransaction& tx, const std::span<const Coin>);
149+
150+
template unsigned int GetP2SHSigOpCount<std::reference_wrapper<const Coin>>(
151+
const CTransaction& tx, const std::span<std::reference_wrapper<const Coin>>);
152+
153+
template <Consensus::CoinRef T>
154+
int64_t GetTransactionSigOpCost(const CTransaction& tx, const std::span<T> coins, script_verify_flags flags)
144155
{
145156
int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
146157

147158
if (tx.IsCoinBase())
148159
return nSigOps;
149160

150161
if (flags & SCRIPT_VERIFY_P2SH) {
151-
nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
162+
nSigOps += GetP2SHSigOpCount(tx, coins) * WITNESS_SCALE_FACTOR;
152163
}
153164

154-
for (unsigned int i = 0; i < tx.vin.size(); i++)
155-
{
156-
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
165+
Assert(coins.size() == tx.vin.size());
166+
auto input_it = tx.vin.begin();
167+
for (auto it = coins.begin(); it != coins.end(); ++it, ++input_it) {
168+
const Coin& coin = *it;
157169
assert(!coin.IsSpent());
158170
const CTxOut &prevout = coin.out;
159-
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, tx.vin[i].scriptWitness, flags);
171+
nSigOps += CountWitnessSigOps(input_it->scriptSig, prevout.scriptPubKey, input_it->scriptWitness, flags);
160172
}
161173
return nSigOps;
162174
}
175+
template int64_t GetTransactionSigOpCost<const Coin>(
176+
const CTransaction& tx, std::span<const Coin> coins, script_verify_flags flags);
163177

164-
bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
165-
{
166-
// are the actual inputs available?
167-
if (!inputs.HaveInputs(tx)) {
168-
return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
169-
strprintf("%s: inputs missing/spent", __func__));
170-
}
178+
template int64_t GetTransactionSigOpCost<std::reference_wrapper<const Coin>>(
179+
const CTransaction& tx, const std::span<std::reference_wrapper<const Coin>> coins, script_verify_flags flags);
171180

181+
template <Consensus::CoinRef T>
182+
bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const std::span<T> coins, int nSpendHeight, CAmount& txfee)
183+
{
172184
CAmount nValueIn = 0;
173-
for (unsigned int i = 0; i < tx.vin.size(); ++i) {
174-
const COutPoint &prevout = tx.vin[i].prevout;
175-
const Coin& coin = inputs.AccessCoin(prevout);
185+
Assert(coins.size() == tx.vin.size());
186+
auto input_it = tx.vin.begin();
187+
for (auto it = coins.begin(); it != coins.end(); ++it, ++input_it) {
188+
const Coin& coin = *it;
176189
assert(!coin.IsSpent());
177190

178191
// If prev is coinbase, check that it's matured
179192
if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
180193
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
181-
strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
194+
strprintf("tried to spend coinbase at depth %d", static_cast<int>(nSpendHeight - coin.nHeight)));
182195
}
183196

184197
// Check for negative or overflow input values
@@ -203,3 +216,9 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state,
203216
txfee = txfee_aux;
204217
return true;
205218
}
219+
220+
template bool Consensus::CheckTxInputs<const Coin>(
221+
const CTransaction& tx, TxValidationState& state, const std::span<const Coin> coins, int nSpendHeight, CAmount& txfee);
222+
223+
template bool Consensus::CheckTxInputs<std::reference_wrapper<const Coin>>(
224+
const CTransaction& tx, TxValidationState& state, const std::span<std::reference_wrapper<const Coin>> coins, int nSpendHeight, CAmount& txfee);

0 commit comments

Comments
 (0)