(self)
| 85 | self.test_rbf() |
| 86 | |
| 87 | def test_independent(self): |
| 88 | self.log.info("Test multiple independent transactions in a package") |
| 89 | node = self.nodes[0] |
| 90 | # For independent transactions, order doesn't matter. |
| 91 | self.assert_testres_equal(self.independent_txns_hex, self.independent_txns_testres) |
| 92 | |
| 93 | self.log.info("Test an otherwise valid package with an extra garbage tx appended") |
| 94 | garbage_tx = node.createrawtransaction([{"txid": "00" * 32, "vout": 5}], [{self.address: 1}]) |
| 95 | tx = tx_from_hex(garbage_tx) |
| 96 | # Only the txid and wtxids are returned because validation is incomplete for the independent txns. |
| 97 | # Package validation is atomic: if the node cannot find a UTXO for any single tx in the package, |
| 98 | # it terminates immediately to avoid unnecessary, expensive signature verification. |
| 99 | package_bad = self.independent_txns_hex + [garbage_tx] |
| 100 | testres_bad = self.independent_txns_testres_blank + [{"txid": tx.rehash(), "wtxid": tx.getwtxid(), "allowed": False, "reject-reason": "missing-inputs"}] |
| 101 | self.assert_testres_equal(package_bad, testres_bad) |
| 102 | |
| 103 | self.log.info("Check testmempoolaccept tells us when some transactions completed validation successfully") |
| 104 | coin = self.coins.pop() |
| 105 | tx_bad_sig_hex = node.createrawtransaction([{"txid": coin["txid"], "vout": 0}], |
| 106 | [{self.address : coin["amount"] - Decimal("0.0001")}, {"fee" : Decimal("0.0001") }]) |
| 107 | tx_bad_sig = tx_from_hex(tx_bad_sig_hex) |
| 108 | testres_bad_sig = node.testmempoolaccept(self.independent_txns_hex + [tx_bad_sig_hex]) |
| 109 | # By the time the signature for the last transaction is checked, all the other transactions |
| 110 | # have been fully validated, which is why the node returns full validation results for all |
| 111 | # transactions here but empty results in other cases. |
| 112 | assert_equal(testres_bad_sig, self.independent_txns_testres + [{ |
| 113 | "txid": tx_bad_sig.rehash(), |
| 114 | "wtxid": tx_bad_sig.getwtxid(), "allowed": False, |
| 115 | "reject-reason": "mempool-script-verify-flag-failed (Operation not valid with the current stack size)" |
| 116 | }]) |
| 117 | |
| 118 | self.log.info("Check testmempoolaccept reports txns in packages that exceed max feerate") |
| 119 | coin = self.coins.pop() |
| 120 | tx_high_fee_raw = node.createrawtransaction([{"txid": coin["txid"], "vout": 0}], |
| 121 | [{self.address : coin["amount"] - Decimal("0.999")}, {"fee" : Decimal("0.999")}]) |
| 122 | tx_high_fee_signed = node.signrawtransactionwithkey(hexstring=tx_high_fee_raw, privkeys=self.privkeys) |
| 123 | assert tx_high_fee_signed["complete"] |
| 124 | tx_high_fee = tx_from_hex(tx_high_fee_signed["hex"]) |
| 125 | testres_high_fee = node.testmempoolaccept([tx_high_fee_signed["hex"]]) |
| 126 | assert_equal(testres_high_fee, [ |
| 127 | {"txid": tx_high_fee.rehash(), "wtxid": tx_high_fee.getwtxid(), "allowed": False, "reject-reason": "max-fee-exceeded"} |
| 128 | ]) |
| 129 | package_high_fee = [tx_high_fee_signed["hex"]] + self.independent_txns_hex |
| 130 | testres_package_high_fee = node.testmempoolaccept(package_high_fee) |
| 131 | assert_equal(testres_package_high_fee, testres_high_fee + self.independent_txns_testres_blank) |
| 132 | |
| 133 | def test_chain(self): |
| 134 | node = self.nodes[0] |
no test coverage detected