Remove support for v21 of bitcoind (#5496)

* Remove support for v21 of bitcoind

* WIP: Remove deprecated rpcs wit legacy wallets

* WIP: Work up to importdescriptor

* Get low-r test case passing

* Simplify test case

* Remove BitcoindV21RpcClientTest and move test cases to BitcoindV24RpcClientTest

* Remove RpcTransactionRpcTest that only works on legacy wallet

* Fix MempoolRpcTest

* Delete MultisigRpcTest that depends on legacy wallet

* Get WalletRpcTest passing, ignore keypoolrefill test case for now until https://github.com/bitcoin/bitcoin/issues/29924 is resolved
This commit is contained in:
Chris Stewart 2024-04-20 16:57:30 -05:00 committed by GitHub
parent c01793dc89
commit 9442dba217
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 370 additions and 1231 deletions

View File

@ -69,27 +69,6 @@ abstract trait GetBlockWithTransactionsResult extends BlockchainResult {
def nextblockhash: Option[DoubleSha256DigestBE]
}
case class GetBlockWithTransactionsResultPreV22(
hash: DoubleSha256DigestBE,
confirmations: Int,
strippedsize: Int,
size: Int,
weight: Int,
height: Int,
version: Int,
versionHex: Int32,
merkleroot: DoubleSha256DigestBE,
tx: Vector[RpcTransactionPreV22],
time: UInt32,
mediantime: UInt32,
nonce: UInt32,
bits: UInt32,
difficulty: BigDecimal,
chainwork: String,
previousblockhash: Option[DoubleSha256DigestBE],
nextblockhash: Option[DoubleSha256DigestBE])
extends GetBlockWithTransactionsResult
case class GetBlockWithTransactionsResultV22(
hash: DoubleSha256DigestBE,
confirmations: Int,
@ -433,14 +412,6 @@ sealed abstract trait GetTxOutResult extends BlockchainResult {
def coinbase: Boolean
}
case class GetTxOutResultPreV22(
bestblock: DoubleSha256DigestBE,
confirmations: Int,
value: Bitcoins,
scriptPubKey: RpcScriptPubKeyPreV22,
coinbase: Boolean)
extends GetTxOutResult
case class GetTxOutResultV22(
bestblock: DoubleSha256DigestBE,
confirmations: Int,

View File

@ -224,12 +224,6 @@ case class NodeBanPreV20(
ban_reason: String)
extends NodeBan
case class NodeBanPostV20(
address: URI,
banned_until: UInt32,
ban_created: UInt32)
extends NodeBan
case class NodeBanPostV22(
address: URI,
ban_created: UInt32,
@ -245,13 +239,6 @@ sealed trait GetNodeAddressesResult extends NetworkResult {
def port: Int
}
case class GetNodeAddressesResultPreV22(
time: FiniteDuration,
services: Int,
address: java.net.URI,
port: Int
) extends GetNodeAddressesResult
case class GetNodeAddressesResultPostV22(
time: FiniteDuration,
services: Int,

View File

@ -4,7 +4,7 @@ import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
import org.bitcoins.core.protocol.transaction.{Transaction, TransactionInput}
import org.bitcoins.core.protocol.{BitcoinAddress, P2PKHAddress, P2SHAddress}
import org.bitcoins.core.protocol.{BitcoinAddress, P2SHAddress}
import org.bitcoins.core.script.ScriptType
import org.bitcoins.crypto.DoubleSha256DigestBE
@ -24,18 +24,6 @@ sealed abstract class RpcTransaction extends RawTransactionResult {
def hex: Option[Transaction]
}
case class RpcTransactionPreV22(
txid: DoubleSha256DigestBE,
hash: DoubleSha256DigestBE,
version: Int,
size: Int,
vsize: Int,
locktime: UInt32,
vin: Vector[TransactionInput],
vout: Vector[RpcTransactionOutputPreV22],
hex: Option[Transaction])
extends RpcTransaction
case class RpcTransactionV22(
txid: DoubleSha256DigestBE,
hash: DoubleSha256DigestBE,
@ -95,14 +83,6 @@ sealed trait DecodeScriptResult extends RawTransactionResult {
def p2sh: P2SHAddress
}
case class DecodeScriptResultPreV22(
asm: String,
typeOfScript: Option[ScriptType],
reqSigs: Option[Int],
addresses: Option[Vector[P2PKHAddress]],
p2sh: P2SHAddress)
extends DecodeScriptResult
case class DecodeScriptResultV22(
asm: String,
typeOfScript: Option[ScriptType],
@ -137,23 +117,6 @@ sealed trait GetRawTransactionResult extends RawTransactionResult {
def blocktime: Option[UInt32]
}
case class GetRawTransactionResultPreV22(
in_active_blockchain: Option[Boolean],
hex: Transaction,
txid: DoubleSha256DigestBE,
hash: DoubleSha256DigestBE,
size: Int,
vsize: Int,
version: Int,
locktime: UInt32,
vin: Vector[GetRawTransactionVin],
vout: Vector[RpcTransactionOutputPreV22],
blockhash: Option[DoubleSha256DigestBE],
confirmations: Option[Int],
time: Option[UInt32],
blocktime: Option[UInt32])
extends GetRawTransactionResult
case class GetRawTransactionResultV22(
in_active_blockchain: Option[Boolean],
hex: Transaction,

View File

@ -30,14 +30,6 @@ sealed abstract class DecodePsbtResult extends RpcPsbtResult {
def fee: Option[Bitcoins]
}
final case class DecodePsbtResultPreV22(
tx: RpcTransactionPreV22,
unknown: Map[String, String],
inputs: Vector[RpcPsbtInputPreV22],
outputs: Vector[RpcPsbtOutput],
fee: Option[Bitcoins])
extends DecodePsbtResult
final case class DecodePsbtResultV22(
tx: RpcTransactionV22,
unknown: Map[String, String],
@ -62,21 +54,6 @@ sealed abstract class RpcPsbtInput extends RpcPsbtResult {
def unknown: Option[Map[String, String]] // The unknown global fields
}
final case class RpcPsbtInputPreV22(
nonWitnessUtxo: Option[RpcTransactionPreV22],
witnessUtxo: Option[PsbtWitnessUtxoInput],
partialSignatures: Option[Map[ECPublicKey, ECDigitalSignature]],
sighash: Option[HashType],
redeemScript: Option[RpcPsbtScript],
witnessScript: Option[RpcPsbtScript],
bip32Derivs: Option[Vector[PsbtBIP32Deriv]],
finalScriptSig: Option[RpcPsbtScript],
finalScriptwitness: Option[
Vector[String]
], // todo(torkelrogstad) needs example of what this looks like
unknown: Option[Map[String, String]] // The unknown global fields
) extends RpcPsbtInput
final case class RpcPsbtInputV22(
nonWitnessUtxo: Option[RpcTransactionV22],
witnessUtxo: Option[PsbtWitnessUtxoInput],

View File

@ -17,7 +17,6 @@ import org.bitcoins.crypto.{
Sha256Hash160Digest
}
import java.io.File
import java.time.ZonedDateTime
sealed abstract class WalletResult
@ -101,21 +100,6 @@ sealed trait GetWalletInfoResult extends WalletResult {
}
case class GetWalletInfoResultPreV22(
walletname: String,
walletversion: Int,
balance: Bitcoins,
unconfirmed_balance: Bitcoins,
immature_balance: Bitcoins,
txcount: Int,
keypoololdest: Option[UInt32],
keypoolsize: Int,
keypoolsize_hd_internal: Int,
paytxfee: BitcoinFeeUnit,
hdmasterkeyid: Option[Sha256Hash160Digest],
unlocked_until: Option[Int])
extends GetWalletInfoResult
case class GetWalletInfoResultPostV22(
walletname: String,
walletversion: Int,
@ -150,9 +134,6 @@ case class RpcAccount(
amount: Bitcoins,
confirmations: Int)
extends WalletResult
case class DumpWalletResult(filename: File)
case class LoadWalletResult(name: String, warning: String) extends WalletResult
case class RescanBlockChainResult(start_height: Int, stop_height: Int)
@ -479,7 +460,12 @@ case class DescriptorsResult(
internal: Option[Boolean],
range: Option[Vector[Int]],
next: Option[Int]
) extends WalletResult
) extends WalletResult {
override def toString(): String = {
s"${getClass.getSimpleName}(desc=$desc,timestamp=$timestamp,active=$active,internal=$internal,range=$range,next=$next)"
}
}
case class EmbeddedResult(
isscript: Boolean,

View File

@ -668,41 +668,6 @@ object JsonReaders {
}
implicit object RpcPsbtInputPreV22Reads extends Reads[RpcPsbtInputPreV22] {
override def reads(json: JsValue): JsResult[RpcPsbtInputPreV22] =
for {
nonWitnessUtxo <- (json \ "non_witness_utxo")
.validateOpt[RpcTransactionPreV22]
witnessUtxo <- (json \ "witness_utxo").validateOpt[PsbtWitnessUtxoInput]
finalScriptSig <- (json \ "final_scriptSig").validateOpt[RpcPsbtScript]
redeemScript <- (json \ "redeem_script").validateOpt[RpcPsbtScript]
sighash <- (json \ "sighash").validateOpt[HashType]
partialSignatures <- (json \ "partial_signatures")
.validateOpt[Map[ECPublicKey, ECDigitalSignature]]
witnessScript <- (json \ "witness_script").validateOpt[RpcPsbtScript]
bip32Derivs <- (json \ "bi32_derivs")
.validateOpt[Vector[PsbtBIP32Deriv]]
finalScriptWitness <-
JsSuccess(None) // todo(torkelrogstad) find an example of this
unknown <- (json \ "unknown").validateOpt[Map[String, String]]
} yield {
bitcoind.RpcPsbtInputPreV22(
nonWitnessUtxo = nonWitnessUtxo,
witnessUtxo = witnessUtxo,
partialSignatures = partialSignatures,
sighash = sighash,
redeemScript = redeemScript,
witnessScript = witnessScript,
bip32Derivs = bip32Derivs,
finalScriptSig = finalScriptSig,
finalScriptwitness = finalScriptWitness,
unknown = unknown
)
}
}
implicit object ScriptTypeReads extends Reads[ScriptType] {
override def reads(json: JsValue): JsResult[ScriptType] =

View File

@ -143,19 +143,9 @@ object JsonSerializers {
implicit val rpcTransactionOutputV22Reads: Reads[RpcTransactionOutputV22] =
Json.reads[RpcTransactionOutputV22]
implicit val rpcTransactionPreV22Reads: Reads[RpcTransactionPreV22] =
Json.reads[RpcTransactionPreV22]
implicit val rpcTransactionV22Reads: Reads[RpcTransactionV22] =
Json.reads[RpcTransactionV22]
implicit val decodeScriptResultPreV22Reads: Reads[DecodeScriptResultPreV22] =
((__ \ "asm").read[String] and
(__ \ "type").readNullable[ScriptType] and
(__ \ "reqSigs").readNullable[Int] and
(__ \ "addresses").readNullable[Vector[P2PKHAddress]] and
(__ \ "p2sh").read[P2SHAddress])(DecodeScriptResultPreV22)
implicit val decodeScriptResultV22Reads: Reads[DecodeScriptResultV22] =
((__ \ "asm").read[String] and
(__ \ "type").readNullable[ScriptType] and
@ -174,10 +164,6 @@ object JsonSerializers {
implicit val getRawTransactionVinReads: Reads[GetRawTransactionVin] =
Json.reads[GetRawTransactionVin]
implicit val getRawTransactionResultPreV22Reads: Reads[
GetRawTransactionResultPreV22] =
Json.reads[GetRawTransactionResultPreV22]
implicit val getRawTransactionResultV22Reads: Reads[
GetRawTransactionResultV22] =
Json.reads[GetRawTransactionResultV22]
@ -262,9 +248,6 @@ object JsonSerializers {
implicit val nodeBanPostV22Reads: Reads[NodeBanPostV22] =
Json.reads[NodeBanPostV22]
implicit val nodeBanPostV20Reads: Reads[NodeBanPostV20] =
Json.reads[NodeBanPostV20]
implicit val nodeBanPreV20Reads: Reads[NodeBanPreV20] =
Json.reads[NodeBanPreV20]
@ -275,10 +258,6 @@ object JsonSerializers {
implicit val getBlockResultReads: Reads[GetBlockResult] =
Json.reads[GetBlockResult]
implicit val getBlockWithTransactionsResultPreV22Reads: Reads[
GetBlockWithTransactionsResultPreV22] =
Json.reads[GetBlockWithTransactionsResultPreV22]
implicit val getBlockWithTransactionsResultV22Reads: Reads[
GetBlockWithTransactionsResultV22] =
Json.reads[GetBlockWithTransactionsResultV22]
@ -347,9 +326,6 @@ object JsonSerializers {
implicit val getMemPoolInfoResultReads: Reads[GetMemPoolInfoResult] =
Json.reads[GetMemPoolInfoResult]
implicit val getTxOutResultPreV22Reads: Reads[GetTxOutResultPreV22] =
Json.reads[GetTxOutResultPreV22]
implicit val getTxOutResultV22Reads: Reads[GetTxOutResultV22] =
Json.reads[GetTxOutResultV22]
@ -407,10 +383,6 @@ object JsonSerializers {
(__ \ "details").read[Vector[TransactionDetails]] and
(__ \ "hex").read[Transaction])(GetTransactionResult)
implicit val getWalletInfoResultReadsPreV22: Reads[
GetWalletInfoResultPreV22] =
Json.reads[GetWalletInfoResultPreV22]
implicit val getWalletInfoResultReadsPostV22: Reads[
GetWalletInfoResultPostV22] =
Json.reads[GetWalletInfoResultPostV22]
@ -425,9 +397,6 @@ object JsonSerializers {
implicit val rpcAccoutReads: Reads[RpcAccount] = Json.reads[RpcAccount]
implicit val dumpWalletResultReads: Reads[DumpWalletResult] =
Json.reads[DumpWalletResult]
implicit val loadWalletResultReads: Reads[LoadWalletResult] =
Json.reads[LoadWalletResult]
@ -625,15 +594,9 @@ object JsonSerializers {
implicit val mapPubKeySignatureReads: Reads[
Map[ECPublicKey, ECDigitalSignature]] = MapPubKeySignatureReads
implicit val rpcPsbtInputPreV22Reads: Reads[RpcPsbtInputPreV22] =
RpcPsbtInputPreV22Reads
implicit val rpcPsbtInputV22Reads: Reads[RpcPsbtInputV22] =
RpcPsbtInputV22Reads
implicit val decodePsbtResultPreV22Reads: Reads[DecodePsbtResultPreV22] =
Json.reads[DecodePsbtResultPreV22]
implicit val decodePsbtResultV22Reads: Reads[DecodePsbtResultV22] =
Json.reads[DecodePsbtResultV22]
@ -646,17 +609,6 @@ object JsonSerializers {
implicit val analyzePsbtResultReads: Reads[AnalyzePsbtResult] =
Json.reads[AnalyzePsbtResult]
implicit val getNodeAddressesPreV22Reads: Reads[
GetNodeAddressesResultPreV22] =
Reads[GetNodeAddressesResultPreV22] { js =>
for {
time <- (js \ "time").validate[Long].map(_.seconds)
services <- (js \ "services").validate[Int]
address <- (js \ "address").validate[URI]
port <- (js \ "port").validate[Int]
} yield GetNodeAddressesResultPreV22(time, services, address, port)
}
implicit val getNodeAddressesPostV22Reads: Reads[
GetNodeAddressesResultPostV22] =
Reads[GetNodeAddressesResultPostV22] { js =>

View File

@ -1,10 +1,10 @@
package org.bitcoins.rpc
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.rpc.util.{NodePair, RpcUtil}
import org.bitcoins.testkit.rpc.{
BitcoindFixturesCachedPairV21,
BitcoindFixturesCachedPairNewest,
BitcoindRpcTestUtil
}
import org.bitcoins.testkit.util.FileUtil
@ -13,7 +13,7 @@ import org.scalatest.{FutureOutcome, Outcome}
import java.io.File
import scala.concurrent.Future
class TestRpcUtilTest extends BitcoindFixturesCachedPairV21 {
class TestRpcUtilTest extends BitcoindFixturesCachedPairNewest {
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val outcomeF: Future[Outcome] = for {
@ -28,7 +28,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairV21 {
behavior of "BitcoindRpcUtil"
it should "create a temp bitcoin directory when creating a DaemonInstance, and then delete it" in {
_: NodePair[BitcoindV21RpcClient] =>
_: NodePair[BitcoindRpcClient] =>
val instance =
BitcoindRpcTestUtil.instance(RpcUtil.randomPort, RpcUtil.randomPort)
val dir = instance.datadir
@ -41,7 +41,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairV21 {
}
it should "be able to generate and sync blocks" in {
nodes: NodePair[BitcoindV21RpcClient] =>
nodes: NodePair[BitcoindRpcClient] =>
val NodePair(first, second) = nodes
for {
address <- second.getNewAddress
@ -57,7 +57,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairV21 {
}
it should "ble able to generate blocks with multiple clients and sync inbetween" in {
nodes: NodePair[BitcoindV21RpcClient] =>
nodes: NodePair[BitcoindRpcClient] =>
val blocksToGenerate = 10
val NodePair(first, second) = nodes
val allClients = nodes.toVector
@ -76,7 +76,7 @@ class TestRpcUtilTest extends BitcoindFixturesCachedPairV21 {
}
it should "be able to find outputs of previous transactions" in {
nodes: NodePair[BitcoindV21RpcClient] =>
nodes: NodePair[BitcoindRpcClient] =>
val NodePair(first, second) = nodes
for {
address <- second.getNewAddress

View File

@ -1,15 +1,14 @@
package org.bitcoins.rpc.common
import org.bitcoins.rpc.client.common.BitcoindVersion
import org.bitcoins.rpc.client.common.BitcoindVersion.V21
import org.bitcoins.testkit.util.BitcoindRpcTest
class BitcoindVersionTest extends BitcoindRpcTest {
behavior of "BitcoindVersion"
it should "return version 21" in {
val version = BitcoindVersion.fromNetworkVersion(210100)
assert(version.equals(V21))
it should "return version 24" in {
val version = BitcoindVersion.fromNetworkVersion(240100)
assert(version.equals(BitcoindVersion.V24))
}
}

View File

@ -1,6 +1,5 @@
package org.bitcoins.rpc.common
import org.bitcoins.commons.jsonmodels.bitcoind.GetMemPoolEntryResultPostV19
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script.ScriptSignature
@ -12,7 +11,7 @@ import org.bitcoins.crypto.DoubleSha256Digest
import org.bitcoins.rpc.BitcoindException
import org.bitcoins.rpc.config.{BitcoindInstanceLocal, BitcoindInstanceRemote}
import org.bitcoins.testkit.rpc.{
BitcoindFixturesCachedPairV21,
BitcoindFixturesCachedPairNewest,
BitcoindRpcTestUtil
}
import org.scalatest.{FutureOutcome, Outcome}
@ -20,7 +19,7 @@ import org.scalatest.{FutureOutcome, Outcome}
import java.io.File
import scala.concurrent.Future
class MempoolRpcTest extends BitcoindFixturesCachedPairV21 {
class MempoolRpcTest extends BitcoindFixturesCachedPairNewest {
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val futOutcome: Future[Outcome] = for {
@ -121,18 +120,9 @@ class MempoolRpcTest extends BitcoindFixturesCachedPairV21 {
txid <-
BitcoindRpcTestUtil
.fundMemPoolTransaction(client, address, Bitcoins(3.2))
entry <- client
.getMemPoolEntry(txid)
.map(_.asInstanceOf[GetMemPoolEntryResultPostV19])
tt <- client.prioritiseTransaction(txid, Bitcoins(1).satoshis)
newEntry <- client
.getMemPoolEntry(txid)
.map(_.asInstanceOf[GetMemPoolEntryResultPostV19])
} yield {
assert(entry.fee == entry.modifiedfee)
assert(tt)
assert(newEntry.fee == entry.fee)
assert(newEntry.modifiedfee == newEntry.fee + Bitcoins(1))
}
}

View File

@ -2,13 +2,12 @@ package org.bitcoins.rpc.common
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.core.crypto.ECPrivateKeyUtil
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.P2PKHAddress
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.wallet.fee.SatoshisPerByte
import org.bitcoins.crypto.{ECPrivateKey, ECPublicKey}
import org.bitcoins.crypto.ECPrivateKey
import org.bitcoins.rpc._
import org.bitcoins.rpc.client.common._
import org.bitcoins.rpc.config.{BitcoindInstanceLocal, BitcoindInstanceRemote}
@ -21,7 +20,6 @@ import org.bitcoins.testkit.util.PekkoUtil
import org.scalatest.{FutureOutcome, Outcome}
import java.io.File
import java.util.Scanner
import scala.concurrent.Future
import scala.concurrent.duration.DurationInt
@ -276,61 +274,6 @@ class MultiWalletRpcTest extends BitcoindFixturesCachedPairNewest {
}
}
it should "be able to dump a private key" in { nodePair =>
val client = nodePair.node2
for {
address <- client.getNewAddress(Some(walletName))
_ <- client.dumpPrivKey(address, Some(walletName))
} yield succeed
}
it should "be able to import a private key" in { nodePair =>
val client = nodePair.node2
val ecPrivateKey = ECPrivateKey.freshPrivateKey
val publicKey = ecPrivateKey.publicKey
val address = P2PKHAddress(publicKey, networkParam)
val localInstance = client.getDaemon match {
case _: BitcoindInstanceRemote =>
sys.error(s"Cannot use remote bitcoind instance in test cases")
case local: BitcoindInstanceLocal =>
local
}
for {
_ <- client.importPrivKey(ecPrivateKey.toPrivateKeyBytes(),
rescan = false,
walletNameOpt = Some(walletName))
key <- client.dumpPrivKey(address, Some(walletName))
result <-
client
.dumpWallet(
localInstance.datadir.getAbsolutePath + "/wallet_dump.dat",
Some(walletName))
} yield {
assert(key.toPrivateKey == ecPrivateKey)
val reader = new Scanner(result.filename)
var found = false
while (reader.hasNext) {
if (
reader.next == ECPrivateKeyUtil.toWIF(
ecPrivateKey.toPrivateKeyBytes(),
networkParam)
) {
found = true
}
}
assert(found)
}
}
it should "be able to import a public key" in { nodePair =>
val client = nodePair.node2
val pubKey = ECPublicKey.freshPublicKey
for {
_ <- client.importPubKey(pubKey, walletNameOpt = Some(walletName))
} yield succeed
}
it should "be able to import multiple addresses with importMulti" in {
nodePair =>
val client = nodePair.node2
@ -367,29 +310,6 @@ class MultiWalletRpcTest extends BitcoindFixturesCachedPairNewest {
}
}
it should "be able to import a wallet" in { nodePair =>
val client = nodePair.node2
val walletClient = client
val localInstance = client.getDaemon match {
case _: BitcoindInstanceRemote =>
sys.error(s"Cannot use remote bitcoind instance in test cases")
case local: BitcoindInstanceLocal =>
local
}
for {
address <- client.getNewAddress(Some(walletName))
walletFile =
localInstance.datadir.getAbsolutePath + "/client_wallet.dat"
fileResult <-
client.dumpWallet(walletFile, walletNameOpt = Some(walletName))
_ <- walletClient.walletPassphrase(password, 1000, Some(walletName))
_ <- walletClient.importWallet(walletFile, Some(walletName))
_ <- walletClient.dumpPrivKey(address, Some(walletName))
} yield assert(fileResult.filename.exists)
}
it should "be able to set the tx fee" in { nodePair =>
val client = nodePair.node2
for {

View File

@ -1,7 +1,6 @@
package org.bitcoins.rpc.common
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.core.protocol.P2PKHAddress
import org.bitcoins.crypto.ECPrivateKey
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.BitcoindInstanceLocal
@ -13,7 +12,7 @@ import scala.concurrent.Future
class MultisigRpcTest extends BitcoindRpcTest {
val instance: BitcoindInstanceLocal =
BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.V21))
BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.newest))
lazy val clientF: Future[BitcoindRpcClient] =
BitcoindRpcTestUtil.startedBitcoindRpcClient(instanceOpt = Some(instance),
@ -36,20 +35,4 @@ class MultisigRpcTest extends BitcoindRpcTest {
} yield succeed
}
it should "be able to add a multi sig address to the wallet" in {
val ecPrivKey1 = ECPrivateKey.freshPrivateKey
val pubKey1 = ecPrivKey1.publicKey
for {
client <- clientF
address <- client.getNewAddress(addressType = AddressType.Legacy)
_ <- {
val pubkey = Left(pubKey1)
val p2pkh = Right(address.asInstanceOf[P2PKHAddress])
client
.addMultiSigAddress(2, Vector(pubkey, p2pkh))
}
} yield succeed
}
}

View File

@ -1,22 +1,14 @@
package org.bitcoins.rpc.common
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script.{
EmptyScriptSignature,
P2SHScriptSignature,
ScriptPubKey,
ScriptSignature
}
import org.bitcoins.core.protocol.transaction.{
BaseTransaction,
TransactionConstants,
TransactionInput,
TransactionOutPoint,
TransactionOutput
}
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.rpc.BitcoindException.InvalidAddressOrKey
import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
@ -27,7 +19,7 @@ import scala.concurrent.Future
class RawTransactionRpcTest extends BitcoindRpcTest {
lazy val clientsF: Future[(BitcoindRpcClient, BitcoindRpcClient)] =
BitcoindRpcTestUtil.createNodePairV21(clientAccum = clientAccum)
BitcoindRpcTestUtil.createNodePair(clientAccum = clientAccum)
behavior of "RawTransactionRpc"
@ -145,15 +137,10 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
for {
(client, server) <- clientsF
address <- client.getNewAddress
pubkey <- BitcoindRpcTestUtil.getPubkey(client, address)
multisig <-
client
.addMultiSigAddress(1, Vector(Left(pubkey.get)), AddressType.Bech32)
txid <-
BitcoindRpcTestUtil
.fundBlockChainTransaction(client, server, multisig.address, fundAmt)
.fundBlockChainTransaction(client, server, address, fundAmt)
rawTx <- client.getTransaction(txid)
tx <- client.decodeRawTransaction(rawTx.hex)
output =
tx.vout
@ -164,7 +151,7 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
rawCreatedTx <- {
val input =
TransactionInput(TransactionOutPoint(txid.flip, UInt32(output.n)),
P2SHScriptSignature(multisig.redeemScript.hex),
EmptyScriptSignature,
UInt32.max - UInt32.one)
client
.createRawTransaction(Vector(input),
@ -177,7 +164,7 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
txid = txid,
vout = output.n,
scriptPubKey = ScriptPubKey.fromAsmHex(output.scriptPubKey.hex),
redeemScript = Some(multisig.redeemScript),
redeemScript = None,
amount = Some(fundAmt)
))
BitcoindRpcTestUtil.signRawTransaction(
@ -189,83 +176,6 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
} yield assert(result.complete)
}
it should "be able to combine raw transactions" in {
val fundAmt = Bitcoins(1.2)
val sendAmt = fundAmt.satoshis - Satoshis(1000)
for {
(client, otherClient) <- clientsF
address1 <- client.getNewAddress
address2 <- otherClient.getNewAddress
pub1 <- BitcoindRpcTestUtil.getPubkey(client, address1)
pub2 <- BitcoindRpcTestUtil.getPubkey(otherClient, address2)
keys = Vector(pub1.get, pub2.get).map(Left(_))
multisig <- client.addMultiSigAddress(2, keys, AddressType.Bech32)
_ <- otherClient.addMultiSigAddress(2, keys, AddressType.Bech32)
txid <- BitcoindRpcTestUtil.fundBlockChainTransaction(client,
otherClient,
multisig.address,
fundAmt)
rawTx <- client.getTransaction(txid)
tx <- client.decodeRawTransaction(rawTx.hex)
output =
tx.vout
.find(output => output.value == fundAmt)
.get
address3 <- client.getNewAddress
ctx = {
val input =
TransactionInput(TransactionOutPoint(txid.flip, UInt32(output.n)),
EmptyScriptSignature,
UInt32.max - UInt32.one)
BaseTransaction(
TransactionConstants.validLockVersion,
Vector(input),
Vector(TransactionOutput(sendAmt, address3.scriptPubKey)),
TransactionConstants.lockTime
)
}
txOpts = {
val scriptPubKey =
ScriptPubKey.fromAsmHex(output.scriptPubKey.hex)
val utxoDep =
RpcOpts.SignRawTransactionOutputParameter(
txid = txid,
vout = output.n,
scriptPubKey = scriptPubKey,
redeemScript = Some(multisig.redeemScript),
amount = Some(Bitcoins(1.2)))
Vector(utxoDep)
}
partialTx1 <- BitcoindRpcTestUtil.signRawTransaction(signer = client,
transaction = ctx,
utxoDeps = txOpts)
partialTx2 <-
BitcoindRpcTestUtil.signRawTransaction(signer = otherClient,
transaction = ctx,
utxoDeps = txOpts)
combinedTx <- {
val txs = Vector(partialTx1.hex, partialTx2.hex)
client.combineRawTransaction(txs)
}
_ <- client.sendRawTransaction(combinedTx)
} yield {
assert(!partialTx1.complete)
assert(partialTx1.hex != ctx)
assert(!partialTx2.complete)
assert(partialTx2.hex != ctx)
}
}
it should "fail to abandon a transaction which has not been sent" in {
clientsF.flatMap { case (client, otherClient) =>
otherClient.getNewAddress.flatMap { address =>

View File

@ -1,9 +1,6 @@
package org.bitcoins.rpc.common
import org.bitcoins.commons.jsonmodels.bitcoind.{
DecodeScriptResultPreV22,
DecodeScriptResultV22
}
import org.bitcoins.commons.jsonmodels.bitcoind.{DecodeScriptResultV22}
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.core.script.ScriptType
import org.bitcoins.crypto.ECPrivateKey
@ -35,17 +32,12 @@ class UtilRpcTest extends BitcoindRpcTest {
val pubKey2 = ecPrivKey2.publicKey
for {
(client, _) <- clientsF
address <- client.getNewAddress(addressType = AddressType.Legacy)
multisig <-
client
.createMultiSig(2, Vector(pubKey1, pubKey2), AddressType.Legacy)
decoded <- client.decodeScript(multisig.redeemScript)
} yield {
decoded match {
case decodedPreV22: DecodeScriptResultPreV22 =>
assert(decodedPreV22.reqSigs.exists(_ == 2))
assert(decoded.typeOfScript.exists(_ == ScriptType.MULTISIG))
assert(decodedPreV22.addresses.get.exists(_ == address))
case decodedV22: DecodeScriptResultV22 =>
assert(decodedV22.typeOfScript.contains(ScriptType.MULTISIG))
}

View File

@ -1,17 +1,17 @@
package org.bitcoins.rpc.common
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts
import org.bitcoins.commons.file.FileUtil
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
AddressType,
WalletFlag
}
import org.bitcoins.core.config.RegTest
import org.bitcoins.core.crypto.ECPrivateKeyUtil
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit, Satoshis}
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.script._
import org.bitcoins.core.protocol.script.descriptor.P2WPKHDescriptor
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.protocol.{Bech32Address, BitcoinAddress, P2PKHAddress}
import org.bitcoins.core.protocol.{Bech32Address, BitcoinAddress}
import org.bitcoins.core.psbt.PSBT
import org.bitcoins.core.wallet.fee.SatoshisPerByte
import org.bitcoins.core.wallet.signer.BitcoinSigner
@ -26,19 +26,17 @@ import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.{BitcoindInstanceLocal, BitcoindInstanceRemote}
import org.bitcoins.rpc.util.RpcUtil
import org.bitcoins.testkit.rpc.{
BitcoindFixturesCachedPairV21,
BitcoindFixturesCachedPairNewest,
BitcoindRpcTestUtil
}
import org.bitcoins.testkit.util.PekkoUtil
import org.scalatest.{FutureOutcome, Outcome}
import java.io.File
import java.util.Scanner
import scala.concurrent.duration.DurationInt
import scala.concurrent.{Await, Future}
import scala.reflect.io.Directory
import scala.concurrent.duration.DurationInt
class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val f: Future[Outcome] = for {
@ -54,7 +52,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
lazy val walletClientF: Future[BitcoindRpcClient] = clientsF.flatMap { _ =>
val walletClient =
BitcoindRpcClient.withActorSystem(
BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.V21)))
BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.newest)))
for {
_ <- startClient(walletClient)
@ -73,25 +71,6 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
behavior of "WalletRpc"
it should "be able to dump the wallet" in { nodePair: FixtureParam =>
val client = nodePair.node1
val localInstance = client.getDaemon match {
case _: BitcoindInstanceRemote =>
sys.error(s"Cannot use remote bitcoind instance in test cases")
case local: BitcoindInstanceLocal =>
local
}
for {
result <- {
val datadir = localInstance.datadir.getAbsolutePath
client.dumpWallet(datadir + "/test.dat")
}
} yield {
assert(result.filename.exists)
assert(result.filename.isFile)
}
}
it should "be able to list wallets" in { nodePair: FixtureParam =>
val client = nodePair.node1
for {
@ -208,7 +187,8 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
}
}
it should "be able to refill the keypool" in { nodePair: FixtureParam =>
it should "be able to refill the keypool" ignore { nodePair: FixtureParam =>
//ignore until: https://github.com/bitcoin/bitcoin/issues/29924
val client = nodePair.node1
for {
info <- client.getWalletInfo
@ -379,31 +359,6 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
}
}
it should "be able to import an address" in { nodePair: FixtureParam =>
val client = nodePair.node1
val otherClient = nodePair.node2
val address = Bech32Address
.fromString("bcrt1q9h9wkz6ad49szfl035wh3qdacuslkp6j9pfp4j")
for {
_ <- otherClient.importAddress(address)
txid <- BitcoindRpcTestUtil.fundBlockChainTransaction(client,
otherClient,
address,
Bitcoins(1.5))
list <- otherClient.listReceivedByAddress(includeWatchOnly = true)
} yield {
val entry =
list
.find(_.involvesWatchonly.contains(true))
.get
assert(entry.address == address)
assert(entry.involvesWatchonly.contains(true))
assert(entry.amount == Bitcoins(1.5))
assert(entry.txids.head == txid)
}
}
it should "be able to get the balance" in { nodePair: FixtureParam =>
val client = nodePair.node1
for {
@ -416,114 +371,6 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
}
}
it should "be able to dump a private key" in { nodePair: FixtureParam =>
val client = nodePair.node1
for {
address <- client.getNewAddress
_ <- client.dumpPrivKey(address)
} yield succeed
}
it should "be able to import a private key" in { nodePair: FixtureParam =>
val client = nodePair.node1
val ecPrivateKey = ECPrivateKey.freshPrivateKey
val publicKey = ecPrivateKey.publicKey
val address = P2PKHAddress(publicKey, networkParam)
val localInstance = client.getDaemon match {
case _: BitcoindInstanceRemote =>
sys.error(s"Cannot use remote bitcoind instance in test cases")
case local: BitcoindInstanceLocal =>
local
}
for {
_ <- client.importPrivKey(ecPrivateKey.toPrivateKeyBytes(),
rescan = false)
key <- client.dumpPrivKey(address)
result <-
client
.dumpWallet(
localInstance.datadir.getAbsolutePath + "/wallet_dump.dat")
} yield {
assert(key.toPrivateKey == ecPrivateKey)
val reader = new Scanner(result.filename)
var found = false
while (reader.hasNext) {
if (
reader.next == ECPrivateKeyUtil.toWIF(
ecPrivateKey.toPrivateKeyBytes(),
networkParam)
) {
found = true
}
}
assert(found)
}
}
it should "be able to import a public key" in { nodePair: FixtureParam =>
val client = nodePair.node1
val pubKey = ECPublicKey.freshPublicKey
for {
_ <- client.importPubKey(pubKey)
} yield succeed
}
it should "be able to import multiple addresses with importMulti" in {
nodePair: FixtureParam =>
val client = nodePair.node1
val privKey = ECPrivateKey.freshPrivateKey
val address1 = P2PKHAddress(privKey.publicKey, networkParam)
val privKey1 = ECPrivateKey.freshPrivateKey
val privKey2 = ECPrivateKey.freshPrivateKey
for {
firstResult <-
client
.createMultiSig(2,
Vector(privKey1.publicKey, privKey2.publicKey),
AddressType.Bech32)
address2 = firstResult.address
secondResult <-
client
.importMulti(
Vector(
RpcOpts.ImportMultiRequest(RpcOpts.ImportMultiAddress(address1),
UInt32(0)),
RpcOpts.ImportMultiRequest(RpcOpts.ImportMultiAddress(address2),
UInt32(0))),
rescan = false
)
} yield {
assert(secondResult.length == 2)
assert(secondResult(0).success)
assert(secondResult(1).success)
}
}
it should "be able to import a wallet" in { nodePair: FixtureParam =>
val client = nodePair.node1
val localInstance = client.getDaemon match {
case _: BitcoindInstanceRemote =>
sys.error(s"Cannot use remote bitcoind instance in test cases")
case local: BitcoindInstanceLocal =>
local
}
for {
walletClient <- walletClientF
address <- client.getNewAddress
walletFile =
localInstance.datadir.getAbsolutePath + "/client_wallet.dat"
fileResult <- client.dumpWallet(walletFile)
_ <- walletClient.walletPassphrase(password, 1000)
_ <- walletClient.importWallet(walletFile)
_ <- walletClient.dumpPrivKey(address)
} yield assert(fileResult.filename.exists)
}
it should "be able to load a wallet" in { nodePair: FixtureParam =>
val client = nodePair.node1
val name = "tmp_wallet"
@ -542,10 +389,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
_ <- client.unloadWallet(walletFile)
loadResult <- walletClient.loadWallet(walletFile)
} yield {
// clean up
val directory = new Directory(new File(walletFile))
directory.deleteRecursively()
FileUtil.removeDirectory(new File(walletFile).toPath)
assert(loadResult.name == walletFile)
}
}
@ -607,7 +451,6 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
// Will throw error if invalid
_ <- client.sendRawTransaction(singedTx)
} yield {
assert(transaction.inputs.length == 2)
assert(
transaction.outputs.contains(
TransactionOutput(Bitcoins(1), address.scriptPubKey)))
@ -618,29 +461,45 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
nodePair: FixtureParam =>
val client = nodePair.node1
val otherClient = nodePair.node2
val privKey = ECPrivateKey.freshPrivateKey
val np = RegTest
val descriptor = P2WPKHDescriptor(privKey, np)
val spk = P2WPKHWitnessSPKV0(privKey.publicKey)
val importedAddress = Bech32Address.fromScriptPubKey(spk, np)
for {
fundingTxId <- otherClient.sendToAddress(importedAddress,
Bitcoins(1.01))
_ <- otherClient.generate(1)
vout <- otherClient
.getRawTransactionRaw(fundingTxId)
.map(_.outputs.zipWithIndex.find(
_._1.scriptPubKey == descriptor.scriptPubKey))
.map(_.get._2)
fundingPrevOut = TransactionOutPoint(fundingTxId, vout)
fundingInput = TransactionInput(fundingPrevOut,
ScriptSignature.empty,
TransactionConstants.sequence)
address <- otherClient.getNewAddress
transactionWithoutFunds <-
transaction <-
client
.createRawTransaction(Vector.empty, Map(address -> Bitcoins(1)))
transactionResult <- client.fundRawTransaction(transactionWithoutFunds)
transaction = transactionResult.hex
signedTx <- client.signRawTransactionWithWallet(transaction).map(_.hex)
.createRawTransaction(inputs = Vector(fundingInput),
outputs = Map(address -> Bitcoins.one))
signedTx <- client
.signRawTransactionWithKey(transaction, Vector(privKey))
.map(_.hex)
_ <- client.broadcastTransaction(signedTx)
// Validate signature against bitcoin-s generated one
outPoint = transaction.inputs.head.previousOutput
prevTx <- client.getRawTransactionRaw(outPoint.txIdBE)
output = prevTx.outputs(outPoint.vout.toInt)
privKey <- client.dumpPrivKey(
BitcoinAddress.fromScriptPubKey(output.scriptPubKey, RegTest))
_ = BitcoinAddress.fromScriptPubKey(output.scriptPubKey, RegTest)
} yield {
val partialSig = BitcoinSigner.signSingle(
ECSignatureParams(P2WPKHV0InputInfo(outPoint,
output.value,
privKey.toPrivateKey.publicKey),
prevTx,
privKey.toPrivateKey,
HashType.sigHashAll),
ECSignatureParams(
P2WPKHV0InputInfo(outPoint, output.value, privKey.publicKey),
prevTx,
privKey,
HashType.sigHashAll),
transaction,
isDummySignature = false
)
@ -737,7 +596,7 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
override def afterAll(): Unit = {
val stopF = walletClientF.map(BitcoindRpcTestUtil.stopServer)
Await.result(stopF, duration)
Await.result(stopF, 30.seconds)
super.afterAll()
}
}

View File

@ -1,214 +0,0 @@
package org.bitcoins.rpc.v21
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
AddressType,
WalletFlag
}
import org.bitcoins.commons.jsonmodels.bitcoind._
import org.bitcoins.core.config.RegTest
import org.bitcoins.core.gcs.{BlockFilter, FilterType}
import org.bitcoins.core.psbt.PSBT
import org.bitcoins.crypto.ECPublicKey
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.testkit.rpc.BitcoindFixturesFundedCachedV21
import java.io.File
import java.nio.file.Files
import scala.concurrent.Future
class BitcoindV21RpcClientTest extends BitcoindFixturesFundedCachedV21 {
behavior of "BitcoindV21RpcClient"
it should "be able to start a V21 bitcoind instance" in {
client: BitcoindV21RpcClient =>
for {
v <- client.version
} yield assert(v == BitcoindVersion.V21)
}
it should "be able to get network info" in {
freshClient: BitcoindV21RpcClient =>
for {
info <- freshClient.getNetworkInfo
} yield {
assert(info.networkactive)
assert(info.localrelay)
}
}
it should "get index info" in { client: BitcoindV21RpcClient =>
def indexSynced(client: BitcoindRpcClient): Future[Boolean] = {
client.getIndexInfo.map { indexes =>
indexes("txindex").best_block_height == 101 && indexes(
"basic block filter index").best_block_height == 101
}
}
for {
_ <- AsyncUtil.retryUntilSatisfiedF(() => indexSynced(client))
indexes <- client.getIndexInfo
} yield {
val txIndexInfo = indexes("txindex")
assert(txIndexInfo.synced)
assert(txIndexInfo.best_block_height == 101)
val blockFilterIndexInfo = indexes("basic block filter index")
assert(blockFilterIndexInfo.synced)
assert(blockFilterIndexInfo.best_block_height == 101)
}
}
it should "be able to get the address info for a given address" in {
client: BitcoindV21RpcClient =>
for {
addr <- client.getNewAddress
info <- client.getAddressInfo(addr)
} yield assert(info.address == addr)
}
it should "get a block filter given a block hash" in {
client: BitcoindV21RpcClient =>
for {
blocks <- client.generate(1)
blockFilter <- client.getBlockFilter(blocks.head, FilterType.Basic)
block <- client.getBlockRaw(blocks.head)
txs <- Future.sequence(
block.transactions
.filterNot(_.isCoinbase)
.map(tx => client.getTransaction(tx.txIdBE)))
prevFilter <- client.getBlockFilter(
block.blockHeader.previousBlockHashBE,
FilterType.Basic)
} yield {
val pubKeys = txs.flatMap(_.hex.outputs.map(_.scriptPubKey)).toVector
val filter = BlockFilter(block, pubKeys)
assert(filter.hash == blockFilter.filter.hash)
assert(
blockFilter.header == filter
.getHeader(prevFilter.header.flip)
.hash
.flip)
}
}
it should "be able to get the balances" in { client: BitcoindV21RpcClient =>
for {
immatureBalance <- client.getBalances
_ <- client.generate(1)
newImmatureBalance <- client.getBalances
} yield {
val blockReward = 50
assert(immatureBalance.mine.immature.toBigDecimal >= 0)
assert(
immatureBalance.mine.trusted.toBigDecimal + blockReward == newImmatureBalance.mine.trusted.toBigDecimal)
}
}
it should "be able to get blockchain info" in {
client: BitcoindV21RpcClient =>
for {
info <- client.getBlockChainInfo
bestHash <- client.getBestBlockHash()
} yield {
assert(info.isInstanceOf[GetBlockChainInfoResultPostV19])
val preV19Info = info.asInstanceOf[GetBlockChainInfoResultPostV19]
assert(preV19Info.chain == RegTest)
assert(preV19Info.softforks.size >= 5)
assert(
preV19Info.softforks.values.exists(
_.isInstanceOf[Bip9SoftforkPostV19]))
assert(preV19Info.bestblockhash == bestHash)
}
}
it should "be able to set the wallet flag 'avoid_reuse'" in {
client: BitcoindV21RpcClient =>
for {
unspentPre <- client.listUnspent
result <- client.setWalletFlag(WalletFlag.AvoidReuse, value = true)
unspentPost <- client.listUnspent
} yield {
assert(result.flag_name == "avoid_reuse")
assert(result.flag_state)
assert(unspentPre.forall(utxo => utxo.reused.isEmpty))
assert(unspentPost.forall(utxo => utxo.reused.isDefined))
}
}
it should "create a wallet with a passphrase" in {
client: BitcoindV21RpcClient =>
for {
_ <- client.createWallet("suredbits", passphrase = "stackingsats")
wallets <- client.listWallets
} yield {
assert(wallets.contains("suredbits"))
}
}
it should "check to see if the utxoUpdate input has been updated" in {
client: BitcoindV21RpcClient =>
val descriptor =
"pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)"
val psbt =
PSBT.fromBase64(
"cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==")
for {
result <- client.utxoUpdatePsbt(psbt, Seq(descriptor))
} yield {
assert(result == psbt)
}
}
it should "correct create multisig and get its descriptor" in {
client: BitcoindV21RpcClient =>
val pubKey1 = ECPublicKey.freshPublicKey
val pubKey2 = ECPublicKey.freshPublicKey
for {
multiSigResult <- client.createMultiSig(2,
Vector(pubKey1, pubKey2),
AddressType.Bech32)
} yield {
// just validate we are able to receive a sane descriptor
// no need to check checksum
assert(
multiSigResult.descriptor.startsWith(
s"wsh(multi(2,${pubKey1.hex},${pubKey2.hex}))#"))
}
}
it should "correctly dump tx out set" in { client: BitcoindV21RpcClient =>
for {
hash <- client.getBestBlockHash()
height <- client.getBestHashBlockHeight()
result <- client.dumpTxOutSet(new File("utxo.dat").toPath)
} yield {
assert(Files.exists(result.path))
// Mild clean up
Files.delete(result.path)
assert(result.base_hash == hash)
assert(result.base_height == height)
assert(result.coins_written > 0)
}
}
it should "correct generate to a descriptor" in {
client: BitcoindV21RpcClient =>
// 2-of-2 multisig descriptor
val descriptor =
"sh(sortedmulti(2,023f720438186fbdfde0c0a403e770a0f32a2d198623a8a982c47b621f8b307640,03ed261094d609d5e02ba6553c2d91e4fd056006ce2fe64aace72b69cb5be3ab9c))#nj9wx7up"
val numBlocks = 10
for {
hashes <- client.generateToDescriptor(numBlocks, descriptor)
} yield assert(hashes.size == numBlocks)
}
}

View File

@ -165,8 +165,6 @@ class BitcoindV22RpcClientTest extends BitcoindFixturesCachedPairV22 {
descript match {
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
assert(walletInfoPostV22.descriptors)
case _: GetWalletInfoResultPreV22 =>
fail("descriptors only available on V22 or higher")
}
}
}
@ -184,8 +182,6 @@ class BitcoindV22RpcClientTest extends BitcoindFixturesCachedPairV22 {
walletPriv match {
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
assert(!walletInfoPostV22.private_keys_enabled)
case _: GetWalletInfoResultPreV22 =>
fail("private key parameter only available on V22 or higher")
}
}
}
@ -208,10 +204,6 @@ class BitcoindV22RpcClientTest extends BitcoindFixturesCachedPairV22 {
_ <- client.unloadWallet("decodeRWallet")
} yield {
decoded match {
case decodedPreV22: DecodeScriptResultPreV22 =>
assert(decodedPreV22.reqSigs.contains(2))
assert(decoded.typeOfScript.contains(ScriptType.MULTISIG))
assert(decodedPreV22.addresses.get.contains(address))
case decodedV22: DecodeScriptResultV22 =>
assert(decodedV22.typeOfScript.contains(ScriptType.MULTISIG))
}

View File

@ -1,23 +1,35 @@
package org.bitcoins.rpc.v24
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
AddressType,
WalletFlag
}
import org.bitcoins.commons.jsonmodels.bitcoind.{
AddressInfoResultPostV18,
AddressInfoResultPostV21,
AddressInfoResultPreV18,
DescriptorsResult
DescriptorsResult,
GetBlockChainInfoResultPostV23
}
import org.bitcoins.core.api.chain.db.BlockHeaderDbHelper
import org.bitcoins.core.config.RegTest
import org.bitcoins.core.currency._
import org.bitcoins.core.gcs.{BlockFilter, FilterType}
import org.bitcoins.core.protocol.{Bech32mAddress, BitcoinAddress}
import org.bitcoins.core.protocol.blockchain.RegTestNetChainParams
import org.bitcoins.core.protocol.script.descriptor.Descriptor
import org.bitcoins.rpc.client.common.BitcoindVersion
import org.bitcoins.core.psbt.PSBT
import org.bitcoins.crypto.ECPublicKey
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
import org.bitcoins.testkit.chain.BlockHeaderHelper
import org.bitcoins.testkit.rpc.BitcoindFixturesFundedCachedV24
import java.io.File
import java.nio.file.Files
import java.time.Instant
import scala.concurrent.Future
class BitcoindV24RpcClientTest extends BitcoindFixturesFundedCachedV24 {
@ -26,6 +38,27 @@ class BitcoindV24RpcClientTest extends BitcoindFixturesFundedCachedV24 {
behavior of "BitcoindV24RpcClient"
it should "get index info" in { client: BitcoindV24RpcClient =>
def indexSynced(client: BitcoindRpcClient): Future[Boolean] = {
client.getIndexInfo.map { indexes =>
indexes("txindex").best_block_height == 101 && indexes(
"basic block filter index").best_block_height == 101
}
}
for {
_ <- AsyncUtil.retryUntilSatisfiedF(() => indexSynced(client))
indexes <- client.getIndexInfo
} yield {
val txIndexInfo = indexes("txindex")
assert(txIndexInfo.synced)
assert(txIndexInfo.best_block_height == 101)
val blockFilterIndexInfo = indexes("basic block filter index")
assert(blockFilterIndexInfo.synced)
assert(blockFilterIndexInfo.best_block_height == 101)
}
}
it should "be able to start a V24 bitcoind instance" in {
client: BitcoindV24RpcClient =>
for {
@ -184,4 +217,154 @@ class BitcoindV24RpcClientTest extends BitcoindFixturesFundedCachedV24 {
assert(Vector(firstAddress, secondAddress) == deriveAddresses)
}
}
it should "be able to get the address info for a given address" in {
client: BitcoindV24RpcClient =>
for {
addr <- client.getNewAddress
info <- client.getAddressInfo(addr)
} yield assert(info.address == addr)
}
it should "get a block filter given a block hash" in {
client: BitcoindV24RpcClient =>
for {
blocks <- client.generate(1)
blockHashBE = blocks.head
blockFilter <- client.getBlockFilter(blockHashBE, FilterType.Basic)
block <- client.getBlockRaw(blockHashBE)
prevOuts = block.transactions
.filterNot(_.isCoinbase)
.flatMap(_.inputs.map(_.previousOutput))
fundingOutputs <- Future.traverse(prevOuts) { outpoint =>
client
.getTransaction(outpoint.txIdBE)
.map(_.hex.outputs(outpoint.idx))
}
prevFilter <- client.getBlockFilter(
block.blockHeader.previousBlockHashBE,
FilterType.Basic)
} yield {
val pubKeys = fundingOutputs.map(_.scriptPubKey).toVector
val filter = BlockFilter(block, pubKeys)
assert(filter.hash == blockFilter.filter.hash)
assert(
blockFilter.header == filter
.getHeader(prevFilter.header.flip)
.hashBE)
}
}
it should "be able to get the balances" in { client: BitcoindV24RpcClient =>
for {
immatureBalance <- client.getBalances
_ <- client.generate(1)
newImmatureBalance <- client.getBalances
} yield {
val blockReward = 50
assert(immatureBalance.mine.immature.toBigDecimal >= 0)
assert(
immatureBalance.mine.trusted.toBigDecimal + blockReward == newImmatureBalance.mine.trusted.toBigDecimal)
}
}
it should "be able to get blockchain info" in {
client: BitcoindV24RpcClient =>
for {
info <- client.getBlockChainInfo
bestHash <- client.getBestBlockHash()
} yield {
assert(info.isInstanceOf[GetBlockChainInfoResultPostV23])
val postV23Info = info.asInstanceOf[GetBlockChainInfoResultPostV23]
assert(postV23Info.chain == RegTest)
assert(postV23Info.bestblockhash == bestHash)
}
}
it should "be able to set the wallet flag 'avoid_reuse'" in {
client: BitcoindV24RpcClient =>
for {
unspentPre <- client.listUnspent
result <- client.setWalletFlag(WalletFlag.AvoidReuse, value = true)
unspentPost <- client.listUnspent
} yield {
assert(result.flag_name == "avoid_reuse")
assert(result.flag_state)
assert(unspentPre.forall(utxo => utxo.reused.isEmpty))
assert(unspentPost.forall(utxo => utxo.reused.isDefined))
}
}
it should "create a wallet with a passphrase" in {
client: BitcoindV24RpcClient =>
for {
_ <- client.createWallet("suredbits", passphrase = "stackingsats")
wallets <- client.listWallets
} yield {
assert(wallets.contains("suredbits"))
}
}
it should "check to see if the utxoUpdate input has been updated" in {
client: BitcoindV24RpcClient =>
val descriptor =
"pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)"
val psbt =
PSBT.fromBase64(
"cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==")
for {
result <- client.utxoUpdatePsbt(psbt, Seq(descriptor))
} yield {
assert(result == psbt)
}
}
it should "correct create multisig and get its descriptor" in {
client: BitcoindV24RpcClient =>
val pubKey1 = ECPublicKey.freshPublicKey
val pubKey2 = ECPublicKey.freshPublicKey
for {
multiSigResult <- client.createMultiSig(2,
Vector(pubKey1, pubKey2),
AddressType.Bech32)
} yield {
// just validate we are able to receive a sane descriptor
// no need to check checksum
assert(
multiSigResult.descriptor.startsWith(
s"wsh(multi(2,${pubKey1.hex},${pubKey2.hex}))#"))
}
}
it should "correctly dump tx out set" in { client: BitcoindV24RpcClient =>
for {
hash <- client.getBestBlockHash()
height <- client.getBestHashBlockHeight()
result <- client.dumpTxOutSet(new File("utxo.dat").toPath)
} yield {
assert(Files.exists(result.path))
// Mild clean up
Files.delete(result.path)
assert(result.base_hash == hash)
assert(result.base_height == height)
assert(result.coins_written > 0)
}
}
it should "correct generate to a descriptor" in {
client: BitcoindV24RpcClient =>
// 2-of-2 multisig descriptor
val descriptor =
"sh(sortedmulti(2,023f720438186fbdfde0c0a403e770a0f32a2d198623a8a982c47b621f8b307640,03ed261094d609d5e02ba6553c2d91e4fd056006ce2fe64aace72b69cb5be3ab9c))#nj9wx7up"
val numBlocks = 10
for {
hashes <- client.generateToDescriptor(numBlocks, descriptor)
} yield assert(hashes.size == numBlocks)
}
}

View File

@ -16,7 +16,6 @@ import org.bitcoins.core.wallet.fee.FeeUnit
import org.bitcoins.crypto.{DoubleSha256DigestBE, StringFactory}
import org.bitcoins.rpc.client.v18.V18AssortedRpc
import org.bitcoins.rpc.client.v20.{V20AssortedRpc, V20MultisigRpc}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
@ -318,7 +317,6 @@ object BitcoindRpcClient {
def fromVersion(version: BitcoindVersion, instance: BitcoindInstance)(implicit
system: ActorSystem): BitcoindRpcClient = {
val bitcoind = version match {
case BitcoindVersion.V21 => BitcoindV21RpcClient.withActorSystem(instance)
case BitcoindVersion.V22 => BitcoindV22RpcClient.withActorSystem(instance)
case BitcoindVersion.V23 => BitcoindV23RpcClient.withActorSystem(instance)
case BitcoindVersion.V24 => BitcoindV24RpcClient.withActorSystem(instance)
@ -347,14 +345,10 @@ object BitcoindVersion
val newest: BitcoindVersion = V24
val standard: Vector[BitcoindVersion] =
Vector(V21, V22, V23, V24)
Vector(V22, V23, V24)
val known: Vector[BitcoindVersion] = standard
case object V21 extends BitcoindVersion {
override def toString: String = "v0.21"
}
case object V22 extends BitcoindVersion {
override def toString: String = "v22"
}
@ -385,7 +379,6 @@ object BitcoindVersion
def fromNetworkVersion(int: Int): BitcoindVersion = {
//need to translate the int 210100 (as an example) to a BitcoindVersion
int.toString.substring(0, 2) match {
case "21" => V21
case "22" => V22
case "23" => V23
case "24" => V24

View File

@ -38,7 +38,7 @@ trait BlockchainRpc extends ChainApi { self: Client =>
def getBlockChainInfo: Future[GetBlockChainInfoResult] = {
self.version.flatMap {
case V22 | V21 =>
case V22 =>
bitcoindCall[GetBlockChainInfoResultPostV19]("getblockchaininfo")
case V23 | V24 | Unknown =>
bitcoindCall[GetBlockChainInfoResultPostV23]("getblockchaininfo")
@ -84,18 +84,12 @@ trait BlockchainRpc extends ChainApi { self: Client =>
}
def getBlockWithTransactions(headerHash: DoubleSha256DigestBE): Future[
GetBlockWithTransactionsResult] = {
GetBlockWithTransactionsResultV22] = {
val isVerboseJsonObject = JsNumber(2)
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetBlockWithTransactionsResultV22](
"getblock",
List(JsString(headerHash.hex), isVerboseJsonObject))
case V21 =>
bitcoindCall[GetBlockWithTransactionsResultPreV22](
"getblock",
List(JsString(headerHash.hex), isVerboseJsonObject))
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetBlockWithTransactionsResultV22](
"getblock",
List(JsString(headerHash.hex), isVerboseJsonObject))
}
}

View File

@ -4,7 +4,8 @@ import org.bitcoins.commons.jsonmodels.bitcoind.{
DeriveAddressesResult,
DescriptorsResult,
GetDescriptorInfoResult,
ImportDescriptorResult
ImportDescriptorResult,
ListDescriptorsResult
}
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.commons.serializers.JsonWriters.DescriptorWrites
@ -46,4 +47,39 @@ trait DescriptorRpc {
bitcoindCall[Vector[ImportDescriptorResult]]("importdescriptors",
List(Json.toJson(imports)))
}
def importDescriptor(
imp: DescriptorsResult): Future[ImportDescriptorResult] = {
importDescriptors(Vector(imp)).map(_.head)
}
def listDescriptors(): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors"
)
}
def listDescriptors(
priv: Option[Boolean],
walletName: String): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors",
List(Json.toJson(priv)),
uriExtensionOpt = Some(walletExtension(walletName))
)
}
def listDescriptors(priv: Option[Boolean]): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors",
List(Json.toJson(priv))
)
}
def listDescriptors(walletName: String): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors",
uriExtensionOpt = Some(walletExtension(walletName))
)
}
}

View File

@ -36,7 +36,7 @@ trait MempoolRpc { self: Client =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
"getmempoolancestors",
List(JsString(txid.hex), JsBoolean(true)))
case V22 | V21 | Unknown =>
case V22 | Unknown =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getmempoolancestors",
List(JsString(txid.hex), JsBoolean(true)))
@ -67,7 +67,7 @@ trait MempoolRpc { self: Client =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
"getmempooldescendants",
List(JsString(txid.hex), JsBoolean(true)))
case V22 | V21 | Unknown =>
case V22 | Unknown =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getmempooldescendants",
List(JsString(txid.hex), JsBoolean(true)))
@ -86,7 +86,7 @@ trait MempoolRpc { self: Client =>
case V24 | V23 | V24 | Unknown =>
bitcoindCall[GetMemPoolEntryResultPostV23]("getmempoolentry",
List(JsString(txid.hex)))
case V22 | V21 | Unknown =>
case V22 | Unknown =>
bitcoindCall[GetMemPoolEntryResultPostV19]("getmempoolentry",
List(JsString(txid.hex)))
}
@ -129,7 +129,7 @@ trait MempoolRpc { self: Client =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
"getrawmempool",
List(JsBoolean(true)))
case V22 | V21 | Unknown =>
case V22 | Unknown =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getrawmempool",
List(JsBoolean(true)))

View File

@ -39,7 +39,7 @@ trait MultisigRpc { self: Client =>
JsArray(keys.map(keyToString)),
JsString(account)) ++ addressType.map(Json.toJson(_)).toList
self.version.flatMap { case V24 | V23 | V22 | V21 | Unknown =>
self.version.flatMap { case V24 | V23 | V22 | Unknown =>
bitcoindCall[MultiSigResultPostV20]("addmultisigaddress",
params,
uriExtensionOpt =
@ -76,7 +76,7 @@ trait MultisigRpc { self: Client =>
keys: Vector[ECPublicKey],
addressType: AddressType,
walletNameOpt: Option[String] = None): Future[MultiSigResult] = {
self.version.flatMap { case V24 | V23 | V22 | V21 | Unknown =>
self.version.flatMap { case V24 | V23 | V22 | Unknown =>
bitcoindCall[MultiSigResultPostV20](
"createmultisig",
List(JsNumber(minSignatures),

View File

@ -63,17 +63,14 @@ trait P2PRpc { self: Client =>
}
def getPeerInfo: Future[Vector[Peer]] = {
self.version.flatMap { case V24 | V23 | V22 | V21 | Unknown =>
self.version.flatMap { case V24 | V23 | V22 | Unknown =>
bitcoindCall[Vector[PeerPostV21]]("getpeerinfo")
}
}
def listBanned: Future[Vector[NodeBan]] = {
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[Vector[NodeBanPostV22]]("listbanned")
case V21 =>
bitcoindCall[Vector[NodeBanPostV20]]("listbanned")
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[Vector[NodeBanPostV22]]("listbanned")
}
}

View File

@ -3,7 +3,6 @@ package org.bitcoins.rpc.client.common
import org.bitcoins.commons.jsonmodels.bitcoind.{
AnalyzePsbtResult,
DecodePsbtResult,
DecodePsbtResultPreV22,
DecodePsbtResultV22,
FinalizePsbtResult
}
@ -85,12 +84,8 @@ trait PsbtRpc {
}
def decodePsbt(psbt: PSBT): Future[DecodePsbtResult] = {
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[DecodePsbtResultV22]("decodepsbt", List(Json.toJson(psbt)))
case V21 =>
bitcoindCall[DecodePsbtResultPreV22]("decodepsbt",
List(Json.toJson(psbt)))
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[DecodePsbtResultV22]("decodepsbt", List(Json.toJson(psbt)))
}
}

View File

@ -3,11 +3,9 @@ package org.bitcoins.rpc.client.common
import org.bitcoins.commons.jsonmodels.bitcoind.{
FundRawTransactionResult,
GetRawTransactionResult,
GetRawTransactionResultPreV22,
GetRawTransactionResultV22,
RpcOpts,
RpcTransaction,
RpcTransactionPreV22,
RpcTransactionV22
}
import org.bitcoins.commons.serializers.JsonSerializers._
@ -42,14 +40,9 @@ trait RawTransactionRpc { self: Client =>
def decodeRawTransaction(transaction: Transaction): Future[RpcTransaction] = {
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[RpcTransactionV22]("decoderawtransaction",
List(JsString(transaction.hex)))
case V21 =>
bitcoindCall[RpcTransactionPreV22]("decoderawtransaction",
List(JsString(transaction.hex)))
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[RpcTransactionV22]("decoderawtransaction",
List(JsString(transaction.hex)))
}
}
@ -101,11 +94,8 @@ trait RawTransactionRpc { self: Client =>
case None => Nil
}
val params = List(JsString(txid.hex), JsBoolean(true)) ++ lastParam
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetRawTransactionResultV22]("getrawtransaction", params)
case V21 =>
bitcoindCall[GetRawTransactionResultPreV22]("getrawtransaction", params)
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetRawTransactionResultV22]("getrawtransaction", params)
}
}

View File

@ -6,13 +6,7 @@ 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 org.bitcoins.rpc.client.common.BitcoindVersion.{
Unknown,
V21,
V22,
V23,
V24
}
import org.bitcoins.rpc.client.common.BitcoindVersion.{Unknown, V22, V23, V24}
import play.api.libs.json._
import scala.concurrent.Future
@ -86,16 +80,10 @@ trait TransactionRpc { self: Client =>
txid: DoubleSha256DigestBE,
vout: Long,
includeMemPool: Boolean = true): Future[GetTxOutResult] = {
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetTxOutResultV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
case V21 =>
bitcoindCall[GetTxOutResultPreV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetTxOutResultV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
}
}
@ -104,16 +92,10 @@ trait TransactionRpc { self: Client =>
vout: Long,
includeMemPool: Boolean = true): Future[Option[GetTxOutResult]] = {
self.version
.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetTxOutResultV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
case V21 =>
bitcoindCall[GetTxOutResultPreV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[GetTxOutResultV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
}
.map(Some(_))
.recover(_ => None)

View File

@ -21,25 +21,21 @@ trait UtilRpc { self: Client =>
}
def decodeScript(script: ScriptPubKey): Future[DecodeScriptResult] = {
self.version.flatMap {
case V22 | V23 | V24 | Unknown =>
bitcoindCall[DecodeScriptResultV22]("decodescript",
List(Json.toJson(script)))
case V21 =>
bitcoindCall[DecodeScriptResultPreV22]("decodescript",
List(Json.toJson(script)))
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[DecodeScriptResultV22]("decodescript",
List(Json.toJson(script)))
}
}
def getIndexInfo: Future[Map[String, IndexInfoResult]] = {
version.flatMap { case V24 | V23 | V22 | V21 | Unknown =>
version.flatMap { case V24 | V23 | V22 | Unknown =>
bitcoindCall[Map[String, IndexInfoResult]]("getindexinfo")
}
}
def getIndexInfo(indexName: String): Future[IndexInfoResult] = {
version.flatMap { case V24 | V23 | V22 | V21 | Unknown =>
version.flatMap { case V24 | V23 | V22 | Unknown =>
bitcoindCall[Map[String, IndexInfoResult]](
"getindexinfo",
List(JsString(indexName))).map(_.head._2)

View File

@ -8,7 +8,6 @@ import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
import org.bitcoins.commons.jsonmodels.bitcoind._
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.commons.serializers.JsonWriters._
import org.bitcoins.core.crypto.ECPrivateKeyUtil
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit}
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.blockchain.MerkleBlock
@ -33,24 +32,6 @@ trait WalletRpc { self: Client =>
uriExtensionOpt = walletNameOpt.map(walletExtension))
}
def dumpPrivKey(
address: BitcoinAddress,
walletNameOpt: Option[String] = None): Future[ECPrivateKeyBytes] = {
bitcoindCall[String]("dumpprivkey",
List(JsString(address.value)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
.map(ECPrivateKeyUtil.fromWIFToPrivateKey)
}
def dumpWallet(
filePath: String,
walletNameOpt: Option[String] = None): Future[DumpWalletResult] = {
bitcoindCall[DumpWalletResult]("dumpwallet",
List(JsString(filePath)),
uriExtensionOpt =
walletNameOpt.map(walletExtension))
}
def encryptWallet(
passphrase: String,
walletNameOpt: Option[String] = None): Future[String] = {
@ -87,20 +68,6 @@ trait WalletRpc { self: Client =>
uriExtensionOpt = Some(walletExtension(walletName)))
}
def importAddress(
address: BitcoinAddress,
account: String = "",
rescan: Boolean = true,
p2sh: Boolean = false,
walletNameOpt: Option[String] = None): Future[Unit] = {
bitcoindCall[Unit]("importaddress",
List(JsString(address.value),
JsString(account),
JsBoolean(rescan),
JsBoolean(p2sh)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
}
private def getNewAddressInternal(
accountOrLabel: String = "",
addressType: Option[AddressType],
@ -169,10 +136,6 @@ trait WalletRpc { self: Client =>
bitcoindCall[GetWalletInfoResultPostV22](
"getwalletinfo",
uriExtensionOpt = walletName.map(walletExtension))
case BitcoindVersion.V21 =>
bitcoindCall[GetWalletInfoResultPreV22](
"getwalletinfo",
uriExtensionOpt = walletName.map(walletExtension))
}
}
@ -194,31 +157,6 @@ trait WalletRpc { self: Client =>
uriExtensionOpt = walletNameOpt.map(walletExtension))
}
def importPubKey(
pubKey: ECPublicKey,
label: String = "",
rescan: Boolean = true,
walletNameOpt: Option[String] = None): Future[Unit] = {
bitcoindCall[Unit](
"importpubkey",
List(JsString(pubKey.hex), JsString(label), JsBoolean(rescan)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
}
def importPrivKey(
key: ECPrivateKeyBytes,
account: String = "",
rescan: Boolean = true,
walletNameOpt: Option[String] = None): Future[Unit] = {
bitcoindCall[Unit](
"importprivkey",
List(JsString(ECPrivateKeyUtil.toWIF(key, network)),
JsString(account),
JsBoolean(rescan)),
uriExtensionOpt = walletNameOpt.map(walletExtension)
)
}
def importMulti(
requests: Vector[RpcOpts.ImportMultiRequest],
rescan: Boolean = true,
@ -262,14 +200,6 @@ trait WalletRpc { self: Client =>
removePrunedFunds(txid.flip, walletNameOpt)
}
def importWallet(
filePath: String,
walletNameOpt: Option[String] = None): Future[Unit] = {
bitcoindCall[Unit]("importwallet",
List(JsString(filePath)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
}
def listAddressGroupings: Future[Vector[Vector[RpcAddress]]] = {
bitcoindCall[Vector[Vector[RpcAddress]]]("listaddressgroupings")
}
@ -404,7 +334,7 @@ trait WalletRpc { self: Client =>
JsBoolean(avoidReuse),
JsBoolean(descriptors))
)
case V21 | Unknown =>
case Unknown =>
bitcoindCall[CreateWalletResult](
"createwallet",
List(JsString(walletName),
@ -424,7 +354,7 @@ trait WalletRpc { self: Client =>
"getaddressinfo",
List(JsString(address.value)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
case V24 | V23 | V22 | V21 | Unknown =>
case V24 | V23 | V22 | Unknown =>
bitcoindCall[AddressInfoResultPostV21](
"getaddressinfo",
List(JsString(address.value)),

View File

@ -5,10 +5,7 @@ import org.bitcoins.commons.jsonmodels.bitcoind.{
GetRpcInfoResult,
ListWalletDirResult
}
import org.bitcoins.commons.jsonmodels.bitcoind.{
GetNodeAddressesResultPostV22,
GetNodeAddressesResultPreV22
}
import org.bitcoins.commons.jsonmodels.bitcoind.{GetNodeAddressesResultPostV22}
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.core.protocol.blockchain.BlockHeader
import org.bitcoins.rpc.client.common.{BitcoindVersion, Client}
@ -33,10 +30,6 @@ trait V18AssortedRpc {
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
"getnodeaddresses",
List(Json.toJson(count)))
case BitcoindVersion.V21 =>
bitcoindCall[Vector[GetNodeAddressesResultPreV22]](
"getnodeaddresses",
List(Json.toJson(count)))
}
}

View File

@ -36,7 +36,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
JsArray(keys.map(keyToString)),
JsString(account)) ++ addressType.map(Json.toJson(_)).toList
self.version.flatMap { case V21 | V22 | V23 | V24 | Unknown =>
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[MultiSigResultPostV20]("addmultisigaddress", params)
}
}
@ -71,7 +71,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
keys: Vector[ECPublicKey],
addressType: AddressType,
walletNameOpt: Option[String] = None): Future[MultiSigResultPostV20] = {
self.version.flatMap { case V21 | V22 | V23 | V24 | Unknown =>
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
bitcoindCall[MultiSigResultPostV20](
"createmultisig",
List(JsNumber(minSignatures),

View File

@ -1,59 +0,0 @@
package org.bitcoins.rpc.client.v21
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.rpc.client.common.{
BitcoindRpcClient,
BitcoindVersion,
DescriptorRpc,
PsbtRpc
}
import org.bitcoins.rpc.client.v20.{V20AssortedRpc, V20MultisigRpc}
import org.bitcoins.rpc.config.BitcoindInstance
import scala.concurrent.Future
import scala.util.Try
/** Class for creating a BitcoindV21 instance that can access RPCs
*/
class BitcoindV21RpcClient(override val instance: BitcoindInstance)(implicit
actorSystem: ActorSystem)
extends BitcoindRpcClient(instance)
with DescriptorRpc
with PsbtRpc
with V20MultisigRpc
with V20AssortedRpc {
override lazy val version: Future[BitcoindVersion] =
Future.successful(BitcoindVersion.V21)
}
object BitcoindV21RpcClient {
/** Creates an RPC client from the given instance.
*
* Behind the scenes, we create an actor system for
* you. You can use `withActorSystem` if you want to
* manually specify an actor system for the RPC client.
*/
def apply(instance: BitcoindInstance): BitcoindV21RpcClient = {
implicit val system: ActorSystem =
ActorSystem.create(BitcoindRpcClient.ActorSystemName)
withActorSystem(instance)
}
/** 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 withActorSystem(instance: BitcoindInstance)(implicit
system: ActorSystem): BitcoindV21RpcClient =
new BitcoindV21RpcClient(instance)(system)
def fromUnknownVersion(
rpcClient: BitcoindRpcClient): Try[BitcoindV21RpcClient] =
Try {
new BitcoindV21RpcClient(rpcClient.instance)(rpcClient.system)
}
}

View File

@ -1,9 +1,6 @@
package org.bitcoins.rpc.client.v22
import org.bitcoins.commons.jsonmodels.bitcoind.{
GetNodeAddressesResultPostV22,
ListDescriptorsResult
}
import org.bitcoins.commons.jsonmodels.bitcoind.{GetNodeAddressesResultPostV22}
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.rpc.client.common.{Client, WalletRpc}
import org.bitcoins.rpc.client.v18.V18AssortedRpc
@ -15,37 +12,6 @@ import scala.concurrent.Future
trait V22AssortedRpc extends V18AssortedRpc with V20AssortedRpc with WalletRpc {
self: Client =>
def listDescriptors(): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors"
)
}
def listDescriptors(
Private: Option[Boolean],
walletName: String): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors",
List(Json.toJson(Private)),
uriExtensionOpt = Some(walletExtension(walletName))
)
}
def listDescriptors(
Private: Option[Boolean]): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors",
List(Json.toJson(Private))
)
}
def listDescriptors(walletName: String): Future[ListDescriptorsResult] = {
bitcoindCall[ListDescriptorsResult](
"listdescriptors",
uriExtensionOpt = Some(walletExtension(walletName))
)
}
private def getNodeAddresses(
count: Option[Int]): Future[Vector[GetNodeAddressesResultPostV22]] = {
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](

View File

@ -55,9 +55,6 @@ sealed trait BitcoindInstanceLocal extends BitcoindInstance {
.last
foundVersion match {
case _: String
if foundVersion.startsWith(BitcoindVersion.V21.toString) =>
BitcoindVersion.V21
case _: String
if foundVersion.startsWith(BitcoindVersion.V22.toString) =>
BitcoindVersion.V22

View File

@ -18,6 +18,8 @@ case class FilterHeader(
CryptoUtil.doubleSHA256(filterHash.bytes ++ prevHeaderHash.bytes)
}
val hashBE: DoubleSha256DigestBE = hash.flip
/** Given the next Block Filter, constructs the next Block Filter Header */
def nextHeader(nextFilter: GolombFilter): FilterHeader = {
FilterHeader(filterHash = nextFilter.hash, prevHeaderHash = this.hash)

View File

@ -1,9 +1,11 @@
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.util.Bech32
import org.bitcoins.crypto.{PublicKey, StringFactory}
import org.bitcoins.crypto.{ECPrivateKey, PublicKey, StringFactory}
import scala.util.Try
@ -42,6 +44,10 @@ case class P2WPKHDescriptor(
checksum: Option[String])
extends ScriptDescriptor {
override val scriptPubKey: P2WPKHWitnessSPKV0 = expression.scriptPubKey
def address(np: NetworkParameters): Bech32Address = {
Bech32Address(scriptPubKey, np)
}
}
case class P2WSHDescriptor(
@ -196,6 +202,19 @@ object P2WPKHDescriptor
checksum: Option[String]): P2WPKHDescriptor = {
P2WPKHDescriptor(e, checksum)
}
def apply(
privKey: ECPrivateKey,
network: NetworkParameters): P2WPKHDescriptor = {
val keyExpression = RawPrivateECPublicKeyExpression(
key = privKey.toPrivateKeyBytes(),
network = network,
originOpt = None)
val p2wpkhExpression = P2WPKHExpression(keyExpression)
val noChecksum = P2WPKHDescriptor(p2wpkhExpression, None)
val checksum = Descriptor.createChecksum(noChecksum)
P2WPKHDescriptor(p2wpkhExpression, Some(checksum))
}
}
object P2WSHDescriptor

View File

@ -31,6 +31,8 @@ case class TransactionOutPoint(txId: DoubleSha256Digest, vout: UInt32)
vout.compare(other.vout)
} else txIdBE.hex.compareTo(other.txIdBE.hex)
}
def idx: Int = vout.toInt
}
/** UInt32s cannot hold negative numbers, but sometimes the Bitcoin Protocol
@ -59,6 +61,10 @@ object TransactionOutPoint
TransactionOutPoint(txId.flip, vout)
}
def apply(txId: DoubleSha256DigestBE, vout: Long): TransactionOutPoint = {
TransactionOutPoint(txId, UInt32(vout))
}
override def fromString(string: String): TransactionOutPoint = {
val idx = string.indexOf(":")
val (txId, vout) = string.splitAt(idx)

View File

@ -44,7 +44,7 @@ trait CLightningRpcTestUtil extends BitcoinSLogger {
def bitcoindInstance(
port: Int = RpcUtil.randomPort,
rpcPort: Int = RpcUtil.randomPort,
bitcoindV: BitcoindVersion = BitcoindVersion.V21)(implicit
bitcoindV: BitcoindVersion = BitcoindVersion.newest)(implicit
system: ActorSystem): BitcoindInstanceLocal = {
BitcoindRpcTestUtil.getInstance(bitcoindVersion = bitcoindV,
port = port,

View File

@ -38,7 +38,7 @@ trait CLightningFixture extends BitcoinSFixture with CachedBitcoindNewest {
}
/** A trait that is useful if you need dual clightning fixtures for your test suite */
trait DualCLightningFixture extends BitcoinSFixture with CachedBitcoindV21 {
trait DualCLightningFixture extends BitcoinSFixture with CachedBitcoindNewest {
override type FixtureParam =
(BitcoindRpcClient, CLightningRpcClient, CLightningRpcClient)
@ -72,7 +72,7 @@ trait DualCLightningFixture extends BitcoinSFixture with CachedBitcoindV21 {
/** Creates two clightnings with no channels opened */
trait CLightningChannelOpenerFixture
extends BitcoinSFixture
with CachedBitcoindV21 {
with CachedBitcoindNewest {
override type FixtureParam =
(BitcoindRpcClient, CLightningRpcClient, CLightningRpcClient)

View File

@ -53,7 +53,7 @@ trait LndRpcTestUtil extends BitcoinSLogger {
port: Int = RpcUtil.randomPort,
rpcPort: Int = RpcUtil.randomPort,
zmqConfig: ZmqConfig = RpcUtil.zmqConfig,
bitcoindV: BitcoindVersion = BitcoindVersion.V21)(implicit
bitcoindV: BitcoindVersion = BitcoindVersion.newest)(implicit
system: ActorSystem): BitcoindInstanceLocal = {
BitcoindRpcTestUtil.getInstance(bitcoindVersion = bitcoindV,
port = port,

View File

@ -1,7 +1,6 @@
package org.bitcoins.testkit.rpc
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
@ -48,40 +47,6 @@ trait BitcoindFixturesFundedCached extends BitcoindFixtures {
}
}
/** Test trait that caches a [[BitcoindV21RpcClient]] that is funded
* and available to use with fixtures
*/
trait BitcoindFixturesFundedCachedV21
extends BitcoinSAsyncFixtureTest
with BitcoindFixturesFundedCached
with CachedBitcoindV21 {
override type FixtureParam = BitcoindV21RpcClient
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
val f: Future[Outcome] = for {
bitcoind <- cachedBitcoindWithFundsF
futOutcome = withV21FundedBitcoindCached(test, bitcoind)
fut <- futOutcome.toFuture
} yield fut
new FutureOutcome(f)
}
def withV21FundedBitcoindCached(
test: OneArgAsyncTest,
bitcoind: BitcoindV21RpcClient): FutureOutcome = {
makeDependentFixture[BitcoindV21RpcClient](
() => Future.successful(bitcoind),
{ case _ =>
Future.unit // don't want to destroy anything since it is cached
})(test)
}
override def afterAll(): Unit = {
super[CachedBitcoindV21].afterAll()
super[BitcoinSAsyncFixtureTest].afterAll()
}
}
/** Test trait that caches a [[BitcoindV22RpcClient]] that is funded
* and available to use with fixtures
*/
@ -222,19 +187,6 @@ trait BitcoindFixturesCachedPair[T <: BitcoindRpcClient]
}
}
trait BitcoindFixturesCachedPairV21
extends BitcoinSAsyncFixtureTest
with BitcoindFixturesCachedPair[BitcoindV21RpcClient] {
override type FixtureParam = NodePair[BitcoindV21RpcClient]
override val version: BitcoindVersion = BitcoindVersion.V21
override def afterAll(): Unit = {
super[BitcoindFixturesCachedPair].afterAll()
super[BitcoinSAsyncFixtureTest].afterAll()
}
}
/** Bitcoind fixtures with two cached bitcoind rpc clients that are [[BitcoindVersion.newest]] that are connected via p2p */
trait BitcoindFixturesCachedPairV22
extends BitcoinSAsyncFixtureTest

View File

@ -30,7 +30,6 @@ import org.bitcoins.crypto.{
import org.bitcoins.rpc.BitcoindException
import org.bitcoins.rpc.client.common.BitcoindVersion._
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
@ -172,7 +171,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
version match {
// default to newest version
case Unknown => getBinary(BitcoindVersion.newest, binaryDirectory)
case known @ (V21 | V22 | V23 | V24) =>
case known @ (V22 | V23 | V24) =>
val fileList = Files
.list(binaryDirectory)
.iterator()
@ -232,20 +231,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
BitcoindInstanceLocal.fromConfig(conf, binary)
}
def v21Instance(
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.V21),
binaryDirectory = binaryDirectory)
def v22Instance(
port: Int = RpcUtil.randomPort,
rpcPort: Int = RpcUtil.randomPort,
@ -298,12 +283,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory)(implicit
system: ActorSystem): BitcoindInstanceLocal = {
bitcoindVersion match {
case BitcoindVersion.V21 =>
BitcoindRpcTestUtil.v21Instance(port,
rpcPort,
zmqConfig,
pruneMode,
binaryDirectory = binaryDirectory)
case BitcoindVersion.V22 =>
BitcoindRpcTestUtil.v22Instance(port,
rpcPort,
@ -335,7 +314,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
val createWalletF = for {
version <- server.version
descriptors = version match {
case V21 | V22 | Unknown =>
case V22 | Unknown =>
false
case V23 | V24 => true
}
@ -634,9 +613,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
val rpc = version match {
case BitcoindVersion.Unknown =>
BitcoindRpcClient.withActorSystem(BitcoindRpcTestUtil.instance())
case BitcoindVersion.V21 =>
BitcoindV21RpcClient.withActorSystem(
BitcoindRpcTestUtil.v21Instance())
case BitcoindVersion.V22 =>
BitcoindV22RpcClient.withActorSystem(
BitcoindRpcTestUtil.v22Instance())
@ -727,16 +703,9 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
}
}
/** Returns a pair of [[org.bitcoins.rpc.client.v21.BitcoindV21RpcClient BitcoindV21RpcClient]]
* that are connected with some blocks in the chain
*/
def createNodePairV21(clientAccum: RpcClientAccum)(implicit
system: ActorSystem): Future[(BitcoindV21RpcClient, BitcoindV21RpcClient)] =
createNodePairInternal(BitcoindVersion.V21, clientAccum)
def createNodePairV22(clientAccum: RpcClientAccum)(implicit
system: ActorSystem): Future[
(BitcoindV21RpcClient, BitcoindV21RpcClient)
(BitcoindV22RpcClient, BitcoindV22RpcClient)
] = //shouldn't this be V22
createNodePairInternal(BitcoindVersion.V22, clientAccum)
@ -744,7 +713,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
* that are connected with some blocks in the chain
*/
def createNodePairV23(clientAccum: RpcClientAccum)(implicit
system: ActorSystem): Future[(BitcoindV21RpcClient, BitcoindV21RpcClient)] =
system: ActorSystem): Future[(BitcoindV23RpcClient, BitcoindV23RpcClient)] =
createNodePairInternal(BitcoindVersion.V23, clientAccum)
/** Returns a triple of [[org.bitcoins.rpc.client.common.BitcoindRpcClient BitcoindRpcClient]]
@ -845,8 +814,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
v23.signRawTransactionWithWallet(transaction, utxoDeps)
case v22: BitcoindV22RpcClient =>
v22.signRawTransactionWithWallet(transaction, utxoDeps)
case v21: BitcoindV21RpcClient =>
v21.signRawTransactionWithWallet(transaction, utxoDeps)
case unknown: BitcoindRpcClient =>
sys.error(
s"Cannot sign tx with unknown version of bitcoind, got=$unknown")

View File

@ -1,7 +1,6 @@
package org.bitcoins.testkit.rpc
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
@ -131,18 +130,6 @@ trait CachedBitcoindBlockFilterRpcNewest
}
}
trait CachedBitcoindV21 extends CachedBitcoindFunded[BitcoindV21RpcClient] {
_: BitcoinSPekkoAsyncTest =>
override protected lazy val cachedBitcoindWithFundsF: Future[
BitcoindV21RpcClient] = {
val _ = isBitcoindUsed.set(true)
BitcoinSFixture
.createBitcoindWithFunds(Some(BitcoindVersion.V21))
.map(_.asInstanceOf[BitcoindV21RpcClient])
}
}
trait CachedBitcoindV22 extends CachedBitcoindFunded[BitcoindV22RpcClient] {
_: BitcoinSPekkoAsyncTest =>
@ -237,25 +224,6 @@ trait CachedBitcoindPair[T <: BitcoindRpcClient]
}
}
trait CachedBitcoindPairV21
extends CachedBitcoindCollection[BitcoindV21RpcClient] {
_: BitcoinSPekkoAsyncTest =>
override val version: BitcoindVersion = BitcoindVersion.V21
lazy val clientsF: Future[NodePair[BitcoindV21RpcClient]] = {
BitcoindRpcTestUtil
.createNodePair[BitcoindV21RpcClient](version)
.map(NodePair.fromTuple)
.map { tuple =>
isClientsUsed.set(true)
val clients = cachedClients.get()
cachedClients.set(clients ++ tuple.toVector)
tuple
}
}
}
trait CachedBitcoindPairV22
extends CachedBitcoindCollection[BitcoindV22RpcClient] {
_: BitcoinSPekkoAsyncTest =>