bitcoin-s/docs/chain/sync-chain.md
Torkel Rogstad c2f37335b8 Bump Scala versions (#697)
* Bump Scala versions

Support Scala 2.12.9
and 2.13.0.

To make this easier, we delete the `scripts` project. Everything
that was in here was covered by content on the website. We also
delete the `doc` folder, as that was a remnant from when `scripts`
was called `doc`.

* Crib uPickle akka-http support while we wait for publish

* Fix compiler warnings

* Add note on test logging to contribution guide

* Reduce duplication in Blockchain implementation

* Use Scala 2.12 for website

* Introduce compat package object for collections converters

* Fix Either compiler warnings

* Add sync-chain and create-wallet docs from deleted scripts

* Fix rebase goofup
2019-08-23 13:53:00 -05:00

2.5 KiB

id title
sync-chain Syncing block headers with Bitcoin-S

Using the chain module of Bitcoin-S it's possible to sync and verify block headers from the Bitcoin blockchain. In this document we demonstrate how to do this, while persisting it to disk. We should be able to read this chain on subsequent runs, assuming we are connected to the same bitcoind instance.

import akka.actor.ActorSystem
import org.bitcoins.chain.blockchain._
import org.bitcoins.chain.blockchain.sync._
import org.bitcoins.chain.models._

import org.bitcoins.rpc.client.common._
import org.bitcoins.testkit.chain._

import scala.concurrent._

implicit val system = ActorSystem()
implicit val exectionContext = system.dispatcher

// We are assuming that a `bitcoind` regtest node is running the background.
// You can see our `bitcoind` guides to see how to connect
// to a local or remote `bitcoind` node.

import org.bitcoins.rpc.config.BitcoindInstance
import org.bitcoins.rpc.client.common.BitcoindRpcClient

val bitcoindInstance = BitcoindInstance.fromDatadir()
val rpcCli = new BitcoindRpcClient(bitcoindInstance)

// Next, we need to create a way to monitor the chain:

val getBestBlockHash = ChainTestUtil.bestBlockHashFnRpc(Future.successful(rpcCli))

val getBlockHeader = ChainTestUtil.getBlockHeaderFnRpc(Future.successful(rpcCli))


// set a data directory
import java.nio.file.Files
val datadir = Files.createTempDirectory("bitcoin-s-test")

// set the currenet network to regtest
import com.typesafe.config.ConfigFactory
val config = ConfigFactory.parseString {
    """
    | bitcoin-s {
    |   network = regtest
    | }
    |""".stripMargin
}

import org.bitcoins.chain.config.ChainAppConfig
implicit val chainConfig = ChainAppConfig(datadir, config)

// Initialize the needed database tables if they don't exist:
val chainProjectInitF = chainConfig.initialize()
val blockHeaderDAO = BlockHeaderDAO()

// Now, do the actual syncing:
val chainHandlerF = ChainHandler.fromDatabase(blockHeaderDAO)

val syncedChainApiF = for {
    _ <- chainProjectInitF
    handler <- chainHandlerF
    synced <- ChainSync.sync(handler, getBlockHeader, getBestBlockHash)
} yield synced


val syncResultF = syncedChainApiF.flatMap { chainApi =>
  chainApi.getBlockCount.map(count => println(s"chain api blockcount=${count}"))

  rpcCli.getBlockCount.map(count => println(s"bitcoind blockcount=${count}"))
}

syncResultF.onComplete { case result =>
  println(s"Sync result=${result}")
  system.terminate()
}