Skip to content

Commit dc5ffe4

Browse files
committed
Add liquidity ads proof
The seller signs a commitment to the lease parameters. It provides the buyer with a way to prove if the seller later cheats.
1 parent b5d614a commit dc5ffe4

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/LiquidityAds.scala

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@
1616

1717
package fr.acinq.eclair.wire.protocol
1818

19-
import fr.acinq.bitcoin.scalacompat.Satoshi
19+
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
20+
import fr.acinq.bitcoin.scalacompat.{ByteVector64, Crypto, Satoshi}
2021
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
2122
import fr.acinq.eclair.payment.relay.Relayer.RelayFees
2223
import fr.acinq.eclair.transactions.Transactions
23-
import fr.acinq.eclair.wire.protocol.CommonCodecs.satoshi32
24+
import fr.acinq.eclair.wire.protocol.CommonCodecs.{blockHeight, millisatoshi32, publicKey, satoshi32}
2425
import fr.acinq.eclair.wire.protocol.TlvCodecs.tmillisatoshi32
25-
import fr.acinq.eclair.{CltvExpiryDelta, MilliSatoshi, ToMilliSatoshiConversion}
26+
import fr.acinq.eclair.{BlockHeight, CltvExpiryDelta, MilliSatoshi, ToMilliSatoshiConversion}
2627
import scodec.Codec
28+
import scodec.bits.ByteVector
2729
import scodec.codecs._
2830

31+
import java.nio.charset.StandardCharsets
32+
2933
/**
3034
* Created by t-bast on 02/01/2023.
3135
*/
@@ -80,4 +84,30 @@ object LiquidityAds {
8084
("channel_fee_max_base_msat" | tmillisatoshi32)
8185
).as[LeaseRates]
8286

87+
/** The seller signs the lease parameters: if they cheat, the buyer can use that signature to prove they cheated. */
88+
case class LeaseWitness(fundingPubKey: PublicKey, leaseEnd: BlockHeight, leaseDuration: Int, maxRelayFeeProportional: Int, maxRelayFeeBase: MilliSatoshi)
89+
90+
object LeaseWitness {
91+
def apply(fundingPubKey: PublicKey, leaseEnd: BlockHeight, leaseDuration: Int, leaseRates: LeaseRates): LeaseWitness = {
92+
LeaseWitness(fundingPubKey, leaseEnd, leaseDuration, leaseRates.maxRelayFeeProportional, leaseRates.maxRelayFeeBase)
93+
}
94+
95+
def sign(nodeKey: PrivateKey, witness: LeaseWitness): ByteVector64 = {
96+
Crypto.sign(Crypto.sha256(leaseWitnessCodec.encode(witness).require.bytes), nodeKey)
97+
}
98+
99+
def verify(nodeId: PublicKey, sig: ByteVector64, witness: LeaseWitness): Boolean = {
100+
Crypto.verifySignature(Crypto.sha256(leaseWitnessCodec.encode(witness).require.bytes), sig, nodeId)
101+
}
102+
}
103+
104+
private val leaseWitnessCodec: Codec[LeaseWitness] = (
105+
("tag" | constant(ByteVector("option_will_fund".getBytes(StandardCharsets.US_ASCII)))) ::
106+
("funding_pubkey" | publicKey) ::
107+
("lease_end" | blockHeight) ::
108+
("lease_duration" | uint32.xmap(l => l.toInt, (i: Int) => i.toLong)) ::
109+
("channel_fee_max_basis" | uint16) ::
110+
("channel_fee_max_base_msat" | millisatoshi32)
111+
).as[LeaseWitness]
112+
83113
}

0 commit comments

Comments
 (0)