Skip to content

jmcore.fee_policy

jmcore.fee_policy

Shared minimum miner-fee policy for CoinJoin participants.

Classes

MinimumFeeRateExceedsCapError

Bases: ValueError

Raised when a required minimum fee rate exceeds the configured cap.

Source code in jmcore/src/jmcore/fee_policy.py
12
13
14
15
16
17
18
class MinimumFeeRateExceedsCapError(ValueError):
    """Raised when a required minimum fee rate exceeds the configured cap."""

    def __init__(self, *, source: str, fee_rate: float) -> None:
        self.source = source
        self.fee_rate = fee_rate
        super().__init__(f"Minimum fee rate from {source} exceeds the configured maximum fee rate")
Attributes
fee_rate = fee_rate instance-attribute
source = source instance-attribute
Methods:
__init__(*, source: str, fee_rate: float) -> None
Source code in jmcore/src/jmcore/fee_policy.py
15
16
17
18
def __init__(self, *, source: str, fee_rate: float) -> None:
    self.source = source
    self.fee_rate = fee_rate
    super().__init__(f"Minimum fee rate from {source} exceeds the configured maximum fee rate")

Functions:

estimate_p2wpkh_vsize(num_inputs: int, num_outputs: int) -> int

Return the conservative P2WPKH virtual-size estimate used by CoinJoin.

Source code in jmcore/src/jmcore/fee_policy.py
21
22
23
def estimate_p2wpkh_vsize(num_inputs: int, num_outputs: int) -> int:
    """Return the conservative P2WPKH virtual-size estimate used by CoinJoin."""
    return num_inputs * 68 + num_outputs * 31 + 11

fee_rate_meets_minimum(fee: int, vsize: int, minimum_fee_rate: float) -> bool

Check whether an integer fee meets the exact minimum fee rate.

Source code in jmcore/src/jmcore/fee_policy.py
26
27
28
def fee_rate_meets_minimum(fee: int, vsize: int, minimum_fee_rate: float) -> bool:
    """Check whether an integer fee meets the exact minimum fee rate."""
    return fee >= 0 and vsize > 0 and fee >= minimum_fee_rate * vsize

resolve_min_fee_rate(backend: Any, *, static_floor: float, block_target: int, max_fee_rate: float) -> float async

Resolve the maximum of static, mempool, and estimate fee floors within the cap.

Source code in jmcore/src/jmcore/fee_policy.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
async def resolve_min_fee_rate(
    backend: Any,
    *,
    static_floor: float,
    block_target: int,
    max_fee_rate: float,
) -> float:
    """Resolve the maximum of static, mempool, and estimate fee floors within the cap."""
    if not _is_finite_positive(static_floor):
        raise ValueError("Minimum fee static floor must be a finite positive sat/vB value")
    if not _is_finite_positive(max_fee_rate):
        raise ValueError("Maximum fee rate must be a finite positive sat/vB value")
    sources: list[tuple[str, float]] = [("static floor", static_floor)]

    try:
        mempool_minimum = await backend.get_mempool_min_fee()
        if mempool_minimum is not None:
            if _is_finite_positive(mempool_minimum):
                sources.append(("mempool minimum", mempool_minimum))
            else:
                logger.warning("Ignoring invalid local mempool minimum fee rate")
    except Exception as exc:
        logger.warning(f"Could not resolve local mempool minimum fee rate: {exc}")

    try:
        can_estimate = backend.can_estimate_fee()
        if isawaitable(can_estimate):
            can_estimate = await can_estimate
        if can_estimate:
            estimate = await backend.estimate_fee(block_target)
            if _is_finite_positive(estimate):
                sources.append(("backend estimate", estimate))
            else:
                logger.warning("Ignoring invalid fee estimate for minimum miner-fee policy")
    except Exception as exc:
        logger.warning(f"Could not resolve fee estimate for minimum miner-fee policy: {exc}")

    source, minimum_fee_rate = max(sources, key=lambda source_and_rate: source_and_rate[1])
    if minimum_fee_rate > max_fee_rate:
        raise MinimumFeeRateExceedsCapError(source=source, fee_rate=minimum_fee_rate)
    return minimum_fee_rate