Use 73 bytes der-encoded signatures in weight estimation (#3210)
What changed, and why it matters
This commit adjusts how Eclair estimates the 'weight' (a measure of transaction size used to calculate Bitcoin mining fees) for funding inputs in Lightning channel transactions. It increases the assumed signature size from 72 to 73 bytes, matching what the Lightning specification recommends and what other implementations like LDK use. The change is defensive: it helps prevent Eclair's interactive transaction proposals from being rejected by peers who think Eclair is under-paying fees, and it avoids edge cases where miners might accept a slightly larger signature than Eclair accounted for.
Treat as a routine correctness/defensive patch. Update nodes to include the revised weight estimation to avoid interactive-tx failures with LDK and other BOLT-compliant peers. No emergency response is warranted; there is no evidence of an exploitable vulnerability in signature handling itself.
Security signals we found
Fee-estimation mismatch between implementations could cause interactive-tx negotiation failures
Under-estimated weight could lead to insufficient fees if a 73-byte high-S signature is accepted by miners
Change aligns with BOLT 3 recommendation and LDK behavior
No signature validation or cryptography change; only weight accounting
Evidence from the diff
The patch changes fundingInputWeight in SegwitV0CommitmentFormat from 384 to 386, reflecting a 73-byte DER-encoded ECDSA signature in the witness instead of 72 bytes. The comment cites BOLT 3 appendix A: funding_input_weight = 4 * 41 + 222 = 386. The test tolerance for anchor-output commitment formats is widened from ±3 to ±4 to accommodate the revised baseline. This is a weight-estimation correction, not a consensus or signature-validation change; Eclair still only produces low-S 72-byte signatures itself.
Changed components
eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scalaeclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scalaSegwitV0CommitmentFormat funding input weight estimationInteractive transaction (interactive-tx) fee negotiationInspect captured patch +5 / −3
diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
index 2375315..0a9e5f3 100644
--- a/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
+++ b/eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala
@@ -97,7 +97,9 @@ object Transactions {
}
sealed trait SegwitV0CommitmentFormat extends CommitmentFormat {
- override val fundingInputWeight = 384
+ // see https://github.com/lightning/bolts/blob/master/03-transactions.md#appendix-a-expected-weights
+ // funding input weight = 4 * funding_input_size + witness_size = 4 * 41 + 222 = 386
+ override val fundingInputWeight = 386
}
/**
diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala
index 9d33fd6..097151a 100644
--- a/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala
+++ b/eclair-core/src/test/scala/fr/acinq/eclair/transactions/TransactionsSpec.scala
@@ -152,8 +152,8 @@ class TransactionsSpec extends AnyFunSuite with Logging {
case _: SimpleTaprootChannelCommitmentFormat => assert(actual == expected)
case _: AnchorOutputsCommitmentFormat =>
// ECDSA signatures are der-encoded, which creates some variability in signature size compared to the baseline.
- assert(actual <= expected + 3)
- assert(actual >= expected - 3)
+ assert(actual <= expected + 4)
+ assert(actual >= expected - 4)
}
}
Why this scored 35/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.