Skip to content

DOGE: native-fee output under 0.01 DOGE is emitted without the soft-dust fee, so the tx sits in the mempool and is never mined #23

Open

Description

@pataegrillo

What happens

On Dogecoin, the native-coin protocol fee is added to the tx as a feeQuote / FEE_DESTINATION output. When the quoted fee is under 0.01 DOGE, that output is a soft-dust output, and the encoder builds the tx with the normal miner fee only. The tx is accepted by our testnet node but no miner picks it up.

Seen on DOGE testnet, 2026-10-15, placing a BET from the wallet (BetFeedDetail form, market #5435):

tx size protocol-fee output miner fee rate result
BET placed from the BET form 6f5cd285f5ab63de40c8947c0e72a8738d182d79fb96523b3cd9344e58000eb5 255 B 0.00986772 DOGE 0.00702325 DOGE 0.0275 DOGE/kB in the node mempool since block 67998665, still unmined 260+ blocks later
Same action (BET v2), Advanced action form, Normal fee bc718dcef8e22f4f711f9c6f156c143b4daf09307703cba7ad0a807fae7e77c0 same shape 0.00984791 DOGE 0.296 DOGE (from the Confirm screen) ~1.1 DOGE/kB mined about 2 minutes later, BET #5439 valid

The rate is not what keeps the first one out: the market-creation tx for the same market (c6147ce7…, 332 B, no fee output) paid only 0.0124 DOGE/kB and was mined, and the stuck BET pays 0.0275 DOGE/kB. The only thing the stuck tx has that the mined low-rate one does not is the sub-0.01 output with a miner fee under 0.01 DOGE.

The stuck tx also holds the sender's only UTXO, so that address cannot do anything else until it expires.

Cause (what I could confirm in code)

xchain-encoder already documents the rule, and has a test for it on outputs it authors itself:

  • SOFT_DUST_FLOOR_BY_COIN comment: Dogecoin relays an output under its 0.01 DOGE soft dust limit only if the whole limit is added to the fee. (src/XChainEncoder/constants.js L54-L59)
  • test/unit/xchain_encoder/xchain_encoder_soft_dust_floor.test.js: "...per output".

But the native-fee output is not an output the encoder authors with that floor:

  • It is appended as a custom output: customOutputs.push({ address: feeQuote.address, value: feeQuote.amount }) (src/XChainEncoder/build_transaction/payload_checks.js L82).
  • Custom outputs are only rejected when value <= 0, deliberately, so that "sub-dust-but-positive DOGE fee values keep working" (src/common/validator/fee_and_utxo_checks.js L225-L229, src/XChainEncoder/build_transaction/data_outputs.js L302-L303).
  • The fee-rate resolution only uses the node estimate (clamped on test chains) and never adds anything per soft-dust output (src/XChainEncoder/build_transaction/fee_rates.js).

So the output value is allowed to be sub-dust (it has to match the indexer's quoted fee), but the miner fee is never raised by 0.01 DOGE to pay for it.

Reproduction (encoder alone, no chain)

xchain-encoder at origin/master 8033833 (v0.23.0), network dogecoin-testnet, one 0.9676 DOGE input, node estimate 0.01 DOGE/kB, 296-byte tx, createTransaction(...) with feeQuote = { address, amount }:

feeOutput=986772 sat  outs=[0,986772,95478248]  minerFee=296000 sat
feeOutput=1000000 sat outs=[0,1000000,95465020] minerFee=296000 sat
feeOutput=1500000 sat outs=[0,1500000,94965020] minerFee=296000 sat

The miner fee is the same whether the fee output is 0.00987, 0.01 or 0.015 DOGE. Nothing is added for the sub-0.01 one.

Not confirmed

  • I did not capture which node or relay hop drops it. Our own node (/Shibetoshi:1.14.9/, testnet) accepts it into its mempool; the rule above is the one the encoder's own comment and test describe.
  • The mined control differs from the stuck tx in miner fee by about 40x, not only by the 0.01 DOGE; I did not isolate "exactly 0.01 DOGE more" from "a higher rate". The market-creation tx above is the evidence that the rate alone is not the cause.

Impact

Any DOGE action paid with a native-coin protocol fee under 0.01 DOGE (cheap actions at current prices; the BET above was 0.0099) can end up stuck, and the wallet gives no sign of it beyond "waiting for a block". Fee-bearing actions on LTC/DOGE are native-fee only (see also xchain-sdk #22 / #25).

Related, wallet side (separate issue if you prefer)

BetFeedDetail.jsx and CreateBetFeedForm.jsx have no FeeSelector, and betActions.js only forwards fee/feePerKb if given, so BET place / create always use the encoder default (0.0275 and 0.0124 DOGE/kB observed here, vs 1 DOGE/kB on forms with the selector). Adding the missing 0.01 DOGE in the encoder would also make those forms' txs mineable.

Activity

  1. javiervarona commented on Oct 19, 2026

    @javiervarona

    Follow-up with a control case, same action and same form, on DOGE testnet.

    On 2026-10-19 I placed another BET from the wallet's BET form (market #5584, BET #5585). It differs from the stuck one in the protocol-fee output, which this time was above 0.01 DOGE:

    tx size protocol-fee output miner fee rate result
    Stuck (2026-10-15) 6f5cd285f5ab63de40c8947c0e72a8738d182d79fb96523b3cd9344e58000eb5 255 B 0.00986772 DOGE (under 0.01) 0.00702325 DOGE 0.0275 DOGE/kB never mined, gone from the node mempool by about 27 h later
    Control (2026-10-19) a058e41e30eee3121e4cabe44332ccd6fff0292dea87b63ba07bc8a9f565f1e0 255 B 0.0101008 DOGE (over 0.01) 0.00341549 DOGE 0.0134 DOGE/kB mined in about 2 minutes, BET #5585 valid

    The control pays about half the rate per kB of the stuck one and was mined, so the rate alone does not explain the stuck tx. The only thing that differs between the two is which side of 0.01 DOGE the fee output falls on. This is consistent with the soft-dust rule described in the issue. It still does not isolate "the missing 0.01 DOGE" as the exact cause: I could not force the protocol fee below 0.01 DOGE to repeat the stuck case, because the quote follows the DOGE price (0.0099 on 10-15, 0.0101 on 10-19).

    One more data point on the wallet side, since this affects whether users can work around it: forms without a fee selector (BET, create market, LIST rename, and others) all send at about 0.013 DOGE/kB, so the missing soft-dust fee and the low default rate add up. That part is in XChain-Platform/xchain-wallet#89.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions