diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 86ab52f1c..8d40b23b6 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -115,6 +115,7 @@ testScripts = [ # 'p2p-segwit.py', 'wallet-dump.py', 'listtransactions.py', + 'p2p-policy.py', # vv Tests less than 60s vv 'p2p-acceptblock.py', 'sendheaders.py', @@ -168,7 +169,6 @@ testScripts = [ 'listsinceblock.py', 'p2p-leaktests.py', 'replace-by-fee.py', - 'p2p-policy.py', 'wallet_create_tx.py', 'liststucktransactions.py', 'addnode.py', diff --git a/qa/rpc-tests/p2p-policy.py b/qa/rpc-tests/p2p-policy.py index eb790a571..eeab75b7b 100644 --- a/qa/rpc-tests/p2p-policy.py +++ b/qa/rpc-tests/p2p-policy.py @@ -52,7 +52,7 @@ class TestNode(NodeConnCB): return wait_until(veracked, timeout=10) # Wait until we have received an inv of a specific tx - def wait_for_tx_inv(self, hash, timeout=30): + def wait_for_tx_inv(self, hash, timeout=120): def have_received_tx_inv(): try: return self.txinvs[hash] @@ -120,7 +120,7 @@ class P2PPolicyTests(BitcoinTestFramework): relay_fee_per_byte = relay_fee / 1000 # create a bunch of UTXO with seed money from the Dogecoin Core wallet - for i in range(10): + for i in range(20): inputs = [self.nodes[0].listunspent()[0]] outputs = { self.srcAddr : ten } tx = self.nodes[0].createrawtransaction(inputs, outputs) @@ -131,51 +131,51 @@ class P2PPolicyTests(BitcoinTestFramework): # test legacy output of 1 DOGE output and 1 DOGE fee output = { self.tgtAddr : 1, self.srcAddr: 8 } - self.run_relay_test(output, None) + self.run_relay_test(output) # test exact relay fee rate output = { self.tgtAddr: ten - relay_fee_per_byte * 192} - tx = self.run_relay_test(output, None) + tx = self.run_relay_test(output, None, 192) # test too low relay fee rate - output = { self.tgtAddr: ten - relay_fee_per_byte * 191 + koinu } - tx = self.run_relay_test(output, 66) # 66 = too low fee + output = { self.tgtAddr: ten - relay_fee_per_byte * 192 + koinu } + tx = self.run_relay_test(output, 66, 192) # 66 = too low fee # test exact dust limit - change = ten - soft_dust_limit - relay_fee_per_byte * 226 + change = ten - soft_dust_limit - relay_fee_per_byte * 225 output = { self.tgtAddr : soft_dust_limit, self.srcAddr: change} - self.run_relay_test(output, None) + self.run_relay_test(output, None, 225) # test soft dust limit with sufficient fee amount = soft_dust_limit - koinu - change = ten - amount - relay_fee_per_byte * 226 - soft_dust_limit + change = ten - amount - relay_fee_per_byte * 225 - soft_dust_limit output = { self.tgtAddr : amount, self.srcAddr: change } - self.run_relay_test(output, None) + self.run_relay_test(output, None, 225) # test soft dust limit with insufficient fee amount = soft_dust_limit - koinu change = ten - amount - relay_fee_per_byte * 225 - soft_dust_limit + koinu output = { self.tgtAddr : amount, self.srcAddr: change } - self.run_relay_test(output, 66) + self.run_relay_test(output, 66, 225) # test a 1 koinu output with sufficient fee amount = koinu - change = ten - amount - relay_fee_per_byte * 226 - soft_dust_limit + change = ten - amount - relay_fee_per_byte * 225 - soft_dust_limit output = { self.tgtAddr : amount, self.srcAddr: change } - self.run_relay_test(output, 64) # 64 = dust + self.run_relay_test(output, 64, 225) # 64 = dust # test a 1 koinu output with insufficient fee amount = koinu change = ten - amount - relay_fee_per_byte * 225 - soft_dust_limit + koinu output = { self.tgtAddr : amount, self.srcAddr: change } - self.run_relay_test(output, 64) + self.run_relay_test(output, 64, 225) # test mempool acceptance and relay outcomes - def run_relay_test(self, output, expected_reject_code): + def run_relay_test(self, output, expected_reject_code=None, expected_size=None): num_rejects = len(self.sendNode.rejects) - tx = self.spend_utxo(output) + tx = self.spend_utxo(output, expected_size) self.sendNode.sync_with_ping(timeout=10) if (expected_reject_code is None): @@ -190,12 +190,21 @@ class P2PPolicyTests(BitcoinTestFramework): return tx # spend seed money with a key not in the Dogecoin Core wallet. - def spend_utxo(self, output): + def spend_utxo(self, output, expected_size, retries=0): # construct the transaction using Dogecoin Core raw tx APIs input = [{ "txid": self.utxo.pop(), "vout": 0, "scriptPubKey": self.srcOutScript }] rawtx = self.nodes[0].createrawtransaction(input, output) signed_tx = self.nodes[0].signrawtransaction(rawtx, input, [self.srcPrivKey]) + # in case we have a smaller or larger tx due to unexpected R size, + # try again, with a limit of 20 times + if (expected_size is not None and len(signed_tx['hex']) != expected_size * 2): + self.utxo.insert(0, input[0]['txid']) + retries += 1 + if retries >= 20: + raise AssertionError("Too many retries") + return self.spend_utxo(output, expected_size, retries) + # import the signed tx into a format the mininode client understands # and send the tx from there rather than from Dogecoin Core, to test # mempool acceptance as it would happen on mainnet: through relay