mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-26 21:42:48 +01:00
2024 10 07 v28 bitcoind (#5696)
* Update to bitcoind v28 * Add macOS arm64 hash * Add 28.0 version for windows * Fix windows hash * Replace 'port' with 'bind' in bitcoin.conf * Fix BitcoindConfig.bind, add -deprecatedrpc=warnings * Add version specific warnings handling for V28 * Add pattern matching based on version to support new json format for warnings fields in Info RPCs * Fix pattern match on V28 * Remove infinite loop w/ 'getnetworkinfo' when determing the version of a BitcoindRpcClient * Pin lndRpcTest to bitcoind v27 until v28 is supported * Add mempoolconflicts to 'gettransaction' RPC * init 'gethdkeys' rpc * WIP: createwalletdescriptor * Get createwalletdescriptor test passing * Revert files
This commit is contained in:
parent
7dc58666b9
commit
38f0f4d692
27 changed files with 463 additions and 97 deletions
|
@ -115,7 +115,6 @@ sealed trait GetBlockChainInfoResult extends BlockchainResult {
|
|||
def size_on_disk: Long
|
||||
def pruned: Boolean
|
||||
def pruneheight: Option[Int]
|
||||
def warnings: String
|
||||
}
|
||||
|
||||
// adds time field removes softforks field
|
||||
|
@ -136,6 +135,23 @@ case class GetBlockChainInfoResultPostV23(
|
|||
warnings: String
|
||||
) extends GetBlockChainInfoResult
|
||||
|
||||
case class GetBlockChainInfoResultPostV27(
|
||||
chain: NetworkParameters,
|
||||
blocks: Int,
|
||||
headers: Int,
|
||||
bestblockhash: DoubleSha256DigestBE,
|
||||
difficulty: BigDecimal,
|
||||
time: Int,
|
||||
mediantime: Int,
|
||||
verificationprogress: BigDecimal,
|
||||
initialblockdownload: Boolean,
|
||||
chainwork: String, // How should this be handled?
|
||||
size_on_disk: Long,
|
||||
pruned: Boolean,
|
||||
pruneheight: Option[Int],
|
||||
warnings: Vector[String]
|
||||
) extends GetBlockChainInfoResult
|
||||
|
||||
case class SoftforkPreV19(
|
||||
id: String,
|
||||
version: Int,
|
||||
|
|
|
@ -34,7 +34,7 @@ case class NetTarget(
|
|||
time_left_in_cycle: UInt32
|
||||
) extends NetworkResult
|
||||
|
||||
trait GetNetworkInfoResult extends NetworkResult {
|
||||
sealed trait GetNetworkInfoResult extends NetworkResult {
|
||||
def version: Int
|
||||
def subversion: String
|
||||
def protocolversion: Int
|
||||
|
@ -44,14 +44,15 @@ trait GetNetworkInfoResult extends NetworkResult {
|
|||
def timeoffset: Int
|
||||
def networkactive: Boolean
|
||||
def connections: Int
|
||||
def connections_in: Int
|
||||
def connections_out: Int
|
||||
def networks: Vector[Network]
|
||||
def relayfee: Bitcoins
|
||||
def incrementalfee: Bitcoins
|
||||
def localaddresses: Vector[NetworkAddress]
|
||||
def warnings: String
|
||||
}
|
||||
|
||||
case class GetNetworkInfoResultPreV21(
|
||||
case class GetNetworkInfoResultV28(
|
||||
version: Int,
|
||||
subversion: String,
|
||||
protocolversion: Int,
|
||||
|
@ -61,11 +62,13 @@ case class GetNetworkInfoResultPreV21(
|
|||
timeoffset: Int,
|
||||
networkactive: Boolean,
|
||||
connections: Int,
|
||||
connections_in: Int,
|
||||
connections_out: Int,
|
||||
networks: Vector[Network],
|
||||
relayfee: Bitcoins,
|
||||
incrementalfee: Bitcoins,
|
||||
localaddresses: Vector[NetworkAddress],
|
||||
warnings: String
|
||||
warnings: Vector[String]
|
||||
) extends GetNetworkInfoResult
|
||||
|
||||
case class GetNetworkInfoResultPostV21(
|
||||
|
|
|
@ -54,7 +54,17 @@ case class BlockTransaction(
|
|||
required: Option[Boolean]
|
||||
) extends OtherResult
|
||||
|
||||
case class GetMiningInfoResult(
|
||||
sealed abstract class GetMiningInfoResult extends OtherResult {
|
||||
def blocks: Int
|
||||
def currentblockweight: Option[Int]
|
||||
def currentblocktx: Option[Int]
|
||||
def difficulty: BigDecimal
|
||||
def networkhashps: BigDecimal
|
||||
def pooledtx: Int
|
||||
def chain: String
|
||||
}
|
||||
|
||||
case class GetMiningInfoResultPre28(
|
||||
blocks: Int,
|
||||
currentblockweight: Option[Int],
|
||||
currentblocktx: Option[Int],
|
||||
|
@ -62,8 +72,19 @@ case class GetMiningInfoResult(
|
|||
networkhashps: BigDecimal,
|
||||
pooledtx: Int,
|
||||
chain: String,
|
||||
warnings: String
|
||||
) extends OtherResult
|
||||
warnings: String)
|
||||
extends GetMiningInfoResult
|
||||
|
||||
case class GetMiningInfoResultV28(
|
||||
blocks: Int,
|
||||
currentblockweight: Option[Int],
|
||||
currentblocktx: Option[Int],
|
||||
difficulty: BigDecimal,
|
||||
networkhashps: BigDecimal,
|
||||
pooledtx: Int,
|
||||
chain: String,
|
||||
warnings: Vector[String])
|
||||
extends GetMiningInfoResult
|
||||
|
||||
case class GetMemoryInfoResult(locked: MemoryManager) extends OtherResult
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.bitcoins.commons.jsonmodels.bitcoind
|
||||
|
||||
import org.bitcoins.commons.serializers.JsonWriters
|
||||
import org.bitcoins.core.currency.Bitcoins
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
|
@ -8,7 +9,8 @@ import org.bitcoins.core.protocol.transaction.{
|
|||
TransactionInput,
|
||||
TransactionOutPoint
|
||||
}
|
||||
import org.bitcoins.commons.serializers.JsonWriters._
|
||||
import org.bitcoins.commons.serializers.JsonWriters.*
|
||||
import org.bitcoins.core.crypto.ExtKey
|
||||
import org.bitcoins.crypto.{
|
||||
DoubleSha256DigestBE,
|
||||
ECPrivateKeyBytes,
|
||||
|
@ -267,4 +269,12 @@ object RpcOpts {
|
|||
override val action: String = "abort"
|
||||
}
|
||||
}
|
||||
|
||||
case class CreateWalletDescriptorOptions(internal: Boolean, hdkey: ExtKey)
|
||||
|
||||
implicit val createWalletDescriptorOptionsWrites
|
||||
: Writes[CreateWalletDescriptorOptions] = {
|
||||
import JsonWriters.ExtKeyWrites
|
||||
Json.writes[CreateWalletDescriptorOptions]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.bitcoins.commons.jsonmodels.bitcoind
|
|||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.LabelPurpose
|
||||
import org.bitcoins.commons.rpc.BitcoindException
|
||||
import org.bitcoins.core.crypto.{ExtPrivateKey, ExtPublicKey}
|
||||
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
|
||||
import org.bitcoins.core.hd.BIP32Path
|
||||
import org.bitcoins.core.number.UInt32
|
||||
|
@ -42,7 +43,34 @@ case class BumpFeeResult(
|
|||
errors: Vector[String]
|
||||
) extends WalletResult
|
||||
|
||||
case class GetTransactionResult(
|
||||
case class HDKeyDescriptor(desc: Descriptor, active: Boolean)
|
||||
case class GetHDKeysResult(
|
||||
xpub: ExtPublicKey,
|
||||
has_private: Boolean,
|
||||
xprv: Option[ExtPrivateKey],
|
||||
descriptors: Vector[HDKeyDescriptor])
|
||||
extends WalletResult
|
||||
|
||||
sealed trait GetTransactionResult extends WalletResult {
|
||||
def amount: Bitcoins
|
||||
def fee: Option[Bitcoins]
|
||||
def confirmations: Int
|
||||
def generated: Option[Boolean]
|
||||
def blockhash: Option[DoubleSha256DigestBE]
|
||||
def blockindex: Option[Int]
|
||||
def blocktime: Option[UInt32]
|
||||
def txid: DoubleSha256DigestBE
|
||||
def walletconflicts: Vector[DoubleSha256DigestBE]
|
||||
def time: UInt32
|
||||
def timereceived: UInt32
|
||||
def bip125_replaceable: Option[String]
|
||||
def comment: Option[String]
|
||||
def to: Option[String]
|
||||
def details: Vector[TransactionDetails]
|
||||
def hex: Transaction
|
||||
}
|
||||
|
||||
case class GetTransactionResultPreV28(
|
||||
amount: Bitcoins,
|
||||
fee: Option[Bitcoins],
|
||||
confirmations: Int,
|
||||
|
@ -54,12 +82,32 @@ case class GetTransactionResult(
|
|||
walletconflicts: Vector[DoubleSha256DigestBE],
|
||||
time: UInt32,
|
||||
timereceived: UInt32,
|
||||
bip125_replaceable: String,
|
||||
bip125_replaceable: Option[String],
|
||||
comment: Option[String],
|
||||
to: Option[String],
|
||||
details: Vector[TransactionDetails],
|
||||
hex: Transaction
|
||||
) extends WalletResult
|
||||
) extends GetTransactionResult
|
||||
|
||||
case class GetTransactionResultV28(
|
||||
amount: Bitcoins,
|
||||
fee: Option[Bitcoins],
|
||||
confirmations: Int,
|
||||
generated: Option[Boolean],
|
||||
blockhash: Option[DoubleSha256DigestBE],
|
||||
blockindex: Option[Int],
|
||||
blocktime: Option[UInt32],
|
||||
txid: DoubleSha256DigestBE,
|
||||
walletconflicts: Vector[DoubleSha256DigestBE],
|
||||
time: UInt32,
|
||||
timereceived: UInt32,
|
||||
bip125_replaceable: Option[String],
|
||||
comment: Option[String],
|
||||
to: Option[String],
|
||||
details: Vector[TransactionDetails],
|
||||
hex: Transaction,
|
||||
mempoolconflicts: Vector[Transaction]
|
||||
) extends GetTransactionResult
|
||||
|
||||
case class SetWalletFlagResult(
|
||||
flag_name: String,
|
||||
|
@ -395,3 +443,5 @@ case class ImportDescriptorResult(
|
|||
) extends WalletResult
|
||||
|
||||
case class PrioritisedTransaction(fee_delta: Satoshis, in_mempool: Boolean)
|
||||
|
||||
case class CreateWalletDescriptorResult(descs: Vector[Descriptor])
|
||||
|
|
|
@ -1743,4 +1743,9 @@ object JsonReaders {
|
|||
}
|
||||
}
|
||||
|
||||
implicit val createWalletDescriptorReads
|
||||
: Reads[CreateWalletDescriptorResult] = {
|
||||
Json.reads[CreateWalletDescriptorResult]
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -190,12 +190,16 @@ object JsonSerializers {
|
|||
implicit val networkAddressReads: Reads[NetworkAddress] =
|
||||
Json.reads[NetworkAddress]
|
||||
|
||||
implicit val geNetworkInfoPreV21Reads: Reads[GetNetworkInfoResultPreV21] =
|
||||
Json.reads[GetNetworkInfoResultPreV21]
|
||||
implicit val getNetworkInfoV28Reads: Reads[GetNetworkInfoResultV28] =
|
||||
Json.reads[GetNetworkInfoResultV28]
|
||||
|
||||
implicit val geNetworkInfoPostV21Reads: Reads[GetNetworkInfoResultPostV21] =
|
||||
implicit val getNetworkInfoPostV21Reads: Reads[GetNetworkInfoResultPostV21] =
|
||||
Json.reads[GetNetworkInfoResultPostV21]
|
||||
|
||||
implicit val getNetworkInfoReads: Reads[GetNetworkInfoResult] = {
|
||||
Json.reads[GetNetworkInfoResult]
|
||||
}
|
||||
|
||||
implicit val satsPerKbReads: Reads[SatoshisPerKiloByte] =
|
||||
new Reads[SatoshisPerKiloByte] {
|
||||
|
||||
|
@ -298,6 +302,15 @@ object JsonSerializers {
|
|||
: Reads[GetBlockChainInfoResultPostV23] =
|
||||
Json.reads[GetBlockChainInfoResultPostV23]
|
||||
|
||||
implicit val getBlockChainInfoResultPost27Reads
|
||||
: Reads[GetBlockChainInfoResultPostV27] = {
|
||||
Json.reads[GetBlockChainInfoResultPostV27]
|
||||
}
|
||||
|
||||
implicit val getBlockchainInfoResult: Reads[GetBlockChainInfoResult] = {
|
||||
Json.reads[GetBlockChainInfoResult]
|
||||
}
|
||||
|
||||
implicit val blockHeaderFormattedReads: Reads[GetBlockHeaderResult] =
|
||||
Json.reads[GetBlockHeaderResult]
|
||||
|
||||
|
@ -393,23 +406,21 @@ object JsonSerializers {
|
|||
implicit val TransactionDetailsReads: Reads[TransactionDetails] =
|
||||
Json.reads[TransactionDetails]
|
||||
|
||||
implicit val getTransactionResultReads: Reads[GetTransactionResult] =
|
||||
((__ \ "amount").read[Bitcoins] and
|
||||
(__ \ "fee").readNullable[Bitcoins] and
|
||||
(__ \ "confirmations").read[Int] and
|
||||
(__ \ "generated").readNullable[Boolean] and
|
||||
(__ \ "blockhash").readNullable[DoubleSha256DigestBE] and
|
||||
(__ \ "blockindex").readNullable[Int] and
|
||||
(__ \ "blocktime").readNullable[UInt32] and
|
||||
(__ \ "txid").read[DoubleSha256DigestBE] and
|
||||
(__ \ "walletconflicts").read[Vector[DoubleSha256DigestBE]] and
|
||||
(__ \ "time").read[UInt32] and
|
||||
(__ \ "timereceived").read[UInt32] and
|
||||
(__ \ "bip125-replaceable").read[String] and
|
||||
(__ \ "comment").readNullable[String] and
|
||||
(__ \ "to").readNullable[String] and
|
||||
(__ \ "details").read[Vector[TransactionDetails]] and
|
||||
(__ \ "hex").read[Transaction])(GetTransactionResult.apply)
|
||||
implicit val hdKeyDescriptor: Reads[HDKeyDescriptor] =
|
||||
Json.reads[HDKeyDescriptor]
|
||||
implicit val getHDKeysReads: Reads[GetHDKeysResult] = {
|
||||
Json.reads[GetHDKeysResult]
|
||||
}
|
||||
implicit val getTranasctionResultPreV28: Reads[GetTransactionResultPreV28] = {
|
||||
Json.reads[GetTransactionResultPreV28]
|
||||
}
|
||||
implicit val getTransactionResultV28: Reads[GetTransactionResultV28] = {
|
||||
Json.reads[GetTransactionResultV28]
|
||||
}
|
||||
|
||||
implicit val getTransactionResultReads: Reads[GetTransactionResult] = {
|
||||
Json.reads[GetTransactionResult]
|
||||
}
|
||||
|
||||
implicit val getWalletInfoResultReadsPostV22
|
||||
: Reads[GetWalletInfoResultPostV22] =
|
||||
|
@ -537,6 +548,12 @@ object JsonSerializers {
|
|||
implicit val getBlockTemplateResultReads: Reads[GetBlockTemplateResult] =
|
||||
Json.reads[GetBlockTemplateResult]
|
||||
|
||||
implicit val miningInfoResultPre28: Reads[GetMiningInfoResultPre28] = {
|
||||
Json.reads[GetMiningInfoResultPre28]
|
||||
}
|
||||
implicit val miningInfoResultV28: Reads[GetMiningInfoResultV28] = {
|
||||
Json.reads[GetMiningInfoResultV28]
|
||||
}
|
||||
implicit val miningInfoReads: Reads[GetMiningInfoResult] =
|
||||
Json.reads[GetMiningInfoResult]
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
package org.bitcoins.commons.serializers
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts._
|
||||
import org.bitcoins.core.currency._
|
||||
import org.bitcoins.core.number._
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.*
|
||||
import org.bitcoins.core.crypto.{ExtKey, ExtPrivateKey, ExtPublicKey}
|
||||
import org.bitcoins.core.currency.*
|
||||
import org.bitcoins.core.number.*
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.ln.LnInvoice
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.script.*
|
||||
import org.bitcoins.core.protocol.script.descriptor.Descriptor
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
import org.bitcoins.core.psbt._
|
||||
import org.bitcoins.core.protocol.transaction.*
|
||||
import org.bitcoins.core.psbt.*
|
||||
import org.bitcoins.core.script.ScriptType
|
||||
import org.bitcoins.core.serializers.PicklerKeys
|
||||
import org.bitcoins.core.util.BytesUtil
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.crypto._
|
||||
import play.api.libs.json._
|
||||
import org.bitcoins.crypto.*
|
||||
import play.api.libs.json.*
|
||||
|
||||
import java.net.URL
|
||||
import scala.collection.mutable
|
||||
|
@ -119,6 +120,16 @@ object JsonWriters {
|
|||
}
|
||||
}
|
||||
|
||||
implicit object ExtKeyWrites extends Writes[ExtKey] {
|
||||
override def writes(key: ExtKey): JsValue = {
|
||||
val str = key match {
|
||||
case xpub: ExtPublicKey => JsString(xpub.toString)
|
||||
case xprv: ExtPrivateKey => JsString(xprv.toStringSensitive)
|
||||
}
|
||||
str
|
||||
}
|
||||
}
|
||||
|
||||
implicit object TransactionInputWrites extends Writes[TransactionInput] {
|
||||
|
||||
override def writes(o: TransactionInput): JsValue =
|
||||
|
|
|
@ -67,7 +67,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
|||
|rpcuser=foobar
|
||||
|rpcpassword=barfoo
|
||||
|[regtest]
|
||||
|port=${RpcUtil.randomPort}
|
||||
|bind=127.0.0.1:${RpcUtil.randomPort}
|
||||
|rpcport=${RpcUtil.randomPort}
|
||||
""".stripMargin
|
||||
|
||||
|
@ -98,7 +98,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
|||
|rpcauth=bitcoin-s:6d7580be1deb4ae52bc4249871845b09$$82b282e7c6493f6982a5a7af9fbb1b671bab702e2f31bbb1c016bb0ea1cc27ca
|
||||
|regtest=1
|
||||
|[regtest]
|
||||
|port=${port}
|
||||
|bind=127.0.0.1:${port}
|
||||
|rpcport=${rpcPort}
|
||||
""".stripMargin
|
||||
|
||||
|
@ -129,7 +129,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
|
|||
|rpcauth=bitcoin-s:6d7580be1deb4ae52bc4249871845b09$$82b282e7c6493f6982a5a7af9fbb1b671bab702e2f31bbb1c016bb0ea1cc27ca
|
||||
|regtest=1
|
||||
|[regtest]
|
||||
|port=${port}
|
||||
|bind=127.0.0.1:${port}
|
||||
|rpcport=${rpcPort}
|
||||
""".stripMargin
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@ class BlockchainRpcTest extends BitcoindFixturesCachedPairNewest {
|
|||
info <- client.getBlockChainInfo
|
||||
bestHash <- client.getBestBlockHash()
|
||||
} yield {
|
||||
assert(info.isInstanceOf[GetBlockChainInfoResultPostV23])
|
||||
val postV23 = info.asInstanceOf[GetBlockChainInfoResultPostV23]
|
||||
assert(info.isInstanceOf[GetBlockChainInfoResultPostV27])
|
||||
val postV23 = info.asInstanceOf[GetBlockChainInfoResultPostV27]
|
||||
assert(postV23.chain == RegTest)
|
||||
assert(postV23.bestblockhash == bestHash)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class MultiWalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
|||
new FutureOutcome(f)
|
||||
}
|
||||
|
||||
private val cachedSetupClientsF: Future[NodePair[BitcoindRpcClient]] = {
|
||||
private lazy val cachedSetupClientsF: Future[NodePair[BitcoindRpcClient]] = {
|
||||
clientsF.flatMap(setupWalletClient)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,16 @@ import org.bitcoins.commons.jsonmodels.bitcoind.{
|
|||
GetWalletInfoResultPostV22
|
||||
}
|
||||
import org.bitcoins.core.config.RegTest
|
||||
import org.bitcoins.core.crypto.ExtPrivateKey
|
||||
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit, Satoshis}
|
||||
import org.bitcoins.core.hd.BIP32Path
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.script.descriptor.{
|
||||
Descriptor,
|
||||
P2SHDescriptor,
|
||||
P2WPKHDescriptor
|
||||
P2WPKHDescriptor,
|
||||
XprvECPublicKeyExpression
|
||||
}
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
import org.bitcoins.core.protocol.{
|
||||
|
@ -49,6 +52,7 @@ import org.scalatest.{FutureOutcome, Outcome}
|
|||
|
||||
import java.io.File
|
||||
import java.time.Instant
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.concurrent.{Await, Future}
|
||||
|
||||
|
@ -64,6 +68,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
|||
new FutureOutcome(f)
|
||||
}
|
||||
|
||||
private val isWalletClientUsed: AtomicBoolean = new AtomicBoolean(false)
|
||||
// This client's wallet is encrypted
|
||||
lazy val walletClientF: Future[BitcoindRpcClient] = clientsF.flatMap { _ =>
|
||||
val instance =
|
||||
|
@ -71,6 +76,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
|||
val walletClient =
|
||||
BitcoindRpcClient(instance)
|
||||
|
||||
isWalletClientUsed.set(true)
|
||||
for {
|
||||
_ <- startClient(walletClient)
|
||||
_ <- walletClient.generate(101)
|
||||
|
@ -830,12 +836,54 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
|||
info <- client.getAddressInfo(addr)
|
||||
} yield assert(info.address == addr)
|
||||
}
|
||||
|
||||
it should "be able to createwalletdescriptor/gethdkeys" in { nodePair =>
|
||||
val client = nodePair.node1
|
||||
val walletName = "v28-createwalletdescriptor"
|
||||
val path = BIP32Path.fromString("m/44'/0'/0'/0")
|
||||
val xpriv = ExtPrivateKey.fromString(
|
||||
"tprv8ZgxMBicQKsPds78rqEk8ATTSqn2fw1zXkwzcsUVattUrjDK8EEDJ3aGXanbUTwBKDmEKatJFNqy6XDt11Na18ZVwEtcxRuLVC5RCEkcNGP")
|
||||
val keyExpression =
|
||||
XprvECPublicKeyExpression(extKey = xpriv,
|
||||
originOpt = None,
|
||||
pathOpt = Some(path),
|
||||
childrenHardenedOpt = Some(None))
|
||||
val desc = P2WPKHDescriptor(keyExpression)
|
||||
val importDesc = DescriptorsResult(desc = desc,
|
||||
timestamp = Instant.now().getEpochSecond,
|
||||
active = true,
|
||||
internal = None,
|
||||
range = Some(Vector(0, 5)),
|
||||
next = None)
|
||||
for {
|
||||
_ <- client.createWallet(walletName = walletName, blank = true)
|
||||
initHdKeys <- client.getHDKeys(walletName)
|
||||
_ = assert(initHdKeys.isEmpty, s"initHdKeys=$initHdKeys")
|
||||
importDescResult <- client.importDescriptor(importDesc,
|
||||
walletName = walletName)
|
||||
_ = assert(importDescResult.success, s"${importDescResult.error}")
|
||||
result <- client.createWalletDescriptor(addressType = AddressType.Bech32m,
|
||||
options = None,
|
||||
walletName = walletName)
|
||||
hdKeys <- client.getHDKeys(walletName = walletName)
|
||||
} yield {
|
||||
assert(result.descs.nonEmpty)
|
||||
assert(hdKeys.nonEmpty)
|
||||
}
|
||||
}
|
||||
|
||||
def startClient(client: BitcoindRpcClient): Future[Unit] = {
|
||||
BitcoindRpcTestUtil.startServers(Vector(client))
|
||||
}
|
||||
|
||||
override def afterAll(): Unit = {
|
||||
val stopF = walletClientF.map(BitcoindRpcTestUtil.stopServer)
|
||||
val stopF = {
|
||||
if (isWalletClientUsed.get) {
|
||||
walletClientF.map(BitcoindRpcTestUtil.stopServer)
|
||||
} else {
|
||||
Future.unit
|
||||
}
|
||||
}
|
||||
Await.result(stopF, 30.seconds)
|
||||
super.afterAll()
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
package org.bitcoins.rpc.v25
|
||||
|
||||
class BitcoindV25RpcClientTest {}
|
|
@ -23,7 +23,7 @@ TaskKeys.downloadBitcoind := {
|
|||
}
|
||||
|
||||
val versions =
|
||||
List("27.1", "26.1", "25.2")
|
||||
List("28.0", "27.1", "26.1", "25.2")
|
||||
|
||||
logger.debug(
|
||||
s"(Maybe) downloading Bitcoin Core binaries for versions: ${versions.mkString(",")}")
|
||||
|
@ -96,7 +96,8 @@ TaskKeys.downloadBitcoind := {
|
|||
Map(
|
||||
"25.2" -> "8d8c387e597e0edfc256f0bbace1dac3ad1ebf4a3c06da3e2975fda333817dea",
|
||||
"26.1" -> "a5b7d206384a8100058d3f2e2f02123a8e49e83f523499e70e86e121a4897d5b",
|
||||
"27.1" -> "c9840607d230d65f6938b81deaec0b98fe9cb14c3a41a5b13b2c05d044a48422"
|
||||
"27.1" -> "c9840607d230d65f6938b81deaec0b98fe9cb14c3a41a5b13b2c05d044a48422",
|
||||
"28.0" -> "7fe294b02b25b51acb8e8e0a0eb5af6bbafa7cd0c5b0e5fcbb61263104a82fbc"
|
||||
)
|
||||
else if (Properties.isMac)
|
||||
Map(
|
||||
|
@ -111,13 +112,18 @@ TaskKeys.downloadBitcoind := {
|
|||
"27.1" -> (if (System.getProperty("os.arch") == "aarch64")
|
||||
"ad4a3fd484077224a82dd56d194efb6e614467f413ab1dfb8776da4d08a4c227"
|
||||
else
|
||||
"e1efd8c4605b2aabc876da93b6eee2bedd868ce7d1f02b0220c1001f903b3e2c")
|
||||
"e1efd8c4605b2aabc876da93b6eee2bedd868ce7d1f02b0220c1001f903b3e2c"),
|
||||
"28.0" -> (if (System.getProperty("os.arch") == "aarch64")
|
||||
"c8108f30dfcc7ddffab33f5647d745414ef9d3298bfe67d243fe9b9cb4df4c12"
|
||||
else
|
||||
"e1efd8c4605b2aabc876da93b6eee2bedd868ce7d1f02b0220c1001f903b3e2c")
|
||||
)
|
||||
else if (Properties.isWin)
|
||||
Map(
|
||||
"25.2" -> "c2ac84f55ee879caefd4414868d318a741c52a7286da190bf7233d86a2ffca69",
|
||||
"26.1" -> "7bd0849e47472aeff99a0ea2c0cefd98f5be829e5a2d3b0168b5a54456cc638a",
|
||||
"27.1" -> "9719871a2c9a45c741e33d670d2319dcd3f8f52a6059e9c435a9a2841188b932"
|
||||
"27.1" -> "9719871a2c9a45c741e33d670d2319dcd3f8f52a6059e9c435a9a2841188b932",
|
||||
"28.0" -> "85282f4ec1bcb0cfe8db0f195e8e0f6fb77cfbe89242a81fff2bc2e9292f7acf"
|
||||
)
|
||||
else sys.error(s"Unsupported OS: ${Properties.osName}")
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@ package org.bitcoins.rpc.client.common
|
|||
import org.apache.pekko.Done
|
||||
import org.apache.pekko.actor.ActorSystem
|
||||
import org.apache.pekko.stream.scaladsl.{Keep, RunnableGraph, Sink, Source}
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
||||
GetNetworkInfoResultPostV21,
|
||||
GetNetworkInfoResultV28
|
||||
}
|
||||
import org.bitcoins.commons.util.BitcoinSLogger
|
||||
import org.bitcoins.core.api.chain.db.BlockHeaderDb
|
||||
import org.bitcoins.core.api.chain.{ChainApi, FilterSyncMarker}
|
||||
|
@ -21,6 +25,7 @@ import org.bitcoins.rpc.client.v20.V20MultisigRpc
|
|||
import org.bitcoins.rpc.client.v25.BitcoindV25RpcClient
|
||||
import org.bitcoins.rpc.client.v26.BitcoindV26RpcClient
|
||||
import org.bitcoins.rpc.client.v27.BitcoindV27RpcClient
|
||||
import org.bitcoins.rpc.client.v28.BitcoindV28RpcClient
|
||||
import org.bitcoins.rpc.config.*
|
||||
|
||||
import java.io.File
|
||||
|
@ -62,11 +67,21 @@ class BitcoindRpcClient(override val instance: BitcoindInstance)(implicit
|
|||
|
||||
private val syncing = new AtomicBoolean(false)
|
||||
|
||||
override def version: Future[BitcoindVersion] = {
|
||||
override lazy val version: Future[BitcoindVersion] = {
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.{
|
||||
getNetworkInfoV28Reads,
|
||||
getNetworkInfoPostV21Reads
|
||||
}
|
||||
instance match {
|
||||
case _: BitcoindInstanceRemote =>
|
||||
getNetworkInfo.map(info =>
|
||||
BitcoindVersion.fromNetworkVersion(info.version))
|
||||
// work around for version specific calls to 'getnetworkinfo'
|
||||
// the return payload is slightly different pre28 and post 28
|
||||
// this can be removed in the future when we drop support for v27 of bitcoind
|
||||
bitcoindCall[GetNetworkInfoResultV28]("getnetworkinfo")
|
||||
.recoverWith { _ =>
|
||||
bitcoindCall[GetNetworkInfoResultPostV21]("getnetworkinfo")
|
||||
}
|
||||
.map(result => BitcoindVersion.fromNetworkVersion(result.version))
|
||||
case local: BitcoindInstanceLocal =>
|
||||
Future.successful(local.getVersion)
|
||||
}
|
||||
|
@ -341,6 +356,7 @@ object BitcoindRpcClient {
|
|||
case BitcoindVersion.V25 => BitcoindV25RpcClient(instance)
|
||||
case BitcoindVersion.V26 => BitcoindV26RpcClient(instance)
|
||||
case BitcoindVersion.V27 => BitcoindV27RpcClient(instance)
|
||||
case BitcoindVersion.V28 => BitcoindV28RpcClient(instance)
|
||||
case BitcoindVersion.Unknown =>
|
||||
sys.error(
|
||||
s"Cannot create a Bitcoin Core RPC client: unsupported version"
|
||||
|
@ -361,6 +377,7 @@ object BitcoindRpcClient {
|
|||
case BitcoindVersion.V25 => new BitcoindV25RpcClient(instance)
|
||||
case BitcoindVersion.V26 => new BitcoindV26RpcClient(instance)
|
||||
case BitcoindVersion.V27 => new BitcoindV27RpcClient(instance)
|
||||
case BitcoindVersion.V28 => new BitcoindV28RpcClient(instance)
|
||||
case BitcoindVersion.Unknown =>
|
||||
sys.error(
|
||||
s"Cannot create a Bitcoin Core RPC client: unsupported version"
|
||||
|
@ -377,10 +394,10 @@ object BitcoindVersion
|
|||
with BitcoinSLogger {
|
||||
|
||||
/** The newest version of `bitcoind` we support */
|
||||
val newest: BitcoindVersion = V27
|
||||
val newest: BitcoindVersion = V28
|
||||
|
||||
val standard: Vector[BitcoindVersion] =
|
||||
Vector(V27, V26, V25)
|
||||
Vector(V28, V27, V26, V25)
|
||||
|
||||
val known: Vector[BitcoindVersion] = standard
|
||||
|
||||
|
@ -396,6 +413,10 @@ object BitcoindVersion
|
|||
override def toString: String = "v27.1"
|
||||
}
|
||||
|
||||
case object V28 extends BitcoindVersion {
|
||||
override def toString: String = "v28.0"
|
||||
}
|
||||
|
||||
case object Unknown extends BitcoindVersion {
|
||||
override def toString: String = "Unknown"
|
||||
}
|
||||
|
@ -417,6 +438,7 @@ object BitcoindVersion
|
|||
case "25" => V25
|
||||
case "26" => V26
|
||||
case "27" => V27
|
||||
case "28" => V28
|
||||
case _ =>
|
||||
logger.warn(
|
||||
s"Unsupported Bitcoin Core version: $int. The latest supported version is ${BitcoindVersion.newest}"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package org.bitcoins.rpc.client.common
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.*
|
||||
import org.bitcoins.commons.serializers.JsonSerializers
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.*
|
||||
import org.bitcoins.core.api.chain.ChainQueryApi.FilterResponse
|
||||
import org.bitcoins.core.api.chain.db.{
|
||||
CompactFilterDb,
|
||||
|
@ -14,7 +14,14 @@ import org.bitcoins.core.gcs.{BlockFilter, FilterHeader, FilterType}
|
|||
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader}
|
||||
import org.bitcoins.core.util.FutureUtil
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
import play.api.libs.json._
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.{
|
||||
Unknown,
|
||||
V25,
|
||||
V26,
|
||||
V27,
|
||||
V28
|
||||
}
|
||||
import play.api.libs.json.*
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
|
@ -39,7 +46,13 @@ trait BlockchainRpc extends ChainApi { self: Client =>
|
|||
}
|
||||
|
||||
def getBlockChainInfo: Future[GetBlockChainInfoResult] = {
|
||||
bitcoindCall[GetBlockChainInfoResultPostV23]("getblockchaininfo")
|
||||
self.version.flatMap {
|
||||
case V25 | V26 | V27 | Unknown =>
|
||||
bitcoindCall[GetBlockChainInfoResultPostV23]("getblockchaininfo")
|
||||
case V28 =>
|
||||
bitcoindCall[GetBlockChainInfoResultPostV27]("getblockchaininfo")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override def getBlockCount(): Future[Int] = {
|
||||
|
|
|
@ -4,15 +4,24 @@ import org.bitcoins.commons.jsonmodels.bitcoind.{
|
|||
GenerateBlockResult,
|
||||
GetBlockTemplateResult,
|
||||
GetMiningInfoResult,
|
||||
GetMiningInfoResultPre28,
|
||||
GetMiningInfoResultV28,
|
||||
PrioritisedTransaction,
|
||||
RpcOpts
|
||||
}
|
||||
import org.bitcoins.commons.serializers.JsonReaders._
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
import org.bitcoins.commons.serializers.JsonReaders.*
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.*
|
||||
import org.bitcoins.core.currency.Satoshis
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.{
|
||||
Unknown,
|
||||
V25,
|
||||
V26,
|
||||
V27,
|
||||
V28
|
||||
}
|
||||
import play.api.libs.json.{JsArray, JsNumber, JsString, Json}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -75,7 +84,12 @@ trait MiningRpc { self: Client with BlockchainRpc =>
|
|||
}
|
||||
|
||||
def getMiningInfo: Future[GetMiningInfoResult] = {
|
||||
bitcoindCall[GetMiningInfoResult]("getmininginfo")
|
||||
self.version.flatMap {
|
||||
case V25 | V26 | V27 | Unknown =>
|
||||
bitcoindCall[GetMiningInfoResultPre28]("getmininginfo")
|
||||
case V28 =>
|
||||
bitcoindCall[GetMiningInfoResultV28]("getmininginfo")
|
||||
}
|
||||
}
|
||||
|
||||
def prioritiseTransaction(
|
||||
|
|
|
@ -4,10 +4,17 @@ import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
|
|||
AddNodeArgument,
|
||||
SetBanCommand
|
||||
}
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.*
|
||||
import org.bitcoins.commons.serializers.JsonSerializers
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.*
|
||||
import org.bitcoins.core.protocol.blockchain.Block
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.{
|
||||
Unknown,
|
||||
V25,
|
||||
V26,
|
||||
V27,
|
||||
V28
|
||||
}
|
||||
import play.api.libs.json.{JsBoolean, JsNumber, JsString}
|
||||
|
||||
import java.net.URI
|
||||
|
@ -62,10 +69,12 @@ trait P2PRpc { self: Client =>
|
|||
}
|
||||
|
||||
def getNetworkInfo: Future[GetNetworkInfoResult] = {
|
||||
bitcoindCall[GetNetworkInfoResultPostV21]("getnetworkinfo")
|
||||
.recoverWith { case _ =>
|
||||
bitcoindCall[GetNetworkInfoResultPreV21]("getnetworkinfo")
|
||||
}
|
||||
self.version.flatMap {
|
||||
case V25 | V26 | V27 | Unknown =>
|
||||
bitcoindCall[GetNetworkInfoResultPostV21]("getnetworkinfo")
|
||||
case V28 =>
|
||||
bitcoindCall[GetNetworkInfoResultV28]("getnetworkinfo")
|
||||
}
|
||||
}
|
||||
|
||||
def getPeerInfo: Future[Vector[PeerInfoResponseV25]] = {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package org.bitcoins.rpc.client.common
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.FeeEstimationMode
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.*
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.*
|
||||
import org.bitcoins.core.currency.Satoshis
|
||||
import org.bitcoins.core.protocol.blockchain.MerkleBlock
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
import play.api.libs.json._
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.{V25, V26, V27, V28}
|
||||
import play.api.libs.json.*
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
|
@ -77,11 +78,20 @@ trait TransactionRpc { self: Client =>
|
|||
watchOnly: Boolean = false,
|
||||
walletName: String = BitcoindRpcClient.DEFAULT_WALLET_NAME
|
||||
): Future[GetTransactionResult] = {
|
||||
bitcoindCall[GetTransactionResult](
|
||||
"gettransaction",
|
||||
List(JsString(txid.hex), JsBoolean(watchOnly)),
|
||||
uriExtensionOpt = Some(walletExtension(walletName))
|
||||
)
|
||||
self.version.flatMap {
|
||||
case V25 | V26 | V27 | BitcoindVersion.Unknown =>
|
||||
bitcoindCall[GetTransactionResultPreV28](
|
||||
"gettransaction",
|
||||
List(JsString(txid.hex), JsBoolean(watchOnly)),
|
||||
uriExtensionOpt = Some(walletExtension(walletName))
|
||||
)
|
||||
case V28 =>
|
||||
bitcoindCall[GetTransactionResultV28](
|
||||
"gettransaction",
|
||||
List(JsString(txid.hex), JsBoolean(watchOnly)),
|
||||
uriExtensionOpt = Some(walletExtension(walletName))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def getTxOut(
|
||||
|
|
|
@ -2,19 +2,21 @@ package org.bitcoins.rpc.client.common
|
|||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
|
||||
AddressType,
|
||||
CreateWalletDescriptorOptions,
|
||||
WalletCreateFundedPsbtOptions,
|
||||
WalletFlag
|
||||
}
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
import org.bitcoins.commons.serializers.JsonWriters._
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.*
|
||||
import org.bitcoins.commons.serializers.JsonReaders
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.*
|
||||
import org.bitcoins.commons.serializers.JsonWriters.*
|
||||
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit}
|
||||
import org.bitcoins.core.protocol.BitcoinAddress
|
||||
import org.bitcoins.core.protocol.blockchain.MerkleBlock
|
||||
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionInput}
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.crypto._
|
||||
import play.api.libs.json._
|
||||
import org.bitcoins.crypto.*
|
||||
import play.api.libs.json.*
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
|
@ -55,6 +57,13 @@ trait WalletRpc { self: Client =>
|
|||
)
|
||||
}
|
||||
|
||||
def getHDKeys(
|
||||
walletName: String = DEFAULT_WALLET): Future[Vector[GetHDKeysResult]] = {
|
||||
bitcoindCall[Vector[GetHDKeysResult]]("gethdkeys",
|
||||
uriExtensionOpt =
|
||||
Some(walletExtension(walletName)))
|
||||
}
|
||||
|
||||
def getReceivedByAddress(
|
||||
address: BitcoinAddress,
|
||||
minConfirmations: Int = 1,
|
||||
|
@ -390,6 +399,18 @@ trait WalletRpc { self: Client =>
|
|||
)
|
||||
}
|
||||
|
||||
def createWalletDescriptor(
|
||||
addressType: AddressType,
|
||||
options: Option[CreateWalletDescriptorOptions] = None,
|
||||
walletName: String = DEFAULT_WALLET)
|
||||
: Future[CreateWalletDescriptorResult] = {
|
||||
import JsonReaders.createWalletDescriptorReads
|
||||
bitcoindCall[CreateWalletDescriptorResult](
|
||||
"createwalletdescriptor",
|
||||
List(Json.toJson(addressType), Json.toJson(options)),
|
||||
uriExtensionOpt = Some(walletExtension(walletName)))
|
||||
}
|
||||
|
||||
def getAddressInfo(
|
||||
address: BitcoinAddress,
|
||||
walletName: String = DEFAULT_WALLET
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package org.bitcoins.rpc.client.v28
|
||||
|
||||
import org.apache.pekko.actor.ActorSystem
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.config.{
|
||||
BitcoindInstance,
|
||||
BitcoindInstanceLocal,
|
||||
BitcoindRpcAppConfig
|
||||
}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
class BitcoindV28RpcClient(override val instance: BitcoindInstance)(implicit
|
||||
actorSystem: ActorSystem,
|
||||
bitcoindRpcAppConfig: BitcoindRpcAppConfig
|
||||
) extends BitcoindRpcClient(instance) {
|
||||
|
||||
override lazy val version: Future[BitcoindVersion] =
|
||||
Future.successful(BitcoindVersion.V28)
|
||||
}
|
||||
|
||||
object BitcoindV28RpcClient {
|
||||
|
||||
/** Creates an RPC client from the given instance, together with the given
|
||||
* actor system. This is for advanced users, where you need fine grained
|
||||
* control over the RPC client.
|
||||
*/
|
||||
def apply(instance: BitcoindInstanceLocal)(implicit
|
||||
system: ActorSystem
|
||||
): BitcoindV28RpcClient =
|
||||
new BitcoindV28RpcClient(instance)(system, instance.bitcoindRpcAppConfig)
|
||||
|
||||
}
|
|
@ -223,7 +223,7 @@ case class BitcoindConfig(
|
|||
lazy val zmqpubhashtx: Option[InetSocketAddress] =
|
||||
getValue("zmqpubhashtx").map(toInetSocketAddress)
|
||||
|
||||
lazy val port: Int = getValue("port").map(_.toInt).getOrElse(network.port)
|
||||
lazy val portOpt: Option[Int] = getValue("port").map(_.toInt)
|
||||
|
||||
/** Defaults to localhost */
|
||||
lazy val bind: URI = new URI({
|
||||
|
@ -233,7 +233,7 @@ case class BitcoindConfig(
|
|||
|
||||
})
|
||||
|
||||
lazy val uri: URI = new URI(s"$bind:$port")
|
||||
lazy val uri: URI = new URI(s"$bind")
|
||||
|
||||
lazy val rpcport: Int =
|
||||
getValue("rpcport").map(_.toInt).getOrElse(network.rpcPort)
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.bitcoins.core.protocol.script.descriptor
|
|||
import org.bitcoins.core.config.NetworkParameters
|
||||
import org.bitcoins.core.number.{UInt64, UInt8}
|
||||
import org.bitcoins.core.protocol.Bech32Address
|
||||
import org.bitcoins.core.protocol.script._
|
||||
import org.bitcoins.core.protocol.script.*
|
||||
import org.bitcoins.core.util.Bech32
|
||||
import org.bitcoins.crypto.{ECPrivateKey, PublicKey, StringFactory}
|
||||
|
||||
|
@ -214,6 +214,13 @@ object P2WPKHDescriptor
|
|||
val checksum = Descriptor.createChecksum(noChecksum)
|
||||
P2WPKHDescriptor(p2wpkhExpression, Some(checksum))
|
||||
}
|
||||
|
||||
def apply(keyExpression: ExtECPublicKeyExpression): P2WPKHDescriptor = {
|
||||
val p2wpkhExpression = P2WPKHExpression(keyExpression)
|
||||
val noChecksum = P2WPKHDescriptor(p2wpkhExpression, None)
|
||||
val checksum = Descriptor.createChecksum(noChecksum)
|
||||
P2WPKHDescriptor(p2wpkhExpression, Some(checksum))
|
||||
}
|
||||
}
|
||||
|
||||
object P2WSHDescriptor
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.scalatest.FutureOutcome
|
|||
import scala.io.Source
|
||||
|
||||
/** A trait that is useful if you need Lnd fixtures for your test suite */
|
||||
trait LndFixture extends BitcoinSFixture with CachedBitcoindNewest {
|
||||
trait LndFixture extends BitcoinSFixture with CachedBitcoindV27 {
|
||||
|
||||
override type FixtureParam = LndRpcClient
|
||||
|
||||
|
@ -38,7 +38,7 @@ trait LndFixture extends BitcoinSFixture with CachedBitcoindNewest {
|
|||
}
|
||||
|
||||
/** A trait that is useful if you need Lnd fixtures for your test suite */
|
||||
trait DualLndFixture extends BitcoinSFixture with CachedBitcoindNewest {
|
||||
trait DualLndFixture extends BitcoinSFixture with CachedBitcoindV27 {
|
||||
|
||||
override type FixtureParam = (BitcoindRpcClient, LndRpcClient, LndRpcClient)
|
||||
|
||||
|
@ -66,7 +66,7 @@ trait DualLndFixture extends BitcoinSFixture with CachedBitcoindNewest {
|
|||
}
|
||||
}
|
||||
|
||||
trait RemoteLndFixture extends BitcoinSFixture with CachedBitcoindNewest {
|
||||
trait RemoteLndFixture extends BitcoinSFixture with CachedBitcoindV27 {
|
||||
|
||||
override type FixtureParam = LndRpcClient
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.bitcoins.core.protocol.transaction.TransactionOutPoint
|
|||
import org.bitcoins.core.wallet.fee.SatoshisPerVirtualByte
|
||||
import org.bitcoins.lnd.rpc.LndRpcClient
|
||||
import org.bitcoins.lnd.rpc.config.{LndInstanceLocal, LndInstanceRemote}
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.{V25, V26, V27, V28}
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.config.{
|
||||
BitcoindAuthCredentials,
|
||||
|
@ -47,6 +48,18 @@ trait LndRpcTestUtil extends BitcoinSLogger {
|
|||
BitcoindRpcTestUtil.startedBitcoindRpcClient(instanceOpt, Vector.newBuilder)
|
||||
}
|
||||
|
||||
def startedBitcoindRpcClient(version: BitcoindVersion)(implicit
|
||||
system: ActorSystem): Future[BitcoindRpcClient] = {
|
||||
val instance = version match {
|
||||
case V25 => BitcoindRpcTestUtil.v25Instance()
|
||||
case V26 => BitcoindRpcTestUtil.v26Instance()
|
||||
case V27 => BitcoindRpcTestUtil.v27Instance()
|
||||
case V28 => BitcoindRpcTestUtil.v28Instance()
|
||||
case BitcoindVersion.Unknown => BitcoindRpcTestUtil.instance()
|
||||
}
|
||||
startedBitcoindRpcClient(Some(instance))
|
||||
}
|
||||
|
||||
/** Creates a bitcoind instance with the given parameters */
|
||||
def bitcoindInstance(
|
||||
port: Int = RpcUtil.randomPort,
|
||||
|
|
|
@ -32,7 +32,8 @@ import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
|||
import org.bitcoins.rpc.client.v25.BitcoindV25RpcClient
|
||||
import org.bitcoins.rpc.client.v26.BitcoindV26RpcClient
|
||||
import org.bitcoins.rpc.client.v27.BitcoindV27RpcClient
|
||||
import org.bitcoins.rpc.config._
|
||||
import org.bitcoins.rpc.client.v28.BitcoindV28RpcClient
|
||||
import org.bitcoins.rpc.config.*
|
||||
import org.bitcoins.rpc.util.{NodePair, RpcUtil}
|
||||
import org.bitcoins.testkit.util.{BitcoindRpcTestClient, FileUtil, TorUtil}
|
||||
import org.bitcoins.util.ListUtil
|
||||
|
@ -41,10 +42,10 @@ import java.io.File
|
|||
import java.net.{InetSocketAddress, URI}
|
||||
import java.nio.file.{Files, Path}
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent._
|
||||
import scala.concurrent.*
|
||||
import scala.concurrent.duration.{DurationInt, FiniteDuration}
|
||||
import scala.jdk.CollectionConverters.IteratorHasAsScala
|
||||
import scala.util._
|
||||
import scala.util.*
|
||||
|
||||
//noinspection AccessorLikeMethodIsEmptyParen
|
||||
trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
||||
|
@ -108,7 +109,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
|rpcuser=$username
|
||||
|rpcpassword=$pass
|
||||
|rpcport=${rpcUri.getPort}
|
||||
|port=${uri.getPort}
|
||||
|bind=127.0.0.1:${uri.getPort}
|
||||
|debug=$isDebug
|
||||
|walletbroadcast=1
|
||||
|mempoolfullrbf=1
|
||||
|
@ -178,7 +179,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
version match {
|
||||
// default to newest version
|
||||
case Unknown => getBinary(BitcoindVersion.newest, binaryDirectory)
|
||||
case known @ (V25 | V26 | V27) =>
|
||||
case known @ (V25 | V26 | V27 | V28) =>
|
||||
val fileList: List[(Path, String)] = Files
|
||||
.list(binaryDirectory)
|
||||
.iterator()
|
||||
|
@ -301,6 +302,22 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
binaryDirectory = binaryDirectory
|
||||
)
|
||||
|
||||
def v28Instance(
|
||||
port: Int = RpcUtil.randomPort,
|
||||
rpcPort: Int = RpcUtil.randomPort,
|
||||
zmqConfig: ZmqConfig = RpcUtil.zmqConfig,
|
||||
pruneMode: Boolean = false,
|
||||
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||
)(implicit system: ActorSystem): BitcoindInstanceLocal =
|
||||
instance(
|
||||
port = port,
|
||||
rpcPort = rpcPort,
|
||||
zmqConfig = zmqConfig,
|
||||
pruneMode = pruneMode,
|
||||
versionOpt = Some(BitcoindVersion.V28),
|
||||
binaryDirectory = binaryDirectory
|
||||
)
|
||||
|
||||
/** Gets an instance of bitcoind with the given version */
|
||||
def getInstance(
|
||||
bitcoindVersion: BitcoindVersion,
|
||||
|
@ -335,6 +352,14 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
pruneMode,
|
||||
binaryDirectory = binaryDirectory
|
||||
)
|
||||
case BitcoindVersion.V28 =>
|
||||
BitcoindRpcTestUtil.v28Instance(
|
||||
port,
|
||||
rpcPort,
|
||||
zmqConfig,
|
||||
pruneMode,
|
||||
binaryDirectory = binaryDirectory
|
||||
)
|
||||
case BitcoindVersion.Unknown =>
|
||||
sys.error(
|
||||
s"Could not create a bitcoind version with version=${BitcoindVersion.Unknown}"
|
||||
|
@ -686,6 +711,9 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
case BitcoindVersion.V27 =>
|
||||
val instance = BitcoindRpcTestUtil.v27Instance()
|
||||
BitcoindV27RpcClient(instance)
|
||||
case BitcoindVersion.V28 =>
|
||||
val instance = BitcoindRpcTestUtil.v28Instance()
|
||||
BitcoindV28RpcClient(instance)
|
||||
}
|
||||
|
||||
// this is safe as long as this method is never
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.bitcoins.testkit.rpc
|
||||
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.client.v27.BitcoindV27RpcClient
|
||||
import org.bitcoins.rpc.util.{NodePair, NodeTriple}
|
||||
import org.bitcoins.testkit.fixtures.BitcoinSFixture
|
||||
import org.bitcoins.testkit.util.BitcoinSPekkoAsyncTest
|
||||
|
@ -105,6 +106,17 @@ trait CachedBitcoindV26 extends CachedBitcoindFunded[BitcoindRpcClient] {
|
|||
}
|
||||
}
|
||||
|
||||
trait CachedBitcoindV27 extends CachedBitcoindFunded[BitcoindV27RpcClient] {
|
||||
_: BitcoinSPekkoAsyncTest =>
|
||||
|
||||
override protected lazy val cachedBitcoindWithFundsF
|
||||
: Future[BitcoindRpcClient] = {
|
||||
val _ = isBitcoindUsed.set(true)
|
||||
BitcoinSFixture
|
||||
.createBitcoindWithFunds(Some(BitcoindVersion.V27))
|
||||
}
|
||||
}
|
||||
|
||||
trait CachedBitcoindNewest extends CachedBitcoindFunded[BitcoindRpcClient] {
|
||||
_: BitcoinSPekkoAsyncTest =>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue