From 6d7fccc7227ea03a05b70d3436f6bf18d37ac917 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Tue, 29 Oct 2024 11:54:34 +0100 Subject: [PATCH] Fix fee estimation when using ECDSA signatures --- packages/cashscript/src/Transaction.ts | 17 +++++++++++++---- packages/utils/src/bip68.ts | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/cashscript/src/Transaction.ts b/packages/cashscript/src/Transaction.ts index 9bae0bc2..f5c78fec 100644 --- a/packages/cashscript/src/Transaction.ts +++ b/packages/cashscript/src/Transaction.ts @@ -21,6 +21,7 @@ import { isUtxoP2PKH, TransactionDetails, Unlocker, + SignatureAlgorithm, } from './interfaces.js'; import { createInputScript, @@ -336,10 +337,18 @@ export class Transaction { } } - // Replace all SignatureTemplate with 65-length placeholder Uint8Arrays - const placeholderArgs = this.encodedFunctionArgs.map((arg) => ( - arg instanceof SignatureTemplate ? placeholder(65) : arg - )); + // Replace all SignatureTemplate with placeholder Uint8Arrays + const placeholderArgs = this.encodedFunctionArgs.map((arg) => { + if (!(arg instanceof SignatureTemplate)) return arg; + + // Schnorr signatures are *always* 65 bytes: 64 for signature + 1 byte for hashtype. + if (arg.getSignatureAlgorithm() === SignatureAlgorithm.SCHNORR) return placeholder(65); + + // ECDSA signatures are at least 71 bytes: 64 bytes for signature + 1 byte for hashtype + 6 bytes for encoding + // overhead. But it may have up to 2 extra bytes for padding, so we overestimate by 2 bytes. + // (see https://transactionfee.info/charts/bitcoin-script-ecdsa-length/) + return placeholder(73); + }); // Create a placeholder preimage of the correct size const placeholderPreimage = this.abiFunction.covenant diff --git a/packages/utils/src/bip68.ts b/packages/utils/src/bip68.ts index 46763061..1c31fc4b 100644 --- a/packages/utils/src/bip68.ts +++ b/packages/utils/src/bip68.ts @@ -1,5 +1,5 @@ // Code taken and adapted from https://github.com/bitcoinjs/bip68 -// If we make signficant changes to this code, we should also take and adapt the tests from that repository. +// If we make significant changes to this code, we should also take and adapt the tests from that repository. // see https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki#compatibility