Fix DLCOracle to be Network Agnostic (#2749)

* Fix DLCOracle to be Network Agnostic

* improve comment

* Added test

* Improve comment
This commit is contained in:
benthecarman 2021-03-03 15:31:56 -06:00 committed by GitHub
parent 99c5d6e29b
commit 2a6da6a4ea
4 changed files with 72 additions and 6 deletions

View file

@ -1,7 +1,8 @@
package org.bitcoins.dlc.oracle package org.bitcoins.dlc.oracle
import org.bitcoins.core.api.dlcoracle.db._ import com.typesafe.config.ConfigFactory
import org.bitcoins.core.api.dlcoracle._ import org.bitcoins.core.api.dlcoracle._
import org.bitcoins.core.api.dlcoracle.db._
import org.bitcoins.core.hd.{HDCoinType, HDPurpose} import org.bitcoins.core.hd.{HDCoinType, HDPurpose}
import org.bitcoins.core.number._ import org.bitcoins.core.number._
import org.bitcoins.core.protocol.Bech32Address import org.bitcoins.core.protocol.Bech32Address
@ -10,9 +11,9 @@ import org.bitcoins.core.protocol.script.P2WPKHWitnessSPKV0
import org.bitcoins.core.protocol.tlv._ import org.bitcoins.core.protocol.tlv._
import org.bitcoins.core.util.TimeUtil import org.bitcoins.core.util.TimeUtil
import org.bitcoins.crypto._ import org.bitcoins.crypto._
import org.bitcoins.testkit.fixtures.DLCOracleFixture
import org.bitcoins.testkitcore.Implicits._ import org.bitcoins.testkitcore.Implicits._
import org.bitcoins.testkitcore.gen.{ChainParamsGenerator, TLVGen} import org.bitcoins.testkitcore.gen.{ChainParamsGenerator, TLVGen}
import org.bitcoins.testkit.fixtures.DLCOracleFixture
import java.time.Instant import java.time.Instant
@ -59,6 +60,51 @@ class DLCOracleTest extends DLCOracleFixture {
} }
} }
it must "have same keys with different network configs" in {
oracleA: DLCOracle =>
// set to mainnet and give separate db
val newConf = oracleA.conf.newConfigOfType(
Vector(ConfigFactory.parseString("bitcoin-s.network = mainnet"),
ConfigFactory.parseString("bitcoin-s.oracle.db.name = oracle1")))
newConf.initialize().flatMap { oracleB =>
assert(oracleA.publicKey == oracleB.publicKey)
val eventName = "test"
val descriptorTLV =
DigitDecompositionEventDescriptorV0TLV(base = UInt16(2),
isSigned = false,
numDigits = 3,
unit = "units",
precision = Int32.zero)
for {
announcementA <- oracleA.createNewEvent(eventName = eventName,
maturationTime = futureTime,
descriptorTLV)
announcementB <- oracleB.createNewEvent(eventName = eventName,
maturationTime = futureTime,
descriptorTLV)
// Can't compare announcementTLV because different nonces might be used for signature
_ = assert(announcementA.publicKey == announcementB.publicKey)
_ = assert(announcementA.eventTLV == announcementB.eventTLV)
eventA <- oracleA.signDigits(eventName, 1)
eventB <- oracleB.signDigits(eventName, 1)
} yield {
(eventA, eventB) match {
case (completedA: CompletedDigitDecompositionV0OracleEvent,
completedB: CompletedDigitDecompositionV0OracleEvent) =>
assert(
completedA.oracleAttestmentV0TLV == completedB.oracleAttestmentV0TLV)
case (_, _) =>
fail("Unexpected outcome")
}
}
}
}
it must "create a new event and list it with pending" in { it must "create a new event and list it with pending" in {
dlcOracle: DLCOracle => dlcOracle: DLCOracle =>
val time = futureTime val time = futureTime

View file

@ -28,10 +28,18 @@ class DLCOracle(private[this] val extPrivateKey: ExtPrivateKeyHardened)(implicit
implicit val ec: ExecutionContext = conf.ec implicit val ec: ExecutionContext = conf.ec
// We have to use Testnet here because before this was dictated by
// by the network config. The default network config was Regtest,
// which uses a Testnet HDCoinType, so that was chosen as the hard coded value.
// It was a mistake to originally have this dictated by the config
// as the oracle should be network agnostic.
// see https://github.com/bitcoin-s/bitcoin-s/issues/2748
private val coinType = HDCoinType.Testnet
private val rValAccount: HDAccount = { private val rValAccount: HDAccount = {
val purpose = conf.kmParams.purpose val purpose = conf.kmParams.purpose
val coin =
HDCoin(purpose, HDCoinType.fromNetwork(conf.network)) val coin = HDCoin(purpose, coinType)
HDAccount(coin, 0) HDAccount(coin, 0)
} }
@ -39,7 +47,7 @@ class DLCOracle(private[this] val extPrivateKey: ExtPrivateKeyHardened)(implicit
private val rValueChainIndex = 0 private val rValueChainIndex = 0
private def signingKey: ECPrivateKey = { private def signingKey: ECPrivateKey = {
val coin = HDCoin(HDPurposes.SegWit, HDCoinType.fromNetwork(conf.network)) val coin = HDCoin(HDPurposes.SegWit, coinType)
val account = HDAccount(coin, 0) val account = HDAccount(coin, 0)
val purpose = coin.purpose val purpose = coin.purpose
val chain = HDChainType.External val chain = HDChainType.External

View file

@ -165,7 +165,13 @@ case class DLCOracleAppConfig(
bip39PasswordOpt) bip39PasswordOpt)
val oracle = new DLCOracle(key)(this) val oracle = new DLCOracle(key)(this)
start().map(_ => oracle) for {
_ <- start()
differentKeyDbs <- oracle.eventDAO.findDifferentPublicKey(
oracle.publicKey)
fixedDbs = differentKeyDbs.map(_.copy(pubkey = oracle.publicKey))
_ <- oracle.eventDAO.updateAll(fixedDbs)
} yield oracle
} }
private lazy val rValueTable: TableQuery[Table[_]] = { private lazy val rValueTable: TableQuery[Table[_]] = {

View file

@ -70,6 +70,12 @@ case class EventDAO()(implicit
safeDatabase.runVec(query.result.transactionally) safeDatabase.runVec(query.result.transactionally)
} }
def findDifferentPublicKey(key: SchnorrPublicKey): Future[Vector[EventDb]] = {
val query = table.filterNot(_.pubkey === key)
safeDatabase.runVec(query.result.transactionally)
}
class EventTable(tag: Tag) extends Table[EventDb](tag, schemaName, "events") { class EventTable(tag: Tag) extends Table[EventDb](tag, schemaName, "events") {
def nonce: Rep[SchnorrNonce] = column("nonce", O.PrimaryKey) def nonce: Rep[SchnorrNonce] = column("nonce", O.PrimaryKey)