Skip to content

Commit

Permalink
removed global variable for blockcount
Browse files Browse the repository at this point in the history
  • Loading branch information
pm47 committed Aug 28, 2019
1 parent 5b5f1f1 commit edf53ec
Show file tree
Hide file tree
Showing 33 changed files with 294 additions and 313 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ case class CltvExpiryDelta(private val underlying: Int) extends Ordered[CltvExpi
/**
* Adds the current block height to the given delta to obtain an absolute expiry.
*/
def toCltvExpiry = CltvExpiry(Globals.blockCount.get() + underlying)
def toCltvExpiry(blockHeight: Long) = CltvExpiry(blockHeight + underlying)

// @formatter:off
def +(other: Int): CltvExpiryDelta = CltvExpiryDelta(underlying + other)
Expand Down
2 changes: 1 addition & 1 deletion eclair-core/src/main/scala/fr/acinq/eclair/Eclair.scala
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ class EclairImpl(appKit: Kit) extends Eclair {
GetInfoResponse(nodeId = appKit.nodeParams.nodeId,
alias = appKit.nodeParams.alias,
chainHash = appKit.nodeParams.chainHash,
blockHeight = Globals.blockCount.intValue(),
blockHeight = appKit.nodeParams.blockCount.intValue(),
publicAddresses = appKit.nodeParams.publicAddresses)
)

Expand Down
37 changes: 0 additions & 37 deletions eclair-core/src/main/scala/fr/acinq/eclair/Globals.scala

This file was deleted.

8 changes: 8 additions & 0 deletions eclair-core/src/main/scala/fr/acinq/eclair/NodeParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import java.io.File
import java.net.InetSocketAddress
import java.nio.file.Files
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicLong

import com.typesafe.config.{Config, ConfigFactory}
import fr.acinq.bitcoin.Crypto.PublicKey
Expand All @@ -41,6 +42,12 @@ import scala.concurrent.duration.FiniteDuration
* Created by PM on 26/02/2017.
*/
case class NodeParams(keyManager: KeyManager,
/**
* This counter holds the current blockchain height.
* It is mainly used to calculate htlc expiries.
* The value is read by all actors, hence it needs to be thread-safe.
*/
blockCount: AtomicLong,
alias: String,
color: Color,
publicAddresses: List[NodeAddress],
Expand Down Expand Up @@ -198,6 +205,7 @@ object NodeParams {

NodeParams(
keyManager = keyManager,
blockCount = new AtomicLong(0),
alias = nodeAlias,
color = Color(color(0), color(1), color(2)),
publicAddresses = addresses,
Expand Down
8 changes: 4 additions & 4 deletions eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class Setup(datadir: File,
val stream = classOf[Setup].getResourceAsStream(addressesFile)
ElectrumClientPool.readServerAddresses(stream, sslEnabled)
}
val electrumClient = system.actorOf(SimpleSupervisor.props(Props(new ElectrumClientPool(addresses)), "electrum-client", SupervisorStrategy.Resume))
val electrumClient = system.actorOf(SimpleSupervisor.props(Props(new ElectrumClientPool(nodeParams.blockCount, addresses)), "electrum-client", SupervisorStrategy.Resume))
Electrum(electrumClient)
}

Expand Down Expand Up @@ -236,11 +236,11 @@ class Setup(datadir: File,
case Bitcoind(bitcoinClient) =>
system.actorOf(SimpleSupervisor.props(Props(new ZMQActor(config.getString("bitcoind.zmqblock"), Some(zmqBlockConnected))), "zmqblock", SupervisorStrategy.Restart))
system.actorOf(SimpleSupervisor.props(Props(new ZMQActor(config.getString("bitcoind.zmqtx"), Some(zmqTxConnected))), "zmqtx", SupervisorStrategy.Restart))
system.actorOf(SimpleSupervisor.props(ZmqWatcher.props(new ExtendedBitcoinClient(new BatchingBitcoinJsonRPCClient(bitcoinClient))), "watcher", SupervisorStrategy.Resume))
system.actorOf(SimpleSupervisor.props(ZmqWatcher.props(nodeParams.blockCount, new ExtendedBitcoinClient(new BatchingBitcoinJsonRPCClient(bitcoinClient))), "watcher", SupervisorStrategy.Resume))
case Electrum(electrumClient) =>
zmqBlockConnected.success(Done)
zmqTxConnected.success(Done)
system.actorOf(SimpleSupervisor.props(Props(new ElectrumWatcher(electrumClient)), "watcher", SupervisorStrategy.Resume))
system.actorOf(SimpleSupervisor.props(Props(new ElectrumWatcher(nodeParams.blockCount, electrumClient)), "watcher", SupervisorStrategy.Resume))
}

router = system.actorOf(SimpleSupervisor.props(Router.props(nodeParams, watcher, Some(routerInitialized)), "router", SupervisorStrategy.Resume))
Expand Down Expand Up @@ -306,7 +306,7 @@ class Setup(datadir: File,
val getInfo = GetInfoResponse(nodeId = nodeParams.nodeId,
alias = nodeParams.alias,
chainHash = nodeParams.chainHash,
blockHeight = Globals.blockCount.intValue(),
blockHeight = nodeParams.blockCount.intValue(),
publicAddresses = nodeParams.publicAddresses)
val apiPassword = config.getString("api.password") match {
case "" => throw EmptyAPIPasswordException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package fr.acinq.eclair.blockchain.bitcoind

import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicLong

import akka.actor.{Actor, ActorLogging, Cancellable, Props, Terminated}
import akka.pattern.pipe
import fr.acinq.bitcoin._
import fr.acinq.eclair.Globals
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.bitcoind.rpc.ExtendedBitcoinClient
import fr.acinq.eclair.channel.BITCOIN_PARENT_TX_CONFIRMED
Expand All @@ -39,7 +39,7 @@ import scala.util.Try
* - also uses bitcoin-core rpc api, most notably for tx confirmation count and blockcount (because reorgs)
* Created by PM on 21/02/2016.
*/
class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = ExecutionContext.global) extends Actor with ActorLogging {
class ZmqWatcher(blockCount: AtomicLong, client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = ExecutionContext.global) extends Actor with ActorLogging {

import ZmqWatcher._

Expand Down Expand Up @@ -80,7 +80,7 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext =
client.getBlockCount.map {
case count =>
log.debug(s"setting blockCount=$count")
Globals.blockCount.set(count)
blockCount.set(count)
context.system.eventStream.publish(CurrentBlockCount(count))
}
// TODO: beware of the herd effect
Expand Down Expand Up @@ -151,7 +151,7 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext =
context become watching(watches + w, addWatchedUtxos(watchedUtxos, w), block2tx, nextTick)

case PublishAsap(tx) =>
val blockCount = Globals.blockCount.get()
val blockCount = this.blockCount.get()
val cltvTimeout = Scripts.cltvTimeout(tx)
val csvTimeout = Scripts.csvTimeout(tx)
if (csvTimeout > 0) {
Expand All @@ -168,7 +168,7 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext =

case WatchEventConfirmed(BITCOIN_PARENT_TX_CONFIRMED(tx), blockHeight, _, _) =>
log.info(s"parent tx of txid=${tx.txid} has been confirmed")
val blockCount = Globals.blockCount.get()
val blockCount = this.blockCount.get()
val csvTimeout = Scripts.csvTimeout(tx)
val absTimeout = blockHeight + csvTimeout
if (absTimeout > blockCount) {
Expand Down Expand Up @@ -226,7 +226,7 @@ class ZmqWatcher(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext =

object ZmqWatcher {

def props(client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = ExecutionContext.global) = Props(new ZmqWatcher(client)(ec))
def props(blockCount: AtomicLong, client: ExtendedBitcoinClient)(implicit ec: ExecutionContext = ExecutionContext.global) = Props(new ZmqWatcher(blockCount, client)(ec))

case object TickNewBlock

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ package fr.acinq.eclair.blockchain.electrum

import java.io.InputStream
import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicLong

import akka.actor.{Actor, ActorRef, FSM, OneForOneStrategy, Props, SupervisorStrategy, Terminated}
import fr.acinq.bitcoin.BlockHeader
import fr.acinq.eclair.Globals
import fr.acinq.eclair.blockchain.CurrentBlockCount
import fr.acinq.eclair.blockchain.electrum.ElectrumClient.SSL
import fr.acinq.eclair.blockchain.electrum.ElectrumClientPool.ElectrumServerAddress
Expand All @@ -32,7 +32,7 @@ import scala.concurrent.ExecutionContext
import scala.concurrent.duration._
import scala.util.Random

class ElectrumClientPool(serverAddresses: Set[ElectrumServerAddress])(implicit val ec: ExecutionContext) extends Actor with FSM[ElectrumClientPool.State, ElectrumClientPool.Data] {
class ElectrumClientPool(blockCount: AtomicLong, serverAddresses: Set[ElectrumServerAddress])(implicit val ec: ExecutionContext) extends Actor with FSM[ElectrumClientPool.State, ElectrumClientPool.Data] {
import ElectrumClientPool._

val statusListeners = collection.mutable.HashSet.empty[ActorRef]
Expand Down Expand Up @@ -166,10 +166,10 @@ class ElectrumClientPool(serverAddresses: Set[ElectrumServerAddress])(implicit v

private def updateBlockCount(blockCount: Long): Unit = {
// when synchronizing we don't want to advertise previous blocks
if (Globals.blockCount.get() < blockCount) {
if (this.blockCount.get() < blockCount) {
log.debug("current blockchain height={}", blockCount)
context.system.eventStream.publish(CurrentBlockCount(blockCount))
Globals.blockCount.set(blockCount)
this.blockCount.set(blockCount)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@
package fr.acinq.eclair.blockchain.electrum

import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicLong

import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props, Stash, Terminated}
import fr.acinq.bitcoin.{BlockHeader, ByteVector32, Satoshi, Script, Transaction, TxIn, TxOut}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.electrum.ElectrumClient.{SSL, computeScriptHash}
import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT, BITCOIN_PARENT_TX_CONFIRMED}
import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.{Globals, ShortChannelId, TxCoordinates}
import fr.acinq.eclair.{ShortChannelId, TxCoordinates}

import scala.collection.SortedMap
import scala.collection.immutable.Queue


class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLogging {
class ElectrumWatcher(blockCount: AtomicLong, client: ActorRef) extends Actor with Stash with ActorLogging {

client ! ElectrumClient.AddStatusListener(self)

Expand Down Expand Up @@ -163,7 +164,7 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi
case ElectrumClient.ServerError(ElectrumClient.GetTransaction(txid, Some(origin: ActorRef)), _) => origin ! GetTxWithMetaResponse(txid, None, tip.time)

case PublishAsap(tx) =>
val blockCount = Globals.blockCount.get()
val blockCount = this.blockCount.get()
val cltvTimeout = Scripts.cltvTimeout(tx)
val csvTimeout = Scripts.csvTimeout(tx)
if (csvTimeout > 0) {
Expand All @@ -184,7 +185,7 @@ class ElectrumWatcher(client: ActorRef) extends Actor with Stash with ActorLoggi

case WatchEventConfirmed(BITCOIN_PARENT_TX_CONFIRMED(tx), blockHeight, _, _) =>
log.info(s"parent tx of txid=${tx.txid} has been confirmed")
val blockCount = Globals.blockCount.get()
val blockCount = this.blockCount.get()
val csvTimeout = Scripts.csvTimeout(tx)
val absTimeout = blockHeight + csvTimeout
if (absTimeout > blockCount) {
Expand Down Expand Up @@ -231,7 +232,7 @@ object ElectrumWatcher extends App {
def receive = {
case ElectrumClient.ElectrumReady(_, _, _) =>
log.info(s"starting watcher")
context become running(context.actorOf(Props(new ElectrumWatcher(client)), "watcher"))
context become running(context.actorOf(Props(new ElectrumWatcher(new AtomicLong(0), client)), "watcher"))
}

def running(watcher: ActorRef): Receive = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ class Channel(val nodeParams: NodeParams, val wallet: EclairWallet, remoteNodeId
handleCommandError(AddHtlcFailed(d.channelId, c.paymentHash, error, origin(c), Some(d.channelUpdate), Some(c)), c)

case Event(c: CMD_ADD_HTLC, d: DATA_NORMAL) =>
Try(Commitments.sendAdd(d.commitments, c, origin(c))) match {
Try(Commitments.sendAdd(d.commitments, c, origin(c), nodeParams.blockCount.get)) match {
case Success(Right((commitments1, add))) =>
if (c.commit) self ! CMD_SIGN
handleCommandSuccess(sender, d.copy(commitments = commitments1)) sending add
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import fr.acinq.eclair.payment._
import fr.acinq.eclair.transactions.Transactions._
import fr.acinq.eclair.transactions._
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{Globals, MilliSatoshi, UInt64, _}
import fr.acinq.eclair.{MilliSatoshi, UInt64, _}

// @formatter:off
case class LocalChanges(proposed: List[UpdateMessage], signed: List[UpdateMessage], acked: List[UpdateMessage]) {
Expand Down Expand Up @@ -118,17 +118,16 @@ object Commitments {
* @param cmd add HTLC command
* @return either Left(failure, error message) where failure is a failure message (see BOLT #4 and the Failure Message class) or Right((new commitments, updateAddHtlc)
*/
def sendAdd(commitments: Commitments, cmd: CMD_ADD_HTLC, origin: Origin): Either[ChannelException, (Commitments, UpdateAddHtlc)] = {
val blockCount = Globals.blockCount.get()
def sendAdd(commitments: Commitments, cmd: CMD_ADD_HTLC, origin: Origin, blockHeight: Long): Either[ChannelException, (Commitments, UpdateAddHtlc)] = {
// our counterparty needs a reasonable amount of time to pull the funds from downstream before we can get refunded (see BOLT 2 and BOLT 11 for a calculation and rationale)
val minExpiry = Channel.MIN_CLTV_EXPIRY_DELTA.toCltvExpiry
val minExpiry = Channel.MIN_CLTV_EXPIRY_DELTA.toCltvExpiry(blockHeight)
if (cmd.cltvExpiry < minExpiry) {
return Left(ExpiryTooSmall(commitments.channelId, minimum = minExpiry, actual = cmd.cltvExpiry, blockCount = blockCount))
return Left(ExpiryTooSmall(commitments.channelId, minimum = minExpiry, actual = cmd.cltvExpiry, blockCount = blockHeight))
}
val maxExpiry = Channel.MAX_CLTV_EXPIRY_DELTA.toCltvExpiry
val maxExpiry = Channel.MAX_CLTV_EXPIRY_DELTA.toCltvExpiry(blockHeight)
// we don't want to use too high a refund timeout, because our funds will be locked during that time if the payment is never fulfilled
if (cmd.cltvExpiry >= maxExpiry) {
return Left(ExpiryTooBig(commitments.channelId, maximum = maxExpiry, actual = cmd.cltvExpiry, blockCount = blockCount))
return Left(ExpiryTooBig(commitments.channelId, maximum = maxExpiry, actual = cmd.cltvExpiry, blockCount = blockHeight))
}

if (cmd.amount < commitments.remoteParams.htlcMinimum) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class LocalPaymentHandler(nodeParams: NodeParams) extends Actor with ActorLoggin
case htlc: UpdateAddHtlc =>
paymentDb.getPendingPaymentRequestAndPreimage(htlc.paymentHash) match {
case Some((paymentPreimage, paymentRequest)) =>
val minFinalExpiry = paymentRequest.minFinalCltvExpiryDelta.getOrElse(Channel.MIN_CLTV_EXPIRY_DELTA).toCltvExpiry
val minFinalExpiry = paymentRequest.minFinalCltvExpiryDelta.getOrElse(Channel.MIN_CLTV_EXPIRY_DELTA).toCltvExpiry(nodeParams.blockCount.get)
// The htlc amount must be equal or greater than the requested amount. A slight overpaying is permitted, however
// it must not be greater than two times the requested amount.
// see https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#failure-messages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class PaymentLifecycle(nodeParams: NodeParams, id: UUID, router: ActorRef, regis
log.info(s"route found: attempt=${failures.size + 1}/${c.maxAttempts} route=${hops.map(_.nextNodeId).mkString("->")} channels=${hops.map(_.lastUpdate.shortChannelId).mkString("->")}")
val firstHop = hops.head
// we add one block in order to not have our htlc fail when a new block has just been found
val finalExpiry = (c.finalCltvExpiryDelta + 1).toCltvExpiry
val finalExpiry = (c.finalCltvExpiryDelta + 1).toCltvExpiry(nodeParams.blockCount.get)

val (cmd, sharedSecrets) = buildCommand(id, c.amount, finalExpiry, c.paymentHash, hops)
register ! Register.ForwardShortId(firstHop.lastUpdate.shortChannelId, cmd)
Expand Down
Loading

0 comments on commit edf53ec

Please sign in to comment.