Add ability to delete Oracle signatures (#2851)

* Add ability to delete Oracle signatures

* Respond to review
This commit is contained in:
benthecarman 2021-04-02 13:55:47 -05:00 committed by GitHub
parent 2554665e89
commit 3dbeac276e
3 changed files with 154 additions and 1 deletions

View File

@ -62,4 +62,18 @@ trait DLCOracleApi {
def signDigits(eventName: String, num: Long): Future[OracleEvent]
def signDigits(oracleEventTLV: OracleEventTLV, num: Long): Future[OracleEvent]
/** Deletes attestations for the given event
*
* WARNING: if previous signatures have been made public
* the oracle private key will be revealed.
*/
def deleteAttestations(eventName: String): Future[OracleEvent]
/** Deletes attestations for the given event
*
* WARNING: if previous signatures have been made public
* the oracle private key will be revealed.
*/
def deleteAttestations(oracleEventTLV: OracleEventTLV): Future[OracleEvent]
}

View File

@ -727,4 +727,112 @@ class DLCOracleTest extends DLCOracleFixture {
SigningVersion.latest))
}
}
it must "create and delete signatures for an enum event" in {
dlcOracle: DLCOracle =>
val descriptor = TLVGen.enumEventDescriptorV0TLV.sampleSome
val outcome = descriptor.outcomes.head
val descriptorV0TLV =
EnumEventDescriptorV0TLV(descriptor.outcomes)
for {
announcement <-
dlcOracle.createNewEvent("test", futureTime, descriptorV0TLV)
_ <-
dlcOracle.signEnumEvent(announcement.eventTLV,
EnumAttestation(outcome))
signedEvent <- dlcOracle.findEvent("test").map(_.get)
_ = {
signedEvent match {
case c: CompletedEnumV0OracleEvent =>
assert(c.attestations.nonEmpty)
assert(c.outcomes.nonEmpty)
case _: PendingOracleEvent | _: CompletedOracleEvent =>
fail()
}
}
_ <- dlcOracle.deleteAttestations("test")
event <- dlcOracle.findEvent("test").map(_.get)
} yield {
event match {
case _: PendingEnumV0OracleEvent => succeed
case _: PendingOracleEvent | _: CompletedOracleEvent =>
fail()
}
}
}
it must "create and delete signatures for a decomp event" in {
dlcOracle: DLCOracle =>
val descriptor =
UnsignedDigitDecompositionEventDescriptor(UInt16(2),
UInt16(3),
"unit",
Int32(0))
for {
_ <- dlcOracle.createNewEvent("test", futureTime, descriptor)
_ <- dlcOracle.signDigits("test", 0)
signedEvent <- dlcOracle.findEvent("test").map(_.get)
_ = {
signedEvent match {
case c: CompletedDigitDecompositionV0OracleEvent =>
assert(c.attestations.nonEmpty)
assert(c.outcomes.nonEmpty)
case _: PendingOracleEvent | _: CompletedOracleEvent =>
fail()
}
}
_ <- dlcOracle.deleteAttestations("test")
event <- dlcOracle.findEvent("test").map(_.get)
} yield {
event match {
case _: PendingDigitDecompositionV0OracleEvent => succeed
case _: PendingOracleEvent | _: CompletedOracleEvent =>
fail()
}
}
}
it must "fail to delete signatures for an unsigned enum event" in {
dlcOracle: DLCOracle =>
val descriptor =
UnsignedDigitDecompositionEventDescriptor(UInt16(2),
UInt16(3),
"unit",
Int32(0))
for {
_ <- dlcOracle.createNewEvent("test", futureTime, descriptor)
signedEvent <- dlcOracle.findEvent("test").map(_.get)
_ = assert(
signedEvent.isInstanceOf[PendingDigitDecompositionV0OracleEvent])
res <- recoverToSucceededIf[IllegalArgumentException](
dlcOracle.deleteAttestations("test"))
} yield res
}
it must "fail to delete signatures for an unsigned decomp event" in {
dlcOracle: DLCOracle =>
val descriptor = TLVGen.enumEventDescriptorV0TLV.sampleSome
for {
_ <- dlcOracle.createNewEvent("test", futureTime, descriptor)
signedEvent <- dlcOracle.findEvent("test").map(_.get)
_ = assert(signedEvent.isInstanceOf[PendingEnumV0OracleEvent])
res <- recoverToSucceededIf[IllegalArgumentException](
dlcOracle.deleteAttestations("test"))
} yield res
}
}

View File

@ -1,5 +1,6 @@
package org.bitcoins.dlc.oracle
import grizzled.slf4j.Logging
import org.bitcoins.core.api.dlcoracle._
import org.bitcoins.core.api.dlcoracle.db._
import org.bitcoins.core.config.BitcoinNetwork
@ -17,7 +18,6 @@ import org.bitcoins.dlc.oracle.config.DLCOracleAppConfig
import org.bitcoins.dlc.oracle.storage._
import org.bitcoins.dlc.oracle.util.EventDbUtil
import org.bitcoins.keymanager.{DecryptedMnemonic, WalletStorage}
import grizzled.slf4j.Logging
import java.time.Instant
import scala.concurrent.{ExecutionContext, Future}
@ -372,6 +372,37 @@ class DLCOracle(private[this] val extPrivateKey: ExtPrivateKeyHardened)(implicit
digitSigs <- Future.sequence(digitSigFs)
} yield OracleEvent.fromEventDbs(signSig ++ digitSigs)
}
/** Deletes attestations for the given event
*
* WARNING: if previous signatures have been made public
* the oracle private key will be revealed.
*/
override def deleteAttestations(eventName: String): Future[OracleEvent] = {
for {
eventOpt <- findEvent(eventName)
_ = require(eventOpt.isDefined,
s"No event found by event name $eventName")
res <- deleteAttestations(eventOpt.get.eventTLV)
} yield res
}
/** Deletes attestations for the given event
*
* WARNING: if previous signatures have been made public
* the oracle private key will be revealed.
*/
override def deleteAttestations(
oracleEventTLV: OracleEventTLV): Future[OracleEvent] = {
for {
eventDbs <- eventDAO.findByOracleEventTLV(oracleEventTLV)
_ = require(eventDbs.exists(_.attestationOpt.isDefined),
s"Event given is unsigned")
updated = eventDbs.map(_.copy(outcomeOpt = None, attestationOpt = None))
_ <- eventDAO.updateAll(updated)
} yield OracleEvent.fromEventDbs(eventDbs)
}
}
object DLCOracle {