2024 07 31 bitcoind callbacks (#5631)

* Add NodeApiCallbacks

* Add BitcoindCallbacks

* Add BitcoindRpcAppConfig

* fix docs

* Add helper method for construction

* Add helper constructor method to avoid explicitly passing BitcoindRpcAppConfig parameter to BitcoindRpcClient when we have a BitcoindInstanceLocal

* Fix docs
This commit is contained in:
Chris Stewart 2024-08-02 07:43:24 -07:00 committed by GitHub
parent 88b1dfd4c5
commit 38850d22e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 200 additions and 155 deletions

View file

@ -3,13 +3,14 @@ package org.bitcoins.server.util
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.stream.scaladsl.{Sink, Source}
import org.bitcoins.commons.util.BitcoinSLogger
import org.bitcoins.core.api.callback.OnBlockReceived
import org.bitcoins.core.api.dlc.wallet.DLCNeutrinoHDWalletApi
import org.bitcoins.core.api.wallet.{NeutrinoWalletApi, WalletApi}
import org.bitcoins.core.gcs.GolombFilter
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader}
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.node._
import org.bitcoins.node.*
import org.bitcoins.node.callback.NodeCallbackStreamManager
import org.bitcoins.wallet.WalletNotInitialized

View file

@ -74,7 +74,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
.isInstanceOf[BitcoindAuthCredentials.CookieBased]
)
val cli = BitcoindRpcClient.withActorSystem(instance)
val cli = BitcoindRpcClient(instance)
testClientStart(cli)
}
@ -94,7 +94,7 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
instance.authCredentials
.isInstanceOf[BitcoindAuthCredentials.PasswordBased]
)
testClientStart(BitcoindRpcClient.withActorSystem(instance))
testClientStart(BitcoindRpcClient(instance))
}
// the values in this conf was generated by executing
@ -132,13 +132,14 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
binary = newestBitcoindBinary
)
testClientStart(BitcoindRpcClient.withActorSystem(instance))
testClientStart(BitcoindRpcClient(instance))
}
it should "parse a bitcoin.conf file, start bitcoind, mine some blocks and quit" in {
val instance =
BitcoindInstanceLocal.fromDatadir(datadir.toFile, newestBitcoindBinary)
val client = BitcoindRpcClient.withActorSystem(instance)
val client =
BitcoindRpcClient(instance)
for {
_ <- startClient(client)
@ -185,7 +186,8 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
binary = newestBitcoindBinary
)
val client = BitcoindRpcClient.withActorSystem(instance)
val client =
BitcoindRpcClient(instance)
for {
_ <- startClient(client)
remoteInstance = BitcoindInstanceRemote(
@ -196,7 +198,9 @@ class BitcoindInstanceTest extends BitcoindRpcTest {
zmqConfig = instance.zmqConfig,
proxyParams = None
)
remoteClient = BitcoindRpcClient.withActorSystem(remoteInstance)
remoteClient = new BitcoindRpcClient(remoteInstance)(
system,
instance.bitcoindRpcAppConfig)
_ <- remoteClient.start()
_ <- remoteClient.isStartedF.map {
case false =>

View file

@ -66,10 +66,10 @@ class WalletRpcTest extends BitcoindFixturesCachedPairNewest {
// This client's wallet is encrypted
lazy val walletClientF: Future[BitcoindRpcClient] = clientsF.flatMap { _ =>
val instance =
BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.newest))
val walletClient =
BitcoindRpcClient.withActorSystem(
BitcoindRpcTestUtil.instance(versionOpt = Some(BitcoindVersion.newest))
)
BitcoindRpcClient(instance)
for {
_ <- startClient(walletClient)

View file

@ -0,0 +1,38 @@
package org.bitcoins.rpc
import org.bitcoins.commons.util.BitcoinSLogger
import org.bitcoins.core.api.CallbackHandler
import org.bitcoins.core.api.callback.{
CallbackFactory,
ModuleCallbacks,
NodeApiCallbacks,
OnBlockReceived
}
import org.bitcoins.core.protocol.blockchain.Block
trait BitcoindCallbacks
extends NodeApiCallbacks
with ModuleCallbacks[BitcoindCallbacks]
with BitcoinSLogger
object BitcoindCallbacks extends CallbackFactory[BitcoindCallbacks] {
private case class BitcoindCallbacksImpl(
onBlockReceived: CallbackHandler[Block, OnBlockReceived])
extends BitcoindCallbacks {
override def +(other: BitcoindCallbacks): BitcoindCallbacks = {
copy(onBlockReceived = onBlockReceived ++ other.onBlockReceived)
}
}
override def empty: BitcoindCallbacks = BitcoindCallbacksImpl(
CallbackHandler.empty)
/** Constructs a set of callbacks that only acts on block received */
def onBlockReceived(f: OnBlockReceived): BitcoindCallbacks = {
BitcoindCallbacksImpl(onBlockReceived =
CallbackHandler[Block, OnBlockReceived](
"onBlockReceived",
Vector(f)
))
}
}

View file

@ -1,6 +1,8 @@
package org.bitcoins.rpc.client.common
import org.apache.pekko.Done
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.stream.scaladsl.{Keep, RunnableGraph, Sink, Source}
import org.bitcoins.commons.util.BitcoinSLogger
import org.bitcoins.core.api.chain.db.BlockHeaderDb
import org.bitcoins.core.api.chain.{ChainApi, FilterSyncMarker}
@ -19,7 +21,7 @@ import org.bitcoins.rpc.client.v20.V20MultisigRpc
import org.bitcoins.rpc.client.v25.BitcoindV25RpcClient
import org.bitcoins.rpc.client.v26.BitcoindV26RpcClient
import org.bitcoins.rpc.client.v27.BitcoindV27RpcClient
import org.bitcoins.rpc.config._
import org.bitcoins.rpc.config.*
import java.io.File
import java.util.concurrent.atomic.AtomicBoolean
@ -35,7 +37,8 @@ import scala.concurrent.Future
* handle them as you see fit.
*/
class BitcoindRpcClient(override val instance: BitcoindInstance)(implicit
override val system: ActorSystem
override val system: ActorSystem,
bitcoindRpcAppConfig: BitcoindRpcAppConfig
) extends Client
with FeeRateApi
with NodeApi
@ -166,7 +169,17 @@ class BitcoindRpcClient(override val instance: BitcoindInstance)(implicit
override def downloadBlocks(
blockHashes: Vector[DoubleSha256DigestBE]
): Future[Unit] = Future.unit
): Future[Unit] = {
val callback =
bitcoindRpcAppConfig.callBacks.executeOnBlockReceivedCallbacks(_)
val graph: RunnableGraph[Future[Done]] = Source(blockHashes)
.mapAsync(FutureUtil.getParallelism)(getBlockRaw)
.toMat(Sink.foreachAsync(1)(callback))(Keep.right)
graph
.run()
.map(_ => ())
}
override def processHeaders(headers: Vector[BlockHeader]): Future[ChainApi] =
Future.successful(this)
@ -294,35 +307,16 @@ class BitcoindRpcClient(override val instance: BitcoindInstance)(implicit
}
object BitcoindRpcClient {
/** The name we give to actor systems we create. We use this information to
* know which actor systems to shut down
*/
private[rpc] val ActorSystemName = "bitcoind-rpc-client-created-by-bitcoin-s"
implicit private lazy val system: ActorSystem =
ActorSystem.create(ActorSystemName)
val DEFAULT_WALLET_NAME: String = "wallet.dat"
/** 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): BitcoindRpcClient = {
withActorSystem(instance)(system)
}
/** 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
def apply(instance: BitcoindInstanceLocal)(implicit
system: ActorSystem
): BitcoindRpcClient =
new BitcoindRpcClient(instance)
new BitcoindRpcClient(instance)(system, instance.bitcoindRpcAppConfig)
/** Constructs a RPC client from the given datadir, or the default datadir if
* no directory is provided. This is always a [[BitcoindInstanceLocal]] since
@ -331,7 +325,7 @@ object BitcoindRpcClient {
def fromDatadir(
datadir: File = BitcoindConfig.DEFAULT_DATADIR,
binary: File
): BitcoindRpcClient = {
)(implicit system: ActorSystem): BitcoindRpcClient = {
val instance = BitcoindInstanceLocal.fromDatadir(datadir, binary)
val cli = BitcoindRpcClient(instance)
cli
@ -340,13 +334,13 @@ object BitcoindRpcClient {
/** Returns a bitcoind with the appropriated version you passed in, the
* bitcoind is NOT started.
*/
def fromVersion(version: BitcoindVersion, instance: BitcoindInstance)(implicit
system: ActorSystem
def fromVersion(version: BitcoindVersion, instance: BitcoindInstanceLocal)(
implicit system: ActorSystem
): BitcoindRpcClient = {
val bitcoind = version match {
case BitcoindVersion.V25 => BitcoindV25RpcClient.withActorSystem(instance)
case BitcoindVersion.V26 => BitcoindV26RpcClient.withActorSystem(instance)
case BitcoindVersion.V27 => BitcoindV27RpcClient.withActorSystem(instance)
case BitcoindVersion.V25 => BitcoindV25RpcClient(instance)
case BitcoindVersion.V26 => BitcoindV26RpcClient(instance)
case BitcoindVersion.V27 => BitcoindV27RpcClient(instance)
case BitcoindVersion.Unknown =>
sys.error(
s"Cannot create a Bitcoin Core RPC client: unsupported version"
@ -355,11 +349,24 @@ object BitcoindRpcClient {
bitcoind
}
def fromVersionNoSystem(
version: BitcoindVersion,
instance: BitcoindInstance
/** Returns a bitcoind with the appropriated version you passed in, the
* bitcoind is NOT started.
*/
def fromVersion(version: BitcoindVersion, instance: BitcoindInstanceRemote)(
implicit
system: ActorSystem,
bitcoindRpcAppConfig: BitcoindRpcAppConfig
): BitcoindRpcClient = {
fromVersion(version, instance)(system)
val bitcoind = version match {
case BitcoindVersion.V25 => new BitcoindV25RpcClient(instance)
case BitcoindVersion.V26 => new BitcoindV26RpcClient(instance)
case BitcoindVersion.V27 => new BitcoindV27RpcClient(instance)
case BitcoindVersion.Unknown =>
sys.error(
s"Cannot create a Bitcoin Core RPC client: unsupported version"
)
}
bitcoind
}
}

View file

@ -323,11 +323,6 @@ trait Client
// i think bitcoind stops asynchronously
// so it returns fast from the 'stop' rpc command
_ <- stopBinary()
_ <- {
if (system.name == BitcoindRpcClient.ActorSystemName) {
system.terminate()
} else Future.unit
}
} yield this.asInstanceOf[BitcoindRpcClient]
}

View file

@ -2,13 +2,17 @@ package org.bitcoins.rpc.client.v25
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.BitcoindInstance
import org.bitcoins.rpc.config.{
BitcoindInstance,
BitcoindInstanceLocal,
BitcoindRpcAppConfig
}
import scala.concurrent.Future
import scala.util.Try
class BitcoindV25RpcClient(override val instance: BitcoindInstance)(implicit
actorSystem: ActorSystem
actorSystem: ActorSystem,
bitcoindRpcAppConfig: BitcoindRpcAppConfig
) extends BitcoindRpcClient(instance) {
override lazy val version: Future[BitcoindVersion] =
@ -17,32 +21,13 @@ class BitcoindV25RpcClient(override val instance: BitcoindInstance)(implicit
object BitcoindV25RpcClient {
/** 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): BitcoindV25RpcClient = {
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
def apply(instance: BitcoindInstanceLocal)(implicit
system: ActorSystem
): BitcoindV25RpcClient =
new BitcoindV25RpcClient(instance)(system)
def fromUnknownVersion(
rpcClient: BitcoindRpcClient
): Try[BitcoindV25RpcClient] =
Try {
new BitcoindV25RpcClient(rpcClient.instance)(rpcClient.system)
}
new BitcoindV25RpcClient(instance)(system, instance.bitcoindRpcAppConfig)
}

View file

@ -2,13 +2,17 @@ package org.bitcoins.rpc.client.v26
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.BitcoindInstance
import org.bitcoins.rpc.config.{
BitcoindInstance,
BitcoindInstanceLocal,
BitcoindRpcAppConfig
}
import scala.concurrent.Future
import scala.util.Try
class BitcoindV26RpcClient(override val instance: BitcoindInstance)(implicit
actorSystem: ActorSystem
actorSystem: ActorSystem,
bitcoindRpcAppConfig: BitcoindRpcAppConfig
) extends BitcoindRpcClient(instance) {
override lazy val version: Future[BitcoindVersion] =
@ -17,32 +21,13 @@ class BitcoindV26RpcClient(override val instance: BitcoindInstance)(implicit
object BitcoindV26RpcClient {
/** 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): BitcoindV26RpcClient = {
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
def apply(instance: BitcoindInstanceLocal)(implicit
system: ActorSystem
): BitcoindV26RpcClient =
new BitcoindV26RpcClient(instance)(system)
def fromUnknownVersion(
rpcClient: BitcoindRpcClient
): Try[BitcoindV26RpcClient] =
Try {
new BitcoindV26RpcClient(rpcClient.instance)(rpcClient.system)
}
new BitcoindV26RpcClient(instance)(system, instance.bitcoindRpcAppConfig)
}

View file

@ -2,13 +2,17 @@ package org.bitcoins.rpc.client.v27
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.BitcoindInstance
import org.bitcoins.rpc.config.{
BitcoindInstance,
BitcoindInstanceLocal,
BitcoindRpcAppConfig
}
import scala.concurrent.Future
import scala.util.Try
class BitcoindV27RpcClient(override val instance: BitcoindInstance)(implicit
actorSystem: ActorSystem
actorSystem: ActorSystem,
bitcoindRpcAppConfig: BitcoindRpcAppConfig
) extends BitcoindRpcClient(instance) {
override lazy val version: Future[BitcoindVersion] =
@ -17,32 +21,13 @@ class BitcoindV27RpcClient(override val instance: BitcoindInstance)(implicit
object BitcoindV27RpcClient {
/** 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): BitcoindV27RpcClient = {
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
def apply(instance: BitcoindInstanceLocal)(implicit
system: ActorSystem
): BitcoindV27RpcClient =
new BitcoindV27RpcClient(instance)(system)
def fromUnknownVersion(
rpcClient: BitcoindRpcClient
): Try[BitcoindV27RpcClient] =
Try {
new BitcoindV27RpcClient(rpcClient.instance)(rpcClient.system)
}
new BitcoindV27RpcClient(instance)(system, instance.bitcoindRpcAppConfig)
}

View file

@ -77,6 +77,10 @@ sealed trait BitcoindInstanceLocal extends BitcoindInstance {
throw exception
}
}
def bitcoindRpcAppConfig: BitcoindRpcAppConfig = {
BitcoindRpcAppConfig.fromDatadir(datadir.toPath)
}
}
/** Refers to a bitcoind instance that is running remotely on another machine */

View file

@ -4,7 +4,10 @@ import com.typesafe.config.Config
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.config.{AppConfig, ConfigOps}
import org.bitcoins.core.api.CallbackConfig
import org.bitcoins.core.api.callback.CallbackFactory
import org.bitcoins.core.api.tor.Socks5ProxyParams
import org.bitcoins.rpc.BitcoindCallbacks
import org.bitcoins.rpc.BitcoindException.InWarmUp
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.util.AppConfigFactoryActorSystem
@ -12,7 +15,7 @@ import org.bitcoins.tor.config.TorAppConfig
import java.io.File
import java.net.{InetSocketAddress, URI}
import java.nio.file._
import java.nio.file.*
import scala.concurrent.duration.DurationInt
import scala.concurrent.{Future, Promise}
@ -26,7 +29,8 @@ case class BitcoindRpcAppConfig(
baseDatadir: Path,
configOverrides: Vector[Config]
)(implicit val system: ActorSystem)
extends AppConfig {
extends AppConfig
with CallbackConfig[BitcoindCallbacks] {
import system.dispatcher
@ -180,12 +184,13 @@ case class BitcoindRpcAppConfig(
bitcoindInstance match {
case local: BitcoindInstanceLocal =>
val version = versionOpt.getOrElse(local.getVersion)
val client = BitcoindRpcClient.fromVersion(version, bitcoindInstance)
val client =
BitcoindRpcClient.fromVersion(version, local)
Future.successful(client)
case _: BitcoindInstanceRemote =>
case remote: BitcoindInstanceRemote =>
// first get a generic rpc client so we can retrieve
// the proper version of the remote running bitcoind
val noVersionRpc = new BitcoindRpcClient(bitcoindInstance)
val noVersionRpc = new BitcoindRpcClient(remote)(system, this)
val versionF = getBitcoindVersion(noVersionRpc)
// if we don't retrieve the proper version, we can
@ -194,7 +199,8 @@ case class BitcoindRpcAppConfig(
// such as blockfilters
// see: https://github.com/bitcoin-s/bitcoin-s/issues/3695#issuecomment-929492945
versionF.map { version =>
BitcoindRpcClient.fromVersion(version, instance = bitcoindInstance)
BitcoindRpcClient.fromVersion(version, instance = remote)(system,
this)
}
}
}
@ -227,6 +233,9 @@ case class BitcoindRpcAppConfig(
version
}
}
override def callbackFactory: CallbackFactory[BitcoindCallbacks] =
BitcoindCallbacks
}
object BitcoindRpcAppConfig

View file

@ -0,0 +1,18 @@
package org.bitcoins.core.api.callback
import org.bitcoins.core.api.{Callback, CallbackHandler}
import org.bitcoins.core.protocol.blockchain.Block
import scala.concurrent.{ExecutionContext, Future}
/** Callback for handling a received block */
trait OnBlockReceived extends Callback[Block]
trait NodeApiCallbacks {
def onBlockReceived: CallbackHandler[Block, OnBlockReceived]
def executeOnBlockReceivedCallbacks(
block: Block
)(implicit ec: ExecutionContext): Future[Unit] = {
onBlockReceived.execute(block)
}
}

View file

@ -5,6 +5,7 @@ title: Chain Query API
```scala mdoc:invisible
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.core.api.callback.OnBlockReceived
import org.bitcoins.core.api.chain.ChainQueryApi
import org.bitcoins.core.api.chain.ChainQueryApi.FilterResponse
import org.bitcoins.crypto._

View file

@ -4,6 +4,7 @@ id: node-api title: Node API
```scala mdoc:invisible
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.core.api.callback.OnBlockReceived
import org.bitcoins.core.api.node._
import org.bitcoins.crypto._
import org.bitcoins.core.protocol.blockchain.Block

View file

@ -43,6 +43,7 @@ For your node to be able to service these filters you will need set
```scala mdoc:invisible
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.chain.config.ChainAppConfig
import org.bitcoins.core.api.callback.OnBlockReceived
import org.bitcoins.core.protocol.blockchain.Block
import org.bitcoins.node._
import org.bitcoins.node.config.NodeAppConfig

View file

@ -130,8 +130,8 @@ class is only intended to cover errors returned by Bitcoin Core. An example of h
handling could look:
```scala mdoc:compile-only
implicit val ec: ExecutionContext = ExecutionContext.global
implicit val system: ActorSystem = ActorSystem()
implicit val ec: ExecutionContext = system.dispatcher
// let's assume you have an already running client,
// so there's no need to start this one

View file

@ -3,15 +3,16 @@ package org.bitcoins.node.networking.peer
import com.typesafe.config.ConfigFactory
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.chain.blockchain.ChainHandler
import org.bitcoins.core.api.callback.OnBlockReceived
import org.bitcoins.core.config.SigNet
import org.bitcoins.core.currency._
import org.bitcoins.core.currency.*
import org.bitcoins.core.gcs.{FilterType, GolombFilter}
import org.bitcoins.core.p2p.HeadersMessage
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader}
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.node.NodeState.{FilterHeaderSync, HeaderSync}
import org.bitcoins.node._
import org.bitcoins.node.*
import org.bitcoins.server.BitcoinSAppConfig
import org.bitcoins.testkit.BitcoinSTestAppConfig
import org.bitcoins.testkit.node.fixture.NeutrinoNodeConnectedWithBitcoind

View file

@ -2,7 +2,12 @@ package org.bitcoins.node
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.commons.util.BitcoinSLogger
import org.bitcoins.core.api.callback.{CallbackFactory, ModuleCallbacks}
import org.bitcoins.core.api.callback.{
CallbackFactory,
ModuleCallbacks,
NodeApiCallbacks,
OnBlockReceived
}
import org.bitcoins.core.api.{Callback, Callback2, CallbackHandler}
import org.bitcoins.core.gcs.GolombFilter
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader, MerkleBlock}
@ -15,7 +20,10 @@ import scala.concurrent.{ExecutionContext, Future}
/** Callbacks for responding to events in the node. The appropriate callback is
* executed whenever the node receives a `getdata` message matching it.
*/
trait NodeCallbacks extends ModuleCallbacks[NodeCallbacks] with BitcoinSLogger {
trait NodeCallbacks
extends ModuleCallbacks[NodeCallbacks]
with NodeApiCallbacks
with BitcoinSLogger {
def onCompactFiltersReceived
: CallbackHandler[Vector[
@ -25,8 +33,6 @@ trait NodeCallbacks extends ModuleCallbacks[NodeCallbacks] with BitcoinSLogger {
def onTxReceived: CallbackHandler[Transaction, OnTxReceived]
def onBlockReceived: CallbackHandler[Block, OnBlockReceived]
def onMerkleBlockReceived: CallbackHandler[
(MerkleBlock, Vector[Transaction]),
OnMerkleBlockReceived
@ -47,7 +53,7 @@ trait NodeCallbacks extends ModuleCallbacks[NodeCallbacks] with BitcoinSLogger {
)
}
def executeOnBlockReceivedCallbacks(
override def executeOnBlockReceivedCallbacks(
block: Block
)(implicit ec: ExecutionContext): Future[Unit] = {
onBlockReceived.execute(
@ -101,9 +107,6 @@ trait NodeCallbacks extends ModuleCallbacks[NodeCallbacks] with BitcoinSLogger {
}
}
/** Callback for handling a received block */
trait OnBlockReceived extends Callback[Block]
/** Callback for handling a received Merkle block with its corresponding TXs */
trait OnMerkleBlockReceived extends Callback2[MerkleBlock, Vector[Transaction]]

View file

@ -11,12 +11,13 @@ import org.apache.pekko.stream.scaladsl.{
}
import org.bitcoins.commons.util.BitcoinSLogger
import org.bitcoins.core.api.CallbackHandler
import org.bitcoins.core.api.callback.OnBlockReceived
import org.bitcoins.core.gcs.GolombFilter
import org.bitcoins.core.protocol.blockchain.{Block, BlockHeader, MerkleBlock}
import org.bitcoins.core.protocol.transaction.Transaction
import org.bitcoins.core.util.StartStopAsync
import org.bitcoins.crypto.DoubleSha256DigestBE
import org.bitcoins.node._
import org.bitcoins.node.*
import java.util.concurrent.atomic.AtomicBoolean
import scala.concurrent.{ExecutionContext, Future}

View file

@ -18,7 +18,7 @@ import org.bitcoins.core.protocol.ln.channel.{
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
import org.bitcoins.core.protocol.ln.node.NodeId
import org.bitcoins.crypto.Sha256Digest
import org.bitcoins.eclair.rpc.api._
import org.bitcoins.eclair.rpc.api.*
import org.bitcoins.eclair.rpc.client.EclairRpcClient
import org.bitcoins.eclair.rpc.config.EclairInstanceLocal
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
@ -768,7 +768,7 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
authCredentials = auth.bitcoinAuthOpt.get,
binary = BitcoindRpcTestUtil.getBinary(bitcoindVersion)
)
BitcoindRpcClient.withActorSystem(bitcoindInstance)
BitcoindRpcClient(bitcoindInstance)
}
bitcoindRpc
}

View file

@ -2,9 +2,10 @@ package org.bitcoins.testkit.fixtures
import org.apache.pekko.actor.ActorSystem
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.config.BitcoindRpcAppConfig
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
import org.bitcoins.testkit.util.BitcoinSAsyncFixtureTest
import org.scalatest._
import org.scalatest.*
import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.util.{Failure, Success}
@ -125,9 +126,11 @@ object BitcoinSFixture {
versionOpt = versionOpt,
enableNeutrino = enableNeutrino
)
val appConfig = BitcoindRpcAppConfig.fromDatadir(instance.datadir.toPath)
val bitcoind = versionOpt match {
case Some(v) => BitcoindRpcClient.fromVersion(v, instance)
case None => new BitcoindRpcClient(instance)
case Some(v) =>
BitcoindRpcClient.fromVersion(v, instance)
case None => new BitcoindRpcClient(instance)(system, appConfig)
}
BitcoindRpcTestUtil.startServers(Vector(bitcoind)).map(_ => bitcoind)
}

View file

@ -618,10 +618,12 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
system: ActorSystem
): Future[(BitcoindRpcClient, BitcoindRpcClient)] = {
implicit val ec: ExecutionContextExecutor = system.getDispatcher
val instance1 = instance()
val instance2 = instance()
val client1: BitcoindRpcClient =
BitcoindRpcClient.withActorSystem(instance())
BitcoindRpcClient(instance1)
val client2: BitcoindRpcClient =
BitcoindRpcClient.withActorSystem(instance())
BitcoindRpcClient(instance2)
startServers(Vector(client1, client2)).map { _ =>
clientAccum ++= List(client1, client2)
@ -673,16 +675,17 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
val clients: Vector[T] = (0 until numNodes).map { _ =>
val rpc = version match {
case BitcoindVersion.Unknown =>
BitcoindRpcClient.withActorSystem(BitcoindRpcTestUtil.instance())
val instance = BitcoindRpcTestUtil.instance()
BitcoindRpcClient(instance)
case BitcoindVersion.V25 =>
BitcoindV25RpcClient.withActorSystem(
BitcoindRpcTestUtil.v25Instance())
val instance = BitcoindRpcTestUtil.v25Instance()
BitcoindV25RpcClient(instance)
case BitcoindVersion.V26 =>
BitcoindV26RpcClient.withActorSystem(
BitcoindRpcTestUtil.v26Instance())
val instance = BitcoindRpcTestUtil.v26Instance()
BitcoindV26RpcClient(instance)
case BitcoindVersion.V27 =>
BitcoindV27RpcClient.withActorSystem(
BitcoindRpcTestUtil.v27Instance())
val instance = BitcoindRpcTestUtil.v27Instance()
BitcoindV27RpcClient(instance)
}
// this is safe as long as this method is never
@ -1071,7 +1074,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
)
// start the bitcoind instance so eclair can properly use it
val rpc = BitcoindRpcClient.withActorSystem(instance)
val rpc = BitcoindRpcClient(instance)
val startedF = startServers(Vector(rpc))
val blocksToGenerate = 102