mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-01 19:21:28 +02:00
Merge bitcoin/bitcoin#29325: consensus: Store transaction nVersion as uint32_t
429ec1aaaa
refactor: Rename CTransaction::nVersion to version (Ava Chow)27e70f1f5b
consensus: Store transaction nVersion as uint32_t (Ava Chow) Pull request description: 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 everywhere it is used and displayed. Since a few alternative implementations have recently been revealed to have made an error with this signedness that would have resulted in consensus failure, I think it makes sense for us to just make this always unsigned to make it clear that the version is treated as unsigned. This would also help us avoid future potential issues with signedness of this value. I believe that this is safe and does not actually change what transactions would or would not be considered both standard and consensus valid. Within consensus, the only use of the version in consensus is in BIP68 validation which was already casting it to uint32_t. Within policy, although it is used as a signed int for the transaction version number check, I do not think that this change would change standardness. Standard transactions are limited to the range [1, 2]. Negative numbers would have fallen under the < 1 condition, but by making it unsigned, they are still non-standard under the > 2 condition. Unsigned and signed ints are serialized and unserialized the same way so there is no change in serialization. ACKs for top commit: maflcko: ACK429ec1aaaa
🐿 glozow: ACK429ec1aaaa
shaavan: ACK429ec1aaaa
💯 Tree-SHA512: 0bcd92a245d7d16c3665d2d4e815a4ef28207ad4a1fb46c6f0203cdafeab1b82c4e95e4bdce7805d80a4f4a46074f6542abad708e970550d38a00d759e3dcef1
This commit is contained in:
@ -560,12 +560,12 @@ class CTxWitness:
|
||||
|
||||
|
||||
class CTransaction:
|
||||
__slots__ = ("hash", "nLockTime", "nVersion", "sha256", "vin", "vout",
|
||||
__slots__ = ("hash", "nLockTime", "version", "sha256", "vin", "vout",
|
||||
"wit")
|
||||
|
||||
def __init__(self, tx=None):
|
||||
if tx is None:
|
||||
self.nVersion = 2
|
||||
self.version = 2
|
||||
self.vin = []
|
||||
self.vout = []
|
||||
self.wit = CTxWitness()
|
||||
@ -573,7 +573,7 @@ class CTransaction:
|
||||
self.sha256 = None
|
||||
self.hash = None
|
||||
else:
|
||||
self.nVersion = tx.nVersion
|
||||
self.version = tx.version
|
||||
self.vin = copy.deepcopy(tx.vin)
|
||||
self.vout = copy.deepcopy(tx.vout)
|
||||
self.nLockTime = tx.nLockTime
|
||||
@ -582,7 +582,7 @@ class CTransaction:
|
||||
self.wit = copy.deepcopy(tx.wit)
|
||||
|
||||
def deserialize(self, f):
|
||||
self.nVersion = int.from_bytes(f.read(4), "little", signed=True)
|
||||
self.version = int.from_bytes(f.read(4), "little")
|
||||
self.vin = deser_vector(f, CTxIn)
|
||||
flags = 0
|
||||
if len(self.vin) == 0:
|
||||
@ -605,7 +605,7 @@ class CTransaction:
|
||||
|
||||
def serialize_without_witness(self):
|
||||
r = b""
|
||||
r += self.nVersion.to_bytes(4, "little", signed=True)
|
||||
r += self.version.to_bytes(4, "little")
|
||||
r += ser_vector(self.vin)
|
||||
r += ser_vector(self.vout)
|
||||
r += self.nLockTime.to_bytes(4, "little")
|
||||
@ -617,7 +617,7 @@ class CTransaction:
|
||||
if not self.wit.is_null():
|
||||
flags |= 1
|
||||
r = b""
|
||||
r += self.nVersion.to_bytes(4, "little", signed=True)
|
||||
r += self.version.to_bytes(4, "little")
|
||||
if flags:
|
||||
dummy = []
|
||||
r += ser_vector(dummy)
|
||||
@ -677,8 +677,8 @@ class CTransaction:
|
||||
return math.ceil(self.get_weight() / WITNESS_SCALE_FACTOR)
|
||||
|
||||
def __repr__(self):
|
||||
return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \
|
||||
% (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)
|
||||
return "CTransaction(version=%i vin=%s vout=%s wit=%s nLockTime=%i)" \
|
||||
% (self.version, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)
|
||||
|
||||
|
||||
class CBlockHeader:
|
||||
|
@ -738,7 +738,7 @@ def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount):
|
||||
hashOutputs = uint256_from_str(hash256(serialize_outputs))
|
||||
|
||||
ss = bytes()
|
||||
ss += txTo.nVersion.to_bytes(4, "little", signed=True)
|
||||
ss += txTo.version.to_bytes(4, "little")
|
||||
ss += ser_uint256(hashPrevouts)
|
||||
ss += ser_uint256(hashSequence)
|
||||
ss += txTo.vin[inIdx].prevout.serialize()
|
||||
@ -817,7 +817,7 @@ def TaprootSignatureMsg(txTo, spent_utxos, hash_type, input_index = 0, scriptpat
|
||||
in_type = hash_type & SIGHASH_ANYONECANPAY
|
||||
spk = spent_utxos[input_index].scriptPubKey
|
||||
ss = bytes([0, hash_type]) # epoch, hash_type
|
||||
ss += txTo.nVersion.to_bytes(4, "little", signed=True)
|
||||
ss += txTo.version.to_bytes(4, "little")
|
||||
ss += txTo.nLockTime.to_bytes(4, "little")
|
||||
if in_type != SIGHASH_ANYONECANPAY:
|
||||
ss += BIP341_sha_prevouts(txTo)
|
||||
|
@ -329,7 +329,7 @@ class MiniWallet:
|
||||
tx = CTransaction()
|
||||
tx.vin = [CTxIn(COutPoint(int(utxo_to_spend['txid'], 16), utxo_to_spend['vout']), nSequence=seq) for utxo_to_spend, seq in zip(utxos_to_spend, sequence)]
|
||||
tx.vout = [CTxOut(amount_per_output, bytearray(self._scriptPubKey)) for _ in range(num_outputs)]
|
||||
tx.nVersion = version
|
||||
tx.version = version
|
||||
tx.nLockTime = locktime
|
||||
|
||||
self.sign_tx(tx)
|
||||
|
Reference in New Issue
Block a user