mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-21 22:31:21 +02:00
tests: Use batched RPC in feature_fee_estimation
feature_fee_estimation has a lot of loops that hit the RPC many times in succession in order to setup scenarios. Using batched requests for these can reduce the test's runtime without effecting the test's behavior.
This commit is contained in:
parent
4ad7272f8b
commit
544cbf776c
@ -23,7 +23,7 @@ from test_framework.wallet import MiniWallet
|
|||||||
|
|
||||||
|
|
||||||
def small_txpuzzle_randfee(
|
def small_txpuzzle_randfee(
|
||||||
wallet, from_node, conflist, unconflist, amount, min_fee, fee_increment
|
wallet, from_node, conflist, unconflist, amount, min_fee, fee_increment, batch_reqs
|
||||||
):
|
):
|
||||||
"""Create and send a transaction with a random fee using MiniWallet.
|
"""Create and send a transaction with a random fee using MiniWallet.
|
||||||
|
|
||||||
@ -57,8 +57,11 @@ def small_txpuzzle_randfee(
|
|||||||
tx.vout[0].nValue = int((total_in - amount - fee) * COIN)
|
tx.vout[0].nValue = int((total_in - amount - fee) * COIN)
|
||||||
tx.vout.append(deepcopy(tx.vout[0]))
|
tx.vout.append(deepcopy(tx.vout[0]))
|
||||||
tx.vout[1].nValue = int(amount * COIN)
|
tx.vout[1].nValue = int(amount * COIN)
|
||||||
|
tx.rehash()
|
||||||
|
txid = tx.hash
|
||||||
|
tx_hex = tx.serialize().hex()
|
||||||
|
|
||||||
txid = from_node.sendrawtransaction(hexstring=tx.serialize().hex(), maxfeerate=0)
|
batch_reqs.append(from_node.sendrawtransaction.get_request(hexstring=tx_hex, maxfeerate=0))
|
||||||
unconflist.append({"txid": txid, "vout": 0, "value": total_in - amount - fee})
|
unconflist.append({"txid": txid, "vout": 0, "value": total_in - amount - fee})
|
||||||
unconflist.append({"txid": txid, "vout": 1, "value": amount})
|
unconflist.append({"txid": txid, "vout": 1, "value": amount})
|
||||||
|
|
||||||
@ -115,13 +118,12 @@ def check_estimates(node, fees_seen):
|
|||||||
check_smart_estimates(node, fees_seen)
|
check_smart_estimates(node, fees_seen)
|
||||||
|
|
||||||
|
|
||||||
def send_tx(wallet, node, utxo, feerate):
|
def make_tx(wallet, utxo, feerate):
|
||||||
"""Broadcast a 1in-1out transaction with a specific input and feerate (sat/vb)."""
|
"""Create a 1in-1out transaction with a specific input and feerate (sat/vb)."""
|
||||||
return wallet.send_self_transfer(
|
return wallet.create_self_transfer(
|
||||||
from_node=node,
|
|
||||||
utxo_to_spend=utxo,
|
utxo_to_spend=utxo,
|
||||||
fee_rate=Decimal(feerate * 1000) / COIN,
|
fee_rate=Decimal(feerate * 1000) / COIN,
|
||||||
)['txid']
|
)
|
||||||
|
|
||||||
|
|
||||||
class EstimateFeeTest(BitcoinTestFramework):
|
class EstimateFeeTest(BitcoinTestFramework):
|
||||||
@ -156,6 +158,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||||||
# resorting to tx's that depend on the mempool when those run out
|
# resorting to tx's that depend on the mempool when those run out
|
||||||
for _ in range(numblocks):
|
for _ in range(numblocks):
|
||||||
random.shuffle(self.confutxo)
|
random.shuffle(self.confutxo)
|
||||||
|
batch_sendtx_reqs = []
|
||||||
for _ in range(random.randrange(100 - 50, 100 + 50)):
|
for _ in range(random.randrange(100 - 50, 100 + 50)):
|
||||||
from_index = random.randint(1, 2)
|
from_index = random.randint(1, 2)
|
||||||
(tx_bytes, fee) = small_txpuzzle_randfee(
|
(tx_bytes, fee) = small_txpuzzle_randfee(
|
||||||
@ -166,9 +169,12 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||||||
Decimal("0.005"),
|
Decimal("0.005"),
|
||||||
min_fee,
|
min_fee,
|
||||||
min_fee,
|
min_fee,
|
||||||
|
batch_sendtx_reqs,
|
||||||
)
|
)
|
||||||
tx_kbytes = tx_bytes / 1000.0
|
tx_kbytes = tx_bytes / 1000.0
|
||||||
self.fees_per_kb.append(float(fee) / tx_kbytes)
|
self.fees_per_kb.append(float(fee) / tx_kbytes)
|
||||||
|
for node in self.nodes:
|
||||||
|
node.batch(batch_sendtx_reqs)
|
||||||
self.sync_mempools(wait=0.1)
|
self.sync_mempools(wait=0.1)
|
||||||
mined = mining_node.getblock(self.generate(mining_node, 1)[0], True)["tx"]
|
mined = mining_node.getblock(self.generate(mining_node, 1)[0], True)["tx"]
|
||||||
# update which txouts are confirmed
|
# update which txouts are confirmed
|
||||||
@ -245,14 +251,20 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||||||
assert_greater_than_or_equal(len(utxos), 250)
|
assert_greater_than_or_equal(len(utxos), 250)
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
# Broadcast 45 low fee transactions that will need to be RBF'd
|
# Broadcast 45 low fee transactions that will need to be RBF'd
|
||||||
|
txs = []
|
||||||
for _ in range(45):
|
for _ in range(45):
|
||||||
u = utxos.pop(0)
|
u = utxos.pop(0)
|
||||||
txid = send_tx(self.wallet, node, u, low_feerate)
|
tx = make_tx(self.wallet, u, low_feerate)
|
||||||
utxos_to_respend.append(u)
|
utxos_to_respend.append(u)
|
||||||
txids_to_replace.append(txid)
|
txids_to_replace.append(tx["txid"])
|
||||||
|
txs.append(tx)
|
||||||
# Broadcast 5 low fee transaction which don't need to
|
# Broadcast 5 low fee transaction which don't need to
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
send_tx(self.wallet, node, utxos.pop(0), low_feerate)
|
tx = make_tx(self.wallet, utxos.pop(0), low_feerate)
|
||||||
|
txs.append(tx)
|
||||||
|
batch_send_tx = [node.sendrawtransaction.get_request(tx["hex"]) for tx in txs]
|
||||||
|
for n in self.nodes:
|
||||||
|
n.batch(batch_send_tx)
|
||||||
# Mine the transactions on another node
|
# Mine the transactions on another node
|
||||||
self.sync_mempools(wait=0.1, nodes=[node, miner])
|
self.sync_mempools(wait=0.1, nodes=[node, miner])
|
||||||
for txid in txids_to_replace:
|
for txid in txids_to_replace:
|
||||||
@ -261,7 +273,12 @@ class EstimateFeeTest(BitcoinTestFramework):
|
|||||||
# RBF the low-fee transactions
|
# RBF the low-fee transactions
|
||||||
while len(utxos_to_respend) > 0:
|
while len(utxos_to_respend) > 0:
|
||||||
u = utxos_to_respend.pop(0)
|
u = utxos_to_respend.pop(0)
|
||||||
send_tx(self.wallet, node, u, high_feerate)
|
tx = make_tx(self.wallet, u, high_feerate)
|
||||||
|
node.sendrawtransaction(tx["hex"])
|
||||||
|
txs.append(tx)
|
||||||
|
dec_txs = [res["result"] for res in node.batch([node.decoderawtransaction.get_request(tx["hex"]) for tx in txs])]
|
||||||
|
self.wallet.scan_txs(dec_txs)
|
||||||
|
|
||||||
|
|
||||||
# Mine the last replacement txs
|
# Mine the last replacement txs
|
||||||
self.sync_mempools(wait=0.1, nodes=[node, miner])
|
self.sync_mempools(wait=0.1, nodes=[node, miner])
|
||||||
|
@ -141,6 +141,10 @@ class MiniWallet:
|
|||||||
if out['scriptPubKey']['hex'] == self._scriptPubKey.hex():
|
if out['scriptPubKey']['hex'] == self._scriptPubKey.hex():
|
||||||
self._utxos.append(self._create_utxo(txid=tx["txid"], vout=out["n"], value=out["value"], height=0))
|
self._utxos.append(self._create_utxo(txid=tx["txid"], vout=out["n"], value=out["value"], height=0))
|
||||||
|
|
||||||
|
def scan_txs(self, txs):
|
||||||
|
for tx in txs:
|
||||||
|
self.scan_tx(tx)
|
||||||
|
|
||||||
def sign_tx(self, tx, fixed_length=True):
|
def sign_tx(self, tx, fixed_length=True):
|
||||||
"""Sign tx that has been created by MiniWallet in P2PK mode"""
|
"""Sign tx that has been created by MiniWallet in P2PK mode"""
|
||||||
assert_equal(self._mode, MiniWalletMode.RAW_P2PK)
|
assert_equal(self._mode, MiniWalletMode.RAW_P2PK)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user