aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAva Chow <github@achow101.com>2024-01-25 16:27:08 -0500
committerAva Chow <github@achow101.com>2024-06-07 12:40:21 -0400
commit27e70f1f5be1f536f2314cd2ea42b4f80d927fbd (patch)
tree0cdfa2c9d06bf39b9839de304975aba80caf3c28 /src
parent6e4d18f37f42894fe9a0d7948c1da3f061fc6b60 (diff)
downloadbitcoin-27e70f1f5be1f536f2314cd2ea42b4f80d927fbd.tar.xz
consensus: Store transaction nVersion as uint32_t
Given that the use of a transaction's nVersion is always as an unsigned int, it doesn't make sense to store it as signed and then cast it to unsigned.
Diffstat (limited to 'src')
-rw-r--r--src/bitcoin-tx.cpp6
-rw-r--r--src/consensus/tx_verify.cpp6
-rw-r--r--src/core_write.cpp4
-rw-r--r--src/primitives/transaction.cpp10
-rw-r--r--src/primitives/transaction.h10
-rw-r--r--src/rpc/rawtransaction.cpp6
-rw-r--r--src/script/interpreter.cpp2
-rw-r--r--src/test/fuzz/util.cpp2
-rw-r--r--src/test/sighash_tests.cpp2
-rw-r--r--src/test/transaction_tests.cpp2
10 files changed, 22 insertions, 28 deletions
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index cfac50e090..c16428a0f4 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -203,12 +203,12 @@ static CAmount ExtractAndValidateValue(const std::string& strValue)
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
{
- int64_t newVersion;
- if (!ParseInt64(cmdVal, &newVersion) || newVersion < 1 || newVersion > TX_MAX_STANDARD_VERSION) {
+ uint32_t newVersion;
+ if (!ParseUInt32(cmdVal, &newVersion) || newVersion < 1 || newVersion > TX_MAX_STANDARD_VERSION) {
throw std::runtime_error("Invalid TX version requested: '" + cmdVal + "'");
}
- tx.nVersion = (int) newVersion;
+ tx.nVersion = newVersion;
}
static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
index 154146f08d..1181cce680 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -48,11 +48,7 @@ std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags
int nMinHeight = -1;
int64_t nMinTime = -1;
- // tx.nVersion is signed integer so requires cast to unsigned otherwise
- // we would be doing a signed comparison and half the range of nVersion
- // wouldn't support BIP 68.
- bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
- && flags & LOCKTIME_VERIFY_SEQUENCE;
+ bool fEnforceBIP68 = tx.nVersion >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE;
// Do not enforce sequence numbers as a relative lock time
// unless we have been instructed to
diff --git a/src/core_write.cpp b/src/core_write.cpp
index 3a2bf865fc..c7dc3a955c 100644
--- a/src/core_write.cpp
+++ b/src/core_write.cpp
@@ -174,9 +174,7 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry
entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
- // Transaction version is actually unsigned in consensus checks, just signed in memory,
- // so cast to unsigned before giving it to the user.
- entry.pushKV("version", static_cast<int64_t>(static_cast<uint32_t>(tx.nVersion)));
+ entry.pushKV("version", tx.nVersion);
entry.pushKV("size", tx.GetTotalSize());
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
entry.pushKV("weight", GetTransactionWeight(tx));
diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp
index b4a860dd9e..0143aec4a5 100644
--- a/src/primitives/transaction.cpp
+++ b/src/primitives/transaction.cpp
@@ -63,8 +63,8 @@ std::string CTxOut::ToString() const
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
}
-CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
-CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime) {}
+CMutableTransaction::CMutableTransaction() : nVersion{CTransaction::CURRENT_VERSION}, nLockTime{0} {}
+CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion{tx.nVersion}, nLockTime{tx.nLockTime} {}
Txid CMutableTransaction::GetHash() const
{
@@ -92,8 +92,8 @@ Wtxid CTransaction::ComputeWitnessHash() const
return Wtxid::FromUint256((HashWriter{} << TX_WITH_WITNESS(*this)).GetHash());
}
-CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime), m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
-CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nLockTime(tx.nLockTime), m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
+CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion{tx.nVersion}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
+CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion{tx.nVersion}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
CAmount CTransaction::GetValueOut() const
{
@@ -115,7 +115,7 @@ unsigned int CTransaction::GetTotalSize() const
std::string CTransaction::ToString() const
{
std::string str;
- str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
+ str += strprintf("CTransaction(hash=%s, ver=%u, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
GetHash().ToString().substr(0,10),
nVersion,
vin.size(),
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 976542cfae..f68be00e4e 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -197,13 +197,13 @@ static constexpr TransactionSerParams TX_NO_WITNESS{.allow_witness = false};
/**
* Basic transaction serialization format:
- * - int32_t nVersion
+ * - uint32_t nVersion
* - std::vector<CTxIn> vin
* - std::vector<CTxOut> vout
* - uint32_t nLockTime
*
* Extended transaction serialization format:
- * - int32_t nVersion
+ * - uint32_t nVersion
* - unsigned char dummy = 0x00
* - unsigned char flags (!= 0)
* - std::vector<CTxIn> vin
@@ -296,7 +296,7 @@ class CTransaction
{
public:
// Default transaction version.
- static const int32_t CURRENT_VERSION=2;
+ static const uint32_t CURRENT_VERSION{2};
// The local variables are made const to prevent unintended modification
// without updating the cached hash value. However, CTransaction is not
@@ -305,7 +305,7 @@ public:
// structure, including the hash.
const std::vector<CTxIn> vin;
const std::vector<CTxOut> vout;
- const int32_t nVersion;
+ const uint32_t nVersion;
const uint32_t nLockTime;
private:
@@ -378,7 +378,7 @@ struct CMutableTransaction
{
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
- int32_t nVersion;
+ uint32_t nVersion;
uint32_t nLockTime;
explicit CMutableTransaction();
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 2ecaeeaf40..012da77f54 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -1748,8 +1748,8 @@ static RPCHelpMan joinpsbts()
}
psbtxs.push_back(psbtx);
// Choose the highest version number
- if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) {
- best_version = static_cast<uint32_t>(psbtx.tx->nVersion);
+ if (psbtx.tx->nVersion > best_version) {
+ best_version = psbtx.tx->nVersion;
}
// Choose the lowest lock time
if (psbtx.tx->nLockTime < best_locktime) {
@@ -1760,7 +1760,7 @@ static RPCHelpMan joinpsbts()
// Create a blank psbt where everything will be added
PartiallySignedTransaction merged_psbt;
merged_psbt.tx = CMutableTransaction();
- merged_psbt.tx->nVersion = static_cast<int32_t>(best_version);
+ merged_psbt.tx->nVersion = best_version;
merged_psbt.tx->nLockTime = best_locktime;
// Merge
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index c969ce45f1..1ebf5425a5 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1743,7 +1743,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
// Fail if the transaction's version number is not set high
// enough to trigger BIP 68 rules.
- if (static_cast<uint32_t>(txTo->nVersion) < 2)
+ if (txTo->nVersion < 2)
return false;
// Sequence numbers with their most significant bit set are not
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index 259b00fcae..a1119297f4 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -45,7 +45,7 @@ CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider,
const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool();
tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ?
CTransaction::CURRENT_VERSION :
- fuzzed_data_provider.ConsumeIntegral<int32_t>();
+ fuzzed_data_provider.ConsumeIntegral<uint32_t>();
tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in);
const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_out);
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index d08d5519a1..d43c474ae1 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -92,7 +92,7 @@ void static RandomScript(CScript &script) {
void static RandomTransaction(CMutableTransaction& tx, bool fSingle)
{
- tx.nVersion = int(InsecureRand32());
+ tx.nVersion = InsecureRand32();
tx.vin.clear();
tx.vout.clear();
tx.nLockTime = (InsecureRandBool()) ? InsecureRand32() : 0;
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index e6cf64611e..384babbde1 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -780,7 +780,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
CheckIsStandard(t);
// Disallowed nVersion
- t.nVersion = -1;
+ t.nVersion = std::numeric_limits<uint32_t>::max();
CheckIsNotStandard(t, "version");
t.nVersion = 0;