mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-01-18 21:34:39 +01:00
Attempt to sync with sendheaders (#537)
* Attempt to sync with sendheaders Fix sync with headers by generating one block in regtest to get out of IBD Fix comment Add more comments Add missing actor system import more clean up * refactor test case to avoid sleeping the thread
This commit is contained in:
parent
67fb821b00
commit
a716d374ca
@ -1,6 +1,8 @@
|
||||
package org.bitcoins.node
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import org.bitcoins.core.crypto.DoubleSha256DigestBE
|
||||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||
import org.bitcoins.rpc.util.RpcUtil
|
||||
import org.bitcoins.testkit.node.NodeUnitTest
|
||||
import org.bitcoins.testkit.node.fixture.SpvNodeConnectedWithBitcoind
|
||||
@ -9,6 +11,8 @@ import org.scalatest.FutureOutcome
|
||||
import scala.concurrent.Future
|
||||
import org.bitcoins.testkit.node.NodeTestUtil
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
|
||||
class SpvNodeTest extends NodeUnitTest {
|
||||
|
||||
override type FixtureParam = SpvNodeConnectedWithBitcoind
|
||||
@ -31,7 +35,7 @@ class SpvNodeTest extends NodeUnitTest {
|
||||
bitcoind.generate(1).map(_.head)
|
||||
}
|
||||
|
||||
//check we have that hash inside of our chain project!
|
||||
//sync our spv node expecting to get that generated hash
|
||||
val spvSyncF = for {
|
||||
_ <- hashF
|
||||
sync <- spvNode.sync()
|
||||
@ -42,6 +46,62 @@ class SpvNodeTest extends NodeUnitTest {
|
||||
.awaitSync(spvNode, bitcoind)
|
||||
.map(_ => succeed)
|
||||
}
|
||||
}
|
||||
|
||||
it must "stay in sync with a bitcoind instance" in {
|
||||
spvNodeConnectedWithBitcoind: SpvNodeConnectedWithBitcoind =>
|
||||
val spvNode = spvNodeConnectedWithBitcoind.spvNode
|
||||
val bitcoind = spvNodeConnectedWithBitcoind.bitcoind
|
||||
|
||||
//we need to generate 1 block for bitcoind to consider
|
||||
//itself out of IBD. bitcoind will not sendheaders
|
||||
//when it believes itself, or it's peer is in IBD
|
||||
val gen1F = bitcoind.generate(1)
|
||||
|
||||
//this needs to be called to get our peer to send us headers
|
||||
//as they happen with the 'sendheaders' message
|
||||
//both our spv node and our bitcoind node _should_ both be at the genesis block (regtest)
|
||||
//at this point so no actual syncing is happening
|
||||
val initSyncF = gen1F.flatMap(_ => spvNode.sync())
|
||||
|
||||
//start generating a block every 10 seconds with bitcoind
|
||||
//this should result in 5 blocks
|
||||
val startGenF = initSyncF.map { _ =>
|
||||
//generate a block every 5 seconds
|
||||
//until we have generated 5 total blocks
|
||||
genBlockInterval(bitcoind)
|
||||
}
|
||||
|
||||
startGenF.flatMap { _ =>
|
||||
//we should expect 5 headers have been announced to us via
|
||||
//the send headers message.
|
||||
val has6BlocksF = RpcUtil.retryUntilSatisfiedF(
|
||||
conditionF = () => spvNode.chainApi.getBlockCount.map(_ == 6),
|
||||
duration = 1.seconds)
|
||||
|
||||
has6BlocksF.map(_ => succeed)
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper method to generate blocks every interval */
|
||||
private def genBlockInterval(bitcoind: BitcoindRpcClient)(
|
||||
implicit system: ActorSystem): Unit = {
|
||||
|
||||
var counter = 0
|
||||
val desiredBlocks = 5
|
||||
val interval = 500.millis
|
||||
|
||||
val genBlock = new Runnable {
|
||||
override def run(): Unit = {
|
||||
if (counter < desiredBlocks) {
|
||||
bitcoind.generate(1)
|
||||
counter = counter + 1
|
||||
} else {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system.scheduler.schedule(interval, interval, genBlock)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.bitcoins.node.networking
|
||||
|
||||
import akka.actor.{Actor, ActorRef, ActorRefFactory, Props}
|
||||
import akka.event.LoggingReceive
|
||||
import akka.io.{IO, Tcp}
|
||||
import akka.util.ByteString
|
||||
import org.bitcoins.core.config.NetworkParameters
|
||||
@ -71,7 +70,7 @@ sealed abstract class ClientActor extends Actor with BitcoinSLogger {
|
||||
*/
|
||||
private def awaitNetworkRequest(
|
||||
peer: ActorRef,
|
||||
unalignedBytes: ByteVector): Receive = LoggingReceive {
|
||||
unalignedBytes: ByteVector): Receive = {
|
||||
case message: NetworkMessage => sendNetworkMessage(message, peer)
|
||||
case payload: NetworkPayload =>
|
||||
val networkMsg = NetworkMessage(network, payload)
|
||||
@ -83,7 +82,7 @@ sealed abstract class ClientActor extends Actor with BitcoinSLogger {
|
||||
}
|
||||
|
||||
/** This context is responsible for initializing a tcp connection with a peer on the bitcoin p2p network */
|
||||
def receive = LoggingReceive {
|
||||
def receive: Receive = {
|
||||
case cmd: Tcp.Command =>
|
||||
//we only accept a Tcp.Connect/Tcp.Connected
|
||||
//message to the default receive on this actor
|
||||
|
@ -4,7 +4,6 @@ import java.net.InetSocketAddress
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import org.bitcoins.core.config.NetworkParameters
|
||||
import org.bitcoins.core.p2p.NetworkIpAddress
|
||||
import org.bitcoins.core.util.BitcoinSLogger
|
||||
import org.bitcoins.db.AppConfig
|
||||
import org.bitcoins.node.SpvNode
|
||||
@ -15,6 +14,8 @@ import org.bitcoins.node.networking.peer.{
|
||||
PeerMessageSender
|
||||
}
|
||||
import org.bitcoins.rpc.client.common.BitcoindRpcClient
|
||||
import org.bitcoins.testkit.BitcoinSAppConfig
|
||||
import org.bitcoins.testkit.BitcoinSAppConfig._
|
||||
import org.bitcoins.testkit.chain.ChainUnitTest
|
||||
import org.bitcoins.testkit.fixtures.BitcoinSFixture
|
||||
import org.bitcoins.testkit.node.fixture.SpvNodeConnectedWithBitcoind
|
||||
@ -29,9 +30,6 @@ import org.scalatest.{
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
import org.bitcoins.testkit.BitcoinSAppConfig
|
||||
import org.bitcoins.testkit.BitcoinSAppConfig._
|
||||
|
||||
trait NodeUnitTest
|
||||
extends BitcoinSFixture
|
||||
with MustMatchers
|
||||
|
Loading…
Reference in New Issue
Block a user