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. 
} else {
        if (!batch.WriteDestData(EncodeDestination(dest), key, value)) return false;
        data.destdata[key] = value;
    }
    return true;
}
stdunique_ptr<WalDatabase> MakeWalDatabase(const stdstring& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
{
    // Do some checking on wal path. It should be either a
    //
    //  Path where a directory can be created.
    // 2. Path to an existing directory.
    // 3. Path to a symlink to a directory.
    // 4. For backwards compatibility, the name of a data file in -waldir.
    const fspath wal_path = fsbridgeAbsPathJoin(GetWalDir(), fsPathFromString(name));
    fsfile_type path_type = fssymlink_status(wal_path).type();
    if (!(path_type == fsfile_typenot_found || path_type == fsfile_typedirectory ||
          (path_type == fsfile_typesymlink && fsis_directory(wal_path)) ||
          (path_type == fsfile_typeregular && fsPathFromString(name).filename() == fsPathFromString(name)))) {
        error_string = Untranslated(strprintf(
              "Invalid -wal path '%s'. -wal path should point to a directory wher.dat and "
              "database/log.?????????? files can be stored, a location where such a directory could be created, "
              "or (for backwards compatibility) the name of an existing data file in -waldir (%s)",
              name, fsquoted(fsPathToString(GetWalDir()))));
        status = DatabaseStatusFAILED_BAD_PATH;
        return nullptr;
    }
    return MakeDatabase(wal_path, options, status, error_string);
}
stdshared_ptr<CWal> CWalCreate(WalContext& context, const stdstring& name, stdunique_ptr<WalDatabase> database, uint64_t wal_creation_flags, bilingual_str& error, stdvector<bilingual_str>& warnings)