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

Code before:
        last_feerate = feerate

        if i == 0:
            assert_equal(e["blocks"], 2)
        else:
            assert_greater_than_or_equal(i + 1, e["blocks"])


def check_estimates(node, fees_seen):
    check_raw_estimates(node, fees_seen)
    check_smart_estimates(node, fees_seen)


def make_tx(wallet, utxo, feerate):
    """Create a 1in-1out transaction with a specific input and feerate (sat/vb)."""
    return wallet.create_self_transfer(
        utxo_to_spend=utxo,
        fee_rate=Decimal(feerate * 1000) / COIN,
    )


class EstimateFeeTest(BitcoinTestFramework):
    def set_test_params(self):
        self.num_nodes = 3
        # whitelist peers to speed up tx relay / mempool sync
        self.noban_tx_relay = True
        self.extra_args = [
            [],
            ["-blockmaxweight=68000"],
            ["-blockmaxweight=32000"],
        ]

    def setup_network(self):
        """
        We'll setup the network to have 3 nodes that all mine with different parameters.
        But first we need to use one node to create a lot of outputs
        which we will use to generate our transactions.
        """
        self.add_nodes(3, extra_args=self.extra_args)
        # Use node0 to mine blocks for input splitting
        # Node1 mines small blocks but that are bigger than the expected transaction rate.
        # NOTE: the CreateNewBlock code starts counting block weight at 4,000 weight,
        # (68k weight is room enough for 120 or so transactions)
        # Node2 is a stingy miner, that
        # produces too small blocks (room for only 55 or so transactions)

    def transact_and_mine(self, numblocks, mining_node):
        min_fee = Decimal("0.00001")
        # We will now mine numblocks blocks generating on average 100 transactions between each block
        # We shuffle our confirmed txout set before each set of transactions
        # small_txpuzzle_randfee will use the transactions that have inputs already in the chain when possible

Review comment (suggestion):
nit: this could be more future-proof and self-documenting:

```suggestion
    fee_est_conservative = node.estimatesmartfee(1, estimate_mode="conservative")['feerate']
    fee_est_economical = node.estimatesmartfee(1, estimate_mode="economical")['feerate']
    fee_est_default = node.estimatesmartfee(1)['feerate']
    assert_equal(fee_est_conservative, expected_conservative)
    assert_equal(fee_est_economical, expected_economical)
    assert_equal(fee_est_default, expected_economical)
```

Code after:
        last_feerate = feerate

        if i == 0:
            assert_equal(e["blocks"], 2)
        else:
            assert_greater_than_or_equal(i + 1, e["blocks"])


def check_estimates(node, fees_seen):
    check_raw_estimates(node, fees_seen)
    check_smart_estimates(node, fees_seen)


def make_tx(wallet, utxo, feerate):
    """Create a 1in-1out transaction with a specific input and feerate (sat/vb)."""
    return wallet.create_self_transfer(
        utxo_to_spend=utxo,
        fee_rate=Decimal(feerate * 1000) / COIN,
    )

def check_fee_estimates_btw_modes(node, expected_conservative, expected_economical):
    fee_est_conservative = node.estimatesmartfee(1, estimate_mode="conservative")['feerate']
    fee_est_economical = node.estimatesmartfee(1, estimate_mode="economical")['feerate']
    fee_est_default = node.estimatesmartfee(1)['feerate']
    assert_equal(fee_est_conservative, expected_conservative)
    assert_equal(fee_est_economical, expected_economical)
    assert_equal(fee_est_default, expected_economical)


class EstimateFeeTest(BitcoinTestFramework):
    def set_test_params(self):
        self.num_nodes = 3
        # whitelist peers to speed up tx relay / mempool sync
        self.noban_tx_relay = True
        self.extra_args = [
            [],
            ["-blockmaxweight=68000"],
            ["-blockmaxweight=32000"],
        ]

    def setup_network(self):
        """
        We'll setup the network to have 3 nodes that all mine with different parameters.
        But first we need to use one node to create a lot of outputs
        which we will use to generate our transactions.
        """
        self.add_nodes(3, extra_args=self.extra_args)
        # Use node0 to mine blocks for input splitting
        # Node1 mines small blocks but that are bigger than the expected transaction rate.
        # NOTE: the CreateNewBlock code starts counting block weight at 4,000 weight,
        # (68k weight is room enough for 120 or so transactions)