jmcore.fee_quantization
jmcore.fee_quantization
Maker fee quantization grid and helpers.
Background
Each maker advertises a per-CoinJoin fee policy. Because policies on the live network are diverse, the realized fee paid to each maker slot is typically unique within a round. A passive on-chain observer can use that uniqueness to attribute an equal output to a specific maker slot when it is reused in a downstream CoinJoin (see issue #508).
The mitigation is fee homogenization: if every maker slot in a round is paid the same effective fee, the within-round fingerprint disappears and the attribution stops working. To make that fee land on a small, shared, public set of values (so it is also stable across rounds and takers), we round fees onto a coarse base-10 grid.
This module only defines the grid and the rounding primitives. The taker-side policy that selects a per-round quantum and the per-slot homogenized fee lives in the taker package; the orderbook watcher uses the same grid (exposed in its JSON payload) to chart where maker offers land.
Attributes
QUANT_ABS: tuple[int, ...] = (0, 100, 200, 500, 1000, 2000, 5000, 10000)
module-attribute
QUANT_REL: tuple[Decimal, ...] = tuple((Decimal(v)) for v in ('0.00002', '0.00005', '0.0001', '0.0002', '0.0005', '0.001', '0.002', '0.005', '0.01', '0.02', '0.05', '0.1'))
module-attribute
Functions:
quantize_abs_down(abs_fee: int) -> int | None
Return the largest absolute grid value <= abs_fee.
Returns None only when abs_fee is negative (no grid value fits);
the grid includes 0 so any non-negative fee resolves to a quantum.
Source code in jmcore/src/jmcore/fee_quantization.py
70 71 72 73 74 75 76 77 78 79 80 81 82 | |
quantize_abs_up(abs_fee: int) -> int | None
Return the smallest absolute grid value >= abs_fee.
Returns None when abs_fee exceeds the largest grid value.
Source code in jmcore/src/jmcore/fee_quantization.py
97 98 99 100 101 102 103 104 105 | |
quantize_rel_down(rel_fee: str | float | Decimal) -> Decimal | None
Return the largest grid value <= rel_fee.
Returns None when rel_fee is below the smallest grid value, meaning
no quantum fits under the configured limit and quantization cannot apply.
Source code in jmcore/src/jmcore/fee_quantization.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
quantize_rel_up(rel_fee: str | float | Decimal) -> Decimal | None
Return the smallest grid value >= rel_fee.
Returns None when rel_fee exceeds the largest grid value.
Source code in jmcore/src/jmcore/fee_quantization.py
85 86 87 88 89 90 91 92 93 94 | |
rel_quantum_to_sats(rel_quantum: Decimal, cj_amount: int) -> int
Convert a relative quantum to satoshis for a given CoinJoin amount.
Uses banker's rounding (ROUND_HALF_EVEN) to match
:func:jmcore.bitcoin.calculate_relative_fee.
Source code in jmcore/src/jmcore/fee_quantization.py
108 109 110 111 112 113 114 | |