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. 
CScript script_pub_key = GetScriptForDestination(pkhash);
    for (const auto& spk_man_pair  m_spk_managers) {
        if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
            LOCK(cs_wal);  // Descrip
            return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
        }
    }
    return SigningResultPRIVATE_KEY_NOT_AVAILABLE;
}
OutputType CWalTransactionChangeType(const stdoptional<OutputType>& change_type, const stdvector<CRecipient>& vecSend) const
{
    //  -changetype is specified, always use that change type.
    if (change_type) {
        return *change_type;
    }
    // if m_default_address_type is legacy, use legacy address as change.
    if (m_default_address_type == OutputTypeLEGACY) {
        return OutputTypeLEGACY;
    }
    bool any_tr{false};
    bool any_wpkh{false};
    bool any_sh{false};
    bool any_pkh{false};
    for (const auto& recipient  vecSend) {
        stdvector<stdvector<uint8_t>> dummy;
        const TxoutType type{Solver(recipient.scriptPubKey, dummy)};
        if (type == TxoutTypeWITNESS_V1_TAPROOT) {
            any_tr = true;
        } else if (type == TxoutTypeWITNESS_V0_KEYHASH) {
            any_wpkh = true;