mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
merge bitcoin#21754: Run feature_cltv with MiniWallet
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
parent
bd750140be
commit
8b7ea28e80
@ -11,7 +11,6 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates at (regtest) block height
|
|||||||
from test_framework.blocktools import (
|
from test_framework.blocktools import (
|
||||||
create_block,
|
create_block,
|
||||||
create_coinbase,
|
create_coinbase,
|
||||||
create_transaction,
|
|
||||||
)
|
)
|
||||||
from test_framework.messages import (
|
from test_framework.messages import (
|
||||||
CTransaction,
|
CTransaction,
|
||||||
@ -29,10 +28,8 @@ from test_framework.test_framework import BitcoinTestFramework
|
|||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_equal,
|
assert_equal,
|
||||||
assert_raises_rpc_error,
|
assert_raises_rpc_error,
|
||||||
hex_str_to_bytes,
|
|
||||||
)
|
)
|
||||||
|
from test_framework.wallet import MiniWallet
|
||||||
from io import BytesIO
|
|
||||||
|
|
||||||
CLTV_HEIGHT = 1351
|
CLTV_HEIGHT = 1351
|
||||||
|
|
||||||
@ -41,19 +38,14 @@ CLTV_HEIGHT = 1351
|
|||||||
# 1) prepending a given script to the scriptSig of vin 0 and
|
# 1) prepending a given script to the scriptSig of vin 0 and
|
||||||
# 2) (optionally) modify the nSequence of vin 0 and the tx's nLockTime
|
# 2) (optionally) modify the nSequence of vin 0 and the tx's nLockTime
|
||||||
def cltv_modify_tx(node, tx, prepend_scriptsig, nsequence=None, nlocktime=None):
|
def cltv_modify_tx(node, tx, prepend_scriptsig, nsequence=None, nlocktime=None):
|
||||||
|
assert_equal(len(tx.vin), 1)
|
||||||
if nsequence is not None:
|
if nsequence is not None:
|
||||||
tx.vin[0].nSequence = nsequence
|
tx.vin[0].nSequence = nsequence
|
||||||
tx.nLockTime = nlocktime
|
tx.nLockTime = nlocktime
|
||||||
|
|
||||||
# Need to re-sign, since nSequence and nLockTime changed
|
tx.vin[0].scriptSig = CScript(prepend_scriptsig + list(CScript(tx.vin[0].scriptSig)))
|
||||||
signed_result = node.signrawtransactionwithwallet(tx.serialize().hex())
|
tx.rehash()
|
||||||
new_tx = CTransaction()
|
return tx
|
||||||
new_tx.deserialize(BytesIO(hex_str_to_bytes(signed_result['hex'])))
|
|
||||||
else:
|
|
||||||
new_tx = tx
|
|
||||||
|
|
||||||
new_tx.vin[0].scriptSig = CScript(prepend_scriptsig + list(CScript(new_tx.vin[0].scriptSig)))
|
|
||||||
return new_tx
|
|
||||||
|
|
||||||
|
|
||||||
def cltv_invalidate(node, tx, failure_reason):
|
def cltv_invalidate(node, tx, failure_reason):
|
||||||
@ -108,27 +100,23 @@ class BIP65Test(BitcoinTestFramework):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def skip_test_if_missing_module(self):
|
|
||||||
self.skip_if_no_wallet()
|
|
||||||
|
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
peer = self.nodes[0].add_p2p_connection(P2PInterface())
|
peer = self.nodes[0].add_p2p_connection(P2PInterface())
|
||||||
|
wallet = MiniWallet(self.nodes[0], raw_script=True)
|
||||||
|
|
||||||
self.test_cltv_info(is_active=False)
|
self.test_cltv_info(is_active=False)
|
||||||
|
|
||||||
self.log.info("Mining %d blocks", CLTV_HEIGHT - 2)
|
self.log.info("Mining %d blocks", CLTV_HEIGHT - 2)
|
||||||
self.coinbase_txids = [self.nodes[0].getblock(b)['tx'][0] for b in self.nodes[0].generate(CLTV_HEIGHT - 2)]
|
wallet.generate(10)
|
||||||
self.nodeaddress = self.nodes[0].getnewaddress()
|
self.nodes[0].generate(CLTV_HEIGHT - 2 - 10)
|
||||||
|
|
||||||
self.log.info("Test that invalid-according-to-CLTV transactions can still appear in a block")
|
self.log.info("Test that invalid-according-to-CLTV transactions can still appear in a block")
|
||||||
|
|
||||||
# create one invalid tx per CLTV failure reason (5 in total) and collect them
|
# create one invalid tx per CLTV failure reason (5 in total) and collect them
|
||||||
invalid_ctlv_txs = []
|
invalid_ctlv_txs = []
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
spendtx = create_transaction(self.nodes[0], self.coinbase_txids[i],
|
spendtx = wallet.create_self_transfer(from_node=self.nodes[0])['tx']
|
||||||
self.nodeaddress, amount=1.0)
|
|
||||||
spendtx = cltv_invalidate(self.nodes[0], spendtx, i)
|
spendtx = cltv_invalidate(self.nodes[0], spendtx, i)
|
||||||
spendtx.rehash()
|
|
||||||
invalid_ctlv_txs.append(spendtx)
|
invalid_ctlv_txs.append(spendtx)
|
||||||
|
|
||||||
tip = self.nodes[0].getbestblockhash()
|
tip = self.nodes[0].getbestblockhash()
|
||||||
@ -162,10 +150,8 @@ class BIP65Test(BitcoinTestFramework):
|
|||||||
|
|
||||||
# create and test one invalid tx per CLTV failure reason (5 in total)
|
# create and test one invalid tx per CLTV failure reason (5 in total)
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
spendtx = create_transaction(self.nodes[0], self.coinbase_txids[10+i],
|
spendtx = wallet.create_self_transfer(from_node=self.nodes[0])['tx']
|
||||||
self.nodeaddress, amount=1.0)
|
|
||||||
spendtx = cltv_invalidate(self.nodes[0], spendtx, i)
|
spendtx = cltv_invalidate(self.nodes[0], spendtx, i)
|
||||||
spendtx.rehash()
|
|
||||||
|
|
||||||
expected_cltv_reject_reason = [
|
expected_cltv_reject_reason = [
|
||||||
"non-mandatory-script-verify-flag (Operation not valid with the current stack size)",
|
"non-mandatory-script-verify-flag (Operation not valid with the current stack size)",
|
||||||
@ -191,7 +177,6 @@ class BIP65Test(BitcoinTestFramework):
|
|||||||
|
|
||||||
self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted")
|
self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted")
|
||||||
spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1)
|
spendtx = cltv_validate(self.nodes[0], spendtx, CLTV_HEIGHT - 1)
|
||||||
spendtx.rehash()
|
|
||||||
|
|
||||||
block.vtx.pop(1)
|
block.vtx.pop(1)
|
||||||
block.vtx.append(spendtx)
|
block.vtx.append(spendtx)
|
||||||
|
@ -17,6 +17,7 @@ from test_framework.messages import (
|
|||||||
from test_framework.script import (
|
from test_framework.script import (
|
||||||
CScript,
|
CScript,
|
||||||
OP_TRUE,
|
OP_TRUE,
|
||||||
|
OP_NOP,
|
||||||
)
|
)
|
||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_equal,
|
assert_equal,
|
||||||
@ -26,9 +27,13 @@ from test_framework.util import (
|
|||||||
|
|
||||||
|
|
||||||
class MiniWallet:
|
class MiniWallet:
|
||||||
def __init__(self, test_node):
|
def __init__(self, test_node, *, raw_script=False):
|
||||||
self._test_node = test_node
|
self._test_node = test_node
|
||||||
self._utxos = []
|
self._utxos = []
|
||||||
|
if raw_script:
|
||||||
|
self._address = None
|
||||||
|
self._scriptPubKey = bytes(CScript([OP_TRUE]))
|
||||||
|
else:
|
||||||
self._address = ADDRESS_BCRT1_P2SH_OP_TRUE
|
self._address = ADDRESS_BCRT1_P2SH_OP_TRUE
|
||||||
self._scriptPubKey = hex_str_to_bytes(self._test_node.validateaddress(self._address)['scriptPubKey'])
|
self._scriptPubKey = hex_str_to_bytes(self._test_node.validateaddress(self._address)['scriptPubKey'])
|
||||||
|
|
||||||
@ -47,7 +52,7 @@ class MiniWallet:
|
|||||||
|
|
||||||
def generate(self, num_blocks):
|
def generate(self, num_blocks):
|
||||||
"""Generate blocks with coinbase outputs to the internal address, and append the outputs to the internal list"""
|
"""Generate blocks with coinbase outputs to the internal address, and append the outputs to the internal list"""
|
||||||
blocks = self._test_node.generatetoaddress(num_blocks, self._address)
|
blocks = self._test_node.generatetodescriptor(num_blocks, f'raw({self._scriptPubKey.hex()})')
|
||||||
for b in blocks:
|
for b in blocks:
|
||||||
cb_tx = self._test_node.getblock(blockhash=b, verbosity=2)['tx'][0]
|
cb_tx = self._test_node.getblock(blockhash=b, verbosity=2)['tx'][0]
|
||||||
self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value']})
|
self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value']})
|
||||||
@ -89,6 +94,10 @@ class MiniWallet:
|
|||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
tx.vin = [CTxIn(COutPoint(int(utxo_to_spend['txid'], 16), utxo_to_spend['vout']))]
|
tx.vin = [CTxIn(COutPoint(int(utxo_to_spend['txid'], 16), utxo_to_spend['vout']))]
|
||||||
tx.vout = [CTxOut(int(send_value * COIN), self._scriptPubKey)]
|
tx.vout = [CTxOut(int(send_value * COIN), self._scriptPubKey)]
|
||||||
|
if not self._address:
|
||||||
|
# raw script
|
||||||
|
tx.vin[0].scriptSig = CScript([OP_NOP] * 24) # pad to identical size
|
||||||
|
else:
|
||||||
tx.vin[0].scriptSig = CScript([CScript([OP_TRUE])])
|
tx.vin[0].scriptSig = CScript([CScript([OP_TRUE])])
|
||||||
tx_hex = tx.serialize().hex()
|
tx_hex = tx.serialize().hex()
|
||||||
|
|
||||||
@ -97,7 +106,7 @@ class MiniWallet:
|
|||||||
if mempool_valid:
|
if mempool_valid:
|
||||||
assert_equal(len(tx_hex) // 2, vsize)
|
assert_equal(len(tx_hex) // 2, vsize)
|
||||||
assert_equal(tx_info['fees']['base'], fee)
|
assert_equal(tx_info['fees']['base'], fee)
|
||||||
return {'txid': tx_info['txid'], 'hex': tx_hex}
|
return {'txid': tx_info['txid'], 'hex': tx_hex, 'tx': tx}
|
||||||
|
|
||||||
def sendrawtransaction(self, *, from_node, tx_hex):
|
def sendrawtransaction(self, *, from_node, tx_hex):
|
||||||
from_node.sendrawtransaction(tx_hex)
|
from_node.sendrawtransaction(tx_hex)
|
||||||
|
Loading…
Reference in New Issue
Block a user