(self)
| 144 | self.generate(self.wallet, 1, sync_fun=self.no_op) |
| 145 | |
| 146 | def test_blockmintxfee_parameter(self): |
| 147 | self.log.info("Test -blockmintxfee setting") |
| 148 | self.restart_node(0, extra_args=['-minrelaytxfee=0', '-persistmempool=0']) |
| 149 | node = self.nodes[0] |
| 150 | |
| 151 | # test default (no parameter), zero and a bunch of arbitrary blockmintxfee rates [sat/kvB] |
| 152 | for blockmintxfee_sat_kvb in (DEFAULT_BLOCK_MIN_TX_FEE, 0, 5, 10, 50, 100, 500, 1000, 2500, 5000, 21000, 333333, 2500000): |
| 153 | blockmintxfee_btc_kvb = blockmintxfee_sat_kvb / Decimal(COIN) |
| 154 | if blockmintxfee_sat_kvb == DEFAULT_BLOCK_MIN_TX_FEE: |
| 155 | self.log.info(f"-> Default -blockmintxfee setting ({blockmintxfee_sat_kvb} sat/kvB)...") |
| 156 | else: |
| 157 | blockmintxfee_parameter = f"-blockmintxfee={blockmintxfee_btc_kvb:.8f}" |
| 158 | self.log.info(f"-> Test {blockmintxfee_parameter} ({blockmintxfee_sat_kvb} sat/kvB)...") |
| 159 | self.restart_node(0, extra_args=[blockmintxfee_parameter, '-minrelaytxfee=0', '-persistmempool=0']) |
| 160 | assert_equal(node.getmininginfo()['blockmintxfee'], blockmintxfee_btc_kvb) |
| 161 | |
| 162 | # submit one tx with exactly the blockmintxfee rate, and one slightly below |
| 163 | tx_with_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb, confirmed_only=True) |
| 164 | assert_equal(tx_with_min_feerate["fee"], get_fee(tx_with_min_feerate["tx"].get_vsize(), blockmintxfee_btc_kvb)) |
| 165 | if blockmintxfee_sat_kvb >= 10: |
| 166 | lowerfee_btc_kvb = blockmintxfee_btc_kvb - Decimal(10)/COIN # 0.01 sat/vbyte lower |
| 167 | assert_greater_than(blockmintxfee_btc_kvb, lowerfee_btc_kvb) |
| 168 | assert_greater_than_or_equal(lowerfee_btc_kvb, 0) |
| 169 | tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=lowerfee_btc_kvb, confirmed_only=True) |
| 170 | assert_equal(tx_below_min_feerate["fee"], get_fee(tx_below_min_feerate["tx"].get_vsize(), lowerfee_btc_kvb)) |
| 171 | else: # go below zero fee by using modified fees |
| 172 | tx_below_min_feerate = self.wallet.send_self_transfer(from_node=node, fee_rate=blockmintxfee_btc_kvb, confirmed_only=True) |
| 173 | node.prioritisetransaction(tx_below_min_feerate["txid"], 0, -11) |
| 174 | |
| 175 | # check that tx below specified fee-rate is neither in template nor in the actual block |
| 176 | block_template = node.getblocktemplate(NORMAL_GBT_REQUEST_PARAMS) |
| 177 | block_template_txids = [tx['txid'] for tx in block_template['transactions']] |
| 178 | |
| 179 | # Unless blockmintxfee is 0, the template shouldn't contain free transactions. |
| 180 | # Note that the real block assembler uses package feerates, but we didn't create dependent transactions so it's ok to use base feerate. |
| 181 | if blockmintxfee_btc_kvb > 0: |
| 182 | for txid in block_template_txids: |
| 183 | tx = node.getmempoolentry(txid) |
| 184 | assert_greater_than(tx['fees']['base'], 0) |
| 185 | |
| 186 | self.generate(self.wallet, 1, sync_fun=self.no_op) |
| 187 | block = node.getblock(node.getbestblockhash(), verbosity=2) |
| 188 | block_txids = [tx['txid'] for tx in block['tx']] |
| 189 | |
| 190 | assert tx_with_min_feerate['txid'] in block_template_txids |
| 191 | assert tx_with_min_feerate['txid'] in block_txids |
| 192 | assert tx_below_min_feerate['txid'] not in block_template_txids |
| 193 | assert tx_below_min_feerate['txid'] not in block_txids |
| 194 | |
| 195 | # Restart node to clear mempool for the next test |
| 196 | self.restart_node(0) |
| 197 | |
| 198 | def test_timewarp(self): |
| 199 | self.log.info("Test timewarp attack mitigation (BIP94)") |
no test coverage detected