Remove support for bitcoind v16 rpc client (#4634)

This commit is contained in:
Chris Stewart 2022-08-21 08:17:16 -05:00 committed by GitHub
parent 713ee75d4c
commit ea123139d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 45 additions and 566 deletions

View File

@ -66,7 +66,7 @@ class DLCWalletBitcoindBackendLoaderTest extends WalletLoaderFixtures {
{ () =>
loadWallet2.isRescanning().map(isRescanning => isRescanning == false)
},
250.millis)
500.millis)
} yield {
assert(loader.isRescanStateEmpty)
}

View File

@ -91,19 +91,11 @@ class WalletRpcTest extends BitcoindFixturesCachedPairV21 {
it should "be able to list wallets" 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 {
wallets <- client.listWallets
} yield {
val expectedFileName =
if (localInstance.getVersion == BitcoindVersion.V16) "wallet.dat"
else ""
val expectedFileName = ""
assert(wallets == Vector(expectedFileName))
}

View File

@ -1,196 +0,0 @@
package org.bitcoins.rpc.v16
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.SignRawTransactionOutputParameter
import org.bitcoins.core.crypto.ECPrivateKeyUtil
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script.{ScriptPubKey, ScriptSignature}
import org.bitcoins.core.protocol.transaction.{
TransactionConstants,
TransactionInput,
TransactionOutPoint
}
import org.bitcoins.crypto.{DoubleSha256DigestBE, ECPrivateKeyBytes}
import org.bitcoins.rpc.client.common.BitcoindVersion
import org.bitcoins.testkit.rpc.{
BitcoindFixturesCachedPairV16,
BitcoindRpcTestUtil
}
import scala.concurrent.duration.DurationInt
class BitcoindV16RpcClientTest extends BitcoindFixturesCachedPairV16 {
behavior of "BitcoindV16RpcClient"
it should "be able to get peer info" in { nodePair: FixtureParam =>
val freshClient = nodePair.node1
val otherFreshClient = nodePair.node2
for {
infoList <- freshClient.getPeerInfo
} yield {
assert(infoList.length >= 0)
val info = infoList.head
assert(info.addnode)
assert(info.networkInfo.addr == otherFreshClient.getDaemon.uri)
}
}
it should "be able to start a V16 bitcoind" in { nodePair: FixtureParam =>
val client = nodePair.node1
val otherClient = nodePair.node2
for {
v <- client.version
v1 <- otherClient.version
} yield {
assert(v == BitcoindVersion.V16)
assert(v1 == BitcoindVersion.V16)
}
}
it should "be able to sign a raw transaction" in { nodePair: FixtureParam =>
val client = nodePair.node1
val otherClient = nodePair.node2
for {
addr <- client.getNewAddress
_ <- otherClient.sendToAddress(addr, Bitcoins.one)
_ <-
otherClient.getNewAddress.flatMap(otherClient.generateToAddress(6, _))
peers <- client.getPeerInfo
_ = assert(peers.exists(_.networkInfo.addr == otherClient.getDaemon.uri))
recentBlock <- otherClient.getBestBlockHash
_ <- AsyncUtil.retryUntilSatisfiedF(
() => BitcoindRpcTestUtil.hasSeenBlock(client, recentBlock),
1.second)
(utxoTxid, utxoVout) <-
client.listUnspent
.map(_.filter(_.address.contains(addr)))
.map(_.head)
.map(utxo => (utxo.txid, utxo.vout))
newAddress <- client.getNewAddress
rawTx <- {
val outPoint = TransactionOutPoint(utxoTxid.flip, UInt32(utxoVout))
val input = TransactionInput(outPoint,
ScriptSignature.empty,
TransactionConstants.sequence)
val outputs = Map(newAddress -> Bitcoins(0.5))
client.createRawTransaction(Vector(input), outputs)
}
signedRawTx <- client.signRawTransaction(rawTx)
} yield {
assert(signedRawTx.complete)
}
}
// copied form the equivalent test in BitcoindV17RpcClientTest
it should "be able to sign a raw transaction with private keys" in {
nodePair: FixtureParam =>
val client = nodePair.node1
val privkeys: List[ECPrivateKeyBytes] =
List("cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N",
"cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA")
.map(ECPrivateKeyUtil.fromWIFToPrivateKey)
val txids =
List("9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71",
"83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02")
.map(DoubleSha256DigestBE.fromHex)
val vouts = List(0, 0)
val inputs: Vector[TransactionInput] = txids
.zip(vouts)
.map { case (txid, vout) =>
TransactionInput.fromTxidAndVout(txid, UInt32(vout))
}
.toVector
val address =
BitcoinAddress.fromString("mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB")
val outputs: Map[BitcoinAddress, Bitcoins] =
Map(address -> Bitcoins(0.1))
val scriptPubKeys =
List("76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac",
"76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac")
.map(ScriptPubKey.fromAsmHex)
val utxoDeps = inputs.zip(scriptPubKeys).map { case (input, pubKey) =>
SignRawTransactionOutputParameter.fromTransactionInput(input, pubKey)
}
for {
rawTx <- client.createRawTransaction(inputs, outputs)
signed <- client.signRawTransaction(
rawTx,
utxoDeps,
privkeys.toVector.map(_.toPrivateKey))
} yield assert(signed.complete)
}
it should "be able to send from an account to an addresss" in {
nodePair: FixtureParam =>
val client = nodePair.node1
val otherClient = nodePair.node2
for {
address <- otherClient.getNewAddress
txid <- client.sendFrom("", address, Bitcoins(1))
transaction <- client.getTransaction(txid)
} yield {
assert(transaction.amount == Bitcoins(-1))
assert(transaction.details.head.address.contains(address))
}
}
it should "be able to get and set the account for a given address" in {
nodePair: FixtureParam =>
val client = nodePair.node1
val account1 = "account_1"
val account2 = "account_2"
for {
address <- client.getNewAddress(account1)
acc1 <- client.getAccount(address)
_ <- client.setAccount(address, account2)
acc2 <- client.getAccount(address)
} yield {
assert(acc1 == account1)
assert(acc2 == account2)
}
}
it should "be able to get all addresses belonging to an account" in {
nodePair: FixtureParam =>
val client = nodePair.node1
for {
address <- client.getNewAddress
addresses <- client.getAddressesByAccount("")
} yield assert(addresses.contains(address))
}
it should "be able to get an account's address" in { nodePair: FixtureParam =>
val client = nodePair.node1
val account = "a_new_account"
for {
address <- client.getAccountAddress(account)
result <- client.getAccount(address)
} yield assert(result == account)
}
it should "be able to move funds from one account to another" in {
nodePair: FixtureParam =>
val client = nodePair.node1
val account = "move_account"
for {
success <- client.move("", account, Bitcoins(1))
map <- client.listAccounts()
} yield {
assert(success)
assert(map(account) == Bitcoins(1))
}
}
}

View File

@ -13,6 +13,7 @@ import org.bitcoins.core.number.UInt32
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.core.protocol.transaction.TransactionInput
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.rpc.util.NodePair
import org.bitcoins.testkit.rpc.{
@ -266,6 +267,5 @@ class BitcoindV17RpcClientTest extends BitcoindFixturesCachedPairV17 {
} yield {
assert(wallets.contains("suredbits"))
}
}
}

