mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 10:46:42 +01:00
2024 04 21 Remove BitcoindV22RpcClient
(#5537)
* WIP: Remove v22 * Remove TestMempoolAcceptRpc, move it into MempoolRpc * Remove downloading of bitcoind v22 from bitcoind-rpc.sbt * move test case above where other test cases create wallets * Remove duplicate test * Remove duplicate test
This commit is contained in:
parent
97fe795693
commit
7b3463229f
31 changed files with 305 additions and 814 deletions
|
@ -106,41 +106,6 @@ sealed trait GetBlockChainInfoResult extends BlockchainResult {
|
|||
def warnings: String
|
||||
}
|
||||
|
||||
case class GetBlockChainInfoResultPreV19(
|
||||
chain: NetworkParameters,
|
||||
blocks: Int,
|
||||
headers: Int,
|
||||
bestblockhash: DoubleSha256DigestBE,
|
||||
difficulty: BigDecimal,
|
||||
mediantime: Int,
|
||||
verificationprogress: BigDecimal,
|
||||
initialblockdownload: Boolean,
|
||||
chainwork: String, // How should this be handled?
|
||||
size_on_disk: Long,
|
||||
pruned: Boolean,
|
||||
pruneheight: Option[Int],
|
||||
softforks: Vector[SoftforkPreV19],
|
||||
bip9_softforks: Map[String, Bip9SoftforkPreV19],
|
||||
warnings: String
|
||||
) extends GetBlockChainInfoResult
|
||||
|
||||
case class GetBlockChainInfoResultPostV19(
|
||||
chain: NetworkParameters,
|
||||
blocks: Int,
|
||||
headers: Int,
|
||||
bestblockhash: DoubleSha256DigestBE,
|
||||
difficulty: BigDecimal,
|
||||
mediantime: Int,
|
||||
verificationprogress: BigDecimal,
|
||||
initialblockdownload: Boolean,
|
||||
chainwork: String, // How should this be handled?
|
||||
size_on_disk: Long,
|
||||
pruned: Boolean,
|
||||
pruneheight: Option[Int],
|
||||
softforks: Map[String, SoftforkPostV19],
|
||||
warnings: String
|
||||
) extends GetBlockChainInfoResult
|
||||
|
||||
// adds time field removes softforks field
|
||||
case class GetBlockChainInfoResultPostV23(
|
||||
chain: NetworkParameters,
|
||||
|
@ -289,25 +254,6 @@ case class GetMemPoolResultPreV19(
|
|||
depends: Vector[DoubleSha256DigestBE]
|
||||
) extends GetMemPoolResult
|
||||
|
||||
case class GetMemPoolResultPostV19(
|
||||
vsize: Int,
|
||||
fee: Option[Bitcoins],
|
||||
modifiedfee: Option[Bitcoins],
|
||||
time: UInt32,
|
||||
height: Int,
|
||||
descendantcount: Int,
|
||||
descendantsize: Int,
|
||||
descendantfees: Option[Bitcoins],
|
||||
ancestorcount: Int,
|
||||
ancestorsize: Int,
|
||||
ancestorfees: Option[Bitcoins],
|
||||
wtxid: DoubleSha256DigestBE,
|
||||
fees: FeeInfo,
|
||||
depends: Vector[DoubleSha256DigestBE]
|
||||
) extends GetMemPoolResult {
|
||||
override def size: Int = vsize
|
||||
}
|
||||
|
||||
// v23 removes 'fee', 'modifiedfee', 'descendantfees', 'ancestorfees'
|
||||
case class GetMemPoolResultPostV23(
|
||||
vsize: Int,
|
||||
|
@ -361,26 +307,6 @@ case class GetMemPoolEntryResultPreV19(
|
|||
depends: Option[Vector[DoubleSha256DigestBE]]
|
||||
) extends GetMemPoolEntryResult
|
||||
|
||||
case class GetMemPoolEntryResultPostV19(
|
||||
vsize: Int,
|
||||
fee: Bitcoins,
|
||||
weight: Int,
|
||||
modifiedfee: Bitcoins,
|
||||
time: UInt32,
|
||||
height: Int,
|
||||
descendantcount: Int,
|
||||
descendantsize: Int,
|
||||
descendantfees: BitcoinFeeUnit,
|
||||
ancestorcount: Int,
|
||||
ancestorsize: Int,
|
||||
ancestorfees: BitcoinFeeUnit,
|
||||
wtxid: DoubleSha256DigestBE,
|
||||
fees: FeeInfo,
|
||||
depends: Option[Vector[DoubleSha256DigestBE]]
|
||||
) extends GetMemPoolEntryResult {
|
||||
override def size: Int = vsize
|
||||
}
|
||||
|
||||
case class GetMemPoolEntryResultPostV23(
|
||||
vsize: Int,
|
||||
weight: Int,
|
||||
|
|
|
@ -272,10 +272,6 @@ object JsonSerializers {
|
|||
implicit val bip9SoftforkPreV19Reads: Reads[Bip9SoftforkPreV19] =
|
||||
Json.reads[Bip9SoftforkPreV19]
|
||||
|
||||
implicit val getBlockChainInfoResultPreV19Reads
|
||||
: Reads[GetBlockChainInfoResultPreV19] =
|
||||
Json.reads[GetBlockChainInfoResultPreV19]
|
||||
|
||||
implicit val bip9SoftforkDetailsReads: Reads[Bip9SoftforkDetails] =
|
||||
Json.reads[Bip9SoftforkDetails]
|
||||
|
||||
|
@ -287,10 +283,6 @@ object JsonSerializers {
|
|||
}
|
||||
}
|
||||
|
||||
implicit val getBlockChainInfoResultPostV19Reads
|
||||
: Reads[GetBlockChainInfoResultPostV19] =
|
||||
Json.reads[GetBlockChainInfoResultPostV19]
|
||||
|
||||
implicit val getBlockChainInfoResultPostV23Reads
|
||||
: Reads[GetBlockChainInfoResultPostV23] =
|
||||
Json.reads[GetBlockChainInfoResultPostV23]
|
||||
|
@ -308,9 +300,6 @@ object JsonSerializers {
|
|||
implicit val getMemPoolResultPreV19Reads: Reads[GetMemPoolResultPreV19] =
|
||||
Json.reads[GetMemPoolResultPreV19]
|
||||
|
||||
implicit val getMemPoolResultPostV19Reads: Reads[GetMemPoolResultPostV19] =
|
||||
Json.reads[GetMemPoolResultPostV19]
|
||||
|
||||
implicit val getMemPoolResultPostV23Reads: Reads[GetMemPoolResultPostV23] =
|
||||
Json.reads[GetMemPoolResultPostV23]
|
||||
|
||||
|
@ -318,10 +307,6 @@ object JsonSerializers {
|
|||
: Reads[GetMemPoolEntryResultPreV19] =
|
||||
Json.reads[GetMemPoolEntryResultPreV19]
|
||||
|
||||
implicit val getMemPoolEntryResultPostV19Reads
|
||||
: Reads[GetMemPoolEntryResultPostV19] =
|
||||
Json.reads[GetMemPoolEntryResultPostV19]
|
||||
|
||||
implicit val getMemPoolEntryResultPostV23Reads
|
||||
: Reads[GetMemPoolEntryResultPostV23] =
|
||||
Json.reads[GetMemPoolEntryResultPostV23]
|
||||
|
@ -838,11 +823,6 @@ object JsonSerializers {
|
|||
Reads.mapReads[DoubleSha256Digest, GetMemPoolResultPreV19](s =>
|
||||
JsSuccess(DoubleSha256Digest.fromHex(s)))
|
||||
|
||||
implicit def mapDoubleSha256DigestReadsPostV19
|
||||
: Reads[Map[DoubleSha256Digest, GetMemPoolResultPostV19]] =
|
||||
Reads.mapReads[DoubleSha256Digest, GetMemPoolResultPostV19](s =>
|
||||
JsSuccess(DoubleSha256Digest.fromHex(s)))
|
||||
|
||||
implicit def mapDoubleSha256DigestReadsPostV23
|
||||
: Reads[Map[DoubleSha256Digest, GetMemPoolResultPostV23]] =
|
||||
Reads.mapReads[DoubleSha256Digest, GetMemPoolResultPostV23](s =>
|
||||
|
@ -853,11 +833,6 @@ object JsonSerializers {
|
|||
Reads.mapReads[DoubleSha256DigestBE, GetMemPoolResultPreV19](s =>
|
||||
JsSuccess(DoubleSha256DigestBE.fromHex(s)))
|
||||
|
||||
implicit def mapDoubleSha256DigestBEReadsPostV19
|
||||
: Reads[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]] =
|
||||
Reads.mapReads[DoubleSha256DigestBE, GetMemPoolResultPostV19](s =>
|
||||
JsSuccess(DoubleSha256DigestBE.fromHex(s)))
|
||||
|
||||
implicit def mapDoubleSha256DigestBEReadsPostV23
|
||||
: Reads[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]] =
|
||||
Reads.mapReads[DoubleSha256DigestBE, GetMemPoolResultPostV23](s =>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package org.bitcoins.rpc.common
|
||||
|
||||
import java.net.URI
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.GetNodeAddressesResultPostV22
|
||||
|
||||
import java.net.URI
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
|
||||
AddNodeArgument,
|
||||
SetBanCommand
|
||||
|
@ -197,4 +198,36 @@ class P2PRpcTest extends BitcoindRpcTest {
|
|||
assert(hash1 == hash2)
|
||||
}
|
||||
}
|
||||
|
||||
it should "take a network input and output addresses of same network" in {
|
||||
val networkOption = Vector("ipv4", "ipv6", "onion", "i2p")
|
||||
for {
|
||||
(client, _) <- clientPairF
|
||||
_ <- Future.traverse(networkOption) { networkType =>
|
||||
val resultVecF: Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
client.getNodeAddresses(networkType, 10)
|
||||
resultVecF.map { resultVec =>
|
||||
resultVec.map { result =>
|
||||
assert(result.network == networkType)
|
||||
}
|
||||
}
|
||||
}
|
||||
} yield {
|
||||
succeed
|
||||
}
|
||||
}
|
||||
|
||||
it should "return a network address" in {
|
||||
for {
|
||||
(client, _) <- clientPairF
|
||||
resultVec <- client.getNodeAddresses()
|
||||
} yield {
|
||||
resultVec.foreach { result =>
|
||||
assert(
|
||||
result.network == "ipv4" || result.network == "ipv6" || result.network == "onion" || result.network == "i2p"
|
||||
)
|
||||
}
|
||||
succeed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
package org.bitcoins.rpc.common
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.{DecodeScriptResultV22, RpcOpts}
|
||||
import org.bitcoins.core.currency.{Bitcoins, Satoshis}
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.P2PKHAddress
|
||||
import org.bitcoins.core.protocol.script.{
|
||||
EmptyScriptSignature,
|
||||
ScriptPubKey,
|
||||
ScriptSignature
|
||||
}
|
||||
import org.bitcoins.core.protocol.transaction._
|
||||
import org.bitcoins.core.script.ScriptType
|
||||
import org.bitcoins.crypto.ECPrivateKey
|
||||
import org.bitcoins.rpc.BitcoindException.InvalidAddressOrKey
|
||||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
|
||||
|
@ -209,4 +213,100 @@ class RawTransactionRpcTest extends BitcoindRpcTest {
|
|||
rawTx <- client.getRawTransactionRaw(sentTx.txid)
|
||||
} yield assert(rawTx.txIdBE == sentTx.txid)
|
||||
}
|
||||
|
||||
it should "be able to decode a reedem script" in {
|
||||
for {
|
||||
(client, _) <- clientsF
|
||||
ecPrivKey1 = ECPrivateKey.freshPrivateKey
|
||||
pubKey1 = ecPrivKey1.publicKey
|
||||
_ <- client.unloadWallet("")
|
||||
_ <- client.createWallet("decodeRWallet")
|
||||
address <- client.getNewAddress(addressType = AddressType.Legacy)
|
||||
multisig <- client.addMultiSigAddress(
|
||||
2,
|
||||
Vector(Left(pubKey1), Right(address.asInstanceOf[P2PKHAddress])))
|
||||
decoded <- client.decodeScript(multisig.redeemScript)
|
||||
_ <- client.loadWallet("")
|
||||
_ <- client.unloadWallet("decodeRWallet")
|
||||
} yield {
|
||||
decoded match {
|
||||
case decodedV22: DecodeScriptResultV22 =>
|
||||
assert(decodedV22.typeOfScript.contains(ScriptType.MULTISIG))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "output more than one txid" in {
|
||||
for {
|
||||
(client, otherClient) <- clientsF
|
||||
blocks <- client.generate(2)
|
||||
firstBlock <- client.getBlock(blocks(0))
|
||||
transaction0 <- client.getTransaction(firstBlock.tx(0))
|
||||
secondBlock <- client.getBlock(blocks(1))
|
||||
transaction1 <- client.getTransaction(secondBlock.tx(0))
|
||||
|
||||
address <- otherClient.getNewAddress
|
||||
|
||||
input0 = TransactionOutPoint(
|
||||
transaction0.txid.flip,
|
||||
UInt32(transaction0.blockindex.get)
|
||||
)
|
||||
input1 = TransactionOutPoint(
|
||||
transaction1.txid.flip,
|
||||
UInt32(transaction1.blockindex.get)
|
||||
)
|
||||
|
||||
transactionFirst <- {
|
||||
val sig: ScriptSignature = ScriptSignature.empty
|
||||
val inputs = Vector(
|
||||
TransactionInput(input0, sig, UInt32(1)),
|
||||
TransactionInput(input1, sig, UInt32(2))
|
||||
)
|
||||
val outputs = Map(address -> Bitcoins(1))
|
||||
client.createRawTransaction(inputs, outputs)
|
||||
}
|
||||
fundedTransactionOne <- client.fundRawTransaction(transactionFirst)
|
||||
signedTransactionOne <- BitcoindRpcTestUtil.signRawTransaction(
|
||||
client,
|
||||
fundedTransactionOne.hex
|
||||
)
|
||||
|
||||
blocksTwo <- client.generate(2)
|
||||
firstBlockTwo <- client.getBlock(blocksTwo(0))
|
||||
transaction2 <- client.getTransaction(firstBlockTwo.tx(0))
|
||||
secondBlockTwo <- client.getBlock(blocksTwo(1))
|
||||
transaction3 <- client.getTransaction(secondBlockTwo.tx(0))
|
||||
|
||||
input2 = TransactionOutPoint(
|
||||
transaction2.txid.flip,
|
||||
UInt32(transaction2.blockindex.get)
|
||||
)
|
||||
input3 = TransactionOutPoint(
|
||||
transaction3.txid.flip,
|
||||
UInt32(transaction3.blockindex.get)
|
||||
)
|
||||
|
||||
transactionSecond <- {
|
||||
val sig: ScriptSignature = ScriptSignature.empty
|
||||
val inputs = Vector(
|
||||
TransactionInput(input2, sig, UInt32(1)),
|
||||
TransactionInput(input3, sig, UInt32(2))
|
||||
)
|
||||
val outputs = Map(address -> Bitcoins(1))
|
||||
client.createRawTransaction(inputs, outputs)
|
||||
}
|
||||
fundedTransactionTwo <- client.fundRawTransaction(transactionSecond)
|
||||
signedTransactionTwo <- BitcoindRpcTestUtil.signRawTransaction(
|
||||
client,
|
||||
fundedTransactionTwo.hex
|
||||
)
|
||||
_ <- client.generate(100) // Can't spend until depth 100
|
||||
mempoolAccept <- client.testMempoolAccept(
|
||||
Vector(signedTransactionOne.hex, signedTransactionTwo.hex)
|
||||
)
|
||||
} yield {
|
||||
val mempooltxid: Int = mempoolAccept.length
|
||||
assert(mempooltxid > 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.bitcoins.rpc.common
|
||||
|
||||
import org.bitcoins.commons.file.FileUtil
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.GetWalletInfoResultPostV22
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.{
|
||||
AddressType,
|
||||
WalletFlag
|
||||
|
@ -625,6 +626,39 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
|
|||
}
|
||||
}
|
||||
|
||||
it should "create a descriptor wallet" in { nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet("")
|
||||
_ <- client.createWallet("descriptorWallet", descriptors = true)
|
||||
descript <- client.getWalletInfo("descriptorWallet")
|
||||
_ <- client.unloadWallet("descriptorWallet")
|
||||
_ <- client.loadWallet("")
|
||||
} yield {
|
||||
descript match {
|
||||
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
|
||||
assert(walletInfoPostV22.descriptors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "create a wallet with private keys disabled" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet("")
|
||||
_ <- client.createWallet("privKeyWallet", disablePrivateKeys = true)
|
||||
walletPriv <- client.getWalletInfo("privKeyWallet")
|
||||
_ <- client.unloadWallet("privKeyWallet")
|
||||
_ <- client.loadWallet("")
|
||||
} yield {
|
||||
walletPriv match {
|
||||
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
|
||||
assert(!walletInfoPostV22.private_keys_enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def startClient(client: BitcoindRpcClient): Future[Unit] = {
|
||||
BitcoindRpcTestUtil.startServers(Vector(client))
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import org.bitcoins.core.psbt.PSBT
|
|||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||
import org.bitcoins.testkit.rpc.BitcoindFixturesFundedCachedNewest
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
/** Tests for PSBT for RPC calls specific to V18 new PSBT calls
|
||||
* @see
|
||||
* https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#test-vectors
|
||||
|
@ -113,4 +115,20 @@ class PsbtRpcTest extends BitcoindFixturesFundedCachedNewest {
|
|||
}
|
||||
}
|
||||
|
||||
it should "decode all the BIP174 example PSBTs" in { client =>
|
||||
val psbts = Vector(
|
||||
"cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAAAA",
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA",
|
||||
"cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAQMEAQAAAAAAAA==",
|
||||
"cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEA3wIAAAABJoFxNx7f8oXpN63upLN7eAAMBWbLs61kZBcTykIXG/YAAAAAakcwRAIgcLIkUSPmv0dNYMW1DAQ9TGkaXSQ18Jo0p2YqncJReQoCIAEynKnazygL3zB0DsA5BCJCLIHLRYOUV663b8Eu3ZWzASECZX0RjTNXuOD0ws1G23s59tnDjZpwq8ubLeXcjb/kzjH+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIACICAurVlmh8qAYEPtw94RbN8p1eklfBls0FXPaYyNAr8k6ZELSmumcAAACAAAAAgAIAAIAAIgIDlPYr6d8ZlSxVh3aK63aYBhrSxKJciU9H2MFitNchPQUQtKa6ZwAAAIABAACAAgAAgAA=",
|
||||
"cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriIGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GELSmumcAAACAAAAAgAQAAIAiBgPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvRC0prpnAAAAgAAAAIAFAACAAAA=",
|
||||
"cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA=",
|
||||
"cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==" // this one is from Core
|
||||
).map(PSBT.fromBase64)
|
||||
|
||||
for {
|
||||
_ <- Future.traverse(psbts)(client.decodePsbt)
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,291 +0,0 @@
|
|||
package org.bitcoins.rpc.v22
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
import org.bitcoins.core.currency.Bitcoins
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.P2PKHAddress
|
||||
import org.bitcoins.core.protocol.script.ScriptSignature
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
TransactionInput,
|
||||
TransactionOutPoint
|
||||
}
|
||||
import org.bitcoins.core.psbt.PSBT
|
||||
import org.bitcoins.core.script.ScriptType
|
||||
import org.bitcoins.crypto.ECPrivateKey
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion
|
||||
import org.bitcoins.rpc.util.NodePair
|
||||
import org.bitcoins.testkit.rpc.{
|
||||
BitcoindFixturesCachedPairV22,
|
||||
BitcoindRpcTestUtil
|
||||
}
|
||||
import org.scalatest.Assertion
|
||||
import scala.concurrent.Future
|
||||
|
||||
class BitcoindV22RpcClientTest extends BitcoindFixturesCachedPairV22 {
|
||||
|
||||
behavior of "BitcoindV22RpcClient"
|
||||
|
||||
it should "be able to start a V22 bitcoind instance" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
v <- client.version
|
||||
} yield assert(v == BitcoindVersion.V22)
|
||||
}
|
||||
|
||||
it should "be able to get network info" in { nodePair: FixtureParam =>
|
||||
val freshClient = nodePair.node1
|
||||
for {
|
||||
info <- freshClient.getNetworkInfo
|
||||
} yield {
|
||||
assert(info.networkactive)
|
||||
assert(info.localrelay)
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to decode a raw transaction" in { nodePair: FixtureParam =>
|
||||
val client1 = nodePair.node1
|
||||
val client2 = nodePair.node2
|
||||
for {
|
||||
transaction <-
|
||||
BitcoindRpcTestUtil
|
||||
.createRawCoinbaseTransaction(client1, client2)
|
||||
rpcTransaction <- client1.decodeRawTransaction(transaction)
|
||||
} yield {
|
||||
assert(rpcTransaction.txid == transaction.txIdBE)
|
||||
assert(rpcTransaction.locktime == transaction.lockTime)
|
||||
assert(rpcTransaction.size == transaction.byteSize)
|
||||
assert(rpcTransaction.version == transaction.version.toInt)
|
||||
assert(rpcTransaction.vsize == transaction.vsize)
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to get a raw transaction using both rpcs available" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
|
||||
for {
|
||||
block <- BitcoindRpcTestUtil.getFirstBlock(client)
|
||||
txid = block.tx.head.txid
|
||||
transaction1 <- client.getRawTransaction(txid)
|
||||
transaction2 <- client.getTransaction(txid)
|
||||
} yield {
|
||||
assert(transaction1.txid == transaction2.txid)
|
||||
assert(transaction1.confirmations.contains(transaction2.confirmations))
|
||||
assert(transaction1.hex == transaction2.hex)
|
||||
|
||||
assert(transaction1.blockhash.isDefined)
|
||||
assert(transaction2.blockhash.isDefined)
|
||||
|
||||
assert(transaction1.blockhash == transaction2.blockhash)
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to get utxo info" in { nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
block <- BitcoindRpcTestUtil.getFirstBlock(client)
|
||||
info1 <- client.getTxOut(block.tx.head.txid, 0)
|
||||
} yield assert(info1.coinbase)
|
||||
}
|
||||
|
||||
it should "decode all the BIP174 example PSBTs" in { nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val psbts = Vector(
|
||||
"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",
|
||||
"cHNidP8BAFUCAAAAASeaIyOl37UfxF8iD6WLD8E+HjNCeSqF1+Ns1jM7XLw5AAAAAAD/////AaBa6gsAAAAAGXapFP/pwAYQl8w7Y28ssEYPpPxCfStFiKwAAAAAAAEBIJVe6gsAAAAAF6kUY0UgD2jRieGtwN8cTRbqjxTA2+uHIgIDsTQcy6doO2r08SOM1ul+cWfVafrEfx5I1HVBhENVvUZGMEMCIAQktY7/qqaU4VWepck7v9SokGQiQFXN8HC2dxRpRC0HAh9cjrD+plFtYLisszrWTt5g6Hhb+zqpS5m9+GFR25qaAQEEIgAgdx/RitRZZm3Unz1WTj28QvTIR3TjYK2haBao7UiNVoEBBUdSIQOxNBzLp2g7avTxI4zW6X5xZ9Vp+sR/HkjUdUGEQ1W9RiED3lXR4drIBeP4pYwfv5uUwC89uq/hJ/78pJlfJvggg71SriIGA7E0HMunaDtq9PEjjNbpfnFn1Wn6xH8eSNR1QYRDVb1GELSmumcAAACAAAAAgAQAAIAiBgPeVdHh2sgF4/iljB+/m5TALz26r+En/vykmV8m+CCDvRC0prpnAAAAgAAAAIAFAACAAAA=",
|
||||
"cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA=",
|
||||
"cHNidP8BACoCAAAAAAFAQg8AAAAAABepFG6Rty1Vk+fUOR4v9E6R6YXDFkHwhwAAAAAAAA==" // this one is from Core
|
||||
).map(PSBT.fromBase64)
|
||||
|
||||
for {
|
||||
_ <- Future.sequence(psbts.map(client.decodePsbt))
|
||||
} yield succeed
|
||||
}
|
||||
|
||||
it should "be able to get a block with verbose transactions" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
blocks <- client.generate(2)
|
||||
block <- client.getBlockWithTransactions(blocks(1))
|
||||
} yield {
|
||||
assert(block.hash == blocks(1))
|
||||
assert(block.tx.length == 1)
|
||||
val tx = block.tx.head
|
||||
assert(tx.vout.head.n == 0)
|
||||
}
|
||||
}
|
||||
|
||||
it should "take a network input and output addresses of same network" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val networkOption = Vector("ipv4", "ipv6", "onion", "i2p")
|
||||
val resultNested: Vector[Future[Unit]] = networkOption.map {
|
||||
networkType =>
|
||||
val resultVecF: Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
client.getNodeAddresses(networkType, 10)
|
||||
resultVecF.map { resultVec =>
|
||||
resultVec.foreach { result =>
|
||||
assert(result.network == networkType)
|
||||
}
|
||||
}
|
||||
}
|
||||
val result: Future[Assertion] = Future
|
||||
.sequence(resultNested)
|
||||
.map(_ => succeed)
|
||||
result
|
||||
}
|
||||
|
||||
it should "return a network address" in { nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val resultVecF: Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
client.getNodeAddresses()
|
||||
resultVecF.map { resultVec =>
|
||||
resultVec.foreach { result =>
|
||||
assert(
|
||||
result.network == "ipv4" || result.network == "ipv6" || result.network == "onion" || result.network == "i2p"
|
||||
)
|
||||
}
|
||||
succeed
|
||||
}
|
||||
}
|
||||
it should "create a descriptor wallet" in { nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet("")
|
||||
_ <- client.createWallet("descriptorWallet", descriptors = true)
|
||||
descript <- client.getWalletInfo("descriptorWallet")
|
||||
_ <- client.unloadWallet("descriptorWallet")
|
||||
_ <- client.loadWallet("")
|
||||
} yield {
|
||||
descript match {
|
||||
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
|
||||
assert(walletInfoPostV22.descriptors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "create a wallet with private keys disabled" in {
|
||||
nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
for {
|
||||
_ <- client.unloadWallet("")
|
||||
_ <- client.createWallet("privKeyWallet", disablePrivateKeys = true)
|
||||
walletPriv <- client.getWalletInfo("privKeyWallet")
|
||||
_ <- client.unloadWallet("privKeyWallet")
|
||||
_ <- client.loadWallet("")
|
||||
} yield {
|
||||
walletPriv match {
|
||||
case walletInfoPostV22: GetWalletInfoResultPostV22 =>
|
||||
assert(!walletInfoPostV22.private_keys_enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to decode a reedem script" in { nodePair: FixtureParam =>
|
||||
val client = nodePair.node1
|
||||
val ecPrivKey1 = ECPrivateKey.freshPrivateKey
|
||||
val pubKey1 = ecPrivKey1.publicKey
|
||||
for {
|
||||
_ <- client.unloadWallet("")
|
||||
_ <- client.createWallet("decodeRWallet")
|
||||
address <- client.getNewAddress(addressType = AddressType.Legacy)
|
||||
multisig <-
|
||||
client
|
||||
.addMultiSigAddress(
|
||||
2,
|
||||
Vector(Left(pubKey1), Right(address.asInstanceOf[P2PKHAddress]))
|
||||
)
|
||||
decoded <- client.decodeScript(multisig.redeemScript)
|
||||
_ <- client.loadWallet("")
|
||||
_ <- client.unloadWallet("decodeRWallet")
|
||||
} yield {
|
||||
decoded match {
|
||||
case decodedV22: DecodeScriptResultV22 =>
|
||||
assert(decodedV22.typeOfScript.contains(ScriptType.MULTISIG))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
it should "output more than one txid" in { nodePair: FixtureParam =>
|
||||
val NodePair(client, otherClient) = nodePair
|
||||
for {
|
||||
blocks <- client.generate(2)
|
||||
firstBlock <- client.getBlock(blocks(0))
|
||||
transaction0 <- client.getTransaction(firstBlock.tx(0))
|
||||
secondBlock <- client.getBlock(blocks(1))
|
||||
transaction1 <- client.getTransaction(secondBlock.tx(0))
|
||||
|
||||
address <- otherClient.getNewAddress
|
||||
|
||||
input0 = TransactionOutPoint(
|
||||
transaction0.txid.flip,
|
||||
UInt32(transaction0.blockindex.get)
|
||||
)
|
||||
input1 = TransactionOutPoint(
|
||||
transaction1.txid.flip,
|
||||
UInt32(transaction1.blockindex.get)
|
||||
)
|
||||
|
||||
transactionFirst <- {
|
||||
val sig: ScriptSignature = ScriptSignature.empty
|
||||
val inputs = Vector(
|
||||
TransactionInput(input0, sig, UInt32(1)),
|
||||
TransactionInput(input1, sig, UInt32(2))
|
||||
)
|
||||
val outputs = Map(address -> Bitcoins(1))
|
||||
client.createRawTransaction(inputs, outputs)
|
||||
}
|
||||
fundedTransactionOne <- client.fundRawTransaction(transactionFirst)
|
||||
signedTransactionOne <- BitcoindRpcTestUtil.signRawTransaction(
|
||||
client,
|
||||
fundedTransactionOne.hex
|
||||
)
|
||||
|
||||
blocksTwo <- client.generate(2)
|
||||
firstBlockTwo <- client.getBlock(blocksTwo(0))
|
||||
transaction2 <- client.getTransaction(firstBlockTwo.tx(0))
|
||||
secondBlockTwo <- client.getBlock(blocksTwo(1))
|
||||
transaction3 <- client.getTransaction(secondBlockTwo.tx(0))
|
||||
|
||||
input2 = TransactionOutPoint(
|
||||
transaction2.txid.flip,
|
||||
UInt32(transaction2.blockindex.get)
|
||||
)
|
||||
input3 = TransactionOutPoint(
|
||||
transaction3.txid.flip,
|
||||
UInt32(transaction3.blockindex.get)
|
||||
)
|
||||
|
||||
transactionSecond <- {
|
||||
val sig: ScriptSignature = ScriptSignature.empty
|
||||
val inputs = Vector(
|
||||
TransactionInput(input2, sig, UInt32(1)),
|
||||
TransactionInput(input3, sig, UInt32(2))
|
||||
)
|
||||
val outputs = Map(address -> Bitcoins(1))
|
||||
client.createRawTransaction(inputs, outputs)
|
||||
}
|
||||
fundedTransactionTwo <- client.fundRawTransaction(transactionSecond)
|
||||
signedTransactionTwo <- BitcoindRpcTestUtil.signRawTransaction(
|
||||
client,
|
||||
fundedTransactionTwo.hex
|
||||
)
|
||||
|
||||
_ <- client.generate(100) // Can't spend until depth 100
|
||||
|
||||
mempoolAccept <- client.testMempoolAccept(
|
||||
Vector(signedTransactionOne.hex, signedTransactionTwo.hex)
|
||||
)
|
||||
} yield {
|
||||
val mempooltxid: Int = mempoolAccept.length
|
||||
assert(mempooltxid > 1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,10 @@ 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 org.bitcoins.testkit.rpc.{
|
||||
BitcoindFixturesFundedCachedV24,
|
||||
BitcoindRpcTestUtil
|
||||
}
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
|
@ -291,6 +294,19 @@ class BitcoindV24RpcClientTest extends BitcoindFixturesFundedCachedV24 {
|
|||
}
|
||||
}
|
||||
|
||||
it should "be able to get a block with verbose transactions" in {
|
||||
client: BitcoindRpcClient =>
|
||||
for {
|
||||
blocks <- client.generate(2)
|
||||
block <- client.getBlockWithTransactions(blocks(1))
|
||||
} yield {
|
||||
assert(block.hash == blocks(1))
|
||||
assert(block.tx.length == 1)
|
||||
val tx = block.tx.head
|
||||
assert(tx.vout.head.n == 0)
|
||||
}
|
||||
}
|
||||
|
||||
it should "be able to set the wallet flag 'avoid_reuse'" in {
|
||||
client: BitcoindV24RpcClient =>
|
||||
for {
|
||||
|
@ -382,4 +398,11 @@ class BitcoindV24RpcClientTest extends BitcoindFixturesFundedCachedV24 {
|
|||
} yield assert(hashes.size == numBlocks)
|
||||
}
|
||||
|
||||
it should "be able to get utxo info" in { client: BitcoindRpcClient =>
|
||||
for {
|
||||
block <- BitcoindRpcTestUtil.getFirstBlock(client)
|
||||
info1 <- client.getTxOut(block.tx.head.txid, 0)
|
||||
} yield assert(info1.coinbase)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ TaskKeys.downloadBitcoind := {
|
|||
}
|
||||
|
||||
val versions =
|
||||
List("24.2", "23.2", "22.0", "0.21.1")
|
||||
List("24.2", "23.2")
|
||||
|
||||
logger.debug(
|
||||
s"(Maybe) downloading Bitcoin Core binaries for versions: ${versions.mkString(",")}")
|
||||
|
@ -96,9 +96,7 @@ TaskKeys.downloadBitcoind := {
|
|||
if (Properties.isLinux)
|
||||
Map(
|
||||
"24.2" -> "7540d6e34c311e355af2fd76e5eee853b76c291978d6b5ebb555c7877e9de38d",
|
||||
"23.2" -> "853b9b0a50800a5b355df7a39dbdd6d7a2339f765e2d31a36d14bd705e7dbce1",
|
||||
"22.0" -> "59ebd25dd82a51638b7a6bb914586201e67db67b919b2a1ff08925a7936d1b16",
|
||||
"0.21.1" -> "366eb44a7a0aa5bd342deea215ec19a184a11f2ca22220304ebb20b9c8917e2b",
|
||||
"23.2" -> "853b9b0a50800a5b355df7a39dbdd6d7a2339f765e2d31a36d14bd705e7dbce1"
|
||||
)
|
||||
else if (Properties.isMac)
|
||||
Map(
|
||||
|
@ -109,16 +107,12 @@ TaskKeys.downloadBitcoind := {
|
|||
"23.2" -> (if (System.getProperty("os.arch") == "aarch64")
|
||||
"33f8680f820327d5f9e64c02e476d03a5b2e5bd403e1b1cb0a82bd7ec2a8dc5e"
|
||||
else
|
||||
"f56f2e21718c3ef13b962775f1e9985eed962ae6237684deebf6b59f799a912f"),
|
||||
"22.0" -> "2744d199c3343b2d94faffdfb2c94d75a630ba27301a70e47b0ad30a7e0155e9",
|
||||
"0.21.1" -> "1ea5cedb64318e9868a66d3ab65de14516f9ada53143e460d50af428b5aec3c7"
|
||||
"f56f2e21718c3ef13b962775f1e9985eed962ae6237684deebf6b59f799a912f")
|
||||
)
|
||||
else if (Properties.isWin)
|
||||
Map(
|
||||
"24.2" -> "544436bc9d5ce017e679bbccfe8a4928fbc840b414ee0240db8c3523ba54340a",
|
||||
"23.2" -> "29dd4c94de8b292fd19fd9475f2f31f891d04f16238bd7defa48eef3f2f8546a",
|
||||
"22.0" -> "9485e4b52ed6cebfe474ab4d7d0c1be6d0bb879ba7246a8239326b2230a77eb1",
|
||||
"0.21.1" -> "94c80f90184cdc7e7e75988a55b38384de262336abd80b1b30121c6e965dc74e"
|
||||
"23.2" -> "29dd4c94de8b292fd19fd9475f2f31f891d04f16238bd7defa48eef3f2f8546a"
|
||||
)
|
||||
else sys.error(s"Unsupported OS: ${Properties.osName}")
|
||||
|
||||
|
|
|
@ -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.v22.BitcoindV22RpcClient
|
||||
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
|
||||
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
|
||||
import org.bitcoins.rpc.config._
|
||||
|
@ -343,7 +342,6 @@ object BitcoindRpcClient {
|
|||
system: ActorSystem
|
||||
): BitcoindRpcClient = {
|
||||
val bitcoind = version match {
|
||||
case BitcoindVersion.V22 => BitcoindV22RpcClient.withActorSystem(instance)
|
||||
case BitcoindVersion.V23 => BitcoindV23RpcClient.withActorSystem(instance)
|
||||
case BitcoindVersion.V24 => BitcoindV24RpcClient.withActorSystem(instance)
|
||||
case BitcoindVersion.Unknown =>
|
||||
|
@ -373,14 +371,10 @@ object BitcoindVersion
|
|||
val newest: BitcoindVersion = V24
|
||||
|
||||
val standard: Vector[BitcoindVersion] =
|
||||
Vector(V22, V23, V24)
|
||||
Vector(V23, V24)
|
||||
|
||||
val known: Vector[BitcoindVersion] = standard
|
||||
|
||||
case object V22 extends BitcoindVersion {
|
||||
override def toString: String = "v22"
|
||||
}
|
||||
|
||||
case object V23 extends BitcoindVersion {
|
||||
override def toString: String = "v23"
|
||||
}
|
||||
|
@ -407,7 +401,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 "22" => V22
|
||||
case "23" => V23
|
||||
case "24" => V24
|
||||
case _ =>
|
||||
|
|
|
@ -39,11 +39,8 @@ trait BlockchainRpc extends ChainApi { self: Client =>
|
|||
}
|
||||
|
||||
def getBlockChainInfo: Future[GetBlockChainInfoResult] = {
|
||||
self.version.flatMap {
|
||||
case V22 =>
|
||||
bitcoindCall[GetBlockChainInfoResultPostV19]("getblockchaininfo")
|
||||
case V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetBlockChainInfoResultPostV23]("getblockchaininfo")
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetBlockChainInfoResultPostV23]("getblockchaininfo")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +92,7 @@ trait BlockchainRpc extends ChainApi { self: Client =>
|
|||
headerHash: DoubleSha256DigestBE
|
||||
): Future[GetBlockWithTransactionsResultV22] = {
|
||||
val isVerboseJsonObject = JsNumber(2)
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetBlockWithTransactionsResultV22](
|
||||
"getblock",
|
||||
List(JsString(headerHash.hex), isVerboseJsonObject)
|
||||
|
|
|
@ -3,10 +3,11 @@ package org.bitcoins.rpc.client.common
|
|||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
import org.bitcoins.commons.serializers.JsonReaders._
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
|
||||
import org.bitcoins.rpc.BitcoindException
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion._
|
||||
import play.api.libs.json.{JsBoolean, JsString}
|
||||
import play.api.libs.json.{JsBoolean, JsString, Json}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
|
@ -34,17 +35,11 @@ trait MempoolRpc { self: Client =>
|
|||
txid: DoubleSha256DigestBE
|
||||
): Future[Map[DoubleSha256DigestBE, GetMemPoolResult]] = {
|
||||
|
||||
self.version.flatMap {
|
||||
case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
|
||||
"getmempoolancestors",
|
||||
List(JsString(txid.hex), JsBoolean(true))
|
||||
)
|
||||
case V22 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
|
||||
"getmempoolancestors",
|
||||
List(JsString(txid.hex), JsBoolean(true))
|
||||
)
|
||||
self.version.flatMap { case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
|
||||
"getmempoolancestors",
|
||||
List(JsString(txid.hex), JsBoolean(true))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,17 +67,11 @@ trait MempoolRpc { self: Client =>
|
|||
def getMemPoolDescendantsVerbose(
|
||||
txid: DoubleSha256DigestBE
|
||||
): Future[Map[DoubleSha256DigestBE, GetMemPoolResult]] = {
|
||||
self.version.flatMap {
|
||||
case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
|
||||
"getmempooldescendants",
|
||||
List(JsString(txid.hex), JsBoolean(true))
|
||||
)
|
||||
case V22 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
|
||||
"getmempooldescendants",
|
||||
List(JsString(txid.hex), JsBoolean(true))
|
||||
)
|
||||
self.version.flatMap { case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
|
||||
"getmempooldescendants",
|
||||
List(JsString(txid.hex), JsBoolean(true))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,17 +85,11 @@ trait MempoolRpc { self: Client =>
|
|||
txid: DoubleSha256DigestBE
|
||||
): Future[GetMemPoolEntryResult] = {
|
||||
|
||||
self.version.flatMap {
|
||||
case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetMemPoolEntryResultPostV23](
|
||||
"getmempoolentry",
|
||||
List(JsString(txid.hex))
|
||||
)
|
||||
case V22 | Unknown =>
|
||||
bitcoindCall[GetMemPoolEntryResultPostV19](
|
||||
"getmempoolentry",
|
||||
List(JsString(txid.hex))
|
||||
)
|
||||
self.version.flatMap { case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetMemPoolEntryResultPostV23](
|
||||
"getmempoolentry",
|
||||
List(JsString(txid.hex))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -147,17 +130,11 @@ trait MempoolRpc { self: Client =>
|
|||
def getRawMemPoolWithTransactions
|
||||
: Future[Map[DoubleSha256DigestBE, GetMemPoolResult]] = {
|
||||
|
||||
self.version.flatMap {
|
||||
case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
|
||||
"getrawmempool",
|
||||
List(JsBoolean(true))
|
||||
)
|
||||
case V22 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
|
||||
"getrawmempool",
|
||||
List(JsBoolean(true))
|
||||
)
|
||||
self.version.flatMap { case V24 | V23 | V24 | Unknown =>
|
||||
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV23]](
|
||||
"getrawmempool",
|
||||
List(JsBoolean(true))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -166,4 +143,13 @@ trait MempoolRpc { self: Client =>
|
|||
bitcoindCall[Unit]("savemempool")
|
||||
}
|
||||
|
||||
def testMempoolAccept(
|
||||
transaction: Vector[Transaction],
|
||||
maxFeeRate: Double = 0.10
|
||||
): Future[Vector[TestMempoolAcceptResultPostV22]] = {
|
||||
bitcoindCall[Vector[TestMempoolAcceptResultPostV22]](
|
||||
"testmempoolaccept",
|
||||
List(Json.toJson(transaction), Json.toJson(maxFeeRate))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ trait MultisigRpc { self: Client =>
|
|||
JsString(account)
|
||||
) ++ addressType.map(Json.toJson(_)).toList
|
||||
|
||||
self.version.flatMap { case V24 | V23 | V22 | Unknown =>
|
||||
self.version.flatMap { case V24 | V23 | Unknown =>
|
||||
bitcoindCall[MultiSigResultPostV20](
|
||||
"addmultisigaddress",
|
||||
params,
|
||||
|
@ -86,7 +86,7 @@ trait MultisigRpc { self: Client =>
|
|||
addressType: AddressType,
|
||||
walletNameOpt: Option[String] = None
|
||||
): Future[MultiSigResult] = {
|
||||
self.version.flatMap { case V24 | V23 | V22 | Unknown =>
|
||||
self.version.flatMap { case V24 | V23 | Unknown =>
|
||||
bitcoindCall[MultiSigResultPostV20](
|
||||
"createmultisig",
|
||||
List(
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package org.bitcoins.rpc.client.common
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.GetMemoryInfoResult
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
||||
GetMemoryInfoResult,
|
||||
GetNodeAddressesResultPostV22
|
||||
}
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.commons.serializers.JsonReaders
|
||||
import org.bitcoins.commons.serializers.JsonSerializers._
|
||||
|
@ -71,4 +74,31 @@ trait NodeRpc { self: Client =>
|
|||
def help(rpcName: String = ""): Future[String] = {
|
||||
bitcoindCall[String]("help", List(JsString(rpcName)))
|
||||
}
|
||||
|
||||
private def getNodeAddresses(
|
||||
count: Option[Int]
|
||||
): Future[Vector[GetNodeAddressesResultPostV22]] = {
|
||||
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
|
||||
"getnodeaddresses",
|
||||
List(Json.toJson(count))
|
||||
)
|
||||
}
|
||||
|
||||
def getNodeAddresses(
|
||||
network: String,
|
||||
count: Int
|
||||
): Future[Vector[GetNodeAddressesResultPostV22]] = {
|
||||
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
|
||||
"getnodeaddresses",
|
||||
List(Json.toJson(count), Json.toJson(network))
|
||||
)
|
||||
}
|
||||
|
||||
def getNodeAddresses(
|
||||
count: Int
|
||||
): Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
getNodeAddresses(Some(count))
|
||||
|
||||
def getNodeAddresses(): Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
getNodeAddresses(None)
|
||||
}
|
||||
|
|
|
@ -64,13 +64,13 @@ trait P2PRpc { self: Client =>
|
|||
}
|
||||
|
||||
def getPeerInfo: Future[Vector[Peer]] = {
|
||||
self.version.flatMap { case V24 | V23 | V22 | Unknown =>
|
||||
self.version.flatMap { case V24 | V23 | Unknown =>
|
||||
bitcoindCall[Vector[PeerPostV21]]("getpeerinfo")
|
||||
}
|
||||
}
|
||||
|
||||
def listBanned: Future[Vector[NodeBan]] = {
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[Vector[NodeBanPostV22]]("listbanned")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ trait PsbtRpc {
|
|||
}
|
||||
|
||||
def decodePsbt(psbt: PSBT): Future[DecodePsbtResult] = {
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[DecodePsbtResultV22]("decodepsbt", List(Json.toJson(psbt)))
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ trait RawTransactionRpc { self: Client =>
|
|||
|
||||
def decodeRawTransaction(transaction: Transaction): Future[RpcTransaction] = {
|
||||
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[RpcTransactionV22](
|
||||
"decoderawtransaction",
|
||||
List(JsString(transaction.hex))
|
||||
|
@ -102,7 +102,7 @@ trait RawTransactionRpc { self: Client =>
|
|||
case None => Nil
|
||||
}
|
||||
val params = List(JsString(txid.hex), JsBoolean(true)) ++ lastParam
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetRawTransactionResultV22]("getrawtransaction", params)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +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, V22, V23, V24}
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.{Unknown, V23, V24}
|
||||
import play.api.libs.json._
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -90,7 +90,7 @@ trait TransactionRpc { self: Client =>
|
|||
vout: Long,
|
||||
includeMemPool: Boolean = true
|
||||
): Future[GetTxOutResult] = {
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetTxOutResultV22](
|
||||
"gettxout",
|
||||
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool))
|
||||
|
@ -104,7 +104,7 @@ trait TransactionRpc { self: Client =>
|
|||
includeMemPool: Boolean = true
|
||||
): Future[Option[GetTxOutResult]] = {
|
||||
self.version
|
||||
.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[GetTxOutResultV22](
|
||||
"gettxout",
|
||||
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool))
|
||||
|
|
|
@ -24,7 +24,7 @@ trait UtilRpc { self: Client =>
|
|||
}
|
||||
|
||||
def decodeScript(script: ScriptPubKey): Future[DecodeScriptResult] = {
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[DecodeScriptResultV22](
|
||||
"decodescript",
|
||||
List(Json.toJson(script))
|
||||
|
@ -34,13 +34,13 @@ trait UtilRpc { self: Client =>
|
|||
}
|
||||
|
||||
def getIndexInfo: Future[Map[String, IndexInfoResult]] = {
|
||||
version.flatMap { case V24 | V23 | V22 | Unknown =>
|
||||
version.flatMap { case V24 | V23 | Unknown =>
|
||||
bitcoindCall[Map[String, IndexInfoResult]]("getindexinfo")
|
||||
}
|
||||
}
|
||||
|
||||
def getIndexInfo(indexName: String): Future[IndexInfoResult] = {
|
||||
version.flatMap { case V24 | V23 | V22 | Unknown =>
|
||||
version.flatMap { case V24 | V23 | Unknown =>
|
||||
bitcoindCall[Map[String, IndexInfoResult]](
|
||||
"getindexinfo",
|
||||
List(JsString(indexName))
|
||||
|
|
|
@ -150,7 +150,7 @@ trait WalletRpc { self: Client =>
|
|||
walletName: Option[String]
|
||||
): Future[GetWalletInfoResult] = {
|
||||
self.version.flatMap {
|
||||
case BitcoindVersion.V22 | BitcoindVersion.V23 | BitcoindVersion.V24 |
|
||||
case BitcoindVersion.V23 | BitcoindVersion.V24 |
|
||||
BitcoindVersion.Unknown =>
|
||||
bitcoindCall[GetWalletInfoResultPostV22](
|
||||
"getwalletinfo",
|
||||
|
@ -376,7 +376,7 @@ trait WalletRpc { self: Client =>
|
|||
descriptors: Boolean = false
|
||||
): Future[CreateWalletResult] =
|
||||
self.version.flatMap {
|
||||
case V24 | V23 | V22 =>
|
||||
case V24 | V23 =>
|
||||
bitcoindCall[CreateWalletResult](
|
||||
"createwallet",
|
||||
List(
|
||||
|
@ -412,7 +412,7 @@ trait WalletRpc { self: Client =>
|
|||
List(JsString(address.value)),
|
||||
uriExtensionOpt = walletNameOpt.map(walletExtension)
|
||||
)
|
||||
case V24 | V23 | V22 | Unknown =>
|
||||
case V24 | V23 | Unknown =>
|
||||
bitcoindCall[AddressInfoResultPostV21](
|
||||
"getaddressinfo",
|
||||
List(JsString(address.value)),
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package org.bitcoins.rpc.client.v18
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.{
|
||||
GetNodeAddressesResult,
|
||||
GetRpcInfoResult,
|
||||
ListWalletDirResult
|
||||
}
|
||||
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}
|
||||
import play.api.libs.json.{JsString, Json}
|
||||
import org.bitcoins.rpc.client.common.{Client}
|
||||
import play.api.libs.json.{JsString}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
|
@ -26,25 +24,6 @@ import scala.concurrent.Future
|
|||
trait V18AssortedRpc {
|
||||
self: Client =>
|
||||
|
||||
private def getNodeAddresses(
|
||||
count: Option[Int]
|
||||
): Future[Vector[GetNodeAddressesResult]] = {
|
||||
self.version.flatMap {
|
||||
case BitcoindVersion.V22 | BitcoindVersion.V23 | BitcoindVersion.V24 |
|
||||
BitcoindVersion.Unknown =>
|
||||
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
|
||||
"getnodeaddresses",
|
||||
List(Json.toJson(count))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def getNodeAddresses(count: Int): Future[Vector[GetNodeAddressesResult]] =
|
||||
getNodeAddresses(Some(count))
|
||||
|
||||
def getNodeAddresses(): Future[Vector[GetNodeAddressesResult]] =
|
||||
getNodeAddresses(None)
|
||||
|
||||
def listWalletDir(): Future[ListWalletDirResult] = {
|
||||
bitcoindCall[ListWalletDirResult]("listwalletdir")
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
|
|||
JsString(account)
|
||||
) ++ addressType.map(Json.toJson(_)).toList
|
||||
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[MultiSigResultPostV20]("addmultisigaddress", params)
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
|
|||
addressType: AddressType,
|
||||
walletNameOpt: Option[String] = None
|
||||
): Future[MultiSigResultPostV20] = {
|
||||
self.version.flatMap { case V22 | V23 | V24 | Unknown =>
|
||||
self.version.flatMap { case V23 | V24 | Unknown =>
|
||||
bitcoindCall[MultiSigResultPostV20](
|
||||
"createmultisig",
|
||||
List(
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package org.bitcoins.rpc.client.v22
|
||||
|
||||
import org.apache.pekko.actor.ActorSystem
|
||||
import org.bitcoins.rpc.client.common.{
|
||||
BitcoindRpcClient,
|
||||
BitcoindVersion,
|
||||
DescriptorRpc,
|
||||
PsbtRpc
|
||||
}
|
||||
import org.bitcoins.rpc.client.v20.V20MultisigRpc
|
||||
import org.bitcoins.rpc.config.BitcoindInstance
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.util.Try
|
||||
|
||||
/** Class for creating a BitcoindV22 instance that can access RPCs
|
||||
*/
|
||||
class BitcoindV22RpcClient(override val instance: BitcoindInstance)(implicit
|
||||
actorSystem: ActorSystem
|
||||
) extends BitcoindRpcClient(instance)
|
||||
with DescriptorRpc
|
||||
with PsbtRpc
|
||||
with V20MultisigRpc
|
||||
with TestMempoolAcceptRpc
|
||||
with V22AssortedRpc {
|
||||
|
||||
override lazy val version: Future[BitcoindVersion] = {
|
||||
Future.successful(BitcoindVersion.V22)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object BitcoindV22RpcClient {
|
||||
|
||||
/** 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): BitcoindV22RpcClient = {
|
||||
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
|
||||
): BitcoindV22RpcClient =
|
||||
new BitcoindV22RpcClient(instance)(system)
|
||||
|
||||
def fromUnknownVersion(
|
||||
rpcClient: BitcoindRpcClient
|
||||
): Try[BitcoindV22RpcClient] =
|
||||
Try {
|
||||
new BitcoindV22RpcClient(rpcClient.instance)(rpcClient.system)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package org.bitcoins.rpc.client.v22
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.TestMempoolAcceptResultPostV22
|
||||
import org.bitcoins.commons.serializers.JsonSerializers.{
|
||||
testMempoolAcceptResultReadsPostV22,
|
||||
transactionWrites
|
||||
}
|
||||
import org.bitcoins.core.protocol.transaction.Transaction
|
||||
import org.bitcoins.rpc.client.common.Client
|
||||
import play.api.libs.json.Json
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
trait TestMempoolAcceptRpc { self: Client =>
|
||||
|
||||
def testMempoolAccept(
|
||||
transaction: Vector[Transaction],
|
||||
maxFeeRate: Double = 0.10
|
||||
): Future[Vector[TestMempoolAcceptResultPostV22]] = {
|
||||
bitcoindCall[Vector[TestMempoolAcceptResultPostV22]](
|
||||
"testmempoolaccept",
|
||||
List(Json.toJson(transaction), Json.toJson(maxFeeRate))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package org.bitcoins.rpc.client.v22
|
||||
|
||||
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
|
||||
import org.bitcoins.rpc.client.v20.V20AssortedRpc
|
||||
import play.api.libs.json.Json
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
trait V22AssortedRpc extends V18AssortedRpc with V20AssortedRpc with WalletRpc {
|
||||
self: Client =>
|
||||
|
||||
private def getNodeAddresses(
|
||||
count: Option[Int]
|
||||
): Future[Vector[GetNodeAddressesResultPostV22]] = {
|
||||
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
|
||||
"getnodeaddresses",
|
||||
List(Json.toJson(count))
|
||||
)
|
||||
}
|
||||
|
||||
def getNodeAddresses(
|
||||
network: String,
|
||||
count: Int
|
||||
): Future[Vector[GetNodeAddressesResultPostV22]] = {
|
||||
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
|
||||
"getnodeaddresses",
|
||||
List(Json.toJson(count), Json.toJson(network))
|
||||
)
|
||||
}
|
||||
|
||||
override def getNodeAddresses(
|
||||
count: Int
|
||||
): Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
getNodeAddresses(Some(count))
|
||||
|
||||
override def getNodeAddresses()
|
||||
: Future[Vector[GetNodeAddressesResultPostV22]] =
|
||||
getNodeAddresses(None)
|
||||
|
||||
}
|
|
@ -59,9 +59,6 @@ sealed trait BitcoindInstanceLocal extends BitcoindInstance {
|
|||
.last
|
||||
|
||||
foundVersion match {
|
||||
case _: String
|
||||
if foundVersion.startsWith(BitcoindVersion.V22.toString) =>
|
||||
BitcoindVersion.V22
|
||||
case _: String
|
||||
if foundVersion.startsWith(BitcoindVersion.V23.toString) =>
|
||||
BitcoindVersion.V23
|
||||
|
|
|
@ -6,9 +6,7 @@ import org.bitcoins.chain.config.ChainAppConfig
|
|||
import org.bitcoins.core.api.node.{NodeType, Peer}
|
||||
import org.bitcoins.node._
|
||||
import org.bitcoins.node.config.NodeAppConfig
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion.V22
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
|
||||
import org.bitcoins.rpc.util.RpcUtil
|
||||
import org.bitcoins.server.BitcoinSAppConfig
|
||||
import org.bitcoins.testkit.chain.ChainUnitTest
|
||||
|
@ -56,37 +54,6 @@ trait NodeUnitTest extends BaseNodeTest {
|
|||
)(test)
|
||||
}
|
||||
|
||||
def withNeutrinoNodeConnectedToBitcoindV22(test: OneArgAsyncTest)(implicit
|
||||
system: ActorSystem,
|
||||
appConfig: BitcoinSAppConfig
|
||||
): FutureOutcome = {
|
||||
val nodeWithBitcoindBuilder
|
||||
: () => Future[NeutrinoNodeConnectedWithBitcoindV22] = { () =>
|
||||
require(appConfig.nodeConf.nodeType == NodeType.NeutrinoNode)
|
||||
for {
|
||||
bitcoind <-
|
||||
BitcoinSFixture
|
||||
.createBitcoindWithFunds(Some(V22))
|
||||
.map(_.asInstanceOf[BitcoindV22RpcClient])
|
||||
peer <- NodeUnitTest.createPeer(bitcoind)
|
||||
node <- NodeUnitTest.createNeutrinoNode(peer, None)(
|
||||
system,
|
||||
appConfig.chainConf,
|
||||
appConfig.nodeConf
|
||||
)
|
||||
started <- node.start()
|
||||
_ <- NodeUnitTest.syncNeutrinoNode(started, bitcoind)
|
||||
} yield NeutrinoNodeConnectedWithBitcoindV22(node, bitcoind)
|
||||
}
|
||||
|
||||
makeDependentFixture(
|
||||
build = nodeWithBitcoindBuilder,
|
||||
destroy = NodeUnitTest.destroyNodeConnectedWithBitcoind(
|
||||
_: NodeConnectedWithBitcoind
|
||||
)(system, appConfig)
|
||||
)(test)
|
||||
}
|
||||
|
||||
def withNeutrinoNodeConnectedToBitcoind(
|
||||
test: OneArgAsyncTest,
|
||||
versionOpt: Option[BitcoindVersion] = None
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.bitcoins.testkit.node.fixture
|
|||
|
||||
import org.bitcoins.node.{NeutrinoNode, Node}
|
||||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
|
||||
|
||||
/** Gives us a fixture that has a Neutrino node connected with the bitcoind
|
||||
* instance
|
||||
|
@ -27,11 +26,6 @@ case class NeutrinoNodeConnectedWithBitcoinds(
|
|||
bitcoinds: Vector[BitcoindRpcClient]
|
||||
) extends NodeConnectedWithBitcoinds
|
||||
|
||||
case class NeutrinoNodeConnectedWithBitcoindV22(
|
||||
node: NeutrinoNode,
|
||||
bitcoind: BitcoindV22RpcClient
|
||||
) extends NodeConnectedWithBitcoind
|
||||
|
||||
case class NeutrinoNodeNotConnectedWithBitcoinds(
|
||||
node: NeutrinoNode,
|
||||
bitcoinds: Vector[BitcoindRpcClient]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.bitcoins.testkit.rpc
|
||||
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
|
||||
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
|
||||
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
|
||||
import org.bitcoins.rpc.util.{NodePair, NodeTriple}
|
||||
|
@ -49,42 +48,6 @@ trait BitcoindFixturesFundedCached extends BitcoindFixtures {
|
|||
}
|
||||
}
|
||||
|
||||
/** Test trait that caches a [[BitcoindV22RpcClient]] that is funded and
|
||||
* available to use with fixtures
|
||||
*/
|
||||
trait BitcoindFixturesFundedCachedV22
|
||||
extends BitcoinSAsyncFixtureTest
|
||||
with BitcoindFixturesFundedCached
|
||||
with CachedBitcoindV22 {
|
||||
override type FixtureParam = BitcoindV22RpcClient
|
||||
|
||||
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
|
||||
val f: Future[Outcome] = for {
|
||||
bitcoind <- cachedBitcoindWithFundsF
|
||||
futOutcome = withV22FundedBitcoindCached(test, bitcoind)
|
||||
fut <- futOutcome.toFuture
|
||||
} yield fut
|
||||
new FutureOutcome(f)
|
||||
}
|
||||
|
||||
def withV22FundedBitcoindCached(
|
||||
test: OneArgAsyncTest,
|
||||
bitcoind: BitcoindV22RpcClient
|
||||
): FutureOutcome = {
|
||||
makeDependentFixture[BitcoindV22RpcClient](
|
||||
() => Future.successful(bitcoind),
|
||||
{ case _ =>
|
||||
Future.unit // don't want to destroy anything since it is cached
|
||||
}
|
||||
)(test)
|
||||
}
|
||||
|
||||
override def afterAll(): Unit = {
|
||||
super[CachedBitcoindV22].afterAll()
|
||||
super[BitcoinSAsyncFixtureTest].afterAll()
|
||||
}
|
||||
}
|
||||
|
||||
/** Test trait that caches a [[BitcoindV23RpcClient]] that is funded and
|
||||
* available to use with fixtures
|
||||
*/
|
||||
|
@ -196,31 +159,6 @@ trait BitcoindFixturesCachedPair[T <: BitcoindRpcClient]
|
|||
}
|
||||
}
|
||||
|
||||
/** Bitcoind fixtures with two cached bitcoind rpc clients that are
|
||||
* [[BitcoindVersion.newest]] that are connected via p2p
|
||||
*/
|
||||
trait BitcoindFixturesCachedPairV22
|
||||
extends BitcoinSAsyncFixtureTest
|
||||
with BitcoindFixturesCachedPair[BitcoindV22RpcClient] {
|
||||
override type FixtureParam = NodePair[BitcoindV22RpcClient]
|
||||
|
||||
override val version: BitcoindVersion = BitcoindVersion.V22
|
||||
|
||||
override def withFixture(test: OneArgAsyncTest): FutureOutcome = {
|
||||
val futOutcome = for {
|
||||
pair <- clientsF
|
||||
futOutcome = with2BitcoindsCached(test, pair)
|
||||
f <- futOutcome.toFuture
|
||||
} yield f
|
||||
new FutureOutcome(futOutcome)
|
||||
}
|
||||
|
||||
override def afterAll(): Unit = {
|
||||
super[BitcoindFixturesCachedPair].afterAll()
|
||||
super[BitcoinSAsyncFixtureTest].afterAll()
|
||||
}
|
||||
}
|
||||
|
||||
trait BitcoindFixturesCachedPairNewest
|
||||
extends BitcoinSAsyncFixtureTest
|
||||
with BitcoindFixturesCachedPair[BitcoindRpcClient] {
|
||||
|
|
|
@ -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.v22.BitcoindV22RpcClient
|
||||
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
|
||||
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
|
||||
import org.bitcoins.rpc.config._
|
||||
|
@ -178,7 +177,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
version match {
|
||||
// default to newest version
|
||||
case Unknown => getBinary(BitcoindVersion.newest, binaryDirectory)
|
||||
case known @ (V22 | V23 | V24) =>
|
||||
case known @ (V23 | V24) =>
|
||||
val fileList = Files
|
||||
.list(binaryDirectory)
|
||||
.iterator()
|
||||
|
@ -242,22 +241,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
BitcoindInstanceLocal.fromConfig(conf, binary)
|
||||
}
|
||||
|
||||
def v22Instance(
|
||||
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.V22),
|
||||
binaryDirectory = binaryDirectory
|
||||
)
|
||||
|
||||
def v23Instance(
|
||||
port: Int = RpcUtil.randomPort,
|
||||
rpcPort: Int = RpcUtil.randomPort,
|
||||
|
@ -300,14 +283,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory
|
||||
)(implicit system: ActorSystem): BitcoindInstanceLocal = {
|
||||
bitcoindVersion match {
|
||||
case BitcoindVersion.V22 =>
|
||||
BitcoindRpcTestUtil.v22Instance(
|
||||
port,
|
||||
rpcPort,
|
||||
zmqConfig,
|
||||
pruneMode,
|
||||
binaryDirectory = binaryDirectory
|
||||
)
|
||||
case BitcoindVersion.V23 =>
|
||||
BitcoindRpcTestUtil.v23Instance(
|
||||
port,
|
||||
|
@ -339,7 +314,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
val createWalletF = for {
|
||||
version <- server.version
|
||||
descriptors = version match {
|
||||
case V22 | Unknown =>
|
||||
case Unknown =>
|
||||
false
|
||||
case V23 | V24 => true
|
||||
}
|
||||
|
@ -666,10 +641,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
val rpc = version match {
|
||||
case BitcoindVersion.Unknown =>
|
||||
BitcoindRpcClient.withActorSystem(BitcoindRpcTestUtil.instance())
|
||||
case BitcoindVersion.V22 =>
|
||||
BitcoindV22RpcClient.withActorSystem(
|
||||
BitcoindRpcTestUtil.v22Instance()
|
||||
)
|
||||
case BitcoindVersion.V23 =>
|
||||
BitcoindV23RpcClient.withActorSystem(
|
||||
BitcoindRpcTestUtil.v23Instance()
|
||||
|
@ -766,13 +737,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
}
|
||||
}
|
||||
|
||||
def createNodePairV22(
|
||||
clientAccum: RpcClientAccum
|
||||
)(implicit system: ActorSystem): Future[
|
||||
(BitcoindV22RpcClient, BitcoindV22RpcClient)
|
||||
] = // shouldn't this be V22
|
||||
createNodePairInternal(BitcoindVersion.V22, clientAccum)
|
||||
|
||||
/** Returns a pair of
|
||||
* [[org.bitcoins.rpc.client.v23.BitcoindV23RpcClient BitcoindV23RpcClient]]
|
||||
* that are connected with some blocks in the chain
|
||||
|
@ -892,8 +856,6 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
v24.signRawTransactionWithWallet(transaction, utxoDeps)
|
||||
case v23: BitcoindV23RpcClient =>
|
||||
v23.signRawTransactionWithWallet(transaction, utxoDeps)
|
||||
case v22: BitcoindV22RpcClient =>
|
||||
v22.signRawTransactionWithWallet(transaction, utxoDeps)
|
||||
case unknown: BitcoindRpcClient =>
|
||||
sys.error(
|
||||
s"Cannot sign tx with unknown version of bitcoind, got=$unknown"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.bitcoins.testkit.rpc
|
||||
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
|
||||
import org.bitcoins.rpc.client.v23.BitcoindV23RpcClient
|
||||
import org.bitcoins.rpc.client.v24.BitcoindV24RpcClient
|
||||
import org.bitcoins.rpc.util.{NodePair, NodeTriple}
|
||||
|
@ -130,18 +129,6 @@ trait CachedBitcoindBlockFilterRpcNewest
|
|||
}
|
||||
}
|
||||
|
||||
trait CachedBitcoindV22 extends CachedBitcoindFunded[BitcoindV22RpcClient] {
|
||||
_: BitcoinSPekkoAsyncTest =>
|
||||
|
||||
override protected lazy val cachedBitcoindWithFundsF
|
||||
: Future[BitcoindV22RpcClient] = {
|
||||
val _ = isBitcoindUsed.set(true)
|
||||
BitcoinSFixture
|
||||
.createBitcoindWithFunds(Some(BitcoindVersion.V22))
|
||||
.map(_.asInstanceOf[BitcoindV22RpcClient])
|
||||
}
|
||||
}
|
||||
|
||||
trait CachedBitcoindV23 extends CachedBitcoindFunded[BitcoindV23RpcClient] {
|
||||
_: BitcoinSPekkoAsyncTest =>
|
||||
|
||||
|
@ -222,34 +209,15 @@ trait CachedBitcoindPair[T <: BitcoindRpcClient]
|
|||
}
|
||||
}
|
||||
|
||||
trait CachedBitcoindPairV22
|
||||
extends CachedBitcoindCollection[BitcoindV22RpcClient] {
|
||||
_: BitcoinSPekkoAsyncTest =>
|
||||
|
||||
override val version: BitcoindVersion = BitcoindVersion.V22
|
||||
|
||||
lazy val clientsF: Future[NodePair[BitcoindV22RpcClient]] = {
|
||||
BitcoindRpcTestUtil
|
||||
.createNodePair[BitcoindV22RpcClient](version)
|
||||
.map(NodePair.fromTuple)
|
||||
.map { tuple =>
|
||||
isClientsUsed.set(true)
|
||||
val clients = cachedClients.get()
|
||||
cachedClients.set(clients ++ tuple.toVector)
|
||||
tuple
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait CachedBitcoindPairNewest
|
||||
extends CachedBitcoindCollection[BitcoindRpcClient] {
|
||||
_: BitcoinSPekkoAsyncTest =>
|
||||
|
||||
override val version: BitcoindVersion = BitcoindVersion.newest
|
||||
|
||||
lazy val clientsF: Future[NodePair[BitcoindV22RpcClient]] = {
|
||||
lazy val clientsF: Future[NodePair[BitcoindRpcClient]] = {
|
||||
BitcoindRpcTestUtil
|
||||
.createNodePair[BitcoindV22RpcClient](version)
|
||||
.createNodePair[BitcoindRpcClient](version)
|
||||
.map(NodePair.fromTuple)
|
||||
.map { tuple =>
|
||||
isClientsUsed.set(true)
|
||||
|
|
Loading…
Add table
Reference in a new issue