mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 10:46:42 +01:00
Add signature ordering to ClaimedDLCStatus.oracleSigs
(#4804)
* Add signature ordering to ClaimedDLCStatus.oracleSigs * fix bug
This commit is contained in:
parent
9c506b639f
commit
8d91abd678
6 changed files with 60 additions and 13 deletions
|
@ -11,6 +11,7 @@ import org.bitcoins.core.protocol.dlc.models.{
|
|||
PayoutAddress
|
||||
}
|
||||
import org.bitcoins.core.util.TimeUtil
|
||||
import org.bitcoins.core.util.sorted.OrderedSchnorrSignatures
|
||||
import org.bitcoins.crypto.Sha256Digest
|
||||
import org.bitcoins.testkitcore.gen.{CryptoGenerators, NumberGenerator, TLVGen}
|
||||
import org.bitcoins.testkitcore.util.BitcoinSJvmTest
|
||||
|
@ -247,7 +248,7 @@ class DLCStatusTest extends BitcoinSJvmTest {
|
|||
offer.collateral,
|
||||
fundingTxId,
|
||||
closingTxId,
|
||||
sigs.toVector,
|
||||
OrderedSchnorrSignatures.fromUnsorted(sigs.toVector),
|
||||
outcome,
|
||||
myPayout = myPayout,
|
||||
counterPartyPayout = theirPayout,
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.bitcoins.core.psbt.PSBT
|
|||
import org.bitcoins.core.serializers.PicklerKeys
|
||||
import org.bitcoins.core.util.{NetworkUtil, TimeUtil}
|
||||
import org.bitcoins.core.util.TimeUtil._
|
||||
import org.bitcoins.core.util.sorted.OrderedSchnorrSignatures
|
||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte}
|
||||
import org.bitcoins.core.wallet.utxo.{AddressLabelTag, TxoState}
|
||||
import org.bitcoins.crypto._
|
||||
|
@ -1190,10 +1191,12 @@ object Picklers {
|
|||
lazy val contractId = ByteVector.fromValidHex(obj("contractId").str)
|
||||
lazy val fundingTxId = DoubleSha256DigestBE(obj("fundingTxId").str)
|
||||
lazy val closingTxId = DoubleSha256DigestBE(obj("closingTxId").str)
|
||||
lazy val oracleSigs =
|
||||
obj("oracleSigs").arr
|
||||
lazy val oracleSigs = {
|
||||
val unsorted = obj("oracleSigs").arr
|
||||
.map(value => SchnorrDigitalSignature(value.str))
|
||||
.toVector
|
||||
OrderedSchnorrSignatures.fromUnsorted(unsorted)
|
||||
}
|
||||
|
||||
val payoutAddressJs = obj("payoutAddress")
|
||||
lazy val payoutAddress: Option[PayoutAddress] = payoutAddressJs match {
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.bitcoins.core.protocol.dlc.models.DLCMessage.{
|
|||
}
|
||||
import org.bitcoins.core.protocol.tlv.OracleAnnouncementTLV
|
||||
import org.bitcoins.core.protocol.transaction.WitnessTransaction
|
||||
import org.bitcoins.core.util.sorted.OrderedSchnorrSignatures
|
||||
import org.bitcoins.core.wallet.fee.FeeUnit
|
||||
import org.bitcoins.crypto._
|
||||
import scodec.bits.ByteVector
|
||||
|
@ -78,7 +79,7 @@ sealed trait ClosedDLCStatus extends SignedDLCStatus {
|
|||
|
||||
sealed trait ClaimedDLCStatus extends ClosedDLCStatus {
|
||||
def oracleOutcome: OracleOutcome
|
||||
def oracleSigs: Vector[SchnorrDigitalSignature]
|
||||
def oracleSigs: OrderedSchnorrSignatures
|
||||
}
|
||||
|
||||
object DLCStatus {
|
||||
|
@ -222,7 +223,7 @@ object DLCStatus {
|
|||
localCollateral: CurrencyUnit,
|
||||
fundingTxId: DoubleSha256DigestBE,
|
||||
closingTxId: DoubleSha256DigestBE,
|
||||
oracleSigs: Vector[SchnorrDigitalSignature],
|
||||
oracleSigs: OrderedSchnorrSignatures,
|
||||
oracleOutcome: OracleOutcome,
|
||||
myPayout: CurrencyUnit,
|
||||
counterPartyPayout: CurrencyUnit,
|
||||
|
@ -253,7 +254,9 @@ object DLCStatus {
|
|||
peer: Option[String])
|
||||
extends ClaimedDLCStatus {
|
||||
override val state: DLCState.RemoteClaimed.type = DLCState.RemoteClaimed
|
||||
override val oracleSigs: Vector[SchnorrDigitalSignature] = Vector(oracleSig)
|
||||
|
||||
override val oracleSigs: OrderedSchnorrSignatures =
|
||||
OrderedSchnorrSignatures(oracleSig)
|
||||
}
|
||||
|
||||
case class Refunded(
|
||||
|
@ -306,7 +309,7 @@ object DLCStatus {
|
|||
}
|
||||
|
||||
def getOracleSignatures(
|
||||
status: DLCStatus): Option[Vector[SchnorrDigitalSignature]] = {
|
||||
status: DLCStatus): Option[OrderedSchnorrSignatures] = {
|
||||
status match {
|
||||
case claimed: ClaimedDLCStatus =>
|
||||
Some(claimed.oracleSigs)
|
||||
|
|
|
@ -11,9 +11,10 @@ abstract class SortedVec[T, B >: T](
|
|||
override val wrapped: Vector[T],
|
||||
ord: Ordering[B])
|
||||
extends SeqWrapper[T] {
|
||||
require(
|
||||
wrapped.init.zip(wrapped.tail).forall { case (x, y) => ord.lteq(x, y) },
|
||||
s"Vector must be sorted. $wrapped")
|
||||
require(wrapped.isEmpty || wrapped.init.zip(wrapped.tail).forall {
|
||||
case (x, y) => ord.lteq(x, y)
|
||||
},
|
||||
s"Vector must be sorted. $wrapped")
|
||||
}
|
||||
|
||||
object SortedVec {
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.bitcoins.core.protocol.dlc.models.{
|
|||
import org.bitcoins.core.protocol.tlv._
|
||||
import org.bitcoins.core.script.interpreter.ScriptInterpreter
|
||||
import org.bitcoins.core.script.util.PreviousOutputMap
|
||||
import org.bitcoins.core.util.sorted.OrderedSchnorrSignatures
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.testkit.wallet.DLCWalletUtil._
|
||||
import org.bitcoins.testkit.wallet.{BitcoinSDualWalletTest, DLCWalletUtil}
|
||||
|
@ -437,6 +438,43 @@ class DLCExecutionTest extends BitcoinSDualWalletTest {
|
|||
} yield succeed
|
||||
}
|
||||
|
||||
it must "throw an exception for a enum contract when do not have all the oracle signatures/outcomes" in {
|
||||
wallets =>
|
||||
val walletA = wallets._1.wallet
|
||||
val resultF = for {
|
||||
contractId <- getContractId(walletA)
|
||||
status <- getDLCStatus(walletA)
|
||||
(goodAttestment, _) = {
|
||||
status.contractInfo match {
|
||||
case single: SingleContractInfo =>
|
||||
DLCWalletUtil.getSigs(single)
|
||||
case disjoint: DisjointUnionContractInfo =>
|
||||
sys.error(
|
||||
s"Cannot retrieve sigs for disjoint union contract, got=$disjoint")
|
||||
}
|
||||
}
|
||||
//purposefully drop these
|
||||
//we cannot drop just a sig, or just an outcome because
|
||||
//of invariants in OracleAttestmentV0TLV
|
||||
badSigs = goodAttestment.sigs.dropRight(1)
|
||||
badOutcomes = goodAttestment.outcomes.dropRight(1)
|
||||
badAttestment = OracleAttestmentV0TLV(
|
||||
eventId = goodAttestment.eventId,
|
||||
publicKey = goodAttestment.publicKey,
|
||||
sigs = OrderedSchnorrSignatures.fromUnsorted(badSigs.toVector),
|
||||
outcomes = badOutcomes)
|
||||
func = (wallet: DLCWallet) =>
|
||||
wallet.executeDLC(contractId, badAttestment).map(_.get)
|
||||
|
||||
result <- dlcExecutionTest(wallets = wallets,
|
||||
asInitiator = true,
|
||||
func = func,
|
||||
expectedOutputs = 1)
|
||||
} yield assert(result)
|
||||
|
||||
recoverToSucceededIf[IllegalArgumentException](resultF)
|
||||
}
|
||||
|
||||
it must "throw an exception when you try to execute a DLC in the SIGNED state" in {
|
||||
wallets =>
|
||||
val walletA = wallets._1.wallet
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.bitcoins.core.protocol.dlc.models.DLCStatus._
|
|||
import org.bitcoins.core.protocol.dlc.models._
|
||||
import org.bitcoins.core.protocol.tlv._
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.crypto.SchnorrDigitalSignature
|
||||
import org.bitcoins.core.util.sorted.OrderedSchnorrSignatures
|
||||
import org.bitcoins.dlc.wallet.accounting.{AccountingUtil, DLCAccountingDbs}
|
||||
import org.bitcoins.dlc.wallet.models._
|
||||
|
||||
|
@ -317,7 +317,7 @@ object DLCStatusBuilder {
|
|||
announcementsWithId: Vector[(OracleAnnouncementV0TLV, Long)],
|
||||
nonceDbs: Vector[OracleNonceDb]): (
|
||||
OracleOutcome,
|
||||
Vector[SchnorrDigitalSignature]) = {
|
||||
OrderedSchnorrSignatures) = {
|
||||
val noncesByAnnouncement: Map[Long, Vector[OracleNonceDb]] =
|
||||
nonceDbs.sortBy(_.index).groupBy(_.announcementId)
|
||||
val oracleOutcome = {
|
||||
|
@ -357,6 +357,7 @@ object DLCStatusBuilder {
|
|||
}
|
||||
|
||||
val sigs = nonceDbs.flatMap(_.signatureOpt)
|
||||
(oracleOutcome, sigs)
|
||||
val ordered = OrderedSchnorrSignatures.fromUnsorted(sigs)
|
||||
(oracleOutcome, ordered)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue