Repository: bitcoin/bitcoin
File: test/functional/test_framework/util.py (Python)

Code before:


def softfork_active(node, key):
    """Return whether a softfork is active."""
    return node.getdeploymentinfo()['deployments'][key]['active']


def set_node_times(nodes, t):
    for node in nodes:
        node.setmocktime(t)


def check_node_connections(*, node, num_in, num_out):
    info = node.getnetworkinfo()
    assert_equal(info["connections_in"], num_in)
    assert_equal(info["connections_out"], num_out)


# Transaction/Block functions
#############################


# Create large OP_RETURN txouts that can be appended to a transaction
# to make it large (helper for constructing large transactions). The
# total serialized size of the txouts is about 66k vbytes.
def gen_return_txouts():
    from .messages import CTxOut
    from .script import CScript, OP_RETURN
    txouts = [CTxOut(nValue=0, scriptPubKey=CScript([OP_RETURN, b'\x01'*67437]))]
    assert_equal(sum([len(txout.serialize()) for txout in txouts]), 67456)
    return txouts


# Create a spend of each passed-in utxo, splicing in "txouts" to each raw
# transaction to make it large.  See gen_return_txouts() above.
def create_lots_of_big_transactions(mini_wallet, node, fee, tx_batch_size, txouts, utxos=None):
    txids = []
    use_internal_utxos = utxos is None
    for _ in range(tx_batch_size):
        tx = mini_wallet.create_self_transfer(
            utxo_to_spend=None if use_internal_utxos else utxos.pop(),
            fee=fee,
        )["tx"]
        tx.vout.extend(txouts)
        res = node.testmempoolaccept([tx.serialize().hex()])[0]
        assert_equal(res['fees']['base'], fee)
        txids.append(node.sendrawtransaction(tx.serialize().hex()))
    return txids


def mine_large_block(test_framework, mini_wallet, node):

Review comment (suggestion):
Maybe assert for this at the beginning of the `fill_mempool`
```python
     assert_equal(node.getnetworkinfo()['relayfee'], Decimal('0.00001000'))
```

Code after:


def softfork_active(node, key):
    """Return whether a softfork is active."""
    return node.getdeploymentinfo()['deployments'][key]['active']


def set_node_times(nodes, t):
    for node in nodes:
        node.setmocktime(t)


def check_node_connections(*, node, num_in, num_out):
    info = node.getnetworkinfo()
    assert_equal(info["connections_in"], num_in)
    assert_equal(info["connections_out"], num_out)

def fill_mempool(test_framework, node, miniwallet):
    """Fill mempool until eviction.

    Allows for simpler testing of scenarios with floating mempoolminfee > minrelay
    Requires -datacarriersize=100000 and
   -maxmempool=5.
    It will not ensure mempools become synced as it
    is based on a single node and assumes -minrelaytxfee
    is 1 sat/vbyte.
    """
    test_framework.log.info("Fill the mempool until eviction is triggered and the mempoolminfee rises")
    txouts = gen_return_txouts()
    relayfee = node.getnetworkinfo()['relayfee']

    assert_equal(relayfee, Decimal('0.00001000'))

    tx_batch_size = 1
    num_of_batches = 75
    # Generate UTXOs to flood the mempool
    # 1 to create a tx initially that will be evicted from the mempool later
    # 75 transactions each with a fee rate higher than the previous one
    test_framework.generate(miniwallet, 1 + (num_of_batches * tx_batch_size))

    # Mine COINBASE_MATURITY - 1 blocks so that the UTXOs are allowed to be spent
    test_framework.generate(node, 100 - 1)

    test_framework.log.debug("Create a mempool tx that will be evicted")
    tx_to_be_evicted_id = miniwallet.send_self_transfer(from_node=node, fee_rate=relayfee)["txid"]

    # Increase the tx fee rate to give the subsequent transactions a higher priority in the mempool
    # The tx has an approx. vsize of 65k, i.e. multiplying the previous fee rate (in sats/kvB)
    # by 130 should result in a fee that corresponds to 2x of that fee rate
    base_fee = relayfee * 130