Skip to content

Commit 4df0266

Browse files
committed
Use specific segwit and taproot input info types
We now use specific subtypes for segwit inputs (which include a redeem script) and taproot inputs (which include a script tree and an internal key). Older codecs have been modified to always return a SegwitInput. v4 codec is modified and uses an empty redeem script as a marker to specify that a script tree is being used, which makes it compatible with the current v4 codec.
1 parent e385171 commit 4df0266

File tree

12 files changed

+130
-92
lines changed

12 files changed

+130
-92
lines changed

eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,10 @@ case class Commitments(params: ChannelParams,
11421142
val localFundingKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, commitment.fundingTxIndex).publicKey
11431143
val remoteFundingKey = commitment.remoteFundingPubKey
11441144
val fundingScript = Script.write(Scripts.multiSig2of2(localFundingKey, remoteFundingKey))
1145-
commitment.commitInput.redeemScriptOrScriptTree == Left(fundingScript)
1145+
commitment.commitInput match {
1146+
case InputInfo.SegwitInput(_, _, redeemScript) => redeemScript == fundingScript
1147+
case _ => false
1148+
}
11461149
}
11471150
}
11481151

eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,10 @@ object Helpers {
376376

377377
def makeFundingPubKeyScript(localFundingKey: PublicKey, remoteFundingKey: PublicKey): ByteVector = write(pay2wsh(multiSig2of2(localFundingKey, remoteFundingKey)))
378378

379-
def makeFundingInputInfo(fundingTxId: TxId, fundingTxOutputIndex: Int, fundingSatoshis: Satoshi, fundingPubkey1: PublicKey, fundingPubkey2: PublicKey): InputInfo = {
379+
def makeFundingInputInfo(fundingTxId: TxId, fundingTxOutputIndex: Int, fundingSatoshis: Satoshi, fundingPubkey1: PublicKey, fundingPubkey2: PublicKey): InputInfo.SegwitInput = {
380380
val fundingScript = multiSig2of2(fundingPubkey1, fundingPubkey2)
381381
val fundingTxOut = TxOut(fundingSatoshis, pay2wsh(fundingScript))
382-
InputInfo(OutPoint(fundingTxId, fundingTxOutputIndex), fundingTxOut, write(fundingScript))
382+
InputInfo.SegwitInput(OutPoint(fundingTxId, fundingTxOutputIndex), fundingTxOut, write(fundingScript))
383383
}
384384

385385
/**

eclair-core/src/main/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunder.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ private class ReplaceableTxFunder(nodeParams: NodeParams,
358358
import fr.acinq.bitcoin.scalacompat.KotlinUtils._
359359

360360
// We create a PSBT with the non-wallet input already signed:
361-
val witnessScript = locallySignedTx.txInfo.input.redeemScriptOrScriptTree match {
362-
case Left(redeemScript) => fr.acinq.bitcoin.Script.parse(redeemScript)
361+
val witnessScript = locallySignedTx.txInfo.input match {
362+
case InputInfo.SegwitInput(_, _, redeemScript) => fr.acinq.bitcoin.Script.parse(redeemScript)
363363
case _ => null
364364
}
365365
val psbt = new Psbt(locallySignedTx.txInfo.tx)

eclair-core/src/main/scala/fr/acinq/eclair/transactions/Transactions.scala

Lines changed: 86 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import fr.acinq.eclair._
2626
import fr.acinq.eclair.blockchain.fee.{ConfirmationTarget, FeeratePerKw}
2727
import fr.acinq.eclair.transactions.CommitmentOutput._
2828
import fr.acinq.eclair.transactions.Scripts._
29+
import fr.acinq.eclair.transactions.Transactions.InputInfo.SegwitInput
2930
import fr.acinq.eclair.wire.protocol.UpdateAddHtlc
3031
import scodec.bits.ByteVector
3132

@@ -102,14 +103,18 @@ object Transactions {
102103
val publicKeyScript: ByteVector = Script.write(Script.pay2tr(internalKey, Some(scriptTree)))
103104
}
104105

105-
case class InputInfo(outPoint: OutPoint, txOut: TxOut, redeemScriptOrScriptTree: Either[ByteVector, ScriptTreeAndInternalKey]) {
106-
val redeemScriptOrEmptyScript: ByteVector = redeemScriptOrScriptTree.swap.getOrElse(ByteVector.empty) // TODO: use the actual script tree for taproot transactions, once we implement them
106+
sealed trait InputInfo {
107+
val outPoint: OutPoint
108+
val txOut: TxOut
107109
}
108110

109111
object InputInfo {
110-
def apply(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector) = new InputInfo(outPoint, txOut, Left(redeemScript))
111-
def apply(outPoint: OutPoint, txOut: TxOut, redeemScript: Seq[ScriptElt]) = new InputInfo(outPoint, txOut, Left(Script.write(redeemScript)))
112-
def apply(outPoint: OutPoint, txOut: TxOut, scriptTree: ScriptTreeAndInternalKey) = new InputInfo(outPoint, txOut, Right(scriptTree))
112+
case class SegwitInput(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector) extends InputInfo
113+
case class TaprootInput(outPoint: OutPoint, txOut: TxOut, scriptTreeAndInternalKey: ScriptTreeAndInternalKey) extends InputInfo
114+
115+
def apply(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector): SegwitInput = SegwitInput(outPoint, txOut, redeemScript)
116+
def apply(outPoint: OutPoint, txOut: TxOut, redeemScript: Seq[ScriptElt]): SegwitInput = SegwitInput(outPoint, txOut, Script.write(redeemScript))
117+
def apply(outPoint: OutPoint, txOut: TxOut, scriptTree: ScriptTreeAndInternalKey): TaprootInput = TaprootInput(outPoint, txOut, scriptTree)
113118
}
114119

115120
/** Owner of a given transaction (local/remote). */
@@ -138,24 +143,29 @@ object Transactions {
138143
sign(key, sighash(txOwner, commitmentFormat))
139144
}
140145

141-
def sign(key: PrivateKey, sighashType: Int): ByteVector64 = {
142-
// NB: the tx may have multiple inputs, we will only sign the one provided in txinfo.input. Bear in mind that the
143-
// signature will be invalidated if other inputs are added *afterwards* and sighashType was SIGHASH_ALL.
144-
val inputIndex = tx.txIn.indexWhere(_.outPoint == input.outPoint)
145-
val sigDER = Transaction.signInput(tx, inputIndex, input.redeemScriptOrEmptyScript, sighashType, input.txOut.amount, SIGVERSION_WITNESS_V0, key)
146-
val sig64 = Crypto.der2compact(sigDER)
147-
sig64
146+
def sign(key: PrivateKey, sighashType: Int): ByteVector64 = input match {
147+
case _:InputInfo.TaprootInput => ByteVector64.Zeroes
148+
case InputInfo.SegwitInput(outPoint, txOut, redeemScript) =>
149+
// NB: the tx may have multiple inputs, we will only sign the one provided in txinfo.input. Bear in mind that the
150+
// signature will be invalidated if other inputs are added *afterwards* and sighashType was SIGHASH_ALL.
151+
val inputIndex = tx.txIn.indexWhere(_.outPoint == outPoint)
152+
val sigDER = Transaction.signInput(tx, inputIndex, redeemScript, sighashType, txOut.amount, SIGVERSION_WITNESS_V0, key)
153+
val sig64 = Crypto.der2compact(sigDER)
154+
sig64
148155
}
149156

150-
def checkSig(sig: ByteVector64, pubKey: PublicKey, txOwner: TxOwner, commitmentFormat: CommitmentFormat): Boolean = {
151-
val sighash = this.sighash(txOwner, commitmentFormat)
152-
val inputIndex = tx.txIn.indexWhere(_.outPoint == input.outPoint)
153-
if (inputIndex >= 0) {
154-
val data = Transaction.hashForSigning(tx, inputIndex, input.redeemScriptOrEmptyScript, sighash, input.txOut.amount, SIGVERSION_WITNESS_V0)
155-
Crypto.verifySignature(data, sig, pubKey)
156-
} else {
157-
false
158-
}
157+
def checkSig(sig: ByteVector64, pubKey: PublicKey, txOwner: TxOwner, commitmentFormat: CommitmentFormat): Boolean = input match {
158+
159+
case _:InputInfo.TaprootInput => false
160+
case InputInfo.SegwitInput(outPoint, txOut, redeemScript) =>
161+
val sighash = this.sighash(txOwner, commitmentFormat)
162+
val inputIndex = tx.txIn.indexWhere(_.outPoint == outPoint)
163+
if (inputIndex >= 0) {
164+
val data = Transaction.hashForSigning(tx, inputIndex, redeemScript, sighash, txOut.amount, SIGVERSION_WITNESS_V0)
165+
Crypto.verifySignature(data, sig, pubKey)
166+
} else {
167+
false
168+
}
159169
}
160170
}
161171

@@ -891,64 +901,86 @@ object Transactions {
891901
commitTx.copy(tx = commitTx.tx.updateWitness(0, witness))
892902
}
893903

894-
def addSigs(mainPenaltyTx: MainPenaltyTx, revocationSig: ByteVector64): MainPenaltyTx = {
895-
val witness = Scripts.witnessToLocalDelayedWithRevocationSig(revocationSig, mainPenaltyTx.input.redeemScriptOrEmptyScript)
896-
mainPenaltyTx.copy(tx = mainPenaltyTx.tx.updateWitness(0, witness))
904+
def addSigs(mainPenaltyTx: MainPenaltyTx, revocationSig: ByteVector64): MainPenaltyTx = mainPenaltyTx.input match {
905+
case InputInfo.SegwitInput(_, _, redeemScript) =>
906+
val witness = Scripts.witnessToLocalDelayedWithRevocationSig(revocationSig, redeemScript)
907+
mainPenaltyTx.copy(tx = mainPenaltyTx.tx.updateWitness(0, witness))
908+
case _ => mainPenaltyTx
897909
}
898910

899-
def addSigs(htlcPenaltyTx: HtlcPenaltyTx, revocationSig: ByteVector64, revocationPubkey: PublicKey): HtlcPenaltyTx = {
900-
val witness = Scripts.witnessHtlcWithRevocationSig(revocationSig, revocationPubkey, htlcPenaltyTx.input.redeemScriptOrEmptyScript)
901-
htlcPenaltyTx.copy(tx = htlcPenaltyTx.tx.updateWitness(0, witness))
911+
def addSigs(htlcPenaltyTx: HtlcPenaltyTx, revocationSig: ByteVector64, revocationPubkey: PublicKey): HtlcPenaltyTx = htlcPenaltyTx.input match {
912+
case InputInfo.SegwitInput(_, _, redeemScript) =>
913+
val witness = Scripts.witnessHtlcWithRevocationSig(revocationSig, revocationPubkey, redeemScript)
914+
htlcPenaltyTx.copy(tx = htlcPenaltyTx.tx.updateWitness(0, witness))
915+
case _ => htlcPenaltyTx
902916
}
903917

904-
def addSigs(htlcSuccessTx: HtlcSuccessTx, localSig: ByteVector64, remoteSig: ByteVector64, paymentPreimage: ByteVector32, commitmentFormat: CommitmentFormat): HtlcSuccessTx = {
905-
val witness = witnessHtlcSuccess(localSig, remoteSig, paymentPreimage, htlcSuccessTx.input.redeemScriptOrEmptyScript, commitmentFormat)
906-
htlcSuccessTx.copy(tx = htlcSuccessTx.tx.updateWitness(0, witness))
918+
def addSigs(htlcSuccessTx: HtlcSuccessTx, localSig: ByteVector64, remoteSig: ByteVector64, paymentPreimage: ByteVector32, commitmentFormat: CommitmentFormat): HtlcSuccessTx = htlcSuccessTx.input match {
919+
case InputInfo.SegwitInput(_, _, redeemScript) =>
920+
val witness = witnessHtlcSuccess(localSig, remoteSig, paymentPreimage, redeemScript, commitmentFormat)
921+
htlcSuccessTx.copy(tx = htlcSuccessTx.tx.updateWitness(0, witness))
922+
case _ => htlcSuccessTx
907923
}
908924

909-
def addSigs(htlcTimeoutTx: HtlcTimeoutTx, localSig: ByteVector64, remoteSig: ByteVector64, commitmentFormat: CommitmentFormat): HtlcTimeoutTx = {
910-
val witness = witnessHtlcTimeout(localSig, remoteSig, htlcTimeoutTx.input.redeemScriptOrEmptyScript, commitmentFormat)
911-
htlcTimeoutTx.copy(tx = htlcTimeoutTx.tx.updateWitness(0, witness))
925+
def addSigs(htlcTimeoutTx: HtlcTimeoutTx, localSig: ByteVector64, remoteSig: ByteVector64, commitmentFormat: CommitmentFormat): HtlcTimeoutTx = htlcTimeoutTx.input match {
926+
case InputInfo.SegwitInput(_, _, redeemScript) =>
927+
val witness = witnessHtlcTimeout(localSig, remoteSig, redeemScript, commitmentFormat)
928+
htlcTimeoutTx.copy(tx = htlcTimeoutTx.tx.updateWitness(0, witness))
929+
case _ => htlcTimeoutTx
912930
}
913931

914-
def addSigs(claimHtlcSuccessTx: ClaimHtlcSuccessTx, localSig: ByteVector64, paymentPreimage: ByteVector32): ClaimHtlcSuccessTx = {
915-
val witness = witnessClaimHtlcSuccessFromCommitTx(localSig, paymentPreimage, claimHtlcSuccessTx.input.redeemScriptOrEmptyScript)
916-
claimHtlcSuccessTx.copy(tx = claimHtlcSuccessTx.tx.updateWitness(0, witness))
932+
def addSigs(claimHtlcSuccessTx: ClaimHtlcSuccessTx, localSig: ByteVector64, paymentPreimage: ByteVector32): ClaimHtlcSuccessTx = claimHtlcSuccessTx.input match {
933+
case InputInfo.SegwitInput(_, _, redeemScript) =>
934+
val witness = witnessClaimHtlcSuccessFromCommitTx(localSig, paymentPreimage, redeemScript)
935+
claimHtlcSuccessTx.copy(tx = claimHtlcSuccessTx.tx.updateWitness(0, witness))
936+
case _ => claimHtlcSuccessTx
917937
}
918938

919-
def addSigs(claimHtlcTimeoutTx: ClaimHtlcTimeoutTx, localSig: ByteVector64): ClaimHtlcTimeoutTx = {
920-
val witness = witnessClaimHtlcTimeoutFromCommitTx(localSig, claimHtlcTimeoutTx.input.redeemScriptOrEmptyScript)
921-
claimHtlcTimeoutTx.copy(tx = claimHtlcTimeoutTx.tx.updateWitness(0, witness))
939+
def addSigs(claimHtlcTimeoutTx: ClaimHtlcTimeoutTx, localSig: ByteVector64): ClaimHtlcTimeoutTx = claimHtlcTimeoutTx.input match {
940+
case InputInfo.SegwitInput(_, _, redeemScript) =>
941+
val witness = witnessClaimHtlcTimeoutFromCommitTx(localSig, redeemScript)
942+
claimHtlcTimeoutTx.copy(tx = claimHtlcTimeoutTx.tx.updateWitness(0, witness))
943+
case _ => claimHtlcTimeoutTx
922944
}
923945

924946
def addSigs(claimP2WPKHOutputTx: ClaimP2WPKHOutputTx, localPaymentPubkey: PublicKey, localSig: ByteVector64): ClaimP2WPKHOutputTx = {
925947
val witness = ScriptWitness(Seq(der(localSig), localPaymentPubkey.value))
926948
claimP2WPKHOutputTx.copy(tx = claimP2WPKHOutputTx.tx.updateWitness(0, witness))
927949
}
928950

929-
def addSigs(claimRemoteDelayedOutputTx: ClaimRemoteDelayedOutputTx, localSig: ByteVector64): ClaimRemoteDelayedOutputTx = {
930-
val witness = witnessClaimToRemoteDelayedFromCommitTx(localSig, claimRemoteDelayedOutputTx.input.redeemScriptOrEmptyScript)
931-
claimRemoteDelayedOutputTx.copy(tx = claimRemoteDelayedOutputTx.tx.updateWitness(0, witness))
951+
def addSigs(claimRemoteDelayedOutputTx: ClaimRemoteDelayedOutputTx, localSig: ByteVector64): ClaimRemoteDelayedOutputTx = claimRemoteDelayedOutputTx.input match {
952+
case InputInfo.SegwitInput(_, _, redeemScript) =>
953+
val witness = witnessClaimToRemoteDelayedFromCommitTx(localSig, redeemScript)
954+
claimRemoteDelayedOutputTx.copy(tx = claimRemoteDelayedOutputTx.tx.updateWitness(0, witness))
955+
case _ => claimRemoteDelayedOutputTx
932956
}
933957

934-
def addSigs(claimDelayedOutputTx: ClaimLocalDelayedOutputTx, localSig: ByteVector64): ClaimLocalDelayedOutputTx = {
935-
val witness = witnessToLocalDelayedAfterDelay(localSig, claimDelayedOutputTx.input.redeemScriptOrEmptyScript)
936-
claimDelayedOutputTx.copy(tx = claimDelayedOutputTx.tx.updateWitness(0, witness))
958+
def addSigs(claimDelayedOutputTx: ClaimLocalDelayedOutputTx, localSig: ByteVector64): ClaimLocalDelayedOutputTx = claimDelayedOutputTx.input match {
959+
case InputInfo.SegwitInput(_, _, redeemScript) =>
960+
val witness = witnessToLocalDelayedAfterDelay(localSig, redeemScript)
961+
claimDelayedOutputTx.copy(tx = claimDelayedOutputTx.tx.updateWitness(0, witness))
962+
case _ => claimDelayedOutputTx
937963
}
938964

939-
def addSigs(htlcDelayedTx: HtlcDelayedTx, localSig: ByteVector64): HtlcDelayedTx = {
940-
val witness = witnessToLocalDelayedAfterDelay(localSig, htlcDelayedTx.input.redeemScriptOrEmptyScript)
941-
htlcDelayedTx.copy(tx = htlcDelayedTx.tx.updateWitness(0, witness))
965+
def addSigs(htlcDelayedTx: HtlcDelayedTx, localSig: ByteVector64): HtlcDelayedTx = htlcDelayedTx.input match {
966+
case InputInfo.SegwitInput(_, _, redeemScript) =>
967+
val witness = witnessToLocalDelayedAfterDelay(localSig, redeemScript)
968+
htlcDelayedTx.copy(tx = htlcDelayedTx.tx.updateWitness(0, witness))
969+
case _ => htlcDelayedTx
942970
}
943971

944-
def addSigs(claimAnchorOutputTx: ClaimLocalAnchorOutputTx, localSig: ByteVector64): ClaimLocalAnchorOutputTx = {
945-
val witness = witnessAnchor(localSig, claimAnchorOutputTx.input.redeemScriptOrEmptyScript)
946-
claimAnchorOutputTx.copy(tx = claimAnchorOutputTx.tx.updateWitness(0, witness))
972+
def addSigs(claimAnchorOutputTx: ClaimLocalAnchorOutputTx, localSig: ByteVector64): ClaimLocalAnchorOutputTx = claimAnchorOutputTx.input match {
973+
case InputInfo.SegwitInput(_, _, redeemScript) =>
974+
val witness = witnessAnchor(localSig, redeemScript)
975+
claimAnchorOutputTx.copy(tx = claimAnchorOutputTx.tx.updateWitness(0, witness))
976+
case _ => claimAnchorOutputTx
947977
}
948978

949-
def addSigs(claimHtlcDelayedPenalty: ClaimHtlcDelayedOutputPenaltyTx, revocationSig: ByteVector64): ClaimHtlcDelayedOutputPenaltyTx = {
950-
val witness = Scripts.witnessToLocalDelayedWithRevocationSig(revocationSig, claimHtlcDelayedPenalty.input.redeemScriptOrEmptyScript)
951-
claimHtlcDelayedPenalty.copy(tx = claimHtlcDelayedPenalty.tx.updateWitness(0, witness))
979+
def addSigs(claimHtlcDelayedPenalty: ClaimHtlcDelayedOutputPenaltyTx, revocationSig: ByteVector64): ClaimHtlcDelayedOutputPenaltyTx = claimHtlcDelayedPenalty.input match {
980+
case InputInfo.SegwitInput(_, _, redeemScript) =>
981+
val witness = Scripts.witnessToLocalDelayedWithRevocationSig(revocationSig, redeemScript)
982+
claimHtlcDelayedPenalty.copy(tx = claimHtlcDelayedPenalty.tx.updateWitness(0, witness))
983+
case _ => claimHtlcDelayedPenalty
952984
}
953985

954986
def addSigs(closingTx: ClosingTx, localFundingPubkey: PublicKey, remoteFundingPubkey: PublicKey, localSig: ByteVector64, remoteSig: ByteVector64): ClosingTx = {

eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelCodecs0.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,12 @@ private[channel] object ChannelCodecs0 {
125125
closingTx => closingTx.tx
126126
)
127127

128-
private case class InputInfoLegacy(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector)
129-
130-
private val inputInfoLegacyCodec: Codec[InputInfoLegacy] = (
128+
private val legacyInputInfoCodec: Codec[InputInfo.SegwitInput] = (
131129
("outPoint" | outPointCodec) ::
132130
("txOut" | txOutCodec) ::
133-
("redeemScript" | varsizebinarydata)).as[InputInfoLegacy]
131+
("redeemScript" | varsizebinarydata)).as[InputInfo.SegwitInput].decodeOnly
134132

135-
val inputInfoCodec: Codec[InputInfo] = inputInfoLegacyCodec.map(legacy => InputInfo(legacy.outPoint, legacy.txOut, Left(legacy.redeemScript))).decodeOnly
133+
val inputInfoCodec: Codec[InputInfo] = legacyInputInfoCodec.upcast[InputInfo]
136134

137135
private val defaultConfirmationTarget: Codec[ConfirmationTarget.Absolute] = provide(ConfirmationTarget.Absolute(BlockHeight(0)))
138136

eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version1/ChannelCodecs1.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,12 @@ private[channel] object ChannelCodecs1 {
9797
closingTx => closingTx.tx
9898
)
9999

100-
private case class InputInfoLegacy(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector)
101-
102-
private val inputInfoLegacyCodec: Codec[InputInfoLegacy] = (
100+
private val legacyInputInfoCodec: Codec[InputInfo.SegwitInput] = (
103101
("outPoint" | outPointCodec) ::
104102
("txOut" | txOutCodec) ::
105-
("redeemScript" | lengthDelimited(bytes))).as[InputInfoLegacy]
103+
("redeemScript" | lengthDelimited(bytes))).as[InputInfo.SegwitInput].decodeOnly
106104

107-
val inputInfoCodec: Codec[InputInfo] = inputInfoLegacyCodec.xmap[InputInfo](legacy => InputInfo(legacy.outPoint, legacy.txOut, Left(legacy.redeemScript)), _ => ???).decodeOnly
105+
val inputInfoCodec: Codec[InputInfo] = legacyInputInfoCodec.upcast[InputInfo]
108106

109107
private val defaultConfirmationTarget: Codec[ConfirmationTarget.Absolute] = provide(ConfirmationTarget.Absolute(BlockHeight(0)))
110108

eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version2/ChannelCodecs2.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,12 @@ private[channel] object ChannelCodecs2 {
101101

102102
val txCodec: Codec[Transaction] = lengthDelimited(bytes.xmap(d => Transaction.read(d.toArray), d => Transaction.write(d)))
103103

104-
private case class InputInfoLegacy(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector)
105-
106-
private val inputInfoLegacyCodec: Codec[InputInfoLegacy] = (
104+
private val legacyInputInfoCodec: Codec[InputInfo.SegwitInput] = (
107105
("outPoint" | outPointCodec) ::
108106
("txOut" | txOutCodec) ::
109-
("redeemScript" | lengthDelimited(bytes))).as[InputInfoLegacy]
107+
("redeemScript" | lengthDelimited(bytes))).as[InputInfo.SegwitInput].decodeOnly
110108

111-
val inputInfoCodec: Codec[InputInfo] = inputInfoLegacyCodec.xmap[InputInfo](legacy => InputInfo(legacy.outPoint, legacy.txOut, Left(legacy.redeemScript)), _ => ???).decodeOnly
109+
val inputInfoCodec: Codec[InputInfo] = legacyInputInfoCodec.upcast[InputInfo]
112110

113111
val outputInfoCodec: Codec[OutputInfo] = (
114112
("index" | uint32) ::

eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,12 @@ private[channel] object ChannelCodecs3 {
113113

114114
val txCodec: Codec[Transaction] = lengthDelimited(bytes.xmap(d => Transaction.read(d.toArray), d => Transaction.write(d)))
115115

116-
private case class InputInfoLegacy(outPoint: OutPoint, txOut: TxOut, redeemScript: ByteVector)
117-
118-
private val inputInfoLegacyCodec: Codec[InputInfoLegacy] = (
116+
private val legacyInputInfoCodec: Codec[InputInfo.SegwitInput] = (
119117
("outPoint" | outPointCodec) ::
120118
("txOut" | txOutCodec) ::
121-
("redeemScript" | lengthDelimited(bytes))).as[InputInfoLegacy]
119+
("redeemScript" | lengthDelimited(bytes))).as[InputInfo.SegwitInput].decodeOnly
122120

123-
val inputInfoCodec: Codec[InputInfo] = inputInfoLegacyCodec.xmap[InputInfo](legacy => InputInfo(legacy.outPoint, legacy.txOut, Left(legacy.redeemScript)), _ => ???).decodeOnly
121+
val inputInfoCodec: Codec[InputInfo] = legacyInputInfoCodec.upcast[InputInfo]
124122

125123
val outputInfoCodec: Codec[OutputInfo] = (
126124
("index" | uint32) ::

0 commit comments

Comments
 (0)