aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release-process.md11
-rw-r--r--src/bench/ccoins_caching.cpp2
-rw-r--r--src/policy/policy.cpp5
-rw-r--r--src/policy/policy.h5
-rw-r--r--src/rpc/blockchain.cpp4
-rw-r--r--src/test/fuzz/coins_view.cpp3
-rw-r--r--src/test/fuzz/transaction.cpp3
-rw-r--r--src/test/script_p2sh_tests.cpp6
-rw-r--r--src/test/transaction_tests.cpp2
-rw-r--r--src/validation.cpp4
-rw-r--r--src/wallet/wallet.cpp1
-rwxr-xr-xtest/functional/feature_taproot.py14
12 files changed, 36 insertions, 24 deletions
diff --git a/doc/release-process.md b/doc/release-process.md
index a61b67c35f..8191c3034d 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -27,11 +27,10 @@ Release Process
#### Before branch-off
* Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/bitcoin/bitcoin/pull/7415) for an example.
-* Update [`src/chainparams.cpp`](/src/chainparams.cpp) m_assumed_blockchain_size and m_assumed_chain_state_size with the current size plus some overhead (see [this](#how-to-calculate-m_assumed_blockchain_size-and-m_assumed_chain_state_size) for information on how to calculate them).
-* Update `src/chainparams.cpp` chainTxData with statistics about the transaction count and rate. Use the output of the RPC `getchaintxstats`, see
- [this pull request](https://github.com/bitcoin/bitcoin/pull/17002) for an example. Reviewers can verify the results by running `getchaintxstats <window_block_count> <window_last_block_hash>` with the `window_block_count` and `window_last_block_hash` from your output.
-* Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc.
-* Update `src/chainparams.cpp` defaultAssumeValid with information from the getblockhash rpc.
+* Update [`src/chainparams.cpp`](/src/chainparams.cpp) m_assumed_blockchain_size and m_assumed_chain_state_size with the current size plus some overhead (see [this](#how-to-calculate-assumed-blockchain-and-chain-state-size) for information on how to calculate them).
+* Update [`src/chainparams.cpp`](/src/chainparams.cpp) chainTxData with statistics about the transaction count and rate. Use the output of the `getchaintxstats` RPC, see
+ [this pull request](https://github.com/bitcoin/bitcoin/pull/20263) for an example. Reviewers can verify the results by running `getchaintxstats <window_block_count> <window_final_block_hash>` with the `window_block_count` and `window_final_block_hash` from your output.
+* Update `src/chainparams.cpp` nMinimumChainWork and defaultAssumeValid (and the block height comment) with information from the `getblockheader` (and `getblockhash`) RPCs.
- The selected value must not be orphaned so it may be useful to set the value two blocks back from the tip.
- Testnet should be set some tens of thousands back from the tip due to reorgs there.
- This update should be reviewed with a reindex-chainstate with assumevalid=0 to catch any defect
@@ -371,7 +370,7 @@ bitcoin.org (see below for bitcoin.org update instructions).
### Additional information
-#### How to calculate `m_assumed_blockchain_size` and `m_assumed_chain_state_size`
+#### <a name="how-to-calculate-assumed-blockchain-and-chain-state-size"></a>How to calculate `m_assumed_blockchain_size` and `m_assumed_chain_state_size`
Both variables are used as a guideline for how much space the user needs on their drive in total, not just strictly for the blockchain.
Note that all values should be taken from a **fully synced** node and have an overhead of 5-10% added on top of its base value.
diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp
index 116de98b14..d5275b0b76 100644
--- a/src/bench/ccoins_caching.cpp
+++ b/src/bench/ccoins_caching.cpp
@@ -45,7 +45,7 @@ static void CCoinsCaching(benchmark::Bench& bench)
// Benchmark.
const CTransaction tx_1(t1);
bench.run([&] {
- bool success = AreInputsStandard(tx_1, coins);
+ bool success = AreInputsStandard(tx_1, coins, false);
assert(success);
});
ECC_Stop();
diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp
index 69f2b456f1..91997aa883 100644
--- a/src/policy/policy.cpp
+++ b/src/policy/policy.cpp
@@ -155,7 +155,7 @@ bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeR
*
* Note that only the non-witness portion of the transaction is checked here.
*/
-bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, bool taproot_active)
{
if (tx.IsCoinBase())
return true; // Coinbases don't use vin normally
@@ -183,6 +183,9 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
return false;
}
+ } else if (whichType == TxoutType::WITNESS_V1_TAPROOT) {
+ // Don't allow Taproot spends unless Taproot is active.
+ if (!taproot_active) return false;
}
}
diff --git a/src/policy/policy.h b/src/policy/policy.h
index 51d67b9390..8090dff4c6 100644
--- a/src/policy/policy.h
+++ b/src/policy/policy.h
@@ -95,10 +95,11 @@ bool IsStandard(const CScript& scriptPubKey, TxoutType& whichType);
bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason);
/**
* Check for standard transaction types
- * @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ * @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ * @param[in] taproot_active Whether or taproot consensus rules are active (used to decide whether spends of them are permitted)
* @return True if all inputs (scriptSigs) use only standard transaction forms
*/
-bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, bool taproot_active);
/**
* Check if the transaction is over standard P2WSH resources limit:
* 3600bytes witnessScript size, 80bytes per witness stack element, 100 witness stack elements
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index a162c1ee70..392073d047 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1816,12 +1816,12 @@ static RPCHelpMan getblockstats()
{RPCResult::Type::NUM, "outs", "The number of outputs"},
{RPCResult::Type::NUM, "subsidy", "The block subsidy"},
{RPCResult::Type::NUM, "swtotal_size", "Total size of all segwit transactions"},
- {RPCResult::Type::NUM, "swtotal_weight", "Total weight of all segwit transactions divided by segwit scale factor (4)"},
+ {RPCResult::Type::NUM, "swtotal_weight", "Total weight of all segwit transactions"},
{RPCResult::Type::NUM, "swtxs", "The number of segwit transactions"},
{RPCResult::Type::NUM, "time", "The block time"},
{RPCResult::Type::NUM, "total_out", "Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])"},
{RPCResult::Type::NUM, "total_size", "Total size of all non-coinbase transactions"},
- {RPCResult::Type::NUM, "total_weight", "Total weight of all non-coinbase transactions divided by segwit scale factor (4)"},
+ {RPCResult::Type::NUM, "total_weight", "Total weight of all non-coinbase transactions"},
{RPCResult::Type::NUM, "totalfee", "The fee total"},
{RPCResult::Type::NUM, "txs", "The number of transactions (including coinbase)"},
{RPCResult::Type::NUM, "utxo_increase", "The increase/decrease in the number of unspent outputs"},
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index c186bef7ae..ac034809b0 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -229,7 +229,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
break;
}
case 1: {
- (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache);
+ (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, false);
+ (void)AreInputsStandard(CTransaction{random_mutable_transaction}, coins_view_cache, true);
break;
}
case 2: {
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index d6deb7fc3d..4f972dea1c 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -95,7 +95,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CCoinsView coins_view;
const CCoinsViewCache coins_view_cache(&coins_view);
- (void)AreInputsStandard(tx, coins_view_cache);
+ (void)AreInputsStandard(tx, coins_view_cache, false);
+ (void)AreInputsStandard(tx, coins_view_cache, true);
(void)IsWitnessStandard(tx, coins_view_cache);
UniValue u(UniValue::VOBJ);
diff --git a/src/test/script_p2sh_tests.cpp b/src/test/script_p2sh_tests.cpp
index f6824a4e5e..856ec6346d 100644
--- a/src/test/script_p2sh_tests.cpp
+++ b/src/test/script_p2sh_tests.cpp
@@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txTo.vin[3].scriptSig << OP_11 << OP_11 << std::vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
txTo.vin[4].scriptSig << std::vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
- BOOST_CHECK(::AreInputsStandard(CTransaction(txTo), coins));
+ BOOST_CHECK(::AreInputsStandard(CTransaction(txTo), coins, false));
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txTo), coins), 22U);
@@ -356,7 +356,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
txToNonStd1.vin[0].scriptSig << std::vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
- BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd1), coins));
+ BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd1), coins, false));
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd1), coins), 16U);
CMutableTransaction txToNonStd2;
@@ -368,7 +368,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
txToNonStd2.vin[0].scriptSig << std::vector<unsigned char>(twentySigops.begin(), twentySigops.end());
- BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd2), coins));
+ BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd2), coins, false));
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd2), coins), 20U);
}
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index b7ee280336..1f520074b1 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -305,7 +305,7 @@ BOOST_AUTO_TEST_CASE(test_Get)
t1.vout[0].nValue = 90*CENT;
t1.vout[0].scriptPubKey << OP_1;
- BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins));
+ BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins, false));
}
static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const CScript& outscript, CTransactionRef& output, CMutableTransaction& input, bool success = true)
diff --git a/src/validation.cpp b/src/validation.cpp
index 423b93479a..8241cb159f 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -690,7 +690,9 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
}
// Check for non-standard pay-to-script-hash in inputs
- if (fRequireStandard && !AreInputsStandard(tx, m_view)) {
+ const auto& params = args.m_chainparams.GetConsensus();
+ auto taproot_state = VersionBitsState(::ChainActive().Tip(), params, Consensus::DEPLOYMENT_TAPROOT, versionbitscache);
+ if (fRequireStandard && !AreInputsStandard(tx, m_view, taproot_state == ThresholdState::ACTIVE)) {
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 6b7d05fdf3..d1cde6aa89 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -100,6 +100,7 @@ bool AddWallet(const std::shared_ptr<CWallet>& wallet)
if (i != vpwallets.end()) return false;
vpwallets.push_back(wallet);
wallet->ConnectScriptPubKeyManNotifiers();
+ wallet->NotifyCanGetAddressesChanged();
return true;
}
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 7b534c1c2f..3e47e24a3b 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -1129,13 +1129,13 @@ def spenders_taproot_inactive():
]
tap = taproot_construct(pub, scripts)
- # Test that keypath spending is valid & standard if compliant, but valid and nonstandard otherwise.
- add_spender(spenders, "inactive/keypath_valid", key=sec, tap=tap)
+ # Test that keypath spending is valid & non-standard, regardless of validity.
+ add_spender(spenders, "inactive/keypath_valid", key=sec, tap=tap, standard=False)
add_spender(spenders, "inactive/keypath_invalidsig", key=sec, tap=tap, standard=False, sighash=bitflipper(default_sighash))
add_spender(spenders, "inactive/keypath_empty", key=sec, tap=tap, standard=False, witness=[])
- # Same for scriptpath spending (but using future features like annex, leaf versions, or OP_SUCCESS is nonstandard).
- add_spender(spenders, "inactive/scriptpath_valid", key=sec, tap=tap, leaf="pk", inputs=[getter("sign")])
+ # Same for scriptpath spending (and features like annex, leaf versions, or OP_SUCCESS don't change this)
+ add_spender(spenders, "inactive/scriptpath_valid", key=sec, tap=tap, leaf="pk", standard=False, inputs=[getter("sign")])
add_spender(spenders, "inactive/scriptpath_invalidsig", key=sec, tap=tap, leaf="pk", standard=False, inputs=[getter("sign")], sighash=bitflipper(default_sighash))
add_spender(spenders, "inactive/scriptpath_invalidcb", key=sec, tap=tap, leaf="pk", standard=False, inputs=[getter("sign")], controlblock=bitflipper(default_controlblock))
add_spender(spenders, "inactive/scriptpath_valid_unkleaf", key=sec, tap=tap, leaf="future_leaf", standard=False, inputs=[getter("sign")])
@@ -1451,7 +1451,11 @@ class TaprootTest(BitcoinTestFramework):
# Pre-taproot activation tests.
self.log.info("Pre-activation tests...")
- self.test_spenders(self.nodes[0], spenders_taproot_inactive(), input_counts=[1, 2, 2, 2, 2, 3])
+ # Run each test twice; once in isolation, and once combined with others. Testing in isolation
+ # means that the standardness is verified in every test (as combined transactions are only standard
+ # when all their inputs are standard).
+ self.test_spenders(self.nodes[0], spenders_taproot_inactive(), input_counts=[1])
+ self.test_spenders(self.nodes[0], spenders_taproot_inactive(), input_counts=[2, 3])
if __name__ == '__main__':