aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bench/rpc_mempool.cpp2
-rw-r--r--src/net.cpp2
-rw-r--r--src/net_processing.cpp2
-rw-r--r--src/netaddress.h6
-rw-r--r--src/qt/test/test_main.cpp2
-rw-r--r--src/rpc/mining.cpp2
-rw-r--r--src/rpc/rawtransaction.cpp4
-rw-r--r--src/span.h8
-rw-r--r--src/test/denialofservice_tests.cpp24
-rw-r--r--src/test/fuzz/tx_pool.cpp2
-rw-r--r--src/test/txpackage_tests.cpp16
-rw-r--r--src/test/validation_block_tests.cpp2
-rw-r--r--src/util/syscall_sandbox.cpp3
-rwxr-xr-xtest/functional/feature_nulldummy.py30
-rwxr-xr-xtest/functional/rpc_decodescript.py65
-rwxr-xr-xtest/functional/rpc_generateblock.py34
-rw-r--r--test/sanitizer_suppressions/ubsan1
17 files changed, 115 insertions, 90 deletions
diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp
index f1eeef8885..67c827d0d3 100644
--- a/src/bench/rpc_mempool.cpp
+++ b/src/bench/rpc_mempool.cpp
@@ -12,7 +12,7 @@
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
LockPoints lp;
- pool.addUnchecked(CTxMemPoolEntry(tx, fee, /* time */ 0, /* height */ 1, /* spendsCoinbase */ false, /* sigOpCost */ 4, lp));
+ pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/1, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
}
static void RpcMempool(benchmark::Bench& bench)
diff --git a/src/net.cpp b/src/net.cpp
index 82e55d4189..d1f1b54007 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -3024,7 +3024,7 @@ void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
size_t nMessageSize = msg.data.size();
LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", msg.m_type, nMessageSize, pnode->GetId());
if (gArgs.GetBoolArg("-capturemessages", false)) {
- CaptureMessage(pnode->addr, msg.m_type, msg.data, /* incoming */ false);
+ CaptureMessage(pnode->addr, msg.m_type, msg.data, /*is_incoming=*/false);
}
TRACE6(net, outbound_message,
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 2185ccc700..a896bb76ae 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -4105,7 +4105,7 @@ bool PeerManagerImpl::ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt
);
if (gArgs.GetBoolArg("-capturemessages", false)) {
- CaptureMessage(pfrom->addr, msg.m_command, MakeUCharSpan(msg.m_recv), /* incoming */ true);
+ CaptureMessage(pfrom->addr, msg.m_command, MakeUCharSpan(msg.m_recv), /*is_incoming=*/true);
}
msg.SetVersion(pfrom->GetCommonVersion());
diff --git a/src/netaddress.h b/src/netaddress.h
index b0b1c5ca9e..a5b74eb35b 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -385,6 +385,12 @@ private:
/**
* Unserialize from a pre-ADDRv2/BIP155 format from an array.
+ *
+ * This function is only called from UnserializeV1Stream() and is a wrapper
+ * for SetLegacyIPv6(); however, we keep it for symmetry with
+ * SerializeV1Array() to have pairs of ser/unser functions and to make clear
+ * that if one is altered, a corresponding reverse modification should be
+ * applied to the other.
*/
void UnserializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE])
{
diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp
index b26cddf4ae..e7a3d724bb 100644
--- a/src/qt/test/test_main.cpp
+++ b/src/qt/test/test_main.cpp
@@ -69,7 +69,7 @@ int main(int argc, char* argv[])
#if defined(WIN32)
if (getenv("QT_QPA_PLATFORM") == nullptr) _putenv_s("QT_QPA_PLATFORM", "minimal");
#else
- setenv("QT_QPA_PLATFORM", "minimal", /* overwrite */ 0);
+ setenv("QT_QPA_PLATFORM", "minimal", 0 /* overwrite */);
#endif
// Don't remove this, it's needed to access
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 518c41d12a..9e2b1ab07e 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -1010,7 +1010,7 @@ static RPCHelpMan submitblock()
bool new_block;
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
RegisterSharedValidationInterface(sc);
- bool accepted = chainman.ProcessNewBlock(Params(), blockptr, /* fForceProcessing */ true, /* fNewBlock */ &new_block);
+ bool accepted = chainman.ProcessNewBlock(Params(), blockptr, /*force_processing=*/true, /*new_block=*/&new_block);
UnregisterSharedValidationInterface(sc);
if (!new_block && accepted) {
return "duplicate";
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 89f2309cb7..2dd121c6f6 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1619,7 +1619,7 @@ static RPCHelpMan utxoupdatepsbt()
}
}
// We don't actually need private keys further on; hide them as a precaution.
- HidingSigningProvider public_provider(&provider, /* nosign */ true, /* nobip32derivs */ false);
+ HidingSigningProvider public_provider(&provider, /*hide_secret=*/true, /*hide_origin=*/false);
// Fetch previous transactions (inputs):
CCoinsView viewDummy;
@@ -1658,7 +1658,7 @@ static RPCHelpMan utxoupdatepsbt()
// Update script/keypath information using descriptor data.
// Note that SignPSBTInput does a lot more than just constructing ECDSA signatures
// we don't actually care about those here, in fact.
- SignPSBTInput(public_provider, psbtx, i, &txdata, /* sighash_type */ 1);
+ SignPSBTInput(public_provider, psbtx, i, &txdata, /*sighash=*/1);
}
// Update script/keypath information using descriptor data.
diff --git a/src/span.h b/src/span.h
index 168162e309..1e347846d8 100644
--- a/src/span.h
+++ b/src/span.h
@@ -30,7 +30,11 @@
/** A Span is an object that can refer to a contiguous sequence of objects.
*
- * It implements a subset of C++20's std::span.
+ * This file implements a subset of C++20's std::span. It can be considered
+ * temporary compatibility code until C++20 and is designed to be a
+ * self-contained abstraction without depending on other project files. For this
+ * reason, Clang lifetimebound is defined here instead of including
+ * <attributes.h>, which also defines it.
*
* Things to be aware of when writing code that deals with Spans:
*
@@ -60,7 +64,7 @@
* types that expose a data() and size() member function), functions that
* accept a Span as input parameter can be called with any compatible
* range-like object. For example, this works:
-*
+ *
* void Foo(Span<const int> arg);
*
* Foo(std::vector<int>{1, 2, 3}); // Works
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index 668ff150ee..765663e0ef 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
// Mock an outbound peer
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr1, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "", ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false);
+ CNode dummyNode1(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr1, /*nKeyedNetGroupIn=*/0, /*nLocalHostNonceIn=*/0, CAddress(), /*addrNameIn=*/"", ConnectionType::OUTBOUND_FULL_RELAY, /*inbound_onion=*/false);
dummyNode1.SetCommonVersion(PROTOCOL_VERSION);
peerLogic->InitializeNode(&dummyNode1);
@@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
static void AddRandomOutboundPeer(std::vector<CNode*>& vNodes, PeerManager& peerLogic, ConnmanTestMsg& connman)
{
CAddress addr(ip(g_insecure_rand_ctx.randbits(32)), NODE_NONE);
- vNodes.emplace_back(new CNode(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "", ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false));
+ vNodes.emplace_back(new CNode(id++, ServiceFlags(NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr, /*nKeyedNetGroupIn=*/0, /*nLocalHostNonceIn=*/0, CAddress(), /*addrNameIn=*/"", ConnectionType::OUTBOUND_FULL_RELAY, /*inbound_onion=*/false));
CNode &node = *vNodes.back();
node.SetCommonVersion(PROTOCOL_VERSION);
@@ -212,9 +212,9 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
std::array<CNode*, 3> nodes;
banman->ClearBanned();
- nodes[0] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[0], /* nKeyedNetGroupIn */ 0,
- /* nLocalHostNonceIn */ 0, CAddress(), /* pszDest */ "",
- ConnectionType::INBOUND, /* inbound_onion */ false};
+ nodes[0] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[0], /*nKeyedNetGroupIn=*/0,
+ /*nLocalHostNonceIn */ 0, CAddress(), /*addrNameIn=*/"",
+ ConnectionType::INBOUND, /*inbound_onion=*/false};
nodes[0]->SetCommonVersion(PROTOCOL_VERSION);
peerLogic->InitializeNode(nodes[0]);
nodes[0]->fSuccessfullyConnected = true;
@@ -228,9 +228,9 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
BOOST_CHECK(nodes[0]->fDisconnect);
BOOST_CHECK(!banman->IsDiscouraged(other_addr)); // Different address, not discouraged
- nodes[1] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[1], /* nKeyedNetGroupIn */ 1,
- /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "",
- ConnectionType::INBOUND, /* inbound_onion */ false};
+ nodes[1] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[1], /*nKeyedNetGroupIn=*/1,
+ /*nLocalHostNonceIn */ 1, CAddress(), /*addrNameIn=*/"",
+ ConnectionType::INBOUND, /*inbound_onion=*/false};
nodes[1]->SetCommonVersion(PROTOCOL_VERSION);
peerLogic->InitializeNode(nodes[1]);
nodes[1]->fSuccessfullyConnected = true;
@@ -259,9 +259,9 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
// Make sure non-IP peers are discouraged and disconnected properly.
- nodes[2] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[2], /* nKeyedNetGroupIn */ 1,
- /* nLocalHostNonceIn */ 1, CAddress(), /* pszDest */ "",
- ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false};
+ nodes[2] = new CNode{id++, NODE_NETWORK, INVALID_SOCKET, addr[2], /*nKeyedNetGroupIn=*/1,
+ /*nLocalHostNonceIn */ 1, CAddress(), /*addrNameIn=*/"",
+ ConnectionType::OUTBOUND_FULL_RELAY, /*inbound_onion=*/false};
nodes[2]->SetCommonVersion(PROTOCOL_VERSION);
peerLogic->InitializeNode(nodes[2]);
nodes[2]->fSuccessfullyConnected = true;
@@ -297,7 +297,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode(id++, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 4, /* nLocalHostNonceIn */ 4, CAddress(), /* pszDest */ "", ConnectionType::INBOUND, /* inbound_onion */ false);
+ CNode dummyNode(id++, NODE_NETWORK, INVALID_SOCKET, addr, /*nKeyedNetGroupIn=*/4, /*nLocalHostNonceIn=*/4, CAddress(), /*addrNameIn=*/"", ConnectionType::INBOUND, /*inbound_onion=*/false);
dummyNode.SetCommonVersion(PROTOCOL_VERSION);
peerLogic->InitializeNode(&dummyNode);
dummyNode.fSuccessfullyConnected = true;
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index 17b5ef88b9..752e882608 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -93,7 +93,7 @@ void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, CCh
const auto info_all = tx_pool.infoAll();
if (!info_all.empty()) {
const auto& tx_to_remove = *PickValue(fuzzed_data_provider, info_all).tx;
- WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, /* dummy */ MemPoolRemovalReason::BLOCK));
+ WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, MemPoolRemovalReason::BLOCK /* dummy */));
std::vector<uint256> all_txids;
tx_pool.queryHashes(all_txids);
assert(all_txids.size() < info_all.size());
diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp
index 537a6ccea1..8d92bee221 100644
--- a/src/test/txpackage_tests.cpp
+++ b/src/test/txpackage_tests.cpp
@@ -73,19 +73,19 @@ BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100Setup)
CKey parent_key;
parent_key.MakeNewKey(true);
CScript parent_locking_script = GetScriptForDestination(PKHash(parent_key.GetPubKey()));
- auto mtx_parent = CreateValidMempoolTransaction(/* input_transaction */ m_coinbase_txns[0], /* vout */ 0,
- /* input_height */ 0, /* input_signing_key */ coinbaseKey,
- /* output_destination */ parent_locking_script,
- /* output_amount */ CAmount(49 * COIN), /* submit */ false);
+ auto mtx_parent = CreateValidMempoolTransaction(/*input_transaction=*/ m_coinbase_txns[0], /*input_vout=*/0,
+ /*input_height=*/ 0, /*input_signing_key=*/coinbaseKey,
+ /*output_destination=*/ parent_locking_script,
+ /*output_amount=*/ CAmount(49 * COIN), /*submit=*/false);
CTransactionRef tx_parent = MakeTransactionRef(mtx_parent);
CKey child_key;
child_key.MakeNewKey(true);
CScript child_locking_script = GetScriptForDestination(PKHash(child_key.GetPubKey()));
- auto mtx_child = CreateValidMempoolTransaction(/* input_transaction */ tx_parent, /* vout */ 0,
- /* input_height */ 101, /* input_signing_key */ parent_key,
- /* output_destination */ child_locking_script,
- /* output_amount */ CAmount(48 * COIN), /* submit */ false);
+ auto mtx_child = CreateValidMempoolTransaction(/*input_transaction=*/ tx_parent, /*input_vout=*/0,
+ /*input_height=*/ 101, /*input_signing_key=*/parent_key,
+ /*output_destination */ child_locking_script,
+ /*output_amount=*/ CAmount(48 * COIN), /*submit=*/false);
CTransactionRef tx_child = MakeTransactionRef(mtx_child);
const auto result_parent_child = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {tx_parent, tx_child}, /* test_accept */ true);
BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(),
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index 8a48d539f8..54873ce6fa 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{
bool ignored;
auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
- return Assert(m_node.chainman)->ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored);
+ return Assert(m_node.chainman)->ProcessNewBlock(Params(), block, /*force_processing=*/true, /*new_block=*/&ignored);
};
// Process all mined blocks
diff --git a/src/util/syscall_sandbox.cpp b/src/util/syscall_sandbox.cpp
index bc69df44f4..6e1cc9b457 100644
--- a/src/util/syscall_sandbox.cpp
+++ b/src/util/syscall_sandbox.cpp
@@ -581,7 +581,7 @@ public:
allowed_syscalls.insert(__NR_fdatasync); // synchronize a file's in-core state with storage device
allowed_syscalls.insert(__NR_flock); // apply or remove an advisory lock on an open file
allowed_syscalls.insert(__NR_fstat); // get file status
- allowed_syscalls.insert(__NR_newfstatat); // get file status
+ allowed_syscalls.insert(__NR_fstatfs); // get file system status
allowed_syscalls.insert(__NR_fsync); // synchronize a file's in-core state with storage device
allowed_syscalls.insert(__NR_ftruncate); // truncate a file to a specified length
allowed_syscalls.insert(__NR_getcwd); // get current working directory
@@ -589,6 +589,7 @@ public:
allowed_syscalls.insert(__NR_getdents64); // get directory entries
allowed_syscalls.insert(__NR_lstat); // get file status
allowed_syscalls.insert(__NR_mkdir); // create a directory
+ allowed_syscalls.insert(__NR_newfstatat); // get file status
allowed_syscalls.insert(__NR_open); // open and possibly create a file
allowed_syscalls.insert(__NR_openat); // open and possibly create a file
allowed_syscalls.insert(__NR_readlink); // read value of a symbolic link
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index 4d59d5a07d..7a84098a83 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -22,7 +22,10 @@ from test_framework.blocktools import (
create_transaction,
)
from test_framework.messages import CTransaction
-from test_framework.script import CScript
+from test_framework.script import (
+ OP_0,
+ OP_TRUE,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
@@ -32,16 +35,11 @@ from test_framework.util import (
NULLDUMMY_ERROR = "non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
-def trueDummy(tx):
- scriptSig = CScript(tx.vin[0].scriptSig)
- newscript = []
- for i in scriptSig:
- if len(newscript) == 0:
- assert len(i) == 0
- newscript.append(b'\x51')
- else:
- newscript.append(i)
- tx.vin[0].scriptSig = CScript(newscript)
+def invalidate_nulldummy_tx(tx):
+ """Transform a NULLDUMMY compliant tx (i.e. scriptSig starts with OP_0)
+ to be non-NULLDUMMY compliant by replacing the dummy with OP_TRUE"""
+ assert_equal(tx.vin[0].scriptSig[0], OP_0)
+ tx.vin[0].scriptSig = bytes([OP_TRUE]) + tx.vin[0].scriptSig[1:]
tx.rehash()
@@ -94,7 +92,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
self.log.info("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation")
test2tx = create_transaction(self.nodes[0], txid2, self.ms_address, amount=47)
- trueDummy(test2tx)
+ invalidate_nulldummy_tx(test2tx)
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize_with_witness().hex(), 0)
self.log.info(f"Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [{COINBASE_MATURITY + 4}]")
@@ -103,7 +101,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
test4tx = create_transaction(self.nodes[0], test2tx.hash, self.address, amount=46)
test6txs = [CTransaction(test4tx)]
- trueDummy(test4tx)
+ invalidate_nulldummy_tx(test4tx)
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize_with_witness().hex(), 0)
self.block_submit(self.nodes[0], [test4tx], accept=False)
@@ -123,11 +121,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
tmpl = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)
assert_equal(tmpl['previousblockhash'], self.lastblockhash)
assert_equal(tmpl['height'], self.lastblockheight + 1)
- block = create_block(tmpl=tmpl, ntime=self.lastblocktime + 1)
- for tx in txs:
- tx.rehash()
- block.vtx.append(tx)
- block.hashMerkleRoot = block.calc_merkle_root()
+ block = create_block(tmpl=tmpl, ntime=self.lastblocktime + 1, txlist=txs)
if with_witness:
add_witness_commitment(block)
block.solve()
diff --git a/test/functional/rpc_decodescript.py b/test/functional/rpc_decodescript.py
index 58432c3dae..8c0f48129a 100755
--- a/test/functional/rpc_decodescript.py
+++ b/test/functional/rpc_decodescript.py
@@ -27,29 +27,29 @@ class DecodeScriptTest(BitcoinTestFramework):
# below are test cases for all of the standard transaction types
- # 1) P2PK scriptSig
+ self.log.info("- P2PK")
# the scriptSig of a public key scriptPubKey simply pushes a signature onto the stack
rpc_result = self.nodes[0].decodescript(push_signature)
assert_equal(signature, rpc_result['asm'])
- # 2) P2PKH scriptSig
+ self.log.info("- P2PKH")
rpc_result = self.nodes[0].decodescript(push_signature + push_public_key)
assert_equal(signature + ' ' + public_key, rpc_result['asm'])
- # 3) multisig scriptSig
+ self.log.info("- multisig")
# this also tests the leading portion of a P2SH multisig scriptSig
# OP_0 <A sig> <B sig>
rpc_result = self.nodes[0].decodescript('00' + push_signature + push_signature)
assert_equal('0 ' + signature + ' ' + signature, rpc_result['asm'])
- # 4) P2SH scriptSig
+ self.log.info("- P2SH")
# an empty P2SH redeemScript is valid and makes for a very simple test case.
# thus, such a spending scriptSig would just need to pass the outer redeemScript
# hash test and leave true on the top of the stack.
rpc_result = self.nodes[0].decodescript('5100')
assert_equal('1 0', rpc_result['asm'])
- # 5) null data scriptSig - no such thing because null data scripts can not be spent.
+ # null data scriptSig - no such thing because null data scripts can not be spent.
# thus, no test case for that standard transaction type is here.
def decodescript_script_pub_key(self):
@@ -63,50 +63,58 @@ class DecodeScriptTest(BitcoinTestFramework):
# below are test cases for all of the standard transaction types
- # 1) P2PK scriptPubKey
+ self.log.info("- P2PK")
# <pubkey> OP_CHECKSIG
rpc_result = self.nodes[0].decodescript(push_public_key + 'ac')
assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm'])
+ assert_equal('pubkey', rpc_result['type'])
# P2PK is translated to P2WPKH
assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
- # 2) P2PKH scriptPubKey
+ self.log.info("- P2PKH")
# OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac')
+ assert_equal('pubkeyhash', rpc_result['type'])
assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm'])
# P2PKH is translated to P2WPKH
+ assert_equal('witness_v0_keyhash', rpc_result['segwit']['type'])
assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
- # 3) multisig scriptPubKey
+ self.log.info("- multisig")
# <m> <A pubkey> <B pubkey> <C pubkey> <n> OP_CHECKMULTISIG
# just imagine that the pub keys used below are different.
# for our purposes here it does not matter that they are the same even though it is unrealistic.
multisig_script = '52' + push_public_key + push_public_key + push_public_key + '53ae'
rpc_result = self.nodes[0].decodescript(multisig_script)
+ assert_equal('multisig', rpc_result['type'])
assert_equal('2 ' + public_key + ' ' + public_key + ' ' + public_key + ' 3 OP_CHECKMULTISIG', rpc_result['asm'])
# multisig in P2WSH
multisig_script_hash = sha256(bytes.fromhex(multisig_script)).hex()
+ assert_equal('witness_v0_scripthash', rpc_result['segwit']['type'])
assert_equal('0 ' + multisig_script_hash, rpc_result['segwit']['asm'])
- # 4) P2SH scriptPubKey
+ self.log.info ("- P2SH")
# OP_HASH160 <Hash160(redeemScript)> OP_EQUAL.
# push_public_key_hash here should actually be the hash of a redeem script.
# but this works the same for purposes of this test.
rpc_result = self.nodes[0].decodescript('a9' + push_public_key_hash + '87')
+ assert_equal('scripthash', rpc_result['type'])
assert_equal('OP_HASH160 ' + public_key_hash + ' OP_EQUAL', rpc_result['asm'])
# P2SH does not work in segwit secripts. decodescript should not return a result for it.
assert 'segwit' not in rpc_result
- # 5) null data scriptPubKey
+ self.log.info("- null data")
# use a signature look-alike here to make sure that we do not decode random data as a signature.
# this matters if/when signature sighash decoding comes along.
# would want to make sure that no such decoding takes place in this case.
signature_imposter = '48304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001'
# OP_RETURN <data>
rpc_result = self.nodes[0].decodescript('6a' + signature_imposter)
+ assert_equal('nulldata', rpc_result['type'])
assert_equal('OP_RETURN ' + signature_imposter[2:], rpc_result['asm'])
- # 6) a CLTV redeem script. redeem scripts are in-effect scriptPubKey scripts, so adding a test here.
+ self.log.info("- CLTV redeem script")
+ # redeem scripts are in-effect scriptPubKey scripts, so adding a test here.
# OP_NOP2 is also known as OP_CHECKLOCKTIMEVERIFY.
# just imagine that the pub keys used below are different.
# for our purposes here it does not matter that they are the same even though it is unrealistic.
@@ -121,55 +129,69 @@ class DecodeScriptTest(BitcoinTestFramework):
# lock until block 500,000
cltv_script = '63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac'
rpc_result = self.nodes[0].decodescript(cltv_script)
+ assert_equal('nonstandard', rpc_result['type'])
assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
# CLTV script in P2WSH
cltv_script_hash = sha256(bytes.fromhex(cltv_script)).hex()
assert_equal('0 ' + cltv_script_hash, rpc_result['segwit']['asm'])
- # 7) P2PK scriptPubKey
+ self.log.info("- P2PK with uncompressed pubkey")
# <pubkey> OP_CHECKSIG
rpc_result = self.nodes[0].decodescript(push_uncompressed_public_key + 'ac')
+ assert_equal('pubkey', rpc_result['type'])
assert_equal(uncompressed_public_key + ' OP_CHECKSIG', rpc_result['asm'])
# uncompressed pubkeys are invalid for checksigs in segwit scripts.
# decodescript should not return a P2WPKH equivalent.
assert 'segwit' not in rpc_result
- # 8) multisig scriptPubKey with an uncompressed pubkey
+ self.log.info("- multisig with uncompressed pubkey")
# <m> <A pubkey> <B pubkey> <n> OP_CHECKMULTISIG
# just imagine that the pub keys used below are different.
# the purpose of this test is to check that a segwit script is not returned for bare multisig scripts
# with an uncompressed pubkey in them.
rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_uncompressed_public_key +'52ae')
+ assert_equal('multisig', rpc_result['type'])
assert_equal('2 ' + public_key + ' ' + uncompressed_public_key + ' 2 OP_CHECKMULTISIG', rpc_result['asm'])
# uncompressed pubkeys are invalid for checksigs in segwit scripts.
# decodescript should not return a P2WPKH equivalent.
assert 'segwit' not in rpc_result
- # 9) P2WPKH scriptpubkey
+ self.log.info("- P2WPKH")
# 0 <PubKeyHash>
rpc_result = self.nodes[0].decodescript('00' + push_public_key_hash)
+ assert_equal('witness_v0_keyhash', rpc_result['type'])
assert_equal('0 ' + public_key_hash, rpc_result['asm'])
# segwit scripts do not work nested into each other.
# a nested segwit script should not be returned in the results.
assert 'segwit' not in rpc_result
- # 10) P2WSH scriptpubkey
+ self.log.info("- P2WSH")
# 0 <ScriptHash>
# even though this hash is of a P2PK script which is better used as bare P2WPKH, it should not matter
# for the purpose of this test.
rpc_result = self.nodes[0].decodescript('0020' + p2wsh_p2pk_script_hash)
+ assert_equal('witness_v0_scripthash', rpc_result['type'])
assert_equal('0 ' + p2wsh_p2pk_script_hash, rpc_result['asm'])
# segwit scripts do not work nested into each other.
# a nested segwit script should not be returned in the results.
assert 'segwit' not in rpc_result
+ self.log.info("- P2TR")
+ # 1 <x-only pubkey>
+ xonly_public_key = '01'*32 # first ever P2TR output on mainnet
+ rpc_result = self.nodes[0].decodescript('5120' + xonly_public_key)
+ assert_equal('witness_v1_taproot', rpc_result['type'])
+ assert_equal('1 ' + xonly_public_key, rpc_result['asm'])
+ assert 'segwit' not in rpc_result
+
def decoderawtransaction_asm_sighashtype(self):
"""Test decoding scripts via RPC command "decoderawtransaction".
This test is in with the "decodescript" tests because they are testing the same "asm" script decodes.
"""
- # this test case uses a random plain vanilla mainnet transaction with a single P2PKH input and output
+ self.log.info("- various mainnet txs")
+ # this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs.
tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000'
rpc_result = self.nodes[0].decoderawtransaction(tx)
assert_equal('304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536', rpc_result['vin'][0]['scriptSig']['asm'])
@@ -185,11 +207,13 @@ class DecodeScriptTest(BitcoinTestFramework):
assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
txSave = tx_from_hex(tx)
+ self.log.info("- tx not passing DER signature checks")
# make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type
tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
rpc_result = self.nodes[0].decoderawtransaction(tx)
assert_equal('OP_RETURN 300602010002010001', rpc_result['vout'][0]['scriptPubKey']['asm'])
+ self.log.info("- tx passing DER signature checks")
# verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks
tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000'
rpc_result = self.nodes[0].decoderawtransaction(tx)
@@ -207,7 +231,7 @@ class DecodeScriptTest(BitcoinTestFramework):
push_signature_2 = '48' + signature_2
signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'
- # 1) P2PK scriptSig
+ self.log.info("- P2PK scriptSig")
txSave.vin[0].scriptSig = bytes.fromhex(push_signature)
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
@@ -217,20 +241,23 @@ class DecodeScriptTest(BitcoinTestFramework):
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
- # 2) multisig scriptSig
+ self.log.info("- multisig scriptSig")
txSave.vin[0].scriptSig = bytes.fromhex('00' + push_signature + push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
- # 3) test a scriptSig that contains more than push operations.
+ self.log.info("- scriptSig that contains more than push operations")
# in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
txSave.vin[0].scriptSig = bytes.fromhex('6a143011020701010101010101020601010101010101')
rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
def run_test(self):
+ self.log.info("Test decoding of standard input scripts [scriptSig]")
self.decodescript_script_sig()
+ self.log.info("Test decoding of standard output scripts [scriptPubKey]")
self.decodescript_script_pub_key()
+ self.log.info("Test 'asm' script decoding of transactions")
self.decoderawtransaction_asm_sighashtype()
if __name__ == '__main__':
diff --git a/test/functional/rpc_generateblock.py b/test/functional/rpc_generateblock.py
index 4dc5c63ff3..7aede0e947 100755
--- a/test/functional/rpc_generateblock.py
+++ b/test/functional/rpc_generateblock.py
@@ -6,6 +6,7 @@
'''
from test_framework.test_framework import BitcoinTestFramework
+from test_framework.wallet import MiniWallet
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
@@ -16,14 +17,13 @@ class GenerateBlockTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
- def skip_test_if_missing_module(self):
- self.skip_if_no_wallet()
-
def run_test(self):
node = self.nodes[0]
+ miniwallet = MiniWallet(node)
+ miniwallet.rescan_utxos()
self.log.info('Generate an empty block to address')
- address = node.getnewaddress()
+ address = miniwallet.get_address()
hash = self.generateblock(node, output=address, transactions=[])['hash']
block = node.getblock(blockhash=hash, verbose=2)
assert_equal(len(block['tx']), 1)
@@ -51,37 +51,31 @@ class GenerateBlockTest(BitcoinTestFramework):
assert_equal(len(block['tx']), 1)
assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address)
- # Generate 110 blocks to spend
- self.generatetoaddress(node, 110, address)
-
# Generate some extra mempool transactions to verify they don't get mined
for _ in range(10):
- node.sendtoaddress(address, 0.001)
+ miniwallet.send_self_transfer(from_node=node)
self.log.info('Generate block with txid')
- txid = node.sendtoaddress(address, 1)
+ txid = miniwallet.send_self_transfer(from_node=node)['txid']
hash = self.generateblock(node, address, [txid])['hash']
block = node.getblock(hash, 1)
assert_equal(len(block['tx']), 2)
assert_equal(block['tx'][1], txid)
self.log.info('Generate block with raw tx')
- utxos = node.listunspent(addresses=[address])
- raw = node.createrawtransaction([{'txid':utxos[0]['txid'], 'vout':utxos[0]['vout']}],[{address:1}])
- signed_raw = node.signrawtransactionwithwallet(raw)['hex']
- hash = self.generateblock(node, address, [signed_raw])['hash']
+ rawtx = miniwallet.create_self_transfer(from_node=node)['hex']
+ hash = self.generateblock(node, address, [rawtx])['hash']
+
block = node.getblock(hash, 1)
assert_equal(len(block['tx']), 2)
txid = block['tx'][1]
- assert_equal(node.gettransaction(txid)['hex'], signed_raw)
+ assert_equal(node.getrawtransaction(txid=txid, verbose=False, blockhash=hash), rawtx)
self.log.info('Fail to generate block with out of order txs')
- raw1 = node.createrawtransaction([{'txid':txid, 'vout':0}],[{address:0.9999}])
- signed_raw1 = node.signrawtransactionwithwallet(raw1)['hex']
- txid1 = node.sendrawtransaction(signed_raw1)
- raw2 = node.createrawtransaction([{'txid':txid1, 'vout':0}],[{address:0.999}])
- signed_raw2 = node.signrawtransactionwithwallet(raw2)['hex']
- assert_raises_rpc_error(-25, 'TestBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [signed_raw2, txid1])
+ txid1 = miniwallet.send_self_transfer(from_node=node)['txid']
+ utxo1 = miniwallet.get_utxo(txid=txid1)
+ rawtx2 = miniwallet.create_self_transfer(from_node=node, utxo_to_spend=utxo1)['hex']
+ assert_raises_rpc_error(-25, 'TestBlockValidity failed: bad-txns-inputs-missingorspent', self.generateblock, node, address, [rawtx2, txid1])
self.log.info('Fail to generate block with txid not in mempool')
missing_txid = '0000000000000000000000000000000000000000000000000000000000000000'
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 2a729c66d9..79a4eba1fc 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -91,7 +91,6 @@ implicit-signed-integer-truncation:leveldb/
implicit-signed-integer-truncation:miner.cpp
implicit-signed-integer-truncation:net.cpp
implicit-signed-integer-truncation:net_processing.cpp
-implicit-signed-integer-truncation:netaddress.cpp
implicit-signed-integer-truncation:streams.h
implicit-signed-integer-truncation:test/arith_uint256_tests.cpp
implicit-signed-integer-truncation:test/skiplist_tests.cpp