|
16 | 16 |
|
17 | 17 | package fr.acinq.eclair.wire.protocol |
18 | 18 |
|
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} |
20 | 21 | import fr.acinq.eclair.blockchain.fee.FeeratePerKw |
21 | 22 | import fr.acinq.eclair.payment.relay.Relayer.RelayFees |
22 | 23 | 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} |
24 | 25 | 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} |
26 | 27 | import scodec.Codec |
| 28 | +import scodec.bits.ByteVector |
27 | 29 | import scodec.codecs._ |
28 | 30 |
|
| 31 | +import java.nio.charset.StandardCharsets |
| 32 | + |
29 | 33 | /** |
30 | 34 | * Created by t-bast on 02/01/2023. |
31 | 35 | */ |
@@ -80,4 +84,30 @@ object LiquidityAds { |
80 | 84 | ("channel_fee_max_base_msat" | tmillisatoshi32) |
81 | 85 | ).as[LeaseRates] |
82 | 86 |
|
| 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 | + |
83 | 113 | } |
0 commit comments