Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: fix dbcrash and fee_estimation extended tests #1298

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions test/functional/feature_dbcrash.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,18 @@ def verify_utxo_hash(self):
assert_equal(nodei_utxo_hash, node3_utxo_hash)

def generate_small_transactions(self, node, count, utxo_list):
FEE = 1000 # TODO: replace this with node relay fee based calculation
num_transactions = 0
random.shuffle(utxo_list)
while len(utxo_list) >= 2 and num_transactions < count:
fee = 1000
tx = CTransaction()
input_amount = 0
for _ in range(2):
utxo = utxo_list.pop()
tx.vin.append(CTxIn(COutPoint(int(utxo['txid'], 16), utxo['vout'])))
input_amount += int(utxo['amount'] * COIN)
output_amount = (input_amount - FEE) // 3
output_amount = (input_amount - fee) // 3
fee = input_amount - (3 * output_amount)

if output_amount <= 0:
# Sanity check -- if we chose inputs that are too small, skip
Expand All @@ -205,6 +206,9 @@ def generate_small_transactions(self, node, count, utxo_list):
for _ in range(3):
tx.vout.append(CTxOut(output_amount, bytes.fromhex(utxo['scriptPubKey'])))

# ELEMENTS: add fee output
tx.vout.append(CTxOut(fee))

# Sign and send the transaction to get into the mempool
tx_signed_hex = node.signrawtransactionwithwallet(tx.serialize().hex())['hex']
node.sendrawtransaction(tx_signed_hex)
Expand Down Expand Up @@ -234,10 +238,13 @@ def run_test(self):
# Main test loop:
# each time through the loop, generate a bunch of transactions,
# and then either mine a single new block on the tip, or some-sized reorg.
for i in range(40):
self.log.info(f"Iteration {i}, generating 2500 transactions {self.restart_counts}")
# ELEMENTS: modified to only run until successfully testing a node crash on restart
# with a maximum of 10 iterations
i = 0
while self.crashed_on_restart < 1:
self.log.info(f"Iteration {i}, generating 3000 transactions {self.restart_counts}")
# Generate a bunch of small-ish transactions
self.generate_small_transactions(self.nodes[3], 2500, utxo_list)
self.generate_small_transactions(self.nodes[3], 3000, utxo_list)
# Pick a random block between current tip, and starting tip
current_height = self.nodes[3].getblockcount()
random_height = random.randint(starting_tip_height, current_height)
Expand Down Expand Up @@ -265,6 +272,11 @@ def run_test(self):
utxo_list = self.nodes[3].listunspent()
self.log.debug(f"Node3 utxo count: {len(utxo_list)}")

if i >= 11:
raise AssertionError(f"12 iterations without node crash, this should not happen")
else:
i += 1

# Check that the utxo hashes agree with node3
# Useful side effect: each utxo cache gets flushed here, so that we
# won't get crashes on shutdown at the end of the test.
Expand Down
9 changes: 6 additions & 3 deletions test/functional/feature_fee_estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,13 @@ def send_tx(node, utxo, feerate):
"""Broadcast a 1in-1out transaction with a specific input and feerate (sat/vb)."""
tx = CTransaction()
tx.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), REDEEM_SCRIPT)]
tx.vout = [CTxOut(int(utxo["amount"] * COIN), P2SH)]
tx.vout = [CTxOut(int(utxo["amount"] * COIN), P2SH), CTxOut(int(utxo["amount"] * COIN))]

# vbytes == bytes as we are using legacy transactions
fee = tx.get_vsize() * feerate
tx.vout[0].nValue -= fee
amount = tx.vout[0].nValue.getAmount()
tx.vout[0].nValue.setToAmount(amount - fee)
tx.vout[1].nValue.setToAmount(fee)

return node.sendrawtransaction(tx.serialize().hex())

Expand Down Expand Up @@ -208,7 +210,7 @@ def transact_and_mine(self, numblocks, mining_node):

def initial_split(self, node):
"""Split two coinbase UTxOs into many small coins"""
utxo_count = 2048
utxo_count = 1450 # ELEMENTS reduced to fit into max tx weight
self.confutxo = []
splitted_amount = Decimal("0.04")
fee = Decimal("0.1")
Expand All @@ -220,6 +222,7 @@ def initial_split(self, node):
]
tx.vout = [CTxOut(int(splitted_amount * COIN), P2SH) for _ in range(utxo_count)]
tx.vout.append(CTxOut(int(change * COIN), P2SH))
tx.vout.append(CTxOut(int(fee * COIN)))
txhex = node.signrawtransactionwithwallet(tx.serialize().hex())["hex"]
txid = node.sendrawtransaction(txhex)
self.confutxo = [
Expand Down
5 changes: 4 additions & 1 deletion test/functional/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,10 @@ def create_confirmed_utxos(test_framework, fee, node, count, **kwargs):
inputs = []
inputs.append({"txid": t["txid"], "vout": t["vout"]})
send_value = t['amount'] - fee
outputs = [{addr1: satoshi_round(send_value / 2)}, {addr2: satoshi_round(send_value / 2)}, {"fee": fee}]
# ELEMENTS: ensure outputs balance with inputs
val1 = satoshi_round(send_value / 2)
val2 = send_value - val1
outputs = [{addr1: val1}, {addr2: val2}, {"fee": fee}]
raw_tx = node.createrawtransaction(inputs, outputs)
signed_tx = node.signrawtransactionwithwallet(raw_tx)["hex"]
node.sendrawtransaction(signed_tx)
Expand Down