View File

@ -29,8 +29,7 @@ TaskKeys.downloadBitcoind := {
"0.20.1",
"0.19.0.1",
"0.18.1",
"0.17.0.1",
"0.16.3")
"0.17.0.1")
logger.debug(
s"(Maybe) downloading Bitcoin Core binaries for versions: ${versions.mkString(",")}")
@ -107,8 +106,7 @@ TaskKeys.downloadBitcoind := {
"0.20.1" -> "376194f06596ecfa40331167c39bc70c355f960280bd2a645fdbf18f66527397",
"0.19.0.1" -> "732cc96ae2e5e25603edf76b8c8af976fe518dd925f7e674710c6c8ee5189204",
"0.18.1" -> "600d1db5e751fa85903e935a01a74f5cc57e1e7473c15fd3e17ed21e202cfe5a",
"0.17.0.1" -> "6ccc675ee91522eee5785457e922d8a155e4eb7d5524bd130eb0ef0f0c4a6008",
"0.16.3" -> "5d422a9d544742bc0df12427383f9c2517433ce7b58cf672b9a9b17c2ef51e4f"
"0.17.0.1" -> "6ccc675ee91522eee5785457e922d8a155e4eb7d5524bd130eb0ef0f0c4a6008"
)
else if (Properties.isMac)
Map(
@ -122,8 +120,7 @@ TaskKeys.downloadBitcoind := {
"0.20.1" -> "b9024dde373ea7dad707363e07ec7e265383204127539ae0c234bff3a61da0d1",
"0.19.0.1" -> "a64e4174e400f3a389abd76f4d6b1853788730013ab1dedc0e64b0a0025a0923",
"0.18.1" -> "b7bbcee7a7540f711b171d6981f939ca8482005fde22689bc016596d80548bb1",
"0.17.0.1" -> "3b1fb3dd596edb656bbc0c11630392e201c1a4483a0e1a9f5dd22b6556cbae12",
"0.16.3" -> "78c3bff3b619a19aed575961ea43cc9e142959218835cf51aede7f0b764fc25d"
"0.17.0.1" -> "3b1fb3dd596edb656bbc0c11630392e201c1a4483a0e1a9f5dd22b6556cbae12"
)
else if (Properties.isWin)
Map(
@ -133,8 +130,7 @@ TaskKeys.downloadBitcoind := {
"0.20.1" -> "e59fba67afce011d32b5d723a3a0be12da1b8a34f5d7966e504520c48d64716d",
"0.19.0.1" -> "7706593de727d893e4b1e750dc296ea682ccee79acdd08bbc81eaacf3b3173cf",
"0.18.1" -> "b0f94ab43c068bac9c10a59cb3f1b595817256a00b84f0b724f8504b44e1314f",
"0.17.0.1" -> "2d0a0aafe5a963beb965b7645f70f973a17f4fa4ddf245b61d532f2a58449f3e",
"0.16.3" -> "52469c56222c1b5344065ef2d3ce6fc58ae42939a7b80643a7e3ee75ec237da9"
"0.17.0.1" -> "2d0a0aafe5a963beb965b7645f70f973a17f4fa4ddf245b61d532f2a58449f3e"
)
else sys.error(s"Unsupported OS: ${Properties.osName}")

View File

@ -22,7 +22,6 @@ import org.bitcoins.crypto.{
DoubleSha256DigestBE,
StringFactory
}
import org.bitcoins.rpc.client.v16.BitcoindV16RpcClient
import org.bitcoins.rpc.client.v17.BitcoindV17RpcClient
import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
@ -333,7 +332,6 @@ object BitcoindRpcClient {
def fromVersion(version: BitcoindVersion, instance: BitcoindInstance)(implicit
system: ActorSystem): BitcoindRpcClient = {
val bitcoind = version match {
case BitcoindVersion.V16 => BitcoindV16RpcClient.withActorSystem(instance)
case BitcoindVersion.V17 => BitcoindV17RpcClient.withActorSystem(instance)
case BitcoindVersion.V18 => BitcoindV18RpcClient.withActorSystem(instance)
case BitcoindVersion.V19 => BitcoindV19RpcClient.withActorSystem(instance)
@ -364,14 +362,10 @@ object BitcoindVersion extends StringFactory[BitcoindVersion] with Logging {
val newest: BitcoindVersion = V23
val standard: Vector[BitcoindVersion] =
Vector(V16, V17, V18, V19, V20, V21, V22, V23)
Vector(V17, V18, V19, V20, V21, V22, V23)
val known: Vector[BitcoindVersion] = standard
case object V16 extends BitcoindVersion {
override def toString: String = "v0.16"
}
case object V17 extends BitcoindVersion {
override def toString: String = "v0.17"
}
@ -418,7 +412,6 @@ object BitcoindVersion extends StringFactory[BitcoindVersion] with Logging {
def fromNetworkVersion(int: Int): BitcoindVersion = {
//need to translate the int 210100 (as an example) to a BitcoindVersion
int.toString.substring(0, 2) match {
case "16" => V16
case "17" => V17
case "18" => V18
case "19" => V19

View File

@ -29,7 +29,7 @@ trait BlockchainRpc { self: Client =>
def getBlockChainInfo: Future[GetBlockChainInfoResult] = {
self.version.flatMap {
case V16 | V17 | V18 =>
case V17 | V18 =>
bitcoindCall[GetBlockChainInfoResultPreV19]("getblockchaininfo")
case V22 | V21 | V20 | V19 =>
bitcoindCall[GetBlockChainInfoResultPostV19]("getblockchaininfo")
@ -85,7 +85,7 @@ trait BlockchainRpc { self: Client =>
"getblock",
List(JsString(headerHash.hex), isVerboseJsonObject))
case V16 | V17 | V18 | V19 | V20 | V21 =>
case V17 | V18 | V19 | V20 | V21 =>
bitcoindCall[GetBlockWithTransactionsResultPreV22](
"getblock",
List(JsString(headerHash.hex), isVerboseJsonObject))

View File

@ -40,7 +40,7 @@ trait MempoolRpc { self: Client =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getmempoolancestors",
List(JsString(txid.hex), JsBoolean(true)))
case V16 | V17 | V18 =>
case V17 | V18 =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPreV19]](
"getmempoolancestors",
List(JsString(txid.hex), JsBoolean(true)))
@ -75,7 +75,7 @@ trait MempoolRpc { self: Client =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getmempooldescendants",
List(JsString(txid.hex), JsBoolean(true)))
case V16 | V17 | V18 =>
case V17 | V18 =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPreV19]](
"getmempooldescendants",
List(JsString(txid.hex), JsBoolean(true)))
@ -97,7 +97,7 @@ trait MempoolRpc { self: Client =>
case V22 | V21 | V20 | V19 | Unknown =>
bitcoindCall[GetMemPoolEntryResultPostV19]("getmempoolentry",
List(JsString(txid.hex)))
case V16 | V17 | V18 =>
case V17 | V18 =>
bitcoindCall[GetMemPoolEntryResultPreV19]("getmempoolentry",
List(JsString(txid.hex)))
}
@ -144,7 +144,7 @@ trait MempoolRpc { self: Client =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getrawmempool",
List(JsBoolean(true)))
case V16 | V17 | V18 =>
case V17 | V18 =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPreV19]](
"getrawmempool",
List(JsBoolean(true)))

View File

@ -46,7 +46,7 @@ trait MultisigRpc { self: Client =>
"addmultisigaddress",
params,
uriExtensionOpt = walletNameOpt.map(walletExtension))
case V16 | V17 | V18 | V19 =>
case V17 | V18 | V19 =>
bitcoindCall[MultiSigResultPreV20]("addmultisigaddress",
params,
uriExtensionOpt =
@ -88,7 +88,7 @@ trait MultisigRpc { self: Client =>
"createmultisig",
List(JsNumber(minSignatures), Json.toJson(keys.map(_.hex))),
uriExtensionOpt = walletNameOpt.map(walletExtension))
case V16 | V17 | V18 | V19 =>
case V17 | V18 | V19 =>
bitcoindCall[MultiSigResultPreV20](
"createmultisig",
List(JsNumber(minSignatures), Json.toJson(keys.map(_.hex))),

View File

@ -68,7 +68,7 @@ trait P2PRpc { self: Client =>
bitcoindCall[Vector[PeerPostV21]]("getpeerinfo")
case V20 =>
bitcoindCall[Vector[PeerV20]]("getpeerinfo")
case V16 | V17 | V18 | V19 =>
case V17 | V18 | V19 =>
bitcoindCall[Vector[PeerPreV20]]("getpeerinfo")
}
}
@ -79,7 +79,7 @@ trait P2PRpc { self: Client =>
bitcoindCall[Vector[NodeBanPostV22]]("listbanned")
case V21 | V20 =>
bitcoindCall[Vector[NodeBanPostV20]]("listbanned")
case V16 | V17 | V18 | V19 =>
case V17 | V18 | V19 =>
bitcoindCall[Vector[NodeBanPreV20]]("listbanned")
}
}

View File

@ -15,7 +15,6 @@ import org.bitcoins.core.protocol.transaction.{Transaction, TransactionInput}
import org.bitcoins.core.psbt.PSBT
import org.bitcoins.rpc.client.common.BitcoindVersion.{
Unknown,
V16,
V17,
V18,
V19,
@ -98,7 +97,7 @@ trait PsbtRpc {
self.version.flatMap {
case V22 | V23 | Unknown =>
bitcoindCall[DecodePsbtResultV22]("decodepsbt", List(Json.toJson(psbt)))
case V16 | V17 | V18 | V19 | V20 | V21 =>
case V17 | V18 | V19 | V20 | V21 =>
bitcoindCall[DecodePsbtResultPreV22]("decodepsbt",
List(Json.toJson(psbt)))
}

View File

@ -47,7 +47,7 @@ trait RawTransactionRpc { self: Client =>
bitcoindCall[RpcTransactionV22]("decoderawtransaction",
List(JsString(transaction.hex)))
case V16 | V17 | V18 | V19 | V20 | V21 =>
case V17 | V18 | V19 | V20 | V21 =>
bitcoindCall[RpcTransactionPreV22]("decoderawtransaction",
List(JsString(transaction.hex)))
}
@ -104,7 +104,7 @@ trait RawTransactionRpc { self: Client =>
self.version.flatMap {
case V22 | V23 | Unknown =>
bitcoindCall[GetRawTransactionResultV22]("getrawtransaction", params)
case V16 | V17 | V18 | V19 | V20 | V21 =>
case V17 | V18 | V19 | V20 | V21 =>
bitcoindCall[GetRawTransactionResultPreV22]("getrawtransaction", params)
}
@ -131,7 +131,7 @@ trait RawTransactionRpc { self: Client =>
val feeParameterF = self.version.map {
case V23 | V22 | V21 | V20 | V19 | Unknown =>
JsNumber(maxfeerate)
case V16 | V17 | V18 =>
case V17 | V18 =>
JsBoolean(maxfeerate == 0)
}

View File

@ -8,7 +8,6 @@ import org.bitcoins.core.protocol.blockchain.MerkleBlock
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
import org.bitcoins.rpc.client.common.BitcoindVersion.{
Unknown,
V16,
V17,
V18,
V19,
@ -96,7 +95,7 @@ trait TransactionRpc { self: Client =>
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))
case V16 | V17 | V18 | V19 | V20 | V21 =>
case V17 | V18 | V19 | V20 | V21 =>
bitcoindCall[GetTxOutResultPreV22](
"gettxout",
List(JsString(txid.hex), JsNumber(vout), JsBoolean(includeMemPool)))

View File

@ -25,7 +25,7 @@ trait UtilRpc { self: Client =>
case V22 | V23 | Unknown =>
bitcoindCall[DecodeScriptResultV22]("decodescript",
List(Json.toJson(script)))
case V16 | V17 | V18 | V19 | V20 | V21 =>
case V17 | V18 | V19 | V20 | V21 =>
bitcoindCall[DecodeScriptResultPreV22]("decodescript",
List(Json.toJson(script)))
}
@ -36,7 +36,7 @@ trait UtilRpc { self: Client =>
version.flatMap {
case V23 | V22 | V21 | Unknown =>
bitcoindCall[Map[String, IndexInfoResult]]("getindexinfo")
case V16 | V17 | V18 | V19 | V20 =>
case V17 | V18 | V19 | V20 =>
Future.failed(
new RuntimeException(
s"getIndexInfo is only for version V21+, got $version"))
@ -49,7 +49,7 @@ trait UtilRpc { self: Client =>
bitcoindCall[Map[String, IndexInfoResult]](
"getindexinfo",
List(JsString(indexName))).map(_.head._2)
case V16 | V17 | V18 | V19 | V20 =>
case V17 | V18 | V19 | V20 =>
Future.failed(
new RuntimeException(
s"getIndexInfo is only for version V21+, got $version"))

View File

@ -169,8 +169,8 @@ trait WalletRpc { self: Client =>
bitcoindCall[GetWalletInfoResultPostV22](
"getwalletinfo",
uriExtensionOpt = walletName.map(walletExtension))
case BitcoindVersion.V16 | BitcoindVersion.V17 | BitcoindVersion.V18 |
BitcoindVersion.V19 | BitcoindVersion.V20 | BitcoindVersion.V21 =>
case BitcoindVersion.V17 | BitcoindVersion.V18 | BitcoindVersion.V19 |
BitcoindVersion.V20 | BitcoindVersion.V21 =>
bitcoindCall[GetWalletInfoResultPreV22](
"getwalletinfo",
uriExtensionOpt = walletName.map(walletExtension))
@ -322,7 +322,7 @@ trait WalletRpc { self: Client =>
"setwalletflag",
List(JsString(flag.toString), Json.toJson(value)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
case V16 | V17 | V18 =>
case V17 | V18 =>
Future.failed(
new UnsupportedOperationException(
"setwalletflag is not available for versions before 0.19"))
@ -333,7 +333,7 @@ trait WalletRpc { self: Client =>
self.version.flatMap {
case V23 | V22 | V21 | V20 | V19 | Unknown =>
bitcoindCall[GetBalancesResult]("getbalances")
case V16 | V17 | V18 =>
case V17 | V18 =>
Future.failed(
new UnsupportedOperationException(
"getbalances is not available for versions before 0.19"))
@ -346,7 +346,7 @@ trait WalletRpc { self: Client =>
bitcoindCall[GetBalancesResult]("getbalances",
uriExtensionOpt =
Some(walletExtension(walletName)))
case V16 | V17 | V18 =>
case V17 | V18 =>
Future.failed(
new UnsupportedOperationException(
"getbalances is not available for versions before 0.19"))
@ -436,7 +436,7 @@ trait WalletRpc { self: Client =>
JsString(passphrase),
JsBoolean(avoidReuse))
)
case V16 | V17 | V18 =>
case V17 | V18 =>
require(passphrase.isEmpty,
"passphrase should not be set for versions before v19")
bitcoindCall[CreateWalletResult](
@ -448,7 +448,7 @@ trait WalletRpc { self: Client =>
address: BitcoinAddress,
walletNameOpt: Option[String] = None): Future[AddressInfoResult] = {
self.version.flatMap {
case V16 | V17 =>
case V17 =>
bitcoindCall[AddressInfoResultPreV18](
"getaddressinfo",
List(JsString(address.value)),

View File

@ -1,130 +0,0 @@
package org.bitcoins.rpc.client.v16
import akka.actor.ActorSystem
import org.bitcoins.commons.jsonmodels.bitcoind.{
RpcOpts,
SignRawTransactionResult
}
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.commons.serializers.JsonWriters._
import org.bitcoins.core.api.chain.ChainQueryApi
import org.bitcoins.core.api.chain.db.{CompactFilterDb, CompactFilterHeaderDb}
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.crypto.{DoubleSha256DigestBE, ECPrivateKey, HashType}
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.BitcoindInstance
import play.api.libs.json._
import scala.concurrent.Future
import scala.util.Try
/** This class is compatible with version 0.16 of Bitcoin Core.
*
* @see [[org.bitcoins.rpc.client.common.BitcoindRpcClient BitcoindRpcClient Scaladocs]]
*/
class BitcoindV16RpcClient(override val instance: BitcoindInstance)(implicit
actorSystem: ActorSystem)
extends BitcoindRpcClient(instance)
with V16AccountRpc
with V16SendRpc {
override lazy val version: Future[BitcoindVersion] =
Future.successful(BitcoindVersion.V16)
override def getFilterCount(): Future[Int] = filtersUnsupported
override def getFiltersBetweenHeights(
startHeight: Int,
endHeight: Int): Future[Vector[ChainQueryApi.FilterResponse]] =
filtersUnsupported
override def getFilterHeaderCount(): Future[Int] = filtersUnsupported
override def getFilterHeadersAtHeight(
height: Int): Future[Vector[CompactFilterHeaderDb]] = filtersUnsupported
override def getBestFilterHeader(): Future[Option[CompactFilterHeaderDb]] =
filtersUnsupported
override def getFilterHeader(
blockHash: DoubleSha256DigestBE): Future[Option[CompactFilterHeaderDb]] =
filtersUnsupported
override def getFilter(
hash: DoubleSha256DigestBE): Future[Option[CompactFilterDb]] =
filtersUnsupported
override def getFiltersAtHeight(
height: Int): Future[Vector[CompactFilterDb]] = filtersUnsupported
def signRawTransaction(
transaction: Transaction): Future[SignRawTransactionResult] =
signRawTransaction(transaction, None, None, None)
private def signRawTransaction(
transaction: Transaction,
utxoDeps: Option[Vector[RpcOpts.SignRawTransactionOutputParameter]],
keys: Option[Vector[ECPrivateKey]],
sigHash: Option[HashType]): Future[SignRawTransactionResult] = {
val utxos: JsValue = utxoDeps.map(Json.toJson(_)).getOrElse(JsNull)
val jsonKeys: JsValue = keys.map(Json.toJson(_)).getOrElse(JsNull)
val params =
List(JsString(transaction.hex),
utxos,
jsonKeys,
Json.toJson(sigHash.getOrElse(HashType.sigHashAll)))
bitcoindCall[SignRawTransactionResult]("signrawtransaction", params)
}
def signRawTransaction(
transaction: Transaction,
utxoDeps: Vector[RpcOpts.SignRawTransactionOutputParameter]): Future[
SignRawTransactionResult] =
signRawTransaction(transaction, Some(utxoDeps), None, None)
def signRawTransaction(
transaction: Transaction,
utxoDeps: Vector[RpcOpts.SignRawTransactionOutputParameter],
keys: Vector[ECPrivateKey]): Future[SignRawTransactionResult] =
signRawTransaction(transaction, Some(utxoDeps), Some(keys), None)
def signRawTransaction(
transaction: Transaction,
utxoDeps: Vector[RpcOpts.SignRawTransactionOutputParameter],
keys: Vector[ECPrivateKey],
sigHash: HashType): Future[SignRawTransactionResult] =
signRawTransaction(transaction, Some(utxoDeps), Some(keys), Some(sigHash))
}
object BitcoindV16RpcClient {
/** 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): BitcoindV16RpcClient = {
implicit val system = 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): BitcoindV16RpcClient =
new BitcoindV16RpcClient(instance)
def fromUnknownVersion(
rpcClient: BitcoindRpcClient): Try[BitcoindV16RpcClient] =
Try {
new BitcoindV16RpcClient(rpcClient.instance)(rpcClient.system)
}
}

View File

@ -1,62 +0,0 @@
package org.bitcoins.rpc.client.v16
import org.bitcoins.commons.jsonmodels.bitcoind.ReceivedAccount
import org.bitcoins.commons.serializers.JsonReaders._
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.core.currency.Bitcoins
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.rpc.client.common.Client
import play.api.libs.json.{JsBoolean, JsNumber, JsString}
import scala.concurrent.Future
/** Bitcoin Core prior to version 0.17 had the concept of
* accounts. This has later been removed, and replaced
* with a label system, as well as functionality for
* having several distinct wallets active at the same time.
*/
trait V16AccountRpc { self: Client =>
def getAccountAddress(account: String): Future[BitcoinAddress] = {
bitcoindCall[BitcoinAddress]("getaccountaddress", List(JsString(account)))
}
def getReceivedByAccount(
account: String,
confirmations: Int = 1): Future[Bitcoins] = {
bitcoindCall[Bitcoins]("getreceivedbyaccount",
List(JsString(account), JsNumber(confirmations)))
}
def getAccount(address: BitcoinAddress): Future[String] = {
bitcoindCall[String]("getaccount", List(JsString(address.value)))
}
def getAddressesByAccount(account: String): Future[Vector[BitcoinAddress]] = {
bitcoindCall[Vector[BitcoinAddress]]("getaddressesbyaccount",
List(JsString(account)))
}
def listAccounts(
confirmations: Int = 1,
includeWatchOnly: Boolean = false): Future[Map[String, Bitcoins]] = {
bitcoindCall[Map[String, Bitcoins]](
"listaccounts",
List(JsNumber(confirmations), JsBoolean(includeWatchOnly)))
}
def setAccount(address: BitcoinAddress, account: String): Future[Unit] = {
bitcoindCall[Unit]("setaccount",
List(JsString(address.value), JsString(account)))
}
def listReceivedByAccount(
confirmations: Int = 1,
includeEmpty: Boolean = false,
includeWatchOnly: Boolean = false): Future[Vector[ReceivedAccount]] = {
bitcoindCall[Vector[ReceivedAccount]]("listreceivedbyaccount",
List(JsNumber(confirmations),
JsBoolean(includeEmpty),
JsBoolean(includeWatchOnly)))
}
}

View File

@ -1,48 +0,0 @@
package org.bitcoins.rpc.client.v16
import org.bitcoins.commons.serializers.JsonReaders._
import org.bitcoins.commons.serializers.JsonSerializers._
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit}
import org.bitcoins.core.protocol.BitcoinAddress
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.rpc.client.common.Client
import play.api.libs.json.{JsNumber, JsString, Json}
import scala.concurrent.Future
/** RPC calls related to transaction sending
* specific to Bitcoin Core 0.16.
*/
trait V16SendRpc { self: Client =>
def move(
fromAccount: String,
toAccount: String,
amount: CurrencyUnit,
comment: String = ""): Future[Boolean] = {
bitcoindCall[Boolean]("move",
List(JsString(fromAccount),
JsString(toAccount),
Json.toJson(Bitcoins(amount.satoshis)),
JsNumber(6),
JsString(comment)))
}
def sendFrom(
fromAccount: String,
toAddress: BitcoinAddress,
amount: CurrencyUnit,
confirmations: Int = 1,
comment: String = "",
toComment: String = ""): Future[DoubleSha256DigestBE] = {
bitcoindCall[DoubleSha256DigestBE](
"sendfrom",
List(JsString(fromAccount),
Json.toJson(toAddress),
Json.toJson(Bitcoins(amount.satoshis)),
JsNumber(confirmations),
JsString(comment),
JsString(toComment))
)
}
}

View File

@ -33,8 +33,8 @@ trait V18AssortedRpc {
bitcoindCall[Vector[GetNodeAddressesResultPostV22]](
"getnodeaddresses",
List(Json.toJson(count)))
case BitcoindVersion.V16 | BitcoindVersion.V17 | BitcoindVersion.V18 |
BitcoindVersion.V19 | BitcoindVersion.V20 | BitcoindVersion.V21 =>
case BitcoindVersion.V17 | BitcoindVersion.V18 | BitcoindVersion.V19 |
BitcoindVersion.V20 | BitcoindVersion.V21 =>
bitcoindCall[Vector[GetNodeAddressesResultPreV22]](
"getnodeaddresses",
List(Json.toJson(count)))

View File

@ -39,7 +39,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
self.version.flatMap {
case V20 | V21 | V22 | V23 | Unknown =>
bitcoindCall[MultiSigResultPostV20]("addmultisigaddress", params)
case version @ (V16 | V17 | V18 | V19) =>
case version @ (V17 | V18 | V19) =>
throw new RuntimeException(
s"Cannot use v20MultisigRpc on an older version, got $version")
}
@ -80,7 +80,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
"createmultisig",
List(JsNumber(minSignatures), Json.toJson(keys.map(_.hex))),
uriExtensionOpt = walletNameOpt.map(walletExtension))
case version @ (V16 | V17 | V18 | V19) =>
case version @ (V17 | V18 | V19) =>
throw new RuntimeException(
s"Cannot use v20MultisigRpc on an older version, got $version")
}

View File

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

View File

@ -1,7 +1,6 @@
package org.bitcoins.testkit.rpc
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v16.BitcoindV16RpcClient
import org.bitcoins.rpc.client.v17.BitcoindV17RpcClient
import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
@ -300,29 +299,6 @@ trait BitcoindFixturesCachedPair[T <: BitcoindRpcClient]
}
}
/** Bitcoind fixtures with two cached BitcoindV16RpcClient that are connected via p2p */
trait BitcoindFixturesCachedPairV16
extends BitcoinSAsyncFixtureTest
with BitcoindFixturesCachedPair[BitcoindV16RpcClient] {
override type FixtureParam = NodePair[BitcoindV16RpcClient]
override val version: BitcoindVersion = BitcoindVersion.V16
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()
}
}
/** Bitcoind fixtures with two cached [[BitcoindV17RpcClient]] that are connected via p2p */
trait BitcoindFixturesCachedPairV17
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.v16.BitcoindV16RpcClient
import org.bitcoins.rpc.client.v17.BitcoindV17RpcClient
import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
@ -176,7 +175,7 @@ trait BitcoindRpcTestUtil extends Logging {
version match {
// default to newest version
case Unknown => getBinary(BitcoindVersion.newest, binaryDirectory)
case known @ (V16 | V17 | V18 | V19 | V20 | V21 | V22 | V23) =>
case known @ (V17 | V18 | V19 | V20 | V21 | V22 | V23) =>
val fileList = Files
.list(binaryDirectory)
.iterator()
@ -213,7 +212,7 @@ trait BitcoindRpcTestUtil extends Logging {
val uri = new URI("http://localhost:" + port)
val rpcUri = new URI("http://localhost:" + rpcPort)
val hasNeutrinoSupport = versionOpt match {
case Some(V16) | Some(V17) | Some(V18) =>
case Some(V17) | Some(V18) =>
false
case Some(V19) | Some(V20) | Some(V21) | Some(V22) | Some(V23) | Some(
Unknown) | None =>
@ -242,20 +241,6 @@ trait BitcoindRpcTestUtil extends Logging {
BitcoindInstanceLocal.fromConfig(conf, binary)
}
def v16Instance(
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.V16),
binaryDirectory = binaryDirectory)
def v17Instance(
port: Int = RpcUtil.randomPort,
rpcPort: Int = RpcUtil.randomPort,
@ -364,12 +349,6 @@ trait BitcoindRpcTestUtil extends Logging {
binaryDirectory: Path = BitcoindRpcTestClient.sbtBinaryDirectory)(implicit
system: ActorSystem): BitcoindInstanceLocal = {
bitcoindVersion match {
case BitcoindVersion.V16 =>
BitcoindRpcTestUtil.v16Instance(port,
rpcPort,
zmqConfig,
pruneMode,
binaryDirectory = binaryDirectory)
case BitcoindVersion.V17 =>
BitcoindRpcTestUtil.v17Instance(port,
rpcPort,
@ -425,7 +404,7 @@ trait BitcoindRpcTestUtil extends Logging {
val createWalletF = for {
version <- server.version
descriptors = version match {
case V16 | V17 | V18 | V19 | V20 | V21 | V22 | Unknown =>
case V17 | V18 | V19 | V20 | V21 | V22 | Unknown =>
false
case V23 => true
}
@ -727,9 +706,6 @@ trait BitcoindRpcTestUtil extends Logging {
val rpc = version match {
case BitcoindVersion.Unknown =>
BitcoindRpcClient.withActorSystem(BitcoindRpcTestUtil.instance())
case BitcoindVersion.V16 =>
BitcoindV16RpcClient.withActorSystem(
BitcoindRpcTestUtil.v16Instance())
case BitcoindVersion.V17 =>
BitcoindV17RpcClient.withActorSystem(
BitcoindRpcTestUtil.v17Instance())
@ -814,13 +790,6 @@ trait BitcoindRpcTestUtil extends Logging {
createNodePairInternal(version)
}
/** Returns a pair of [[org.bitcoins.rpc.client.v16.BitcoindV16RpcClient BitcoindV16RpcClient]]
* that are connected with some blocks in the chain
*/
def createNodePairV16(clientAccum: RpcClientAccum)(implicit
system: ActorSystem): Future[(BitcoindV16RpcClient, BitcoindV16RpcClient)] =
createNodePairInternal(BitcoindVersion.V16, clientAccum)
/** Returns a pair of [[org.bitcoins.rpc.client.v17.BitcoindV17RpcClient BitcoindV17RpcClient]]
* that are connected with some blocks in the chain
*/
@ -987,29 +956,24 @@ trait BitcoindRpcTestUtil extends Logging {
signer match {
case v17: BitcoindV17RpcClient =>
v17.signRawTransactionWithWallet(transaction, utxoDeps)
case v16: BitcoindV16RpcClient =>
v16.signRawTransaction(transaction, utxoDeps)
case v20: BitcoindV20RpcClient =>
v20.signRawTransactionWithWallet(transaction)
case v21: BitcoindV21RpcClient =>
v21.signRawTransactionWithWallet(transaction)
case unknown: BitcoindRpcClient =>
val v16T = BitcoindV16RpcClient.fromUnknownVersion(unknown)
val v17T = BitcoindV17RpcClient.fromUnknownVersion(unknown)
val v18T = BitcoindV18RpcClient.fromUnknownVersion(unknown)
val v19T = BitcoindV19RpcClient.fromUnknownVersion(unknown)
(v16T, v17T, v18T, v19T) match {
case (Failure(_), Failure(_), Failure(_), Failure(_)) =>
(v17T, v18T, v19T) match {
case (Failure(_), Failure(_), Failure(_)) =>
throw new RuntimeException(
"Could not figure out version of provided bitcoind RPC client!" +
"This should not happen, managed to construct different versioned RPC clients from one single client")
case (Success(v16), _, _, _) =>
v16.signRawTransaction(transaction, utxoDeps)
case (_, Success(v17), _, _) =>
case (Success(v17), _, _) =>
v17.signRawTransactionWithWallet(transaction, utxoDeps)
case (_, _, Success(v18), _) =>
case (_, Success(v18), _) =>
v18.signRawTransactionWithWallet(transaction, utxoDeps)
case (_, _, _, Success(v19)) =>
case (_, _, Success(v19)) =>
v19.signRawTransactionWithWallet(transaction, utxoDeps)
}
}
@ -1024,8 +988,6 @@ trait BitcoindRpcTestUtil extends Logging {
client match {
case v17: BitcoindV17RpcClient =>
v17.getAddressInfo(address).map(_.pubkey)
case v16: BitcoindV16RpcClient =>
v16.getAddressInfo(address).map(_.pubkey)
case other: BitcoindRpcClient =>
other.version.flatMap { v =>
if (v.toString >= BitcoindVersion.V17.toString) {