diff --git a/core/src/main/scala/org/bitcoins/core/bloom/BloomFilter.scala b/core/src/main/scala/org/bitcoins/core/bloom/BloomFilter.scala
index f70d71cf6e..e4479eb6aa 100644
--- a/core/src/main/scala/org/bitcoins/core/bloom/BloomFilter.scala
+++ b/core/src/main/scala/org/bitcoins/core/bloom/BloomFilter.scala
@@ -142,7 +142,8 @@ sealed abstract class BloomFilter extends NetworkElement {
/**
* Checks if the transaction's txid, or any of the constants in it's scriptPubKeys/scriptSigs match our BloomFilter
- * See [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#filter-matching-algorithm BIP37]]
+ *
+ * @see [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#filter-matching-algorithm BIP37]]
* for exact details on what is relevant to a bloom filter and what is not relevant
*/
def isRelevant(transaction: Transaction): Boolean = {
@@ -150,8 +151,9 @@ sealed abstract class BloomFilter extends NetworkElement {
//pull out all of the constants in the scriptPubKey's
val constantsWithOutputIndex = scriptPubKeys.zipWithIndex.flatMap {
case (scriptPubKey, index) =>
- val constants = scriptPubKey.asm.filter(_.isInstanceOf[ScriptConstant])
- constants.map(c => (c, index))
+ scriptPubKey.asm.collect {
+ case c: ScriptConstant => (c, index)
+ }
}
//check if the bloom filter contains any of the script constants in our outputs
@@ -162,8 +164,9 @@ sealed abstract class BloomFilter extends NetworkElement {
val scriptSigs = transaction.inputs.map(_.scriptSignature)
val constantsWithInputIndex = scriptSigs.zipWithIndex.flatMap {
case (scriptSig, index) =>
- val constants = scriptSig.asm.filter(_.isInstanceOf[ScriptConstant])
- constants.map(c => (c, index))
+ scriptSig.asm.collect {
+ case c: ScriptConstant => (c, index)
+ }
}
//check if the filter contains any of the prevouts in this tx
val containsOutPoint =
@@ -180,7 +183,8 @@ sealed abstract class BloomFilter extends NetworkElement {
/**
* Updates this bloom filter to contain the relevant information for the given Transaction
- * See [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#filter-matching-algorithm BIP37]]
+ *
+ * @see [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#filter-matching-algorithm BIP37]]
* for the exact details on what parts of a transaction is added to the bloom filter
*/
def update(transaction: Transaction): BloomFilter = flags match {
@@ -190,12 +194,11 @@ sealed abstract class BloomFilter extends NetworkElement {
val outPoints: Seq[TransactionOutPoint] =
scriptPubKeys.zipWithIndex.flatMap {
case (scriptPubKey, index) =>
- //constants that matched inside of our current filter
- val constants = scriptPubKey.asm.filter(c =>
- c.isInstanceOf[ScriptConstant] && contains(c.bytes))
- //we need to create a new outpoint in the filter if a constant in the scriptPubKey matched
- constants.map(_ =>
- TransactionOutPoint(transaction.txId, UInt32(index)))
+ // we filter all constants, and create an outpoint if the constant matches our filter
+ scriptPubKey.asm.collect {
+ case c: ScriptConstant if contains(c.bytes) =>
+ TransactionOutPoint(transaction.txId, UInt32(index))
+ }
}
logger.debug("Inserting outPoints: " + outPoints)
@@ -221,7 +224,8 @@ sealed abstract class BloomFilter extends NetworkElement {
/**
* Updates a bloom filter according to the rules specified by the
* [[org.bitcoins.core.bloom.BloomUpdateP2PKOnly BloomUpdateP2PKOnly]] flag
- * See [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#filter-matching-algorithm BIP37]]
+ *
+ * @see [[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#filter-matching-algorithm BIP37]]
* for the exact rules on updating a bloom filter with this flag set
*/
def updateP2PKOnly(
diff --git a/core/src/main/scala/org/bitcoins/core/p2p/Inventory.scala b/core/src/main/scala/org/bitcoins/core/p2p/Inventory.scala
index c88897111d..b16dc1ca5e 100644
--- a/core/src/main/scala/org/bitcoins/core/p2p/Inventory.scala
+++ b/core/src/main/scala/org/bitcoins/core/p2p/Inventory.scala
@@ -25,6 +25,8 @@ trait Inventory extends NetworkElement {
def hash: DoubleSha256Digest
override def bytes: ByteVector = RawInventorySerializer.write(this)
+
+ override def toString(): String = s"Inventory($typeIdentifier, $hash)"
}
object Inventory extends Factory[Inventory] {
@@ -43,6 +45,3 @@ object Inventory extends Factory[Inventory] {
InventoryImpl(typeIdentifier, hash)
}
}
-
-
-
diff --git a/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala b/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala
index 172edd92ff..6717e1f2aa 100644
--- a/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala
+++ b/core/src/main/scala/org/bitcoins/core/p2p/NetworkPayload.scala
@@ -327,6 +327,18 @@ trait InventoryMessage extends DataPayload {
override def commandName = NetworkPayload.invCommandName
override def bytes: ByteVector = RawInventoryMessageSerializer.write(this)
+
+ override def toString(): String = {
+ val invCount = inventoryCount.toInt
+ val limit = 5
+ val invList = if (invCount > limit) {
+ inventories.take(limit).mkString + "..."
+ } else {
+ inventories.mkString
+ }
+ s"InventoryMessage($invCount inv(s)${if (invList.nonEmpty) ", " + invList
+ else ""})"
+ }
}
/**
@@ -453,8 +465,11 @@ trait TransactionMessage extends DataPayload {
* The transaction being sent over the wire
*/
def transaction: Transaction
+
override def commandName = NetworkPayload.transactionCommandName
override def bytes: ByteVector = RawTransactionMessageSerializer.write(this)
+
+ override def toString(): String = s"TransactionMessage(${transaction.txIdBE})"
}
/**
diff --git a/core/src/test/resources/common-logback.xml b/core/src/test/resources/common-logback.xml
index 2ae8f82657..1272cb05b1 100644
--- a/core/src/test/resources/common-logback.xml
+++ b/core/src/test/resources/common-logback.xml
@@ -34,6 +34,9 @@
+
+
+
diff --git a/node-test/src/test/scala/org/bitcoins/node/NodeWithWalletTest.scala b/node-test/src/test/scala/org/bitcoins/node/NodeWithWalletTest.scala
new file mode 100644
index 0000000000..551d98f315
--- /dev/null
+++ b/node-test/src/test/scala/org/bitcoins/node/NodeWithWalletTest.scala
@@ -0,0 +1,143 @@
+package org.bitcoins.node
+
+import org.bitcoins.core.currency._
+import org.bitcoins.chain.blockchain.ChainHandler
+import org.bitcoins.chain.config.ChainAppConfig
+import org.bitcoins.chain.models.BlockHeaderDAO
+import org.bitcoins.node.config.NodeAppConfig
+import org.bitcoins.node.models.Peer
+import org.scalatest.FutureOutcome
+import org.bitcoins.testkit.BitcoinSAppConfig
+import org.bitcoins.wallet.config.WalletAppConfig
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
+
+import scala.concurrent.Future
+import org.bitcoins.node.networking.peer.DataMessageHandler
+import scala.concurrent.Promise
+import scala.concurrent.duration._
+import org.scalatest.compatible.Assertion
+import org.scalatest.exceptions.TestFailedException
+import org.bitcoins.core.crypto.DoubleSha256Digest
+import org.bitcoins.rpc.util.AsyncUtil
+import org.bitcoins.testkit.node.NodeTestUtil
+import akka.actor.Cancellable
+import org.bitcoins.core.protocol.transaction.Transaction
+import org.bitcoins.core.crypto.DoubleSha256DigestBE
+
+class NodeWithWalletTest extends BitcoinSWalletTest {
+
+ override type FixtureParam = WalletWithBitcoind
+
+ def withFixture(test: OneArgAsyncTest): FutureOutcome =
+ withNewWalletAndBitcoind(test)
+
+ it must "load a bloom filter and receive information about received payments" in {
+ param =>
+ val WalletWithBitcoind(wallet, rpc) = param
+
+ /**
+ * This is not ideal, how do we get one implicit value (`config`)
+ * to resolve to multiple implicit parameters?
+ */
+ implicit val nodeConfig: NodeAppConfig = config
+ implicit val chainConfig: ChainAppConfig = config
+
+ var expectedTxId: Option[DoubleSha256Digest] = None
+ var unexpectedTxId: Option[DoubleSha256Digest] = None
+ var cancellable: Option[Cancellable] = None
+
+ val completionP = Promise[Assertion]
+
+ val callbacks = {
+ val onBlock: DataMessageHandler.OnBlockReceived = { block =>
+ completionP.failure(
+ new TestFailedException(
+ s"Received a block! We are only expecting merkle blocks",
+ failedCodeStackDepth = 0))
+ }
+
+ val onTx: DataMessageHandler.OnTxReceived = { tx =>
+ if (expectedTxId.contains(tx.txId)) {
+ cancellable.map(_.cancel())
+ completionP.success(succeed)
+ } else if (unexpectedTxId.contains(tx.txId)) {
+ completionP.failure(
+ new TestFailedException(
+ s"Got ${tx.txId}, which is a TX we expect to NOT get notified about!",
+ failedCodeStackDepth = 0))
+ } else {
+ logger.info(s"Didn't match expected TX or unexpected TX")
+ }
+ }
+
+ SpvNodeCallbacks(
+ onBlockReceived = Seq(onBlock),
+ onTxReceived = Seq(onTx)
+ )
+ }
+
+ def processWalletTx(tx: DoubleSha256DigestBE) = {
+ expectedTxId = Some(tx.flip)
+ // how long we're waiting for a tx notify before failing the test
+ val delay = 15.seconds
+ val runnable: Runnable = new Runnable {
+ override def run = {
+ val msg =
+ s"Did not receive sent transaction within $delay"
+ logger.error(msg)
+ completionP.failure(new TestFailedException(msg, 0))
+ }
+ }
+
+ cancellable = Some(actorSystem.scheduler.scheduleOnce(delay, runnable))
+ tx
+ }
+
+ for {
+ _ <- config.initialize()
+
+ address <- wallet.getNewAddress()
+ bloom <- wallet.getBloomFilter()
+
+ spv <- {
+ val peer = Peer.fromBitcoind(rpc.instance)
+ val chainHandler = {
+ val bhDao = BlockHeaderDAO()
+ ChainHandler(bhDao, config)
+ }
+
+ val spv =
+ SpvNode(peer,
+ chainHandler,
+ bloomFilter = bloom,
+ callbacks = callbacks)
+ spv.start()
+ }
+ _ <- spv.sync()
+ _ <- NodeTestUtil.awaitSync(spv, rpc)
+
+ ourTxid <- rpc.sendToAddress(address, 1.bitcoin).map(processWalletTx)
+
+ notOurTxid <- rpc.getNewAddress
+ .flatMap(rpc.sendToAddress(_, 1.bitcoin))
+ .map { tx =>
+ // we're generating a TX from bitcoind that should _not_ trigger
+ // our bloom filter, and not get sent to us. if it gets sent to
+ // us we fail the test
+ unexpectedTxId = Some(tx.flip)
+ tx
+ }
+
+ ourTx <- rpc.getTransaction(ourTxid)
+ notOurTx <- rpc.getTransaction(notOurTxid)
+
+ assertion <- {
+ assert(bloom.isRelevant(ourTx.hex))
+ assert(!bloom.isRelevant(notOurTx.hex))
+
+ completionP.future
+ }
+ } yield assertion
+
+ }
+}
diff --git a/node-test/src/test/scala/org/bitcoins/node/SpvNodeTest.scala b/node-test/src/test/scala/org/bitcoins/node/SpvNodeTest.scala
index cb199414c7..d503d98684 100644
--- a/node-test/src/test/scala/org/bitcoins/node/SpvNodeTest.scala
+++ b/node-test/src/test/scala/org/bitcoins/node/SpvNodeTest.scala
@@ -7,6 +7,7 @@ import org.bitcoins.testkit.node.fixture.SpvNodeConnectedWithBitcoind
import org.scalatest.FutureOutcome
import scala.concurrent.Future
+import org.bitcoins.testkit.node.NodeTestUtil
class SpvNodeTest extends NodeUnitTest {
@@ -36,16 +37,9 @@ class SpvNodeTest extends NodeUnitTest {
sync <- spvNode.sync()
} yield sync
- def isSameBestHash(): Future[Boolean] = {
- for {
- spvBestHash <- spvNode.chainApi.getBestBlockHash
- hash <- hashF
- } yield spvBestHash == hash
- }
-
spvSyncF.flatMap { _ =>
- RpcUtil
- .retryUntilSatisfiedF(isSameBestHash)
+ NodeTestUtil
+ .awaitSync(spvNode, bitcoind)
.map(_ => succeed)
}
diff --git a/node/src/main/scala/org/bitcoins/node/Main.scala b/node/src/main/scala/org/bitcoins/node/Main.scala
index 0361f69ec0..3d2fe149ba 100644
--- a/node/src/main/scala/org/bitcoins/node/Main.scala
+++ b/node/src/main/scala/org/bitcoins/node/Main.scala
@@ -39,7 +39,7 @@ object Main extends App with BitcoinSLogger {
val peer = Peer(nip)
logger.info(s"Starting spv node")
- val spvNodeF = SpvNode(peer, chainApi).start()
+ val spvNodeF = SpvNode(peer, chainApi, bloomFilter = ???).start()
logger.info(s"Starting SPV node sync")
spvNodeF.map { spvNode =>
diff --git a/node/src/main/scala/org/bitcoins/node/SpvNode.scala b/node/src/main/scala/org/bitcoins/node/SpvNode.scala
index 91a3f41748..39a3fa4b6a 100644
--- a/node/src/main/scala/org/bitcoins/node/SpvNode.scala
+++ b/node/src/main/scala/org/bitcoins/node/SpvNode.scala
@@ -15,8 +15,16 @@ import org.bitcoins.node.networking.peer.{
import org.bitcoins.rpc.util.AsyncUtil
import scala.concurrent.Future
+import org.bitcoins.core.bloom.BloomFilter
+import org.bitcoins.core.p2p.FilterLoadMessage
+import org.bitcoins.core.p2p.NetworkPayload
-case class SpvNode(peer: Peer, chainApi: ChainApi)(
+case class SpvNode(
+ peer: Peer,
+ chainApi: ChainApi,
+ bloomFilter: BloomFilter,
+ callbacks: SpvNodeCallbacks = SpvNodeCallbacks.empty
+)(
implicit system: ActorSystem,
nodeAppConfig: NodeAppConfig,
chainAppConfig: ChainAppConfig)
@@ -24,7 +32,7 @@ case class SpvNode(peer: Peer, chainApi: ChainApi)(
import system.dispatcher
private val peerMsgRecv =
- PeerMessageReceiver.newReceiver
+ PeerMessageReceiver.newReceiver(callbacks)
private val client: Client =
Client(context = system, peer = peer, peerMessageReceiver = peerMsgRecv)
@@ -33,6 +41,16 @@ case class SpvNode(peer: Peer, chainApi: ChainApi)(
PeerMessageSender(client, nodeAppConfig.network)
}
+ /**
+ * Sends the given P2P to our peer.
+ * This method is useful for playing around
+ * with P2P messages, therefore marked as
+ * `private[node]`.
+ */
+ private[node] def send(msg: NetworkPayload): Unit = {
+ peerMsgSender.sendMsg(msg)
+ }
+
/** Starts our spv node */
def start(): Future[SpvNode] = {
for {
@@ -51,8 +69,12 @@ case class SpvNode(peer: Peer, chainApi: ChainApi)(
this
}
}
-
- } yield node
+ } yield {
+ logger.info(s"Sending bloomfilter=${bloomFilter.hex} to $peer")
+ val filterMsg = FilterLoadMessage(bloomFilter)
+ val _ = send(filterMsg)
+ node
+ }
}
/** Stops our spv node */
diff --git a/node/src/main/scala/org/bitcoins/node/SpvNodeCallbacks.scala b/node/src/main/scala/org/bitcoins/node/SpvNodeCallbacks.scala
new file mode 100644
index 0000000000..ec9ce11647
--- /dev/null
+++ b/node/src/main/scala/org/bitcoins/node/SpvNodeCallbacks.scala
@@ -0,0 +1,26 @@
+package org.bitcoins.node
+
+import org.bitcoins.node.networking.peer.DataMessageHandler._
+
+/**
+ * Callbacks for responding to events in the SPV node.
+ * The approriate callback is executed whenver the node receives
+ * a `getdata` message matching it.
+ *
+ */
+case class SpvNodeCallbacks(
+ onTxReceived: Seq[OnTxReceived] = Seq.empty,
+ onBlockReceived: Seq[OnBlockReceived] = Seq.empty,
+ onMerkleBlockReceived: Seq[OnMerkleBlockReceived] = Seq.empty
+)
+
+object SpvNodeCallbacks {
+
+ /** Empty callbacks that does nothing with the received data */
+ val empty: SpvNodeCallbacks =
+ SpvNodeCallbacks(
+ onTxReceived = Seq.empty,
+ onBlockReceived = Seq.empty,
+ onMerkleBlockReceived = Seq.empty
+ )
+}
diff --git a/node/src/main/scala/org/bitcoins/node/models/Peer.scala b/node/src/main/scala/org/bitcoins/node/models/Peer.scala
index b27fef26a0..c699f268d7 100644
--- a/node/src/main/scala/org/bitcoins/node/models/Peer.scala
+++ b/node/src/main/scala/org/bitcoins/node/models/Peer.scala
@@ -4,6 +4,7 @@ import java.net.InetSocketAddress
import org.bitcoins.core.p2p.NetworkIpAddress
import org.bitcoins.db.DbRowAutoInc
+import org.bitcoins.rpc.config.BitcoindInstance
case class Peer(networkIpAddress: NetworkIpAddress, id: Option[Long] = None)
extends DbRowAutoInc[Peer] {
@@ -15,6 +16,9 @@ case class Peer(networkIpAddress: NetworkIpAddress, id: Option[Long] = None)
this.copy(id = Some(id))
}
+ override def toString(): String =
+ s"Peer(${networkIpAddress.address}:${networkIpAddress.port})"
+
}
object Peer {
@@ -27,4 +31,12 @@ object Peer {
val nip = NetworkIpAddress.fromInetSocketAddress(socket = socket)
fromNetworkIpAddress(nip)
}
+
+ /**
+ * Constructs a peer from the given `bitcoind` instance
+ */
+ def fromBitcoind(bitcoind: BitcoindInstance): Peer = {
+ val socket = new InetSocketAddress(bitcoind.uri.getHost, bitcoind.p2pPort)
+ fromSocket(socket)
+ }
}
diff --git a/node/src/main/scala/org/bitcoins/node/networking/peer/DataMessageHandler.scala b/node/src/main/scala/org/bitcoins/node/networking/peer/DataMessageHandler.scala
index 0788c79b27..45035bd67b 100644
--- a/node/src/main/scala/org/bitcoins/node/networking/peer/DataMessageHandler.scala
+++ b/node/src/main/scala/org/bitcoins/node/networking/peer/DataMessageHandler.scala
@@ -5,28 +5,36 @@ import org.bitcoins.chain.blockchain.ChainHandler
import org.bitcoins.chain.config.ChainAppConfig
import org.bitcoins.chain.models.BlockHeaderDAO
import org.bitcoins.core.util.{BitcoinSLogger, FutureUtil}
-import org.bitcoins.core.p2p.{
- DataPayload,
- HeadersMessage,
- InventoryMessage
-}
+import org.bitcoins.core.p2p.{DataPayload, HeadersMessage, InventoryMessage}
import scala.concurrent.{ExecutionContext, Future}
+import org.bitcoins.core.protocol.blockchain.Block
+import org.bitcoins.core.protocol.blockchain.MerkleBlock
+import org.bitcoins.core.protocol.transaction.Transaction
+import org.bitcoins.core.p2p.BlockMessage
+import org.bitcoins.core.p2p.TransactionMessage
+import org.bitcoins.core.p2p.MerkleBlockMessage
+import org.bitcoins.node.SpvNodeCallbacks
+import org.bitcoins.core.p2p.GetDataMessage
/** This actor is meant to handle a [[org.bitcoins.node.messages.DataPayload]]
* that a peer to sent to us on the p2p network, for instance, if we a receive a
* [[HeadersMessage]] we should store those headers in our database
*/
-class DataMessageHandler()(
+class DataMessageHandler(callbacks: SpvNodeCallbacks)(
implicit ec: ExecutionContext,
appConfig: ChainAppConfig)
extends BitcoinSLogger {
+ val callbackNum = callbacks.onBlockReceived.length + callbacks.onMerkleBlockReceived.length + callbacks.onTxReceived.length
+ logger.debug(s"Given $callbackNum of callback(s)")
+
private val blockHeaderDAO: BlockHeaderDAO = BlockHeaderDAO()
def handleDataPayload(
payload: DataPayload,
peerMsgSender: PeerMessageSender): Future[Unit] = {
+
payload match {
case headersMsg: HeadersMessage =>
val headers = headersMsg.headers
@@ -38,6 +46,14 @@ class DataMessageHandler()(
val lastHash = headers.last.hash
peerMsgSender.sendGetHeadersMessage(lastHash)
}
+ case msg: BlockMessage =>
+ Future { callbacks.onBlockReceived.foreach(_.apply(msg.block)) }
+ case msg: TransactionMessage =>
+ Future { callbacks.onTxReceived.foreach(_.apply(msg.transaction)) }
+ case msg: MerkleBlockMessage =>
+ Future {
+ callbacks.onMerkleBlockReceived.foreach(_.apply(msg.merkleBlock))
+ }
case invMsg: InventoryMessage =>
handleInventoryMsg(invMsg = invMsg, peerMsgSender = peerMsgSender)
}
@@ -47,8 +63,25 @@ class DataMessageHandler()(
invMsg: InventoryMessage,
peerMsgSender: PeerMessageSender): Future[Unit] = {
logger.info(s"Received inv=${invMsg}")
-
+ val getData = GetDataMessage(invMsg.inventories)
+ peerMsgSender.sendMsg(getData)
FutureUtil.unit
}
}
+
+object DataMessageHandler {
+
+ /** Callback for handling a received block */
+ type OnBlockReceived = Block => Unit
+
+ /** Callback for handling a received Merkle block */
+ type OnMerkleBlockReceived = MerkleBlock => Unit
+
+ /** Callback for handling a received transaction */
+ type OnTxReceived = Transaction => Unit
+
+ /** Does nothing */
+ def noop[T]: T => Unit = _ => ()
+
+}
diff --git a/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageReceiver.scala b/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageReceiver.scala
index 55eecbec60..eedd37a586 100644
--- a/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageReceiver.scala
+++ b/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageReceiver.scala
@@ -8,9 +8,15 @@ import org.bitcoins.node.config.NodeAppConfig
import org.bitcoins.core.p2p._
import org.bitcoins.node.models.Peer
import org.bitcoins.node.networking.Client
-import org.bitcoins.node.networking.peer.PeerMessageReceiverState.{Disconnected, Initializing, Normal, Preconnection}
+import org.bitcoins.node.networking.peer.PeerMessageReceiverState.{
+ Disconnected,
+ Initializing,
+ Normal,
+ Preconnection
+}
import scala.util.{Failure, Success, Try}
+import org.bitcoins.node.SpvNodeCallbacks
/**
* Responsible for receiving messages from a peer on the
@@ -21,13 +27,13 @@ import scala.util.{Failure, Success, Try}
*/
class PeerMessageReceiver(
state: PeerMessageReceiverState,
+ callbacks: SpvNodeCallbacks
+)(
+ implicit ref: ActorRefFactory,
nodeAppConfig: NodeAppConfig,
- chainAppConfig: ChainAppConfig)(implicit ref: ActorRefFactory)
+ chainAppConfig: ChainAppConfig)
extends BitcoinSLogger {
- implicit private val nodeConfig = nodeAppConfig
- implicit private val chainConfig = chainAppConfig
-
import ref.dispatcher
//TODO: Really bad to just modify this internal state
@@ -107,13 +113,13 @@ class PeerMessageReceiver(
def handleNetworkMessageReceived(
networkMsgRecv: PeerMessageReceiver.NetworkMessageReceived): Unit = {
- //create a way to send a response if we need too
- val peerMsgSender =
- PeerMessageSender(networkMsgRecv.client, chainAppConfig.network)
+ val client = networkMsgRecv.client
- logger.info(
- s"Received message=${networkMsgRecv.msg.header.commandName} from peer=${peerOpt
- .map(_.socket)} ")
+ //create a way to send a response if we need too
+ val peerMsgSender = PeerMessageSender(client, chainAppConfig.network)
+
+ logger.debug(
+ s"Received message=${networkMsgRecv.msg.header.commandName} from peer=${client.peer} ")
networkMsgRecv.msg.payload match {
case controlPayload: ControlPayload =>
handleControlPayload(payload = controlPayload, sender = peerMsgSender)
@@ -134,7 +140,7 @@ class PeerMessageReceiver(
private def handleDataPayload(
payload: DataPayload,
sender: PeerMessageSender): Unit = {
- val dataMsgHandler = new DataMessageHandler()
+ val dataMsgHandler = new DataMessageHandler(callbacks)
//else it means we are receiving this data payload from a peer,
//we need to handle it
dataMsgHandler.handleDataPayload(payload, sender)
@@ -225,20 +231,20 @@ object PeerMessageReceiver {
case class NetworkMessageReceived(msg: NetworkMessage, client: Client)
extends PeerMessageReceiverMsg
- def apply(state: PeerMessageReceiverState)(
+ def apply(
+ state: PeerMessageReceiverState,
+ callbacks: SpvNodeCallbacks = SpvNodeCallbacks.empty)(
implicit ref: ActorRefFactory,
nodeAppConfig: NodeAppConfig,
chainAppConfig: ChainAppConfig
): PeerMessageReceiver = {
- new PeerMessageReceiver(state, nodeAppConfig, chainAppConfig)(ref)
+ new PeerMessageReceiver(state, callbacks)
}
- def newReceiver(
+ def newReceiver(callbacks: SpvNodeCallbacks = SpvNodeCallbacks.empty)(
implicit nodeAppConfig: NodeAppConfig,
chainAppConfig: ChainAppConfig,
ref: ActorRefFactory): PeerMessageReceiver = {
- new PeerMessageReceiver(state = PeerMessageReceiverState.fresh(),
- nodeAppConfig,
- chainAppConfig)(ref)
+ new PeerMessageReceiver(state = PeerMessageReceiverState.fresh(), callbacks)
}
}
diff --git a/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageSender.scala b/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageSender.scala
index 33fadb054c..b80a71cfc8 100644
--- a/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageSender.scala
+++ b/node/src/main/scala/org/bitcoins/node/networking/peer/PeerMessageSender.scala
@@ -9,24 +9,17 @@ import org.bitcoins.core.util.BitcoinSLogger
import org.bitcoins.core.p2p._
import org.bitcoins.node.networking.Client
-/**
- * Created by chris on 6/7/16.
- * This actor is the middle man between our [[Client]] and higher level actors such as
- * [[org.bitcoins.node.networking.BlockActor]]. When it receives a message, it tells [[Client]] to create connection to a peer,
- * then it exchanges [[VersionMessage]], [[VerAckMessage]] and [[org.bitcoins.node.messages.PingMessage]]/[[PongMessage]] message
- * with our peer on the network. When the Client finally responds to the [[NetworkMessage]] we originally
- * sent it sends that [[NetworkMessage]] back to the actor that requested it.
- */
class PeerMessageSender(client: Client)(implicit np: NetworkParameters)
extends BitcoinSLogger {
private val socket = client.peer.socket
- /** Initiates a connection with the given [[Peer]] */
+ /** Initiates a connection with the given peer */
def connect(): Unit = {
logger.info(s"Attempting to connect to peer=$socket")
(client.actor ! Tcp.Connect(socket))
}
+ /** Disconnects the given peer */
def disconnect(): Unit = {
logger.info(s"Disconnecting peer at socket=${socket}")
(client.actor ! Tcp.Close)
@@ -53,7 +46,7 @@ class PeerMessageSender(client: Client)(implicit np: NetworkParameters)
sendMsg(sendHeadersMsg)
}
- private def sendMsg(msg: NetworkPayload): Unit = {
+ private[node] def sendMsg(msg: NetworkPayload): Unit = {
logger.debug(
s"PeerMessageSender sending to peer=${socket} msg=${msg.commandName}")
val newtworkMsg = NetworkMessage(np, msg)
@@ -80,9 +73,6 @@ object PeerMessageSender {
/** Accumulators network messages while we are doing a handshake with our peer
* and caches a peer handler actor so we can send a [[HandshakeFinished]]
* message back to the actor when we are fully connected
- *
- * @param networkMsgs
- * @param peerHandler
*/
case class MessageAccumulator(
networkMsgs: Vector[(ActorRef, NetworkMessage)],
diff --git a/project/Deps.scala b/project/Deps.scala
index d75bb919cd..3fc205e2b2 100644
--- a/project/Deps.scala
+++ b/project/Deps.scala
@@ -191,6 +191,7 @@ object Deps {
Compile.slf4j,
Compile.scalacheck,
Compile.scalaTest,
+ Test.akkaTestkit,
Test.ammonite
)
diff --git a/testkit/src/main/scala/org/bitcoins/testkit/BitcoinSAppConfig.scala b/testkit/src/main/scala/org/bitcoins/testkit/BitcoinSAppConfig.scala
index b9a016061f..543e9de52f 100644
--- a/testkit/src/main/scala/org/bitcoins/testkit/BitcoinSAppConfig.scala
+++ b/testkit/src/main/scala/org/bitcoins/testkit/BitcoinSAppConfig.scala
@@ -16,7 +16,7 @@ import com.typesafe.config.ConfigFactory
* of this class can be passed in anywhere a wallet,
* chain or node config is required.
*/
-case class BitcoinSAppConfig(confs: Config*) {
+case class BitcoinSAppConfig(private val confs: Config*) {
val walletConf = WalletAppConfig(confs: _*)
val nodeConf = NodeAppConfig(confs: _*)
val chainConf = ChainAppConfig(confs: _*)
@@ -29,6 +29,16 @@ case class BitcoinSAppConfig(confs: Config*) {
Future.sequence(futures).map(_ => ())
}
+
+ /** The underlying config the result of our fields derive from */
+ lazy val config = {
+ assert(chainConf.config == nodeConf.config)
+ assert(nodeConf.config == walletConf.config)
+
+ // there's nothing special about nodeConf, they should all
+ // be equal
+ nodeConf.config
+ }
}
/**
diff --git a/testkit/src/main/scala/org/bitcoins/testkit/node/NodeTestUtil.scala b/testkit/src/main/scala/org/bitcoins/testkit/node/NodeTestUtil.scala
index d0c89d6cb1..2f806ea0dc 100644
--- a/testkit/src/main/scala/org/bitcoins/testkit/node/NodeTestUtil.scala
+++ b/testkit/src/main/scala/org/bitcoins/testkit/node/NodeTestUtil.scala
@@ -13,11 +13,17 @@ import org.bitcoins.node.models.Peer
import org.bitcoins.node.networking.Client
import org.bitcoins.node.networking.peer.PeerMessageReceiver
import org.bitcoins.rpc.client.common.BitcoindRpcClient
+import org.bitcoins.node.SpvNode
+import scala.concurrent.Future
+import scala.concurrent.ExecutionContext
+import scala.concurrent.duration._
+import akka.actor.ActorSystem
+import org.bitcoins.core.util.BitcoinSLogger
+import org.bitcoins.rpc.util.AsyncUtil
+import org.bitcoins.core.bloom.BloomFilter
+import org.bitcoins.core.bloom.BloomUpdateAll
-/**
- * Created by chris on 6/2/16.
- */
-abstract class NodeTestUtil {
+abstract class NodeTestUtil extends BitcoinSLogger {
//txid on testnet 44e504f5b7649d215be05ad9f09026dee95201244a3b218013c504a6a49a26ff
//this tx has multiple inputs and outputs
@@ -54,6 +60,9 @@ abstract class NodeTestUtil {
"721101001f693a1ceb6eabcd03f7f7e22a763efec0f4fd1618a50558283b23600000000000e933b17e7f39aa00f24cabbae1e618ecbfbd70a3ecc4f63072dc790000000000e53160d1edccfd7feed401233c274fbc229f7f0d2b6152735344ec0000000000110274616c7161a8aca8390e1a472f22de7470368e5066f20d050000000000008f98d517947a765069f976de05f910a65743fbac59a430aaf30d350000000000572b328dc2155a853157bebcc616fc82fd6996cb348d6a3cd929c500000000007d2c3eca25e06b684132325c85673675b928c3d0ee2eec553c01000000000000a5e239f5b4c6998078e71a065bd71216583e88bf80a93d170253460000000000b6c926f4cb309d2d87f40d4790905f3f29cd05f3ea26854e060700000000000032668e2de62f181cdeabad351318008288993b3db3e411216aad70000000000079f9e80a6ffe62ab13daa65e6410c8d36d513e198fc161b90cd1d40000000000bbf6a01b2faeb102d177ab03131263166790548181ff3cb04308000000000000b90ef011e62cd6c259939ac4ad372c5f395718a93ade933fd5503b0000000000f346a56f2fa278919c40cdde7ea424058543ce2237f6c9df174e2300000000002fd1795f0dbbc70f7a41d369d4b89c56bf1c6cf2c43ef8f8ed00000000000000643a31c93787ab66b51a4ccfc2ce867d855f4ad64b2a3136e1a12d00000000001323867c8b11027eac79e0cc71fce91f24b1066c6423e69ec409000000000000d1eb1916bab3839da423f1e5aa1c271204bd5564bac6fefd498e0f0000000000a4dcf02c42a71b5b10433917dda89a0d34984a065c0b05a52d03000000000000c57477df9128ef4f71366c4a89e432445d94b0c2b02e7a9ccb060000000000004c45281d6afa17835d264cc8ba181b8c51501247c128d644e2000000000000005c6d201f400a544250bae463ff28f47d53f32d97ae27b5b73b5f580000000000b1def34939f027654943457d69e104304c9798c0af837a7e1f1500000000000069164c8213a0d6b38fe1d9a2c63bcfb5808b65f6e50376726a120000000000002893d0fdafe84e3670a31b22ba80edfb841746462417bad024ac5e0000000000063015920d27befb9ff25f9a1989cda07e4ce62fa9ac8ec0f5b401000000000040a936762fbde4b51bea3ad59dfe202f16dd220761235172960c000000000000332d487a5cc80c00296c43c5bec6b6b1a41a499ce2efd6b6d8514b00000000009400a26083d0551175374c45746488d1c9eaea8d891e69f2e57c5712000000005d62facd94114f5ee55ab6e6797a5c6a8d0e0626b9200ffdf647f15c0000000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000000000000000000000000000000000000000000000000000000000000000000000"
def getHeadersMsg = GetHeadersMessage(rawGetHeadersMsg)
+ val emptyBloomFilter: BloomFilter =
+ BloomFilter(numElements = 1, falsePositiveRate = 1, flags = BloomUpdateAll)
+
/** These are the first 5 block headers on testnet, this does NOT include the genesis block header */
lazy val firstFiveTestNetBlockHeaders: List[BlockHeader] = {
List(
@@ -95,6 +104,27 @@ abstract class NodeTestUtil {
Peer.fromNetworkIpAddress(networkIpAddress)
}
+ /** Checks if the given SPV node and bitcoind is synced */
+ def isSameBestHash(node: SpvNode, rpc: BitcoindRpcClient)(
+ implicit ec: ExecutionContext): Future[Boolean] = {
+ val hashF = rpc.getBestBlockHash
+ val spvHashF = node.chainApi.getBestBlockHash
+ for {
+ spvBestHash <- spvHashF
+ hash <- hashF
+ } yield {
+ spvBestHash == hash
+ }
+ }
+
+ /** Awaits sync between the given SPV node and bitcoind client */
+ def awaitSync(node: SpvNode, rpc: BitcoindRpcClient)(
+ implicit sys: ActorSystem): Future[Unit] = {
+ import sys.dispatcher
+ AsyncUtil
+ .retryUntilSatisfiedF(() => isSameBestHash(node, rpc), 500.milliseconds)
+ }
+
}
object NodeTestUtil extends NodeTestUtil
diff --git a/testkit/src/main/scala/org/bitcoins/testkit/node/NodeUnitTest.scala b/testkit/src/main/scala/org/bitcoins/testkit/node/NodeUnitTest.scala
index 3e90336b69..949ef8a0ba 100644
--- a/testkit/src/main/scala/org/bitcoins/testkit/node/NodeUnitTest.scala
+++ b/testkit/src/main/scala/org/bitcoins/testkit/node/NodeUnitTest.scala
@@ -9,13 +9,22 @@ import org.bitcoins.core.util.BitcoinSLogger
import org.bitcoins.db.AppConfig
import org.bitcoins.node.SpvNode
import org.bitcoins.node.models.Peer
-import org.bitcoins.node.networking.peer.{PeerHandler, PeerMessageReceiver, PeerMessageSender}
+import org.bitcoins.node.networking.peer.{
+ PeerHandler,
+ PeerMessageReceiver,
+ PeerMessageSender
+}
import org.bitcoins.rpc.client.common.BitcoindRpcClient
import org.bitcoins.testkit.chain.ChainUnitTest
import org.bitcoins.testkit.fixtures.BitcoinSFixture
import org.bitcoins.testkit.node.fixture.SpvNodeConnectedWithBitcoind
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
-import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll, FutureOutcome, MustMatchers}
+import org.scalatest.{
+ BeforeAndAfter,
+ BeforeAndAfterAll,
+ FutureOutcome,
+ MustMatchers
+}
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
@@ -60,7 +69,7 @@ trait NodeUnitTest
def buildPeerMessageReceiver(): PeerMessageReceiver = {
val receiver =
- PeerMessageReceiver.newReceiver
+ PeerMessageReceiver.newReceiver()
receiver
}
@@ -95,7 +104,10 @@ trait NodeUnitTest
val peer = createPeer(bitcoind)
for {
chainApi <- chainApiF
- } yield SpvNode(peer = peer, chainApi = chainApi)
+ } yield
+ SpvNode(peer = peer,
+ chainApi = chainApi,
+ bloomFilter = NodeTestUtil.emptyBloomFilter)
}
def withSpvNode(test: OneArgAsyncTest)(
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/util/BitcoinSWalletTest.scala b/testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala
similarity index 96%
rename from wallet-test/src/test/scala/org/bitcoins/wallet/util/BitcoinSWalletTest.scala
rename to testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala
index 26c7398fdd..7f72ab32fe 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/util/BitcoinSWalletTest.scala
+++ b/testkit/src/main/scala/org/bitcoins/testkit/wallet/BitcoinSWalletTest.scala
@@ -1,9 +1,8 @@
-package org.bitcoins.wallet.util
+package org.bitcoins.testkit.wallet
import akka.actor.ActorSystem
import akka.testkit.TestKit
import org.bitcoins.core.config.RegTest
-import org.bitcoins.core.crypto.MnemonicCode
import org.bitcoins.core.protocol.blockchain.ChainParams
import org.bitcoins.core.util.BitcoinSLogger
import org.bitcoins.rpc.client.common.BitcoindRpcClient
@@ -14,7 +13,6 @@ import org.bitcoins.wallet.api.{
InitializeWalletSuccess,
UnlockedWalletApi
}
-import org.bitcoins.wallet.config.WalletAppConfig
import org.bitcoins.wallet.db.{WalletDbManagement}
import org.scalatest._
@@ -22,7 +20,6 @@ import scala.concurrent.duration.{DurationInt, FiniteDuration}
import scala.concurrent.{ExecutionContext, Future}
import org.bitcoins.db.AppConfig
import org.bitcoins.testkit.BitcoinSAppConfig
-import org.bitcoins.testkit.BitcoinSAppConfig._
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/util/WalletTestUtil.scala b/testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala
similarity index 97%
rename from wallet-test/src/test/scala/org/bitcoins/wallet/util/WalletTestUtil.scala
rename to testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala
index c0bead76cc..650c09a952 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/util/WalletTestUtil.scala
+++ b/testkit/src/main/scala/org/bitcoins/testkit/wallet/WalletTestUtil.scala
@@ -1,4 +1,4 @@
-package org.bitcoins.wallet.util
+package org.bitcoins.testkit.wallet
import org.bitcoins.core.config.RegTest
import org.bitcoins.core.crypto._
@@ -10,7 +10,6 @@ import org.bitcoins.core.protocol.blockchain.{
import org.bitcoins.core.protocol.script.ScriptPubKey
import org.bitcoins.testkit.core.gen.CryptoGenerators
import org.bitcoins.wallet.models.AccountDb
-import org.bitcoins.wallet.HDUtil
import scodec.bits.HexStringSyntax
import org.bitcoins.core.hd._
import org.bitcoins.core.protocol.script.ScriptWitness
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/LegacyWalletTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/LegacyWalletTest.scala
index 467496ae88..1610563fa0 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/LegacyWalletTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/LegacyWalletTest.scala
@@ -1,7 +1,7 @@
package org.bitcoins.wallet
import org.bitcoins.wallet.api.UnlockedWalletApi
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest.FutureOutcome
import org.bitcoins.wallet.api.UnlockWalletError.BadPassword
import org.bitcoins.wallet.api.UnlockWalletError.JsonParsingError
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/SegwitWalletTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/SegwitWalletTest.scala
index 34e0001465..5f406b7009 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/SegwitWalletTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/SegwitWalletTest.scala
@@ -1,7 +1,7 @@
package org.bitcoins.wallet
import org.bitcoins.wallet.api.UnlockedWalletApi
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest.FutureOutcome
import org.bitcoins.wallet.api.UnlockWalletError.BadPassword
import org.bitcoins.wallet.api.UnlockWalletError.JsonParsingError
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/WalletIntegrationTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/WalletIntegrationTest.scala
index bbde0d2ed9..8d8dd9d0bf 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/WalletIntegrationTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/WalletIntegrationTest.scala
@@ -5,7 +5,7 @@ import org.bitcoins.core.number.UInt32
import org.bitcoins.core.wallet.fee.SatoshisPerByte
import org.bitcoins.testkit.rpc.BitcoindRpcTestUtil
import org.bitcoins.wallet.api.{AddUtxoError, AddUtxoSuccess, WalletApi}
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest.FutureOutcome
import scala.concurrent.Future
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/WalletStorageTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/WalletStorageTest.scala
index de3ac90799..3628b91c3e 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/WalletStorageTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/WalletStorageTest.scala
@@ -1,6 +1,6 @@
package org.bitcoins.wallet
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest.FutureOutcome
import org.bitcoins.testkit.fixtures.EmptyFixture
import org.bitcoins.testkit.core.gen.CryptoGenerators
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/WalletUnitTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/WalletUnitTest.scala
index bd035fd840..ad82371b01 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/WalletUnitTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/WalletUnitTest.scala
@@ -1,7 +1,7 @@
package org.bitcoins.wallet
import org.bitcoins.wallet.api.UnlockedWalletApi
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest.FutureOutcome
import org.bitcoins.wallet.api.UnlockWalletError.BadPassword
import org.bitcoins.wallet.api.UnlockWalletError.JsonParsingError
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AccountDAOFixture.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AccountDAOFixture.scala
index 981f0f4e1e..7c9cd1b6db 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AccountDAOFixture.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AccountDAOFixture.scala
@@ -2,20 +2,20 @@ package org.bitcoins.wallet.fixtures
import org.bitcoins.wallet.db.WalletDbManagement
import org.bitcoins.wallet.models.AccountDAO
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest._
import scala.concurrent.Future
import org.bitcoins.wallet.config.WalletAppConfig
trait AccountDAOFixture extends fixture.AsyncFlatSpec with BitcoinSWalletTest {
- override final type FixtureParam = AccountDAO
+ final override type FixtureParam = AccountDAO
// to get around the config in `BitcoinSWalletTest` not resolving
// as an AppConfig
- private implicit val walletConfig: WalletAppConfig = config.walletConf
+ implicit private val walletConfig: WalletAppConfig = config.walletConf
- override final def withFixture(test: OneArgAsyncTest): FutureOutcome =
+ final override def withFixture(test: OneArgAsyncTest): FutureOutcome =
makeDependentFixture(createAccountTable, dropAccountTable)(test)
private def dropAccountTable(accountDAO: AccountDAO): Future[Unit] = {
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AddressDAOFixture.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AddressDAOFixture.scala
index 393b0c1a81..9c1479808a 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AddressDAOFixture.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/AddressDAOFixture.scala
@@ -4,7 +4,7 @@ import scala.concurrent.Future
import org.bitcoins.wallet.db.WalletDbManagement
import org.bitcoins.wallet.models.{AccountDAO, AddressDAO}
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest._
import org.bitcoins.wallet.config.WalletAppConfig
@@ -14,14 +14,14 @@ import org.bitcoins.wallet.config.WalletAppConfig
*/
trait AddressDAOFixture extends fixture.AsyncFlatSpec with BitcoinSWalletTest {
- override final type FixtureParam = (AccountDAO, AddressDAO)
+ final override type FixtureParam = (AccountDAO, AddressDAO)
- override final def withFixture(test: OneArgAsyncTest): FutureOutcome =
+ final override def withFixture(test: OneArgAsyncTest): FutureOutcome =
makeDependentFixture(createTables, dropTables)(test)
// to get around the config in `BitcoinSWalletTest` not resolving
// as an AppConfig
- private implicit val walletConfig: WalletAppConfig = config.walletConf
+ implicit private val walletConfig: WalletAppConfig = config.walletConf
private def dropTables(daos: FixtureParam): Future[Unit] = {
val (account, address) = daos
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/DAOFixture.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/DAOFixture.scala
index f41aef2e5c..b49edd1a40 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/DAOFixture.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/DAOFixture.scala
@@ -1,7 +1,7 @@
package org.bitcoins.wallet.fixtures
import org.bitcoins.wallet.db.WalletDbManagement
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest._
import slick.jdbc.SQLiteProfile.api._
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/UtxoDAOFixture.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/UtxoDAOFixture.scala
index 9fe26c7c6c..99cd94232a 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/UtxoDAOFixture.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/fixtures/UtxoDAOFixture.scala
@@ -2,7 +2,7 @@ package org.bitcoins.wallet.fixtures
import org.bitcoins.wallet.db.WalletDbManagement
import org.bitcoins.wallet.models.UTXOSpendingInfoDAO
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
import org.scalatest._
import scala.concurrent.Future
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/models/AccountDAOTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/models/AccountDAOTest.scala
index 59e9a7e310..66dd73638a 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/models/AccountDAOTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/models/AccountDAOTest.scala
@@ -2,7 +2,7 @@ package org.bitcoins.wallet.models
import org.bitcoins.testkit.core.gen.CryptoGenerators
import org.bitcoins.wallet.fixtures.AccountDAOFixture
-import org.bitcoins.wallet.util.{BitcoinSWalletTest, WalletTestUtil}
+import org.bitcoins.testkit.wallet.{BitcoinSWalletTest, WalletTestUtil}
class AccountDAOTest extends BitcoinSWalletTest with AccountDAOFixture {
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/models/AddressDAOTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/models/AddressDAOTest.scala
index 2414eb7b92..e48f0614d7 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/models/AddressDAOTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/models/AddressDAOTest.scala
@@ -8,7 +8,7 @@ import org.bitcoins.core.protocol.P2SHAddress
import org.bitcoins.core.script.ScriptType
import org.bitcoins.core.util.CryptoUtil
import org.bitcoins.wallet.fixtures.AddressDAOFixture
-import org.bitcoins.wallet.util.{BitcoinSWalletTest, WalletTestUtil}
+import org.bitcoins.testkit.wallet.{BitcoinSWalletTest, WalletTestUtil}
import org.bitcoins.core.hd.HDChainType
import org.bitcoins.core.hd.SegWitHDPath
import org.bitcoins.wallet.Wallet
diff --git a/wallet-test/src/test/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAOTest.scala b/wallet-test/src/test/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAOTest.scala
index 06bbe0eb51..1564dea4b5 100644
--- a/wallet-test/src/test/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAOTest.scala
+++ b/wallet-test/src/test/scala/org/bitcoins/wallet/models/UTXOSpendingInfoDAOTest.scala
@@ -7,8 +7,8 @@ import org.bitcoins.core.protocol.transaction.{
}
import org.bitcoins.wallet.fixtures.UtxoDAOFixture
import org.bitcoins.wallet.Wallet
-import org.bitcoins.wallet.util.WalletTestUtil
-import org.bitcoins.wallet.util.BitcoinSWalletTest
+import org.bitcoins.testkit.wallet.WalletTestUtil
+import org.bitcoins.testkit.wallet.BitcoinSWalletTest
class UTXOSpendingInfoDAOTest extends BitcoinSWalletTest with UtxoDAOFixture {
behavior of "UTXOSpendingInfoDAO"