Support for Bitcoin Core v22 (#3834)

* Support for Bitcoin Core v22

* respond to the PR comments
This commit is contained in:
rorp 2021-11-19 11:58:27 -08:00 committed by GitHub
parent ea6ac56fd5
commit a6898defe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 306 additions and 62 deletions

View File

@ -13,7 +13,7 @@ import scala.concurrent.Future
class UtilRpcTest extends BitcoindRpcTest {
lazy val clientsF: Future[(BitcoindRpcClient, BitcoindRpcClient)] =
BitcoindRpcTestUtil.createNodePair(clientAccum = clientAccum)
BitcoindRpcTestUtil.createNodePairV21(clientAccum = clientAccum)
behavior of "RpcUtilTest"

View File

@ -0,0 +1,52 @@
package org.bitcoins.rpc.v22
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.AddressType
import org.bitcoins.core.protocol.P2PKHAddress
import org.bitcoins.core.script.ScriptType
import org.bitcoins.crypto.ECPrivateKey
import org.bitcoins.rpc.client.common.BitcoindVersion
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.testkit.rpc.BitcoindFixturesFundedCachedV22
class BitcoindV22RpcClientTest extends BitcoindFixturesFundedCachedV22 {
behavior of "BitcoindV22RpcClient"
it should "be able to start a V22 bitcoind instance" in {
client: BitcoindV22RpcClient =>
for {
v <- client.version
} yield assert(v == BitcoindVersion.V22)
}
it should "be able to get network info" in {
freshClient: BitcoindV22RpcClient =>
for {
info <- freshClient.getNetworkInfo
} yield {
assert(info.networkactive)
assert(info.localrelay)
}
}
it should "be able to decode a reedem script" in {
client: BitcoindV22RpcClient =>
val ecPrivKey1 = ECPrivateKey.freshPrivateKey
val pubKey1 = ecPrivKey1.publicKey
for {
address <- client.getNewAddress(addressType = AddressType.Legacy)
multisig <-
client
.addMultiSigAddress(
2,
Vector(Left(pubKey1), Right(address.asInstanceOf[P2PKHAddress])))
decoded <- client.decodeScript(multisig.redeemScript)
} yield {
assert(decoded.typeOfScript.contains(ScriptType.MULTISIG))
// these fields are deprecated since v22
assert(decoded.reqSigs.isEmpty)
assert(decoded.addresses.isEmpty)
}
}
}

View File

@ -25,7 +25,8 @@ TaskKeys.downloadBitcoind := {
"0.18.99" // TODO: change this when new version compiled on suredbits server
val versions =
List("0.21.1",
List("22.0",
"0.21.1",
"0.20.1",
"0.19.0.1",
"0.18.1",

View File

@ -27,6 +27,7 @@ import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.rpc.client.v20.BitcoindV20RpcClient
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.config.{
BitcoindConfig,
BitcoindInstance,
@ -219,14 +220,14 @@ class BitcoindRpcClient(override val instance: BitcoindInstance)(implicit
protected def filtersUnsupported: Future[Nothing] = {
version.map { v =>
throw new UnsupportedOperationException(
s"bitcoind $v does not support block filters")
s"Bitcoin Core $v does not support block filters")
}
}
protected def filterHeadersUnsupported: Future[Nothing] = {
version.map { v =>
throw new UnsupportedOperationException(
s"bitcoind $v does not support block filters headers through the rpc")
s"Bitcoin Core $v does not support block filters headers through the rpc")
}
}
}
@ -282,11 +283,12 @@ object BitcoindRpcClient {
case BitcoindVersion.V19 => BitcoindV19RpcClient.withActorSystem(instance)
case BitcoindVersion.V20 => BitcoindV20RpcClient.withActorSystem(instance)
case BitcoindVersion.V21 => BitcoindV21RpcClient.withActorSystem(instance)
case BitcoindVersion.V22 => BitcoindV22RpcClient.withActorSystem(instance)
case BitcoindVersion.Experimental =>
BitcoindV18RpcClient.withActorSystem(instance)
case BitcoindVersion.Unknown =>
sys.error(
s"Cannot create a bitcoind from a unknown or experimental version")
s"Cannot create a Bitcoin Core RPC client: unsupported version")
}
bitcoind
@ -304,9 +306,10 @@ sealed trait BitcoindVersion
object BitcoindVersion extends StringFactory[BitcoindVersion] {
/** The newest version of `bitcoind` we support */
val newest: BitcoindVersion = V21
val newest: BitcoindVersion = V22
val standard: Vector[BitcoindVersion] = Vector(V16, V17, V18, V19, V20, V21)
val standard: Vector[BitcoindVersion] =
Vector(V16, V17, V18, V19, V20, V21, V22)
val known: Vector[BitcoindVersion] = standard :+ Experimental
@ -334,6 +337,10 @@ object BitcoindVersion extends StringFactory[BitcoindVersion] {
override def toString: String = "v0.21"
}
case object V22 extends BitcoindVersion {
override def toString: String = "v22"
}
case object Experimental extends BitcoindVersion {
override def toString: String = "v0.18.99"
}
@ -366,6 +373,7 @@ object BitcoindVersion extends StringFactory[BitcoindVersion] {
case "19" => V19
case "20" => V20
case "21" => V21
case "22" => V22
case _ => Unknown
}
}

View File

@ -31,7 +31,7 @@ trait BlockchainRpc { self: Client =>
self.version.flatMap {
case V16 | V17 | V18 =>
bitcoindCall[GetBlockChainInfoResultPreV19]("getblockchaininfo")
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[GetBlockChainInfoResultPostV19]("getblockchaininfo")
}
}

View File

@ -32,7 +32,7 @@ trait MempoolRpc { self: Client =>
Map[DoubleSha256DigestBE, GetMemPoolResult]] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getmempoolancestors",
List(JsString(txid.hex), JsBoolean(true)))
@ -63,7 +63,7 @@ trait MempoolRpc { self: Client =>
def getMemPoolDescendantsVerbose(txid: DoubleSha256DigestBE): Future[
Map[DoubleSha256DigestBE, GetMemPoolResult]] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getmempooldescendants",
List(JsString(txid.hex), JsBoolean(true)))
@ -83,7 +83,7 @@ trait MempoolRpc { self: Client =>
txid: DoubleSha256DigestBE): Future[GetMemPoolEntryResult] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[GetMemPoolEntryResultPostV19]("getmempoolentry",
List(JsString(txid.hex)))
case V16 | V17 | V18 =>
@ -125,7 +125,7 @@ trait MempoolRpc { self: Client =>
Map[DoubleSha256DigestBE, GetMemPoolResult]] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[Map[DoubleSha256DigestBE, GetMemPoolResultPostV19]](
"getrawmempool",
List(JsBoolean(true)))

View File

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

View File

@ -64,7 +64,7 @@ trait P2PRpc { self: Client =>
def getPeerInfo: Future[Vector[Peer]] = {
self.version.flatMap {
case V21 | Unknown =>
case V22 | V21 | Unknown =>
bitcoindCall[Vector[PeerPostV21]]("getpeerinfo")
case V20 =>
bitcoindCall[Vector[PeerV20]]("getpeerinfo")
@ -75,7 +75,7 @@ trait P2PRpc { self: Client =>
def listBanned: Future[Vector[NodeBan]] = {
self.version.flatMap {
case V21 | V20 | Unknown =>
case V22 | V21 | V20 | Unknown =>
bitcoindCall[Vector[NodeBanPostV20]]("listbanned")
case V16 | V17 | V18 | V19 | Experimental =>
bitcoindCall[Vector[NodeBanPreV20]]("listbanned")

View File

@ -111,7 +111,7 @@ trait RawTransactionRpc { self: Client =>
maxfeerate: Double = 0.10): Future[DoubleSha256DigestBE] = {
val feeParameterF = self.version.map {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
JsNumber(maxfeerate)
case V16 | V17 | V18 =>
JsBoolean(maxfeerate == 0)

View File

@ -26,7 +26,7 @@ trait UtilRpc { self: Client =>
def getIndexInfo: Future[Map[String, IndexInfoResult]] = {
version.flatMap {
case V21 | Unknown =>
case V22 | V21 | Unknown =>
bitcoindCall[Map[String, IndexInfoResult]]("getindexinfo")
case V16 | V17 | V18 | V19 | V20 | Experimental =>
Future.failed(
@ -37,7 +37,7 @@ trait UtilRpc { self: Client =>
def getIndexInfo(indexName: String): Future[IndexInfoResult] = {
version.flatMap {
case V21 | Unknown =>
case V22 | V21 | Unknown =>
bitcoindCall[Map[String, IndexInfoResult]](
"getindexinfo",
List(JsString(indexName))).map(_.head._2)

View File

@ -307,7 +307,7 @@ trait WalletRpc { self: Client =>
): Future[SetWalletFlagResult] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[SetWalletFlagResult](
"setwalletflag",
List(JsString(flag.toString), Json.toJson(value)),
@ -321,7 +321,7 @@ trait WalletRpc { self: Client =>
def getBalances: Future[GetBalancesResult] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[GetBalancesResult]("getbalances")
case V16 | V17 | V18 =>
Future.failed(
@ -332,7 +332,7 @@ trait WalletRpc { self: Client =>
def getBalances(walletName: String): Future[GetBalancesResult] = {
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[GetBalancesResult]("getbalances",
uriExtensionOpt =
Some(walletExtension(walletName)))
@ -405,7 +405,7 @@ trait WalletRpc { self: Client =>
blank: Boolean = false,
passphrase: String = ""): Future[CreateWalletResult] =
self.version.flatMap {
case V21 | V20 | V19 | Experimental | Unknown =>
case V22 | V21 | V20 | V19 | Experimental | Unknown =>
bitcoindCall[CreateWalletResult]("createwallet",
List(JsString(walletName),
JsBoolean(disablePrivateKeys),
@ -433,7 +433,7 @@ trait WalletRpc { self: Client =>
"getaddressinfo",
List(JsString(address.value)),
uriExtensionOpt = walletNameOpt.map(walletExtension))
case V21 | Unknown =>
case V22 | V21 | Unknown =>
bitcoindCall[AddressInfoResultPostV21](
"getaddressinfo",
List(JsString(address.value)),

View File

@ -37,7 +37,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
JsString(account)) ++ addressType.map(Json.toJson(_)).toList
self.version.flatMap {
case V20 | V21 | Unknown =>
case V20 | V21 | V22 | Unknown =>
bitcoindCall[MultiSigResultPostV20]("addmultisigaddress", params)
case version @ (V16 | V17 | V18 | V19 | Experimental) =>
throw new RuntimeException(
@ -75,7 +75,7 @@ trait V20MultisigRpc extends MultisigRpc { self: Client =>
keys: Vector[ECPublicKey],
walletNameOpt: Option[String] = None): Future[MultiSigResultPostV20] = {
self.version.flatMap {
case V20 | V21 | Unknown =>
case V20 | V21 | V22 | Unknown =>
bitcoindCall[MultiSigResultPostV20](
"createmultisig",
List(JsNumber(minSignatures), Json.toJson(keys.map(_.hex))),

View File

@ -79,7 +79,7 @@ class BitcoindV21RpcClient(override val instance: BitcoindInstance)(implicit
} yield Vector(filter.filterDb(height))
}
override lazy val version: Future[BitcoindVersion.V21.type] =
override lazy val version: Future[BitcoindVersion] =
Future.successful(BitcoindVersion.V21)
/** $signRawTx

View File

@ -0,0 +1,50 @@
package org.bitcoins.rpc.client.v22
import akka.actor.ActorSystem
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
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 BitcoindV21RpcClient(instance) {
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)
}
}

View File

@ -70,6 +70,8 @@ sealed trait BitcoindInstanceLocal extends BitcoindInstance {
BitcoindVersion.V20
case _: String if foundVersion.startsWith(BitcoindVersion.V21.toString) =>
BitcoindVersion.V21
case _: String if foundVersion.startsWith(BitcoindVersion.V22.toString) =>
BitcoindVersion.V22
case _: String => BitcoindVersion.Unknown
}
}

View File

@ -12,6 +12,7 @@ The Bitcoin Core RPC client in Bitcoin-S currently supports the Bitcoin Core
- 0.19
- 0.20
- 0.21
- 22
version lines. It can be set up to work with both local and remote Bitcoin Core servers.

View File

@ -12,7 +12,7 @@ import org.bitcoins.node._
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.node.NodeUnitTest
import org.bitcoins.testkit.node.fixture.SpvNodeConnectedWithBitcoindV21
import org.bitcoins.testkit.node.fixture.SpvNodeConnectedWithBitcoindV22
import org.bitcoins.testkit.tor.CachedTor
import org.scalatest.FutureOutcome
@ -24,14 +24,14 @@ class DataMessageHandlerTest extends NodeUnitTest with CachedTor {
override protected def getFreshConfig: BitcoinSAppConfig =
BitcoinSTestAppConfig.getSpvWithEmbeddedDbTestConfig(pgUrl, Vector.empty)
override type FixtureParam = SpvNodeConnectedWithBitcoindV21
override type FixtureParam = SpvNodeConnectedWithBitcoindV22
override def withFixture(test: OneArgAsyncTest): FutureOutcome =
withSpvNodeConnectedToBitcoindV21(test)(system, getFreshConfig)
withSpvNodeConnectedToBitcoindV22(test)(system, getFreshConfig)
it must "catch errors and not fail when processing an invalid payload" in {
param: SpvNodeConnectedWithBitcoindV21 =>
val SpvNodeConnectedWithBitcoindV21(spv, _) = param
param: SpvNodeConnectedWithBitcoindV22 =>
val SpvNodeConnectedWithBitcoindV22(spv, _) = param
val sender = spv.peerMsgSenders(0)
for {
@ -55,7 +55,7 @@ class DataMessageHandlerTest extends NodeUnitTest with CachedTor {
it must "verify OnMerkleBlock callbacks are executed" in {
param: FixtureParam =>
val SpvNodeConnectedWithBitcoindV21(spv, bitcoind) = param
val SpvNodeConnectedWithBitcoindV22(spv, bitcoind) = param
val resultP: Promise[(MerkleBlock, Vector[Transaction])] = Promise()
@ -92,7 +92,7 @@ class DataMessageHandlerTest extends NodeUnitTest with CachedTor {
it must "verify OnBlockReceived callbacks are executed" in {
param: FixtureParam =>
val SpvNodeConnectedWithBitcoindV21(spv, bitcoind) = param
val SpvNodeConnectedWithBitcoindV22(spv, bitcoind) = param
val resultP: Promise[Block] = Promise()
@ -124,7 +124,7 @@ class DataMessageHandlerTest extends NodeUnitTest with CachedTor {
it must "verify OnBlockHeadersReceived callbacks are executed" in {
param: FixtureParam =>
val SpvNodeConnectedWithBitcoindV21(spv, bitcoind) = param
val SpvNodeConnectedWithBitcoindV22(spv, bitcoind) = param
val resultP: Promise[Vector[BlockHeader]] = Promise()
@ -159,7 +159,7 @@ class DataMessageHandlerTest extends NodeUnitTest with CachedTor {
it must "verify OnCompactFilterReceived callbacks are executed" in {
param: FixtureParam =>
val SpvNodeConnectedWithBitcoindV21(spv, bitcoind) = param
val SpvNodeConnectedWithBitcoindV22(spv, bitcoind) = param
val resultP: Promise[Vector[(DoubleSha256Digest, GolombFilter)]] =
Promise()

View File

@ -2,22 +2,22 @@ package org.bitcoins.testkit.node
import akka.actor.ActorSystem
import org.bitcoins.core.api.node.NodeType
import org.bitcoins.node.models.Peer
import org.bitcoins.node.Node
import org.bitcoins.node.models.Peer
import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.node.NodeUnitTest.{createPeer, syncNeutrinoNode}
import org.bitcoins.testkit.node.fixture.{
NeutrinoNodeConnectedWithBitcoind,
NeutrinoNodeConnectedWithBitcoinds,
SpvNodeConnectedWithBitcoind,
SpvNodeConnectedWithBitcoindV21
SpvNodeConnectedWithBitcoindV19
}
import org.bitcoins.testkit.rpc.{
CachedBitcoind,
CachedBitcoindNewest,
CachedBitcoindPairV21,
CachedBitcoindPairV22,
CachedBitcoindV19
}
import org.bitcoins.testkit.tor.CachedTor
@ -49,7 +49,7 @@ trait NodeTestWithCachedBitcoind extends BaseNodeTest with CachedTor {
bitcoind = bitcoind)(
system, // Force V18 because Spv is disabled on versions after
appConfig),
{ case x: SpvNodeFundedWalletBitcoind =>
{ x: SpvNodeFundedWalletBitcoind =>
tearDownNodeWithBitcoind(x)
}
)(test)
@ -75,7 +75,7 @@ trait NodeTestWithCachedBitcoind extends BaseNodeTest with CachedTor {
makeDependentFixture[SpvNodeConnectedWithBitcoind](
build = nodeWithBitcoindBuilder,
{ case x: SpvNodeConnectedWithBitcoind =>
{ x: SpvNodeConnectedWithBitcoind =>
NodeUnitTest.destroyNode(x.node)
})(test)
}
@ -96,7 +96,7 @@ trait NodeTestWithCachedBitcoind extends BaseNodeTest with CachedTor {
}
makeDependentFixture[NeutrinoNodeConnectedWithBitcoind](
build = nodeWithBitcoindBuilder,
{ case x: NeutrinoNodeConnectedWithBitcoind =>
{ x: NeutrinoNodeConnectedWithBitcoind =>
tearDownNode(x.node)
})(test)
}
@ -120,7 +120,7 @@ trait NodeTestWithCachedBitcoind extends BaseNodeTest with CachedTor {
}
makeDependentFixture[NeutrinoNodeConnectedWithBitcoinds](
build = nodeWithBitcoindBuilder,
{ case x: NeutrinoNodeConnectedWithBitcoinds =>
{ x: NeutrinoNodeConnectedWithBitcoinds =>
tearDownNode(x.node)
})(test)
}
@ -139,7 +139,7 @@ trait NodeTestWithCachedBitcoind extends BaseNodeTest with CachedTor {
bip39PasswordOpt = bip39PasswordOpt,
bitcoind,
walletCallbacks = walletCallbacks)(system, appConfig),
{ case x: NeutrinoNodeFundedWalletBitcoind =>
{ x: NeutrinoNodeFundedWalletBitcoind =>
tearDownNodeWithBitcoind(x)
}
)(test)
@ -188,10 +188,10 @@ trait NodeTestWithCachedBitcoindNewest
trait NodeTestWithCachedBitcoindPair
extends NodeTestWithCachedBitcoind
with CachedBitcoindPairV21 {
with CachedBitcoindPairV22 {
override def afterAll(): Unit = {
super[CachedBitcoindPairV21].afterAll()
super[CachedBitcoindPairV22].afterAll()
super[NodeTestWithCachedBitcoind].afterAll()
}
}
@ -202,11 +202,11 @@ trait NodeTestWithCachedBitcoindV19
def withSpvNodeConnectedToBitcoindV19Cached(
test: OneArgAsyncTest,
bitcoind: BitcoindV21RpcClient)(implicit
bitcoind: BitcoindV19RpcClient)(implicit
system: ActorSystem,
appConfig: BitcoinSAppConfig): FutureOutcome = {
val nodeWithBitcoindBuilder: () => Future[
SpvNodeConnectedWithBitcoindV21] = { () =>
SpvNodeConnectedWithBitcoindV19] = { () =>
require(appConfig.nodeConf.nodeType == NodeType.SpvNode)
for {
peer <- createPeer(bitcoind)
@ -215,12 +215,12 @@ trait NodeTestWithCachedBitcoindV19
appConfig.nodeConf)
started <- node.start()
_ <- NodeUnitTest.syncSpvNode(started, bitcoind)
} yield SpvNodeConnectedWithBitcoindV21(node, bitcoind)
} yield SpvNodeConnectedWithBitcoindV19(node, bitcoind)
}
makeDependentFixture[SpvNodeConnectedWithBitcoindV21](
makeDependentFixture[SpvNodeConnectedWithBitcoindV19](
build = nodeWithBitcoindBuilder,
{ case x: SpvNodeConnectedWithBitcoindV21 =>
{ x: SpvNodeConnectedWithBitcoindV19 =>
NodeUnitTest.destroyNode(x.node)
}
)(test)

View File

@ -10,9 +10,10 @@ import org.bitcoins.node._
import org.bitcoins.node.config.NodeAppConfig
import org.bitcoins.node.models.Peer
import org.bitcoins.node.networking.peer._
import org.bitcoins.rpc.client.common.BitcoindVersion.{V18, V21}
import org.bitcoins.rpc.client.common.BitcoindVersion.{V18, V21, V22}
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.util.RpcUtil
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.chain.ChainUnitTest
@ -22,12 +23,7 @@ import org.bitcoins.testkit.node.NodeUnitTest.{
emptyPeer,
syncNeutrinoNode
}
import org.bitcoins.testkit.node.fixture.{
NeutrinoNodeConnectedWithBitcoind,
NodeConnectedWithBitcoind,
SpvNodeConnectedWithBitcoind,
SpvNodeConnectedWithBitcoindV21
}
import org.bitcoins.testkit.node.fixture._
import org.bitcoins.testkit.wallet.{BitcoinSWalletTest, WalletWithBitcoindRpc}
import org.bitcoins.testkitcore.node.P2PMessageTestUtil
import org.bitcoins.wallet.WalletCallbacks
@ -120,6 +116,33 @@ trait NodeUnitTest extends BaseNodeTest {
)(test)
}
def withSpvNodeConnectedToBitcoindV22(test: OneArgAsyncTest)(implicit
system: ActorSystem,
appConfig: BitcoinSAppConfig): FutureOutcome = {
val nodeWithBitcoindBuilder: () => Future[
SpvNodeConnectedWithBitcoindV22] = { () =>
require(appConfig.nodeConf.nodeType == NodeType.SpvNode)
for {
bitcoind <-
BitcoinSFixture
.createBitcoindWithFunds(Some(V22))
.map(_.asInstanceOf[BitcoindV22RpcClient])
peer <- createPeer(bitcoind)
node <- NodeUnitTest.createSpvNode(peer)(system,
appConfig.chainConf,
appConfig.nodeConf)
started <- node.start()
_ <- NodeUnitTest.syncSpvNode(started, bitcoind)
} yield SpvNodeConnectedWithBitcoindV22(node, bitcoind)
}
makeDependentFixture(
build = nodeWithBitcoindBuilder,
destroy = NodeUnitTest.destroyNodeConnectedWithBitcoind(
_: NodeConnectedWithBitcoind)(system, appConfig)
)(test)
}
def withNeutrinoNodeConnectedToBitcoind(
test: OneArgAsyncTest,
versionOpt: Option[BitcoindVersion] = None)(implicit

View File

@ -2,7 +2,9 @@ package org.bitcoins.testkit.node.fixture
import org.bitcoins.node.{NeutrinoNode, Node, SpvNode}
import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
/** Gives us a fixture that has a SPV node connected with the bitcoind instance */
trait NodeConnectedWithBitcoind {
@ -15,11 +17,21 @@ case class SpvNodeConnectedWithBitcoind(
bitcoind: BitcoindRpcClient)
extends NodeConnectedWithBitcoind
case class SpvNodeConnectedWithBitcoindV22(
node: SpvNode,
bitcoind: BitcoindV22RpcClient)
extends NodeConnectedWithBitcoind
case class SpvNodeConnectedWithBitcoindV21(
node: SpvNode,
bitcoind: BitcoindV21RpcClient)
extends NodeConnectedWithBitcoind
case class SpvNodeConnectedWithBitcoindV19(
node: SpvNode,
bitcoind: BitcoindV19RpcClient)
extends NodeConnectedWithBitcoind
case class NeutrinoNodeConnectedWithBitcoind(
node: NeutrinoNode,
bitcoind: BitcoindRpcClient)

View File

@ -7,6 +7,7 @@ import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.rpc.client.v20.BitcoindV20RpcClient
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.util.{NodePair, NodeTriple}
import org.bitcoins.testkit.EmbeddedPg
import org.bitcoins.testkit.fixtures.BitcoinSFixture
@ -189,6 +190,40 @@ trait BitcoindFixturesFundedCachedV21
}
}
/** 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()
}
}
trait BitcoindFixturesFundedCachedNewest
extends BitcoinSAsyncFixtureTest
with BitcoindFixturesFundedCached

View File

@ -36,6 +36,7 @@ import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.rpc.client.v20.BitcoindV20RpcClient
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.config._
import org.bitcoins.rpc.util.RpcUtil
import org.bitcoins.testkit.util.{BitcoindRpcTestClient, FileUtil, TorUtil}
@ -174,7 +175,7 @@ trait BitcoindRpcTestUtil extends Logging {
version match {
// default to newest version
case Unknown => getBinary(BitcoindVersion.newest, binaryDirectory)
case known @ (Experimental | V16 | V17 | V18 | V19 | V20 | V21) =>
case known @ (Experimental | V16 | V17 | V18 | V19 | V20 | V21 | V22) =>
val fileList = Files
.list(binaryDirectory)
.iterator()
@ -223,8 +224,8 @@ trait BitcoindRpcTestUtil extends Logging {
val hasNeutrinoSupport = versionOpt match {
case Some(V16) | Some(V17) | Some(V18) =>
false
case Some(V19) | Some(V20) | Some(V21) | Some(Experimental) | Some(
Unknown) | None =>
case Some(V19) | Some(V20) | Some(V21) | Some(V22) | Some(Experimental) |
Some(Unknown) | None =>
true
}
val configFile =
@ -334,6 +335,20 @@ trait BitcoindRpcTestUtil extends Logging {
versionOpt = Some(BitcoindVersion.V21),
binaryDirectory = binaryDirectory)
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 vExperimentalInstance(
port: Int = RpcUtil.randomPort,
rpcPort: Int = RpcUtil.randomPort,
@ -394,6 +409,12 @@ trait BitcoindRpcTestUtil extends Logging {
zmqConfig,
pruneMode,
binaryDirectory = binaryDirectory)
case BitcoindVersion.V22 =>
BitcoindRpcTestUtil.v22Instance(port,
rpcPort,
zmqConfig,
pruneMode,
binaryDirectory = binaryDirectory)
case BitcoindVersion.Experimental =>
BitcoindRpcTestUtil.vExperimentalInstance(port,
rpcPort,
@ -728,6 +749,9 @@ trait BitcoindRpcTestUtil extends Logging {
case BitcoindVersion.V21 =>
BitcoindV21RpcClient.withActorSystem(
BitcoindRpcTestUtil.v21Instance())
case BitcoindVersion.V22 =>
BitcoindV22RpcClient.withActorSystem(
BitcoindRpcTestUtil.v22Instance())
case BitcoindVersion.Experimental =>
BitcoindV19RpcClient.withActorSystem(
BitcoindRpcTestUtil.vExperimentalInstance())
@ -836,6 +860,10 @@ trait BitcoindRpcTestUtil extends Logging {
system: ActorSystem): Future[(BitcoindV21RpcClient, BitcoindV21RpcClient)] =
createNodePairInternal(BitcoindVersion.V21, clientAccum)
def createNodePairV22(clientAccum: RpcClientAccum)(implicit
system: ActorSystem): Future[(BitcoindV21RpcClient, BitcoindV21RpcClient)] =
createNodePairInternal(BitcoindVersion.V22, clientAccum)
/** Returns a triple of [[org.bitcoins.rpc.client.common.BitcoindRpcClient BitcoindRpcClient]]
* that are connected with some blocks in the chain
*/

View File

@ -6,6 +6,7 @@ import org.bitcoins.rpc.client.v18.BitcoindV18RpcClient
import org.bitcoins.rpc.client.v19.BitcoindV19RpcClient
import org.bitcoins.rpc.client.v20.BitcoindV20RpcClient
import org.bitcoins.rpc.client.v21.BitcoindV21RpcClient
import org.bitcoins.rpc.client.v22.BitcoindV22RpcClient
import org.bitcoins.rpc.util.{NodePair, NodeTriple}
import org.bitcoins.testkit.fixtures.BitcoinSFixture
import org.bitcoins.testkit.util.BitcoinSAkkaAsyncTest
@ -131,6 +132,18 @@ trait CachedBitcoindV21 extends CachedBitcoindFunded[BitcoindV21RpcClient] {
}
}
trait CachedBitcoindV22 extends CachedBitcoindFunded[BitcoindV22RpcClient] {
_: BitcoinSAkkaAsyncTest =>
override protected lazy val cachedBitcoindWithFundsF: Future[
BitcoindV22RpcClient] = {
val _ = isBitcoindUsed.set(true)
BitcoinSFixture
.createBitcoindWithFunds(Some(BitcoindVersion.V22))
.map(_.asInstanceOf[BitcoindV22RpcClient])
}
}
trait CachedBitcoindCollection[T <: BitcoindRpcClient]
extends CachedBitcoind[T] {
_: BitcoinSAkkaAsyncTest =>
@ -208,6 +221,25 @@ trait CachedBitcoindPairV21
}
}
trait CachedBitcoindPairV22
extends CachedBitcoindCollection[BitcoindV21RpcClient] {
_: BitcoinSAkkaAsyncTest =>
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 CachedBitcoindTriple[T <: BitcoindRpcClient]
extends CachedBitcoindCollection[T] {
_: BitcoinSAkkaAsyncTest =>