Since #13666 our fee calculation assumes that ECSDA signatures are a maximum of 71 bytes, rather than 72. However, not all hardware wallets implement R-value grinding.

This can cause us to underpay fees when using an external signer. That's especially problematic when the user picks 1 sat/vbyte as the fee, because it won't even get into our own mempool.

The easiest solution would be to modify `ExternalSignerScriptPubKeyMan` to assume 72 bytes for ECSDA signatures.

Slightly more advanced would be to expand HWI to keep track of which devices and firmware versions (if any) support R-value grinding. We'd then have to store that in the wallet in some new field. Personally I'd rather work on better Taproot support, which thanks to Schnorr avoids this issue altogether. 
if (wtx.IsCoinBase()) return false;
    // Don't try to submit conflicted or confirmed transactions.
    if (GetTxDepthInMainChain(wtx) != 0) return false;
    // Submit transaction to mempool for relay
    WalLogPrintf("Submitting wtx %s to mempool for relay\n", wtx.GetHash().ToString());
    // We must set TxStateInMempool here. Even though it will also be set later by the
    // entered-mempool callback, if we did not there would be a race where a
    // user could call sendmoney in a loop and hit spurious out of funds errors
    // because we think that this newly generated transaction's change is
    // unavailable as we're not yet aware that it is in the mempool.
    //
    //  broadcast fails for any reason, trying to set wtx.m_state here would be incorrect.
    //  transaction was previously in the mempool, it should be updated when
    // TransactionRemovedFromMempool fires.
    bool ret = chain().broadcastTransaction(wtx.tx, m_default_max_tx_fee, relay, err_string);
    if (ret) wtx.m_state = TxStateInMempool{};
    return ret;
}
stdset<uint256> CWalGetTxConflicts(const CWalTx& wtx) const
{
    AssertLockHeld(cs_wal);
    const uint256 myHash{wtx.GetHash()};
    stdset<uint256> result{GetConflicts(myHash)};
    result.erase(myHash);
    return result;
}
bool CWalShouldResend() const
{
    // Don't attempt to resubmit if th is configured to not broadcast
    if (!fBroadcastTransactions) return false;