Skip to content

Commit

Permalink
Disable headers over DNS on testnet
Browse files Browse the repository at this point in the history
The service is only available on mainnet.
  • Loading branch information
t-bast committed Sep 30, 2020
1 parent e1c487c commit 4a7034d
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package fr.acinq.eclair.blockchain.watchdogs
import akka.actor.typed.Behavior
import akka.actor.typed.eventstream.EventStream
import akka.actor.typed.scaladsl.Behaviors
import fr.acinq.bitcoin.BlockHeader
import fr.acinq.bitcoin.{BlockHeader, ByteVector32}
import fr.acinq.eclair.blockchain.CurrentBlockCount
import fr.acinq.eclair.blockchain.watchdogs.Monitoring.{Metrics, Tags}

Expand Down Expand Up @@ -47,7 +47,7 @@ object BlockchainWatchdog {
* @param maxRandomDelay to avoid the herd effect whenever a block is created, we add a random delay before we query
* secondary blockchain sources. This parameter specifies the maximum delay we'll allow.
*/
def apply(blockCountDelta: Int, maxRandomDelay: FiniteDuration): Behavior[Command] = {
def apply(chainHash: ByteVector32, blockCountDelta: Int, maxRandomDelay: FiniteDuration): Behavior[Command] = {
Behaviors.setup { context =>
context.system.eventStream ! EventStream.Subscribe(context.messageAdapter[CurrentBlockCount](cbc => WrappedCurrentBlockCount(cbc.blockCount)))
Behaviors.withTimers { timers =>
Expand All @@ -57,7 +57,7 @@ object BlockchainWatchdog {
timers.startSingleTimer(CheckLatestHeaders(blockCount), delay)
Behaviors.same
case CheckLatestHeaders(blockCount) =>
context.spawn(HeadersOverDns(blockCount, blockCountDelta), HeadersOverDns.Name) ! HeadersOverDns.CheckLatestHeaders(context.self)
context.spawn(HeadersOverDns(chainHash, blockCount, blockCountDelta), HeadersOverDns.Name) ! HeadersOverDns.CheckLatestHeaders(context.self)
Behaviors.same
case LatestHeaders(blockCount, blockHeaders, source) =>
val missingBlocks = blockHeaders match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import akka.actor.typed.scaladsl.adapter.TypedActorRefOps
import akka.actor.typed.{ActorRef, Behavior}
import akka.io.dns.{AAAARecord, DnsProtocol}
import akka.io.{Dns, IO}
import fr.acinq.bitcoin.BlockHeader
import fr.acinq.bitcoin.{Block, BlockHeader, ByteVector32}
import fr.acinq.eclair.blockchain.watchdogs.BlockchainWatchdog.BlockHeaderAt
import fr.acinq.eclair.blockchain.watchdogs.Monitoring.{Metrics, Tags}
import org.slf4j.Logger
Expand All @@ -44,19 +44,24 @@ object HeadersOverDns {
private case class WrappedDnsFailed(cause: Throwable) extends Command
// @formatter:on

def apply(currentBlockCount: Long, blockCountDelta: Int): Behavior[Command] = {
def apply(chainHash: ByteVector32, currentBlockCount: Long, blockCountDelta: Int): Behavior[Command] = {
Behaviors.setup { context =>
val dnsAdapters = {
context.messageAdapter[DnsProtocol.Resolved](WrappedDnsResolved)
context.messageAdapter[Status.Failure](f => WrappedDnsFailed(f.cause))
}.toClassic
Behaviors.receiveMessage {
case CheckLatestHeaders(replyTo) =>
(currentBlockCount until currentBlockCount + blockCountDelta).foreach(blockCount => {
val hostname = s"$blockCount.${blockCount / 10000}.bitcoinheaders.net"
IO(Dns)(context.system.classicSystem).tell(DnsProtocol.resolve(hostname, DnsProtocol.Ip(ipv4 = false, ipv6 = true)), dnsAdapters)
})
collect(replyTo, currentBlockCount, Set.empty, blockCountDelta)
case CheckLatestHeaders(replyTo) => chainHash match {
case Block.LivenetGenesisBlock.hash =>
(currentBlockCount until currentBlockCount + blockCountDelta).foreach(blockCount => {
val hostname = s"$blockCount.${blockCount / 10000}.bitcoinheaders.net"
IO(Dns)(context.system.classicSystem).tell(DnsProtocol.resolve(hostname, DnsProtocol.Ip(ipv4 = false, ipv6 = true)), dnsAdapters)
})
collect(replyTo, currentBlockCount, Set.empty, blockCountDelta)
case _ =>
// Headers over DNS is only supported for mainnet.
Behaviors.stopped
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ package fr.acinq.eclair.blockchain.watchdogs

import akka.actor.testkit.typed.scaladsl.{LogCapturing, LoggingTestKit, ScalaTestWithActorTestKit}
import akka.actor.typed.eventstream.EventStream
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.Block
import fr.acinq.eclair.blockchain.CurrentBlockCount
import org.scalatest.funsuite.AnyFunSuiteLike

import scala.concurrent.duration.DurationInt

class BlockchainWatchdogSpec extends ScalaTestWithActorTestKit with AnyFunSuiteLike with LogCapturing {
class BlockchainWatchdogSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("application")) with AnyFunSuiteLike with LogCapturing {

test("fetch block headers from secondary blockchain sources") {
val watchdog = testKit.spawn(BlockchainWatchdog(10, 1 second))
test("fetch block headers from DNS on mainnet") {
val watchdog = testKit.spawn(BlockchainWatchdog(Block.LivenetGenesisBlock.hash, 10, 1 second))
LoggingTestKit.warn("headers-over-dns: we are 9 blocks late: we may be eclipsed from the bitcoin network").expect {
system.eventStream ! EventStream.Publish(CurrentBlockCount(630561))
}(testKit.system)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,26 @@
package fr.acinq.eclair.blockchain.watchdogs

import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.{Block, BlockHeader}
import fr.acinq.eclair.blockchain.watchdogs.BlockchainWatchdog.{BlockHeaderAt, LatestHeaders}
import fr.acinq.eclair.blockchain.watchdogs.HeadersOverDns.CheckLatestHeaders
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits.HexStringSyntax

class HeadersOverDnsSpec extends ScalaTestWithActorTestKit with AnyFunSuiteLike {
import scala.concurrent.duration.DurationInt

class HeadersOverDnsSpec extends ScalaTestWithActorTestKit(ConfigFactory.load("application")) with AnyFunSuiteLike {

test("fetch genesis block header") {
val headersOverDns = testKit.spawn(HeadersOverDns(0, 1))
val headersOverDns = testKit.spawn(HeadersOverDns(Block.LivenetGenesisBlock.hash, 0, 1))
val sender = testKit.createTestProbe[LatestHeaders]()
headersOverDns ! CheckLatestHeaders(sender.ref)
sender.expectMessage(LatestHeaders(0, Set(BlockHeaderAt(0, Block.LivenetGenesisBlock.header)), HeadersOverDns.Name))
}

test("fetch first 3 block headers") {
val headersOverDns = testKit.spawn(HeadersOverDns(0, 3))
val headersOverDns = testKit.spawn(HeadersOverDns(Block.LivenetGenesisBlock.hash, 0, 3))
val sender = testKit.createTestProbe[LatestHeaders]()
headersOverDns ! CheckLatestHeaders(sender.ref)
val expectedHeaders = Set(
Expand All @@ -45,7 +48,7 @@ class HeadersOverDnsSpec extends ScalaTestWithActorTestKit with AnyFunSuiteLike
}

test("fetch some block headers") {
val headersOverDns = testKit.spawn(HeadersOverDns(630450, 5))
val headersOverDns = testKit.spawn(HeadersOverDns(Block.LivenetGenesisBlock.hash, 630450, 5))
val sender = testKit.createTestProbe[LatestHeaders]()
headersOverDns ! CheckLatestHeaders(sender.ref)
val expectedHeaders = Set(
Expand All @@ -59,10 +62,17 @@ class HeadersOverDnsSpec extends ScalaTestWithActorTestKit with AnyFunSuiteLike
}

test("fetch future block headers") {
val headersOverDns = testKit.spawn(HeadersOverDns(60000000, 2))
val headersOverDns = testKit.spawn(HeadersOverDns(Block.LivenetGenesisBlock.hash, 60000000, 2))
val sender = testKit.createTestProbe[LatestHeaders]()
headersOverDns ! CheckLatestHeaders(sender.ref)
sender.expectMessage(LatestHeaders(60000000, Set.empty, HeadersOverDns.Name))
}

test("ignore testnet requests") {
val headersOverDns = testKit.spawn(HeadersOverDns(Block.TestnetGenesisBlock.hash, 0, 1))
val sender = testKit.createTestProbe[LatestHeaders]()
headersOverDns ! CheckLatestHeaders(sender.ref)
sender.expectNoMessage(1 second)
}

}

0 comments on commit 4a7034d

Please sign in to comment.