2021 11 03 protocol version (#3793)

* ProtocolVersion WIP

* Start incorporating protocol version into DLC Offer

* Fix doc
This commit is contained in:
Chris Stewart 2021-11-03 15:13:19 -05:00 committed by GitHub
parent 18726c10bb
commit aa748c012f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 72 additions and 23 deletions

View file

@ -15,6 +15,7 @@ import org.bitcoins.core.protocol.transaction.{Transaction, TransactionOutPoint}
import org.bitcoins.core.protocol.{BitcoinAddress, BlockStamp} import org.bitcoins.core.protocol.{BitcoinAddress, BlockStamp}
import org.bitcoins.core.psbt.InputPSBTRecord.PartialSignature import org.bitcoins.core.psbt.InputPSBTRecord.PartialSignature
import org.bitcoins.core.psbt.PSBT import org.bitcoins.core.psbt.PSBT
import org.bitcoins.core.serializers.PicklerKeys
import org.bitcoins.core.util.TimeUtil import org.bitcoins.core.util.TimeUtil
import org.bitcoins.core.util.TimeUtil._ import org.bitcoins.core.util.TimeUtil._
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte

View file

@ -4,8 +4,8 @@ import akka.actor.{ActorSystem, Cancellable}
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
import org.bitcoins.cli.CliCommand._ import org.bitcoins.cli.CliCommand._
import org.bitcoins.cli.ConsoleCli import org.bitcoins.cli.ConsoleCli
import org.bitcoins.commons.serializers.PicklerKeys
import org.bitcoins.core.dlc.accounting.RateOfReturnUtil import org.bitcoins.core.dlc.accounting.RateOfReturnUtil
import org.bitcoins.core.serializers.PicklerKeys
import org.bitcoins.core.wallet.fee.FeeUnit import org.bitcoins.core.wallet.fee.FeeUnit
import org.bitcoins.gui.dialog._ import org.bitcoins.gui.dialog._
import org.bitcoins.gui.dlc.DLCPaneModel import org.bitcoins.gui.dlc.DLCPaneModel

View file

@ -2,11 +2,11 @@ package org.bitcoins.server
import akka.http.scaladsl.model.ContentTypes import akka.http.scaladsl.model.ContentTypes
import akka.http.scaladsl.testkit.ScalatestRouteTest import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.bitcoins.commons.serializers.PicklerKeys
import org.bitcoins.core.api.dlc.node.DLCNodeApi import org.bitcoins.core.api.dlc.node.DLCNodeApi
import org.bitcoins.core.currency.{Bitcoins, Satoshis} import org.bitcoins.core.currency.{Bitcoins, Satoshis}
import org.bitcoins.core.protocol.dlc.models.ContractInfo import org.bitcoins.core.protocol.dlc.models.ContractInfo
import org.bitcoins.core.protocol.tlv.OracleAnnouncementTLV import org.bitcoins.core.protocol.tlv.OracleAnnouncementTLV
import org.bitcoins.core.serializers.PicklerKeys
import org.bitcoins.server.routes.ServerCommand import org.bitcoins.server.routes.ServerCommand
import org.scalamock.scalatest.MockFactory import org.scalamock.scalatest.MockFactory
import org.scalatest.wordspec.AnyWordSpec import org.scalatest.wordspec.AnyWordSpec

View file

@ -928,6 +928,7 @@ class RoutesSpec extends AnyWordSpec with ScalatestRouteTest with MockFactory {
val contractInfoTLV = contractInfo.toTLV val contractInfoTLV = contractInfo.toTLV
val offer = DLCOffer( val offer = DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = contractInfo, contractInfo = contractInfo,
pubKeys = dummyDLCKeys, pubKeys = dummyDLCKeys,
totalCollateral = Satoshis(2500), totalCollateral = Satoshis(2500),

View file

@ -10,7 +10,7 @@ import org.bitcoins.core.protocol.dlc.models.DLCMessage.{
DLCSign DLCSign
} }
import org.bitcoins.core.protocol.dlc.models._ import org.bitcoins.core.protocol.dlc.models._
import org.bitcoins.core.protocol.tlv.EnumOutcome import org.bitcoins.core.protocol.tlv.{DLCOfferTLV, EnumOutcome}
import org.bitcoins.core.psbt.InputPSBTRecord.PartialSignature import org.bitcoins.core.psbt.InputPSBTRecord.PartialSignature
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
import org.bitcoins.crypto._ import org.bitcoins.crypto._
@ -47,6 +47,7 @@ class DLCMessageTest extends BitcoinSJvmTest {
it must "not allow a negative collateral for a DLCOffer" in { it must "not allow a negative collateral for a DLCOffer" in {
assertThrows[IllegalArgumentException]( assertThrows[IllegalArgumentException](
DLCOffer( DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = ContractInfo.dummy, contractInfo = ContractInfo.dummy,
pubKeys = DLCPublicKeys(dummyPubKey, dummyAddress), pubKeys = DLCPublicKeys(dummyPubKey, dummyAddress),
totalCollateral = Satoshis(-1), totalCollateral = Satoshis(-1),
@ -63,6 +64,7 @@ class DLCMessageTest extends BitcoinSJvmTest {
it must "not allow same change and fund output serial id for a DLCOffer" in { it must "not allow same change and fund output serial id for a DLCOffer" in {
assertThrows[IllegalArgumentException]( assertThrows[IllegalArgumentException](
DLCOffer( DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = ContractInfo.dummy, contractInfo = ContractInfo.dummy,
pubKeys = DLCPublicKeys(dummyPubKey, dummyAddress), pubKeys = DLCPublicKeys(dummyPubKey, dummyAddress),
totalCollateral = Satoshis(-1), totalCollateral = Satoshis(-1),

View file

@ -28,6 +28,7 @@ import scodec.bits.ByteVector
case class DLCTxBuilder(offer: DLCOffer, accept: DLCAcceptWithoutSigs) { case class DLCTxBuilder(offer: DLCOffer, accept: DLCAcceptWithoutSigs) {
val DLCOffer(_, val DLCOffer(_,
_,
DLCPublicKeys(offerFundingKey: ECPublicKey, DLCPublicKeys(offerFundingKey: ECPublicKey,
offerFinalAddress: BitcoinAddress), offerFinalAddress: BitcoinAddress),
offerTotalCollateral: Satoshis, offerTotalCollateral: Satoshis,

View file

@ -77,6 +77,7 @@ object DLCMessage {
* @param timeouts The set of timeouts for the CETs * @param timeouts The set of timeouts for the CETs
*/ */
case class DLCOffer( case class DLCOffer(
protocolVersionOpt: Option[Int],
contractInfo: ContractInfo, contractInfo: ContractInfo,
pubKeys: DLCPublicKeys, pubKeys: DLCPublicKeys,
totalCollateral: Satoshis, totalCollateral: Satoshis,
@ -110,9 +111,10 @@ object DLCMessage {
changeAddress.networkParameters.chainParams.genesisBlock.blockHeader.hash changeAddress.networkParameters.chainParams.genesisBlock.blockHeader.hash
DLCOfferTLV( DLCOfferTLV(
protocolVersionOpt = protocolVersionOpt,
contractFlags = 0x00, contractFlags = 0x00,
chainHash = chainHash, chainHash = chainHash,
contractInfo.toTLV, contractInfo = contractInfo.toTLV,
fundingPubKey = pubKeys.fundingKey, fundingPubKey = pubKeys.fundingKey,
payoutSPK = pubKeys.payoutAddress.scriptPubKey, payoutSPK = pubKeys.payoutAddress.scriptPubKey,
payoutSerialId = payoutSerialId, payoutSerialId = payoutSerialId,
@ -140,6 +142,7 @@ object DLCMessage {
val contractInfo = ContractInfo.fromTLV(offer.contractInfo) val contractInfo = ContractInfo.fromTLV(offer.contractInfo)
DLCOffer( DLCOffer(
protocolVersionOpt = offer.protocolVersionOpt,
contractInfo = contractInfo, contractInfo = contractInfo,
pubKeys = DLCPublicKeys( pubKeys = DLCPublicKeys(
offer.fundingPubKey, offer.fundingPubKey,

View file

@ -1369,6 +1369,7 @@ object FundingSignaturesV0TLV extends TLVFactory[FundingSignaturesV0TLV] {
sealed trait DLCSetupTLV extends TLV sealed trait DLCSetupTLV extends TLV
case class DLCOfferTLV( case class DLCOfferTLV(
protocolVersionOpt: Option[Int],
contractFlags: Byte, contractFlags: Byte,
chainHash: DoubleSha256Digest, chainHash: DoubleSha256Digest,
contractInfo: ContractInfoV0TLV, contractInfo: ContractInfoV0TLV,
@ -1391,7 +1392,12 @@ case class DLCOfferTLV(
override val tpe: BigSizeUInt = DLCOfferTLV.tpe override val tpe: BigSizeUInt = DLCOfferTLV.tpe
override val value: ByteVector = { override val value: ByteVector = {
ByteVector(contractFlags) ++ val versionBytes = protocolVersionOpt match {
case Some(v) => UInt32(v).bytes
case None => ByteVector.empty
}
versionBytes ++
ByteVector(contractFlags) ++
chainHash.bytes ++ chainHash.bytes ++
contractInfo.bytes ++ contractInfo.bytes ++
fundingPubKey.bytes ++ fundingPubKey.bytes ++
@ -1409,11 +1415,18 @@ case class DLCOfferTLV(
} }
object DLCOfferTLV extends TLVFactory[DLCOfferTLV] { object DLCOfferTLV extends TLVFactory[DLCOfferTLV] {
/** No version for now */
val currentVersionOpt: Option[Int] = None
val currentVersionU32: Option[UInt32] = {
currentVersionOpt.map(UInt32(_))
}
override val tpe: BigSizeUInt = BigSizeUInt(42778) override val tpe: BigSizeUInt = BigSizeUInt(42778)
override def fromTLVValue(value: ByteVector): DLCOfferTLV = { override def fromTLVValue(value: ByteVector): DLCOfferTLV = {
val iter = ValueIterator(value) val iter = ValueIterator(value)
val protocolVersionOpt = None
val contractFlags = iter.take(1).head val contractFlags = iter.take(1).head
val chainHash = iter.take(DoubleSha256Digest, 32) val chainHash = iter.take(DoubleSha256Digest, 32)
val contractInfo = iter.take(ContractInfoV0TLV) val contractInfo = iter.take(ContractInfoV0TLV)
@ -1431,20 +1444,21 @@ object DLCOfferTLV extends TLVFactory[DLCOfferTLV] {
val contractTimeout = BlockTimeStamp(iter.takeU32()) val contractTimeout = BlockTimeStamp(iter.takeU32())
DLCOfferTLV( DLCOfferTLV(
contractFlags, protocolVersionOpt = protocolVersionOpt,
chainHash, contractFlags = contractFlags,
contractInfo, chainHash = chainHash,
fundingPubKey, contractInfo = contractInfo,
payoutSPK, fundingPubKey = fundingPubKey,
payoutSerialId, payoutSPK = payoutSPK,
totalCollateralSatoshis, payoutSerialId = payoutSerialId,
fundingInputs, totalCollateralSatoshis = totalCollateralSatoshis,
changeSPK, fundingInputs = fundingInputs,
changeSerialId, changeSPK = changeSPK,
fundingOutputSerialId, changeSerialId = changeSerialId,
feeRate, fundOutputSerialId = fundingOutputSerialId,
contractMaturityBound, feeRate = feeRate,
contractTimeout contractMaturityBound = contractMaturityBound,
contractTimeout = contractTimeout
) )
} }

View file

@ -1,4 +1,4 @@
package org.bitcoins.commons.serializers package org.bitcoins.core.serializers
object PicklerKeys { object PicklerKeys {
final val myCollateral: String = "myCollateral" final val myCollateral: String = "myCollateral"
@ -17,4 +17,7 @@ object PicklerKeys {
final val payoutKey: String = "payout" final val payoutKey: String = "payout"
final val extraPrecisionKey: String = "extraPrecision" final val extraPrecisionKey: String = "extraPrecision"
final val isEndpointKey: String = "isEndpoint" final val isEndpointKey: String = "isEndpoint"
//offers
final val protocolVersionKey: String = "protocolVersion"
} }

View file

@ -4,6 +4,7 @@ import org.bitcoins.core.number.{UInt16, UInt64}
import org.bitcoins.core.protocol.BigSizeUInt import org.bitcoins.core.protocol.BigSizeUInt
import org.bitcoins.core.protocol.script.EmptyScriptPubKey import org.bitcoins.core.protocol.script.EmptyScriptPubKey
import org.bitcoins.core.protocol.tlv._ import org.bitcoins.core.protocol.tlv._
import org.bitcoins.core.serializers.PicklerKeys
import org.bitcoins.crypto.{CryptoUtil, NetworkElement} import org.bitcoins.crypto.{CryptoUtil, NetworkElement}
import org.bitcoins.dlc.testgen.ByteVectorWrapper._ import org.bitcoins.dlc.testgen.ByteVectorWrapper._
import play.api.libs.json._ import play.api.libs.json._
@ -285,7 +286,8 @@ object DLCParsingTestVector extends TestVectorParser[DLCParsingTestVector] {
}) })
) )
DLCTLVTestVector(tlv, "funding_signatures_v0", fields) DLCTLVTestVector(tlv, "funding_signatures_v0", fields)
case DLCOfferTLV(contractFlags, case DLCOfferTLV(versionOpt,
contractFlags,
chainHash, chainHash,
contractInfo, contractInfo,
fundingPubKey, fundingPubKey,
@ -299,7 +301,13 @@ object DLCParsingTestVector extends TestVectorParser[DLCParsingTestVector] {
feeRate, feeRate,
contractMaturityBound, contractMaturityBound,
contractTimeout) => contractTimeout) =>
val fields = Vector( val version = versionOpt match {
case Some(version) =>
Vector(PicklerKeys.protocolVersionKey -> Element(UInt16(version)))
case None =>
Vector.empty
}
val fields = version ++ Vector(
"tpe" -> Element(UInt16(DLCOfferTLV.tpe.toInt)), "tpe" -> Element(UInt16(DLCOfferTLV.tpe.toInt)),
"contractFlags" -> Element(ByteVector(contractFlags)), "contractFlags" -> Element(ByteVector(contractFlags)),
"chainHash" -> Element(chainHash), "chainHash" -> Element(chainHash),

View file

@ -229,6 +229,7 @@ object DLCTLVGen {
} }
def dlcOffer( def dlcOffer(
protocolVersionOpt: Option[Int] = DLCOfferTLV.currentVersionOpt,
contractInfo: ContractInfo = genContractInfo(), contractInfo: ContractInfo = genContractInfo(),
fundingPubKey: ECPublicKey = ECPublicKey.freshPublicKey, fundingPubKey: ECPublicKey = ECPublicKey.freshPublicKey,
payoutAddress: BitcoinAddress = address(), payoutAddress: BitcoinAddress = address(),
@ -242,6 +243,7 @@ object DLCTLVGen {
contractMaturityBound: BlockTimeStamp = BlockTimeStamp(100), contractMaturityBound: BlockTimeStamp = BlockTimeStamp(100),
contractTimeout: BlockTimeStamp = BlockTimeStamp(200)): DLCOffer = { contractTimeout: BlockTimeStamp = BlockTimeStamp(200)): DLCOffer = {
DLCOffer( DLCOffer(
protocolVersionOpt,
contractInfo, contractInfo,
DLCPublicKeys(fundingPubKey, payoutAddress), DLCPublicKeys(fundingPubKey, payoutAddress),
totalCollateral, totalCollateral,
@ -256,6 +258,7 @@ object DLCTLVGen {
} }
def dlcOfferTLV( def dlcOfferTLV(
protocolVersionOpt: Option[Int] = DLCOfferTLV.currentVersionOpt,
contractInfo: ContractInfo = genContractInfo(), contractInfo: ContractInfo = genContractInfo(),
fundingPubKey: ECPublicKey = ECPublicKey.freshPublicKey, fundingPubKey: ECPublicKey = ECPublicKey.freshPublicKey,
payoutAddress: BitcoinAddress = address(), payoutAddress: BitcoinAddress = address(),
@ -269,6 +272,7 @@ object DLCTLVGen {
contractMaturityBound: BlockTimeStamp = BlockTimeStamp(100), contractMaturityBound: BlockTimeStamp = BlockTimeStamp(100),
contractTimeout: BlockTimeStamp = BlockTimeStamp(200)): DLCOfferTLV = { contractTimeout: BlockTimeStamp = BlockTimeStamp(200)): DLCOfferTLV = {
dlcOffer( dlcOffer(
protocolVersionOpt,
contractInfo, contractInfo,
fundingPubKey, fundingPubKey,
payoutAddress, payoutAddress,
@ -285,6 +289,7 @@ object DLCTLVGen {
} }
def dlcOfferParsingTestVector( def dlcOfferParsingTestVector(
protocolVersionOpt: Option[Int] = DLCOfferTLV.currentVersionOpt,
contractInfo: ContractInfo = genContractInfo(), contractInfo: ContractInfo = genContractInfo(),
fundingPubKey: ECPublicKey = ECPublicKey.freshPublicKey, fundingPubKey: ECPublicKey = ECPublicKey.freshPublicKey,
payoutAddress: BitcoinAddress = address(), payoutAddress: BitcoinAddress = address(),
@ -300,6 +305,7 @@ object DLCTLVGen {
BlockTimeStamp(200)): DLCParsingTestVector = { BlockTimeStamp(200)): DLCParsingTestVector = {
DLCParsingTestVector( DLCParsingTestVector(
dlcOfferTLV( dlcOfferTLV(
protocolVersionOpt,
contractInfo, contractInfo,
fundingPubKey, fundingPubKey,
payoutAddress, payoutAddress,

View file

@ -117,6 +117,7 @@ case class DLCPartyParams(
def toOffer(params: DLCParams): DLCOffer = { def toOffer(params: DLCParams): DLCOffer = {
DLCOffer( DLCOffer(
DLCOfferTLV.currentVersionOpt,
ContractInfo( ContractInfo(
EnumContractDescriptor(params.contractInfo.map(_.toMapEntry)), EnumContractDescriptor(params.contractInfo.map(_.toMapEntry)),
params.oracleInfo), params.oracleInfo),

View file

@ -709,6 +709,7 @@ class WalletDLCSetupTest extends BitcoinSDualWalletTest {
"fdd824b4caaec7479cc9d37003f5add6504d035054ffeac8637a990305a45cfecc1062044c3f68b45318f57e41c4544a4a950c0744e2a80854349a3426b00ad86da5090b9e942dc6df2ae87f007b45b0ccd63e6c354d92c4545fc099ea3e137e54492d1efdd822500001a6a09c7c83c50b34f9db560a2e14fef2eab5224c15b18c7114331756364bfce65ffe3800fdd8062400030c44656d6f637261745f77696e0e52657075626c6963616e5f77696e056f746865720161")) "fdd824b4caaec7479cc9d37003f5add6504d035054ffeac8637a990305a45cfecc1062044c3f68b45318f57e41c4544a4a950c0744e2a80854349a3426b00ad86da5090b9e942dc6df2ae87f007b45b0ccd63e6c354d92c4545fc099ea3e137e54492d1efdd822500001a6a09c7c83c50b34f9db560a2e14fef2eab5224c15b18c7114331756364bfce65ffe3800fdd8062400030c44656d6f637261745f77696e0e52657075626c6963616e5f77696e056f746865720161"))
val offerData = DLCOffer( val offerData = DLCOffer(
DLCOfferTLV.currentVersionOpt,
ContractInfo(contractDescriptor, oracleInfo), ContractInfo(contractDescriptor, oracleInfo),
dummyDLCKeys, dummyDLCKeys,
Satoshis(5000), Satoshis(5000),

View file

@ -372,6 +372,7 @@ abstract class DLCWallet
BlockTimeStamp(refundLocktime)) BlockTimeStamp(refundLocktime))
offer = DLCOffer( offer = DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = contractInfo, contractInfo = contractInfo,
pubKeys = dlcPubKeys, pubKeys = dlcPubKeys,
totalCollateral = collateral.satoshis, totalCollateral = collateral.satoshis,

View file

@ -6,6 +6,7 @@ import org.bitcoins.core.number.UInt64
import org.bitcoins.core.protocol.BitcoinAddress import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.dlc.models.DLCMessage._ import org.bitcoins.core.protocol.dlc.models.DLCMessage._
import org.bitcoins.core.protocol.dlc.models._ import org.bitcoins.core.protocol.dlc.models._
import org.bitcoins.core.protocol.tlv.DLCOfferTLV
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
import org.bitcoins.crypto._ import org.bitcoins.crypto._
@ -39,6 +40,7 @@ case class DLCOfferDb(
feeRate: SatoshisPerVirtualByte, feeRate: SatoshisPerVirtualByte,
dlcTimeouts: DLCTimeouts): DLCOffer = { dlcTimeouts: DLCTimeouts): DLCOffer = {
DLCOffer( DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = contractInfo, contractInfo = contractInfo,
pubKeys = dlcPubKeys, pubKeys = dlcPubKeys,
totalCollateral = collateral.satoshis, totalCollateral = collateral.satoshis,

View file

@ -174,6 +174,7 @@ Currently, only the most basic Lightning messages are defined (`Ping`, `Pong`, `
```scala mdoc:to-string ```scala mdoc:to-string
val offerTLV = DLCOfferTLV( val offerTLV = DLCOfferTLV(
protocolVersionOpt = None,
contractFlags = 0.toByte, contractFlags = 0.toByte,
chainHash = DoubleSha256Digest.empty, chainHash = DoubleSha256Digest.empty,
contractInfo = contractInfo.toTLV, contractInfo = contractInfo.toTLV,

View file

@ -15,6 +15,7 @@ import org.bitcoins.core.protocol.dlc.models.DLCMessage.DLCAccept
import org.bitcoins.core.protocol.dlc.models._ import org.bitcoins.core.protocol.dlc.models._
import org.bitcoins.core.protocol.dlc.sign.DLCTxSigner import org.bitcoins.core.protocol.dlc.sign.DLCTxSigner
import org.bitcoins.core.protocol.script.ScriptPubKey import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.core.protocol.tlv.DLCOfferTLV
import org.bitcoins.core.protocol.transaction.Transaction import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
import org.bitcoins.core.wallet.utxo.{InputInfo, ScriptSignatureParams} import org.bitcoins.core.wallet.utxo.{InputInfo, ScriptSignatureParams}
@ -208,6 +209,7 @@ object TestDLCClient {
} }
val offer = DLCMessage.DLCOffer( val offer = DLCMessage.DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = offerOutcomes, contractInfo = offerOutcomes,
pubKeys = offerPubKeys, pubKeys = offerPubKeys,
totalCollateral = offerInput.satoshis, totalCollateral = offerInput.satoshis,

View file

@ -403,6 +403,7 @@ trait TLVGen {
} }
DLCOfferTLV( DLCOfferTLV(
protocolVersionOpt = None, //TODO: Comeback and change this
contractFlags = 0.toByte, contractFlags = 0.toByte,
chainHash = chainHash, chainHash = chainHash,
contractInfo = contractInfo, contractInfo = contractInfo,

View file

@ -147,6 +147,7 @@ object DLCWalletUtil extends Logging {
DLCMessage.genSerialId(Vector(sampleOfferChangeSerialId)) DLCMessage.genSerialId(Vector(sampleOfferChangeSerialId))
lazy val sampleDLCOffer: DLCOffer = DLCOffer( lazy val sampleDLCOffer: DLCOffer = DLCOffer(
protocolVersionOpt = DLCOfferTLV.currentVersionOpt,
contractInfo = sampleContractInfo, contractInfo = sampleContractInfo,
pubKeys = dummyDLCKeys, pubKeys = dummyDLCKeys,
totalCollateral = half, totalCollateral = half,