mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-20 02:27:32 +01:00
Merge branch 'wip-bolts' into wip-persist3
This commit is contained in:
commit
817704f5da
@ -47,7 +47,8 @@ object Boot extends App with Logging {
|
||||
class Setup() extends Logging {
|
||||
|
||||
logger.info(s"hello!")
|
||||
logger.info(s"nodeid=${Globals.Node.publicKey.toBin} alias=${Globals.Node.alias}")
|
||||
val nodeParams = NodeParams.loadFromConfiguration()
|
||||
logger.info(s"nodeid=${nodeParams.privateKey.publicKey.toBin} alias=${nodeParams.alias}")
|
||||
val config = ConfigFactory.load()
|
||||
|
||||
implicit lazy val system = ActorSystem()
|
||||
@ -103,11 +104,11 @@ class Setup() extends Logging {
|
||||
case "noop" => system.actorOf(Props[NoopPaymentHandler], name = "payment-handler")
|
||||
}
|
||||
val register = system.actorOf(Props(new Register), name = "register")
|
||||
val relayer = system.actorOf(Relayer.props(Globals.Node.privateKey, paymentHandler), name = "relayer")
|
||||
val relayer = system.actorOf(Relayer.props(nodeParams.privateKey, paymentHandler), name = "relayer")
|
||||
val router = system.actorOf(Router.props(watcher, db), name = "router")
|
||||
val paymentInitiator = system.actorOf(PaymentInitiator.props(Globals.Node.publicKey, router), "payment-initiator")
|
||||
val switchboard = system.actorOf(Switchboard.props(watcher, router, relayer, finalScriptPubKey, db), name = "switchboard")
|
||||
val server = system.actorOf(Server.props(switchboard, new InetSocketAddress(config.getString("eclair.server.host"), config.getInt("eclair.server.port"))), "server")
|
||||
val switchboard = system.actorOf(Switchboard.props(nodeParams, watcher, router, relayer, finalScriptPubKey, db), name = "switchboard")
|
||||
val paymentInitiator = system.actorOf(PaymentInitiator.props(nodeParams.privateKey.publicKey, router), "payment-initiator")
|
||||
val server = system.actorOf(Server.props(nodeParams, switchboard, new InetSocketAddress(config.getString("eclair.server.host"), config.getInt("eclair.server.port"))), "server")
|
||||
|
||||
val _setup = this
|
||||
val api = new Service {
|
||||
|
@ -1,50 +1,12 @@
|
||||
package fr.acinq.eclair
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import fr.acinq.bitcoin.{BinaryData, DeterministicWallet}
|
||||
import fr.acinq.eclair.router.Router
|
||||
|
||||
import scala.compat.Platform
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
||||
/**
|
||||
* Created by PM on 25/01/2016.
|
||||
*/
|
||||
object Globals {
|
||||
val config = ConfigFactory.load().getConfig("eclair")
|
||||
|
||||
object Node {
|
||||
val seed: BinaryData = config.getString("node.seed")
|
||||
val master = DeterministicWallet.generate(seed)
|
||||
val extendedPrivateKey = DeterministicWallet.derivePrivateKey(master, DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil)
|
||||
val privateKey = extendedPrivateKey.privateKey
|
||||
val extendedPublicKey = DeterministicWallet.publicKey(extendedPrivateKey)
|
||||
val publicKey = extendedPublicKey.publicKey
|
||||
val id = publicKey.toBin.toString()
|
||||
val alias = config.getString("node.alias").take(32)
|
||||
val color: (Byte, Byte, Byte) = (config.getInt("node.color.r").toByte, config.getInt("node.color.g").toByte, config.getInt("node.color.b").toByte)
|
||||
val address = new InetSocketAddress(config.getString("server.host"), config.getInt("server.port"))
|
||||
}
|
||||
|
||||
val global_features = BinaryData("")
|
||||
val local_features = BinaryData("05") // channels_public and initial_routing_sync
|
||||
|
||||
val expiry_delta_blocks = config.getInt("expiry-delta-blocks")
|
||||
val htlc_minimum_msat = config.getInt("htlc-minimum-msat")
|
||||
val delay_blocks = config.getInt("delay-blocks")
|
||||
val mindepth_blocks = config.getInt("mindepth-blocks")
|
||||
val feeratePerKw = 10000
|
||||
val fee_base_msat = config.getInt("fee-base-msat")
|
||||
val fee_proportional_millionth = config.getInt("fee-proportional-millionth")
|
||||
|
||||
val default_anchor_amount = 1000000
|
||||
|
||||
// channel reserve can't be more than 5% of the funding amount (recommended: 1%)
|
||||
val max_reserve_to_funding_ratio = 0.05
|
||||
|
||||
/**
|
||||
* This counter holds the current blockchain height.
|
||||
@ -53,3 +15,5 @@ object Globals {
|
||||
*/
|
||||
val blockCount = new AtomicLong(0)
|
||||
}
|
||||
|
||||
|
||||
|
64
eclair-node/src/main/scala/fr/acinq/eclair/NodeParams.scala
Normal file
64
eclair-node/src/main/scala/fr/acinq/eclair/NodeParams.scala
Normal file
@ -0,0 +1,64 @@
|
||||
package fr.acinq.eclair
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import fr.acinq.bitcoin.{BinaryData, DeterministicWallet}
|
||||
import fr.acinq.bitcoin.Crypto.PrivateKey
|
||||
import fr.acinq.bitcoin.DeterministicWallet.ExtendedPrivateKey
|
||||
|
||||
/**
|
||||
* Created by PM on 26/02/2017.
|
||||
*/
|
||||
case class NodeParams(extendedPrivateKey: ExtendedPrivateKey,
|
||||
privateKey: PrivateKey,
|
||||
alias: String,
|
||||
color: (Byte, Byte, Byte),
|
||||
address: InetSocketAddress,
|
||||
globalFeatures: BinaryData,
|
||||
localFeatures: BinaryData,
|
||||
dustLimitSatoshis: Long,
|
||||
maxHtlcValueInFlightMsat: Long,
|
||||
maxAcceptedHtlcs: Int,
|
||||
expiryDeltaBlocks: Int,
|
||||
htlcMinimumMsat: Int,
|
||||
delayBlocks: Int,
|
||||
minDepthBlocks: Int,
|
||||
feeratePerKw: Int,
|
||||
feeBaseMsat: Int,
|
||||
feeProportionalMillionth: Int,
|
||||
reserveToFundingRatio: Double,
|
||||
maxReserveToFundingRatio: Double)
|
||||
|
||||
object NodeParams {
|
||||
|
||||
def loadFromConfiguration(): NodeParams = {
|
||||
val config = ConfigFactory.load().getConfig("eclair")
|
||||
|
||||
val seed: BinaryData = config.getString("node.seed")
|
||||
val master = DeterministicWallet.generate(seed)
|
||||
val extendedPrivateKey = DeterministicWallet.derivePrivateKey(master, DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil)
|
||||
|
||||
NodeParams(
|
||||
extendedPrivateKey = extendedPrivateKey,
|
||||
privateKey = extendedPrivateKey.privateKey,
|
||||
alias = config.getString("node.alias").take(32),
|
||||
color = (config.getInt("node.color.r").toByte, config.getInt("node.color.g").toByte, config.getInt("node.color.b").toByte),
|
||||
address = new InetSocketAddress(config.getString("server.host"), config.getInt("server.port")),
|
||||
globalFeatures = BinaryData(""),
|
||||
localFeatures = BinaryData("05"), // channels_public and initial_routing_sync
|
||||
dustLimitSatoshis = 542,
|
||||
maxHtlcValueInFlightMsat = Long.MaxValue,
|
||||
maxAcceptedHtlcs = 100,
|
||||
expiryDeltaBlocks = config.getInt("expiry-delta-blocks"),
|
||||
htlcMinimumMsat = config.getInt("htlc-minimum-msat"),
|
||||
delayBlocks = config.getInt("delay-blocks"),
|
||||
minDepthBlocks = config.getInt("mindepth-blocks"),
|
||||
feeratePerKw = 10000,
|
||||
feeBaseMsat = config.getInt("fee-base-msat"),
|
||||
feeProportionalMillionth = config.getInt("fee-proportional-millionth"),
|
||||
reserveToFundingRatio = 0.01, // recommended by BOLT #2
|
||||
maxReserveToFundingRatio = 0.05 // channel reserve can't be more than 5% of the funding amount (recommended: 1%)
|
||||
)
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ case class ChannelRecord(id: Long, state: ChannelState)
|
||||
*/
|
||||
|
||||
object Channel {
|
||||
def props(remote: ActorRef, blockchain: ActorRef, router: ActorRef, relayer: ActorRef, db: SimpleDb) = Props(new Channel(remote, blockchain, router, relayer, db))
|
||||
def props(nodeParams: NodeParams, remote: ActorRef, blockchain: ActorRef, router: ActorRef, relayer: ActorRef, db: SimpleDb) = Props(new Channel(nodeParams, remote, blockchain, router, relayer, db))
|
||||
|
||||
def makeChannelDb(db: SimpleDb): SimpleTypedDb[Long, ChannelRecord] = {
|
||||
def channelid2String(id: Long) = s"channel-$id"
|
||||
@ -47,7 +47,7 @@ object Channel {
|
||||
}
|
||||
}
|
||||
|
||||
class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relayer: ActorRef, db: SimpleDb)(implicit ec: ExecutionContext = ExecutionContext.Implicits.global) extends LoggingFSM[State, Data] {
|
||||
class Channel(nodeParams: NodeParams, val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relayer: ActorRef, db: SimpleDb)(implicit ec: ExecutionContext = ExecutionContext.Implicits.global) extends LoggingFSM[State, Data] {
|
||||
|
||||
import Channel._
|
||||
|
||||
@ -141,7 +141,7 @@ class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relay
|
||||
|
||||
when(WAIT_FOR_OPEN_CHANNEL)(handleExceptions {
|
||||
case Event(open: OpenChannel, DATA_WAIT_FOR_OPEN_CHANNEL(INPUT_INIT_FUNDEE(_, _, localParams, remoteInit))) =>
|
||||
Try(Funding.validateParams(open.channelReserveSatoshis, open.fundingSatoshis)) match {
|
||||
Try(Funding.validateParams(nodeParams, open.channelReserveSatoshis, open.fundingSatoshis)) match {
|
||||
case Failure(t) =>
|
||||
log.warning(t.getMessage)
|
||||
remote ! Error(open.temporaryChannelId, t.getMessage.getBytes)
|
||||
@ -149,7 +149,7 @@ class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relay
|
||||
case Success(_) =>
|
||||
context.system.eventStream.publish(ChannelCreated(open.temporaryChannelId, context.parent, self, localParams, remoteNodeId))
|
||||
// TODO: maybe also check uniqueness of temporary channel id
|
||||
val minimumDepth = Globals.mindepth_blocks
|
||||
val minimumDepth = nodeParams.minDepthBlocks
|
||||
val firstPerCommitmentPoint = Generators.perCommitPoint(localParams.shaSeed, 0)
|
||||
val accept = AcceptChannel(temporaryChannelId = open.temporaryChannelId,
|
||||
dustLimitSatoshis = localParams.dustLimitSatoshis,
|
||||
@ -195,7 +195,7 @@ class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relay
|
||||
|
||||
when(WAIT_FOR_ACCEPT_CHANNEL)(handleExceptions {
|
||||
case Event(accept: AcceptChannel, DATA_WAIT_FOR_ACCEPT_CHANNEL(INPUT_INIT_FUNDER(_, temporaryChannelId, fundingSatoshis, pushMsat, localParams, remoteInit), open)) =>
|
||||
Try(Funding.validateParams(accept.channelReserveSatoshis, fundingSatoshis)) match {
|
||||
Try(Funding.validateParams(nodeParams, accept.channelReserveSatoshis, fundingSatoshis)) match {
|
||||
case Failure(t) =>
|
||||
log.warning(t.getMessage)
|
||||
remote ! Error(temporaryChannelId, t.getMessage.getBytes)
|
||||
@ -375,7 +375,7 @@ class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relay
|
||||
// this clock will be used to detect htlc timeouts
|
||||
context.system.eventStream.subscribe(self, classOf[CurrentBlockCount])
|
||||
if (Funding.announceChannel(params.localParams.localFeatures, params.remoteParams.localFeatures)) {
|
||||
val (localNodeSig, localBitcoinSig) = Announcements.signChannelAnnouncement(d.channelId, Globals.Node.privateKey, remoteNodeId, d.params.localParams.fundingPrivKey, d.params.remoteParams.fundingPubKey)
|
||||
val (localNodeSig, localBitcoinSig) = Announcements.signChannelAnnouncement(d.channelId, nodeParams.privateKey, remoteNodeId, d.params.localParams.fundingPrivKey, d.params.remoteParams.fundingPubKey)
|
||||
val annSignatures = AnnouncementSignatures(d.channelId, localNodeSig, localBitcoinSig)
|
||||
// FD remote ! annSignatures
|
||||
goto(WAIT_FOR_ANN_SIGNATURES) using DATA_WAIT_FOR_ANN_SIGNATURES(params, commitments.copy(remoteNextCommitInfo = Right(nextPerCommitmentPoint)).addToUnackedMessages(annSignatures), annSignatures)
|
||||
@ -396,10 +396,10 @@ class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relay
|
||||
when(WAIT_FOR_ANN_SIGNATURES)(handleExceptions {
|
||||
case Event(AnnouncementSignatures(_, remoteNodeSig, remoteBitcoinSig), d@DATA_WAIT_FOR_ANN_SIGNATURES(params, commitments, _)) =>
|
||||
log.info(s"announcing channel ${d.channelId} on the network")
|
||||
val (localNodeSig, localBitcoinSig) = Announcements.signChannelAnnouncement(d.channelId, Globals.Node.privateKey, remoteNodeId, d.params.localParams.fundingPrivKey, d.params.remoteParams.fundingPubKey)
|
||||
val channelAnn = Announcements.makeChannelAnnouncement(d.channelId, Globals.Node.publicKey, remoteNodeId, d.params.localParams.fundingPrivKey.publicKey, d.params.remoteParams.fundingPubKey, localNodeSig, remoteNodeSig, localBitcoinSig, remoteBitcoinSig)
|
||||
val nodeAnn = Announcements.makeNodeAnnouncement(Globals.Node.privateKey, Globals.Node.alias, Globals.Node.color, Globals.Node.address :: Nil, Platform.currentTime / 1000)
|
||||
val channelUpdate = Announcements.makeChannelUpdate(Globals.Node.privateKey, remoteNodeId, d.commitments.channelId, Globals.expiry_delta_blocks, Globals.htlc_minimum_msat, Globals.fee_base_msat, Globals.fee_proportional_millionth, Platform.currentTime / 1000)
|
||||
val (localNodeSig, localBitcoinSig) = Announcements.signChannelAnnouncement(d.channelId, nodeParams.privateKey, remoteNodeId, d.params.localParams.fundingPrivKey, d.params.remoteParams.fundingPubKey)
|
||||
val channelAnn = Announcements.makeChannelAnnouncement(d.channelId, nodeParams.privateKey.publicKey, remoteNodeId, d.params.localParams.fundingPrivKey.publicKey, d.params.remoteParams.fundingPubKey, localNodeSig, remoteNodeSig, localBitcoinSig, remoteBitcoinSig)
|
||||
val nodeAnn = Announcements.makeNodeAnnouncement(nodeParams.privateKey, nodeParams.alias, nodeParams.color, nodeParams.address :: Nil, Platform.currentTime / 1000)
|
||||
val channelUpdate = Announcements.makeChannelUpdate(nodeParams.privateKey, remoteNodeId, d.commitments.channelId, nodeParams.expiryDeltaBlocks, nodeParams.htlcMinimumMsat, nodeParams.feeBaseMsat, nodeParams.feeProportionalMillionth, Platform.currentTime / 1000)
|
||||
router ! channelAnn
|
||||
router ! nodeAnn
|
||||
router ! channelUpdate
|
||||
@ -850,7 +850,7 @@ class Channel(val r: ActorRef, val blockchain: ActorRef, router: ActorRef, relay
|
||||
remote = r
|
||||
// this is a brand new channel
|
||||
if (Funding.announceChannel(d.params.localParams.localFeatures, d.params.remoteParams.localFeatures)) {
|
||||
val (localNodeSig, localBitcoinSig) = Announcements.signChannelAnnouncement(d.channelId, Globals.Node.privateKey, remoteNodeId, d.params.localParams.fundingPrivKey, d.params.remoteParams.fundingPubKey)
|
||||
val (localNodeSig, localBitcoinSig) = Announcements.signChannelAnnouncement(d.channelId, nodeParams.privateKey, remoteNodeId, d.params.localParams.fundingPrivKey, d.params.remoteParams.fundingPubKey)
|
||||
val annSignatures = AnnouncementSignatures(d.channelId, localNodeSig, localBitcoinSig)
|
||||
remote ! annSignatures
|
||||
} else {
|
||||
|
@ -4,7 +4,7 @@ import fr.acinq.bitcoin.Crypto.{Point, PublicKey, Scalar, sha256}
|
||||
import fr.acinq.bitcoin.Script._
|
||||
import fr.acinq.bitcoin.{OutPoint, _}
|
||||
import fr.acinq.eclair.Features.Unset
|
||||
import fr.acinq.eclair.{Features, Globals}
|
||||
import fr.acinq.eclair.{Features, Globals, NodeParams}
|
||||
import fr.acinq.eclair.crypto.Generators
|
||||
import fr.acinq.eclair.transactions.Scripts._
|
||||
import fr.acinq.eclair.transactions.Transactions._
|
||||
@ -22,9 +22,9 @@ object Helpers {
|
||||
|
||||
object Funding {
|
||||
|
||||
def validateParams(channelReserveSatoshis: Long, fundingSatoshis: Long): Unit = {
|
||||
def validateParams(nodeParams: NodeParams, channelReserveSatoshis: Long, fundingSatoshis: Long): Unit = {
|
||||
val reserveToFundingRatio = channelReserveSatoshis.toDouble / fundingSatoshis
|
||||
require(reserveToFundingRatio <= Globals.max_reserve_to_funding_ratio, s"channelReserveSatoshis too high: ratio=$reserveToFundingRatio max=${Globals.max_reserve_to_funding_ratio}")
|
||||
require(reserveToFundingRatio <= nodeParams.maxReserveToFundingRatio, s"channelReserveSatoshis too high: ratio=$reserveToFundingRatio max=${nodeParams.maxReserveToFundingRatio}")
|
||||
}
|
||||
|
||||
def makeFundingInputInfo(fundingTxId: BinaryData, fundingTxOutputIndex: Int, fundingSatoshis: Satoshi, fundingPubkey1: PublicKey, fundingPubkey2: PublicKey): InputInfo = {
|
||||
|
@ -27,7 +27,7 @@ class GUIUpdater(primaryStage: Stage, mainController: MainController, setup: Set
|
||||
}
|
||||
|
||||
val graph = new SimpleGraph[BinaryData, NamedEdge](classOf[NamedEdge])
|
||||
graph.addVertex(Globals.Node.publicKey)
|
||||
graph.addVertex(setup.nodeParams.privateKey.publicKey)
|
||||
|
||||
def receive: Receive = main(Map())
|
||||
|
||||
|
@ -65,7 +65,7 @@ class Handlers(setup: Setup) extends Logging {
|
||||
(paymentHandler ? 'genh).mapTo[BinaryData].map { h =>
|
||||
Platform.runLater(new Runnable() {
|
||||
override def run = {
|
||||
textarea.setText(s"${Globals.Node.id}:$amountMsat:${h.toString()}")
|
||||
textarea.setText(s"${setup.nodeParams.privateKey.publicKey}:$amountMsat:${h.toString()}")
|
||||
textarea.requestFocus
|
||||
textarea.selectAll
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class MainController(val handlers: Handlers, val stage: Stage, val setup: Setup,
|
||||
initNotifs
|
||||
|
||||
// init status bar
|
||||
labelNodeId.setText(s"${Globals.Node.id}")
|
||||
labelNodeId.setText(s"${setup.nodeParams.privateKey.publicKey}")
|
||||
labelApi.setText(s"${setup.config.getInt("eclair.api.port")}")
|
||||
labelServer.setText(s"${setup.config.getInt("eclair.server.port")}")
|
||||
bitcoinVersion.setText(s"v${setup.bitcoinVersion}")
|
||||
@ -98,8 +98,8 @@ class MainController(val handlers: Handlers, val stage: Stage, val setup: Setup,
|
||||
|
||||
// init context
|
||||
contextMenu = ContextMenuUtils.buildCopyContext(List(
|
||||
new CopyAction("Copy Pubkey", Globals.Node.id),
|
||||
new CopyAction("Copy URI", s"${Globals.Node.id}@${Globals.Node.address.getHostString}:${Globals.Node.address.getPort}" )))
|
||||
new CopyAction("Copy Pubkey", s"${setup.nodeParams.privateKey.publicKey}"),
|
||||
new CopyAction("Copy URI", s"${setup.nodeParams.privateKey.publicKey}@${setup.nodeParams.address.getHostString}:${setup.nodeParams.address.getPort}" )))
|
||||
|
||||
// init channels tab
|
||||
if (channelBox.getChildren.size() > 0) {
|
||||
|
@ -5,7 +5,7 @@ import java.net.InetSocketAddress
|
||||
import akka.actor.{Props, _}
|
||||
import akka.io.{IO, Tcp}
|
||||
import fr.acinq.bitcoin.Crypto.PublicKey
|
||||
import fr.acinq.eclair.Globals
|
||||
import fr.acinq.eclair.{Globals, NodeParams}
|
||||
import fr.acinq.eclair.crypto.Noise.KeyPair
|
||||
import fr.acinq.eclair.crypto.TransportHandler
|
||||
import fr.acinq.eclair.crypto.TransportHandler.HandshakeCompleted
|
||||
@ -14,7 +14,7 @@ import fr.acinq.eclair.wire.LightningMessage
|
||||
/**
|
||||
* Created by PM on 27/10/2015.
|
||||
*/
|
||||
class Client(switchboard: ActorRef, address: InetSocketAddress, remoteNodeId: PublicKey, origin: ActorRef) extends Actor with ActorLogging {
|
||||
class Client(nodeParams: NodeParams, switchboard: ActorRef, address: InetSocketAddress, remoteNodeId: PublicKey, origin: ActorRef) extends Actor with ActorLogging {
|
||||
|
||||
import Tcp._
|
||||
import context.system
|
||||
@ -31,7 +31,7 @@ class Client(switchboard: ActorRef, address: InetSocketAddress, remoteNodeId: Pu
|
||||
val connection = sender
|
||||
val transport = context.actorOf(Props(
|
||||
new TransportHandler[LightningMessage](
|
||||
KeyPair(Globals.Node.publicKey.toBin, Globals.Node.privateKey.toBin),
|
||||
KeyPair(nodeParams.privateKey.publicKey.toBin, nodeParams.privateKey.toBin),
|
||||
Some(remoteNodeId),
|
||||
connection = connection,
|
||||
serializer = LightningMessageSerializer)))
|
||||
@ -53,6 +53,6 @@ class Client(switchboard: ActorRef, address: InetSocketAddress, remoteNodeId: Pu
|
||||
|
||||
object Client extends App {
|
||||
|
||||
def props(switchboard: ActorRef, address: InetSocketAddress, remoteNodeId: PublicKey, origin: ActorRef): Props = Props(classOf[Client], switchboard, address, remoteNodeId, origin)
|
||||
def props(nodeParams: NodeParams, switchboard: ActorRef, address: InetSocketAddress, remoteNodeId: PublicKey, origin: ActorRef): Props = Props(new Client(nodeParams, switchboard, address, remoteNodeId, origin))
|
||||
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ import java.net.InetSocketAddress
|
||||
|
||||
import akka.actor.{ActorRef, LoggingFSM, PoisonPill, Props, Terminated}
|
||||
import fr.acinq.bitcoin.Crypto.{PrivateKey, PublicKey}
|
||||
import fr.acinq.bitcoin.{BinaryData, DeterministicWallet}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, DeterministicWallet}
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.crypto.TransportHandler.{HandshakeCompleted, Listener, Serializer}
|
||||
import fr.acinq.eclair.db.{JavaSerializer, SimpleDb, SimpleTypedDb}
|
||||
import fr.acinq.eclair.io.Switchboard.{NewChannel, NewConnection}
|
||||
import fr.acinq.eclair.router.SendRoutingState
|
||||
import fr.acinq.eclair.wire._
|
||||
import fr.acinq.eclair.{Features, Globals}
|
||||
import fr.acinq.eclair.{Features, Globals, NodeParams}
|
||||
|
||||
import scala.compat.Platform
|
||||
|
||||
@ -42,7 +42,7 @@ case class PeerRecord(id: PublicKey, address: Option[InetSocketAddress])
|
||||
/**
|
||||
* Created by PM on 26/08/2016.
|
||||
*/
|
||||
class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) extends LoggingFSM[State, Data] {
|
||||
class Peer(nodeParams: NodeParams, remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) extends LoggingFSM[State, Data] {
|
||||
|
||||
import Peer._
|
||||
|
||||
@ -56,7 +56,7 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
stay
|
||||
|
||||
case Event(c: ChannelRecord, d@DisconnectedData(offlineChannels)) =>
|
||||
val (channel, _) = createChannel(null, c.id, false, db)
|
||||
val (channel, _) = createChannel(nodeParams, null, c.id, false, 0, db) // TODO: fixme using a dedicated restore message
|
||||
channel ! INPUT_RESTORED(c.id, c.state)
|
||||
stay using d.copy(offlineChannels = offlineChannels :+ HotChannel(c.id, channel))
|
||||
|
||||
@ -71,7 +71,7 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
log.info(s"registering as a listener to $transport")
|
||||
transport ! Listener(self)
|
||||
context watch transport
|
||||
transport ! Init(globalFeatures = Globals.global_features, localFeatures = Globals.local_features)
|
||||
transport ! Init(globalFeatures = nodeParams.globalFeatures, localFeatures = nodeParams.localFeatures)
|
||||
goto(INITIALIZING) using InitializingData(transport, channels)
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
case Event(remoteInit: Init, InitializingData(transport, offlineChannels)) =>
|
||||
import fr.acinq.eclair.Features._
|
||||
log.info(s"$remoteNodeId has features: channelPublic=${channelPublic(remoteInit.localFeatures)} initialRoutingSync=${initialRoutingSync(remoteInit.localFeatures)}")
|
||||
if (Features.areFeaturesCompatible(Globals.local_features, remoteInit.localFeatures)) {
|
||||
if (Features.areFeaturesCompatible(nodeParams.localFeatures, remoteInit.localFeatures)) {
|
||||
if (Features.initialRoutingSync(remoteInit.localFeatures) != Unset) {
|
||||
router ! SendRoutingState(transport)
|
||||
}
|
||||
@ -111,7 +111,7 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
case Event(c: NewChannel, d@ConnectedData(transport, remoteInit, channels)) =>
|
||||
log.info(s"requesting a new channel to $remoteNodeId with fundingSatoshis=${c.fundingSatoshis} and pushMsat=${c.pushMsat}")
|
||||
val temporaryChannelId = Platform.currentTime
|
||||
val (channel, localParams) = createChannel(transport, temporaryChannelId, funder = true, db)
|
||||
val (channel, localParams) = createChannel(nodeParams, transport, temporaryChannelId, funder = true, c.fundingSatoshis.toLong, db)
|
||||
channel ! INPUT_INIT_FUNDER(remoteNodeId, temporaryChannelId, c.fundingSatoshis.amount, c.pushMsat.amount, localParams, remoteInit)
|
||||
stay using d.copy(channels = channels + (temporaryChannelId -> channel))
|
||||
|
||||
@ -135,7 +135,7 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
case Event(msg: OpenChannel, d@ConnectedData(transport, remoteInit, channels)) =>
|
||||
log.info(s"accepting a new channel to $remoteNodeId")
|
||||
val temporaryChannelId = msg.temporaryChannelId
|
||||
val (channel, localParams) = createChannel(transport, temporaryChannelId, funder = false, db)
|
||||
val (channel, localParams) = createChannel(nodeParams, transport, temporaryChannelId, funder = false, fundingSatoshis = msg.fundingSatoshis, db)
|
||||
channel ! INPUT_INIT_FUNDEE(remoteNodeId, temporaryChannelId, localParams, remoteInit)
|
||||
channel ! msg
|
||||
stay using d.copy(channels = channels + (temporaryChannelId -> channel))
|
||||
@ -163,9 +163,9 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
stay using d.copy(channels = channels - channelId)
|
||||
}
|
||||
|
||||
def createChannel(transport: ActorRef, temporaryChannelId: Long, funder: Boolean, db: SimpleDb): (ActorRef, LocalParams) = {
|
||||
val localParams = makeChannelParams(temporaryChannelId, defaultFinalScriptPubKey, funder)
|
||||
val channel = context.actorOf(Channel.props(transport, watcher, router, relayer, db), s"channel-$temporaryChannelId")
|
||||
def createChannel(nodeParams: NodeParams, transport: ActorRef, temporaryChannelId: Long, funder: Boolean, fundingSatoshis: Long, db: SimpleDb): (ActorRef, LocalParams) = {
|
||||
val localParams = makeChannelParams(nodeParams, temporaryChannelId, defaultFinalScriptPubKey, funder, fundingSatoshis)
|
||||
val channel = context.actorOf(Channel.props(nodeParams, transport, watcher, router, relayer, db), s"channel-$temporaryChannelId")
|
||||
context watch channel
|
||||
(channel, localParams)
|
||||
}
|
||||
@ -174,28 +174,28 @@ class Peer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watc
|
||||
|
||||
object Peer {
|
||||
|
||||
def props(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) = Props(classOf[Peer], remoteNodeId, address_opt, watcher, router, relayer, defaultFinalScriptPubKey, db)
|
||||
def props(nodeParams: NodeParams, remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress], watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) = Props(new Peer(nodeParams, remoteNodeId, address_opt, watcher, router, relayer, defaultFinalScriptPubKey, db))
|
||||
|
||||
def generateKey(keyPath: Seq[Long]): PrivateKey = DeterministicWallet.derivePrivateKey(Globals.Node.extendedPrivateKey, keyPath).privateKey
|
||||
def generateKey(nodeParams: NodeParams, keyPath: Seq[Long]): PrivateKey = DeterministicWallet.derivePrivateKey(nodeParams.extendedPrivateKey, keyPath).privateKey
|
||||
|
||||
def makeChannelParams(keyIndex: Long, defaultFinalScriptPubKey: BinaryData, isFunder: Boolean): LocalParams =
|
||||
def makeChannelParams(nodeParams: NodeParams, keyIndex: Long, defaultFinalScriptPubKey: BinaryData, isFunder: Boolean, fundingSatoshis: Long): LocalParams =
|
||||
LocalParams(
|
||||
dustLimitSatoshis = 542,
|
||||
maxHtlcValueInFlightMsat = Long.MaxValue,
|
||||
channelReserveSatoshis = 0,
|
||||
htlcMinimumMsat = 0,
|
||||
feeratePerKw = Globals.feeratePerKw,
|
||||
toSelfDelay = Globals.delay_blocks,
|
||||
maxAcceptedHtlcs = 100,
|
||||
fundingPrivKey = generateKey(keyIndex :: 0L :: Nil),
|
||||
revocationSecret = generateKey(keyIndex :: 1L :: Nil),
|
||||
paymentKey = generateKey(keyIndex :: 2L :: Nil),
|
||||
delayedPaymentKey = generateKey(keyIndex :: 3L :: Nil),
|
||||
dustLimitSatoshis = nodeParams.dustLimitSatoshis,
|
||||
maxHtlcValueInFlightMsat = nodeParams.maxHtlcValueInFlightMsat,
|
||||
channelReserveSatoshis = (nodeParams.reserveToFundingRatio * fundingSatoshis).toLong,
|
||||
htlcMinimumMsat = nodeParams.htlcMinimumMsat,
|
||||
feeratePerKw = nodeParams.feeratePerKw,
|
||||
toSelfDelay = nodeParams.delayBlocks,
|
||||
maxAcceptedHtlcs = nodeParams.maxAcceptedHtlcs,
|
||||
fundingPrivKey = generateKey(nodeParams, keyIndex :: 0L :: Nil),
|
||||
revocationSecret = generateKey(nodeParams, keyIndex :: 1L :: Nil),
|
||||
paymentKey = generateKey(nodeParams, keyIndex :: 2L :: Nil),
|
||||
delayedPaymentKey = generateKey(nodeParams, keyIndex :: 3L :: Nil),
|
||||
defaultFinalScriptPubKey = defaultFinalScriptPubKey,
|
||||
shaSeed = Globals.Node.seed,
|
||||
shaSeed = Crypto.sha256(generateKey(nodeParams, keyIndex :: 4L :: Nil).toBin), // TODO: check that
|
||||
isFunder = isFunder,
|
||||
globalFeatures = Globals.global_features,
|
||||
localFeatures = Globals.local_features
|
||||
globalFeatures = nodeParams.globalFeatures,
|
||||
localFeatures = nodeParams.localFeatures
|
||||
)
|
||||
|
||||
def makePeerDb(db: SimpleDb): SimpleTypedDb[PublicKey, PeerRecord] = {
|
||||
|
@ -8,12 +8,12 @@ import fr.acinq.eclair.crypto.Noise.KeyPair
|
||||
import fr.acinq.eclair.crypto.TransportHandler
|
||||
import fr.acinq.eclair.crypto.TransportHandler.HandshakeCompleted
|
||||
import fr.acinq.eclair.wire.LightningMessage
|
||||
import fr.acinq.eclair.{Globals, TCPBindError}
|
||||
import fr.acinq.eclair.{Globals, NodeParams, TCPBindError}
|
||||
|
||||
/**
|
||||
* Created by PM on 27/10/2015.
|
||||
*/
|
||||
class Server(switchboard: ActorRef, address: InetSocketAddress) extends Actor with ActorLogging {
|
||||
class Server(nodeParams: NodeParams, switchboard: ActorRef, address: InetSocketAddress) extends Actor with ActorLogging {
|
||||
|
||||
import Tcp._
|
||||
import context.system
|
||||
@ -35,7 +35,7 @@ class Server(switchboard: ActorRef, address: InetSocketAddress) extends Actor wi
|
||||
val connection = sender
|
||||
val transport = context.actorOf(Props(
|
||||
new TransportHandler[LightningMessage](
|
||||
KeyPair(Globals.Node.publicKey.toBin, Globals.Node.privateKey.toBin),
|
||||
KeyPair(nodeParams.privateKey.publicKey.toBin, nodeParams.privateKey.toBin),
|
||||
None,
|
||||
connection = connection,
|
||||
serializer = LightningMessageSerializer)))
|
||||
@ -49,7 +49,7 @@ class Server(switchboard: ActorRef, address: InetSocketAddress) extends Actor wi
|
||||
|
||||
object Server {
|
||||
|
||||
def props(switchboard: ActorRef, address: InetSocketAddress): Props = Props(classOf[Server], switchboard, address)
|
||||
def props(nodeParams: NodeParams, switchboard: ActorRef, address: InetSocketAddress): Props = Props(new Server(nodeParams, switchboard, address))
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ import java.net.InetSocketAddress
|
||||
import akka.actor.{Actor, ActorLogging, ActorRef, Props, Status, Terminated}
|
||||
import fr.acinq.bitcoin.Crypto.PublicKey
|
||||
import fr.acinq.bitcoin.{BinaryData, MilliSatoshi, Satoshi, ScriptElt}
|
||||
import fr.acinq.eclair.Globals
|
||||
import fr.acinq.eclair.channel.ChannelRecord
|
||||
import fr.acinq.eclair.{Globals, NodeParams}
|
||||
import fr.acinq.eclair.crypto.TransportHandler.HandshakeCompleted
|
||||
import fr.acinq.eclair.db.{ChannelState, SimpleDb}
|
||||
|
||||
@ -14,9 +14,10 @@ import fr.acinq.eclair.db.{ChannelState, SimpleDb}
|
||||
* Ties network connections to peers.
|
||||
* Created by PM on 14/02/2017.
|
||||
*/
|
||||
class Switchboard(watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) extends Actor with ActorLogging {
|
||||
class Switchboard(nodeParams: NodeParams, watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) extends Actor with ActorLogging {
|
||||
|
||||
import Switchboard._
|
||||
|
||||
val peerDb = Peer.makePeerDb(db)
|
||||
|
||||
def receive: Receive = main(Map(), Map())
|
||||
@ -35,8 +36,7 @@ class Switchboard(watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaul
|
||||
|
||||
case channelRecord: ChannelRecord => peers(channelRecord.state.remotePubKey) forward channelRecord
|
||||
|
||||
case NewConnection(Globals.Node.publicKey, _, _) =>
|
||||
sender ! Status.Failure(new RuntimeException("cannot open connection with oneself"))
|
||||
case NewConnection(publicKey, _, _) if publicKey == nodeParams.privateKey.publicKey =>
|
||||
|
||||
case NewConnection(remoteNodeId, address, newChannel_opt) =>
|
||||
val connection = connections.get(remoteNodeId) match {
|
||||
@ -46,8 +46,8 @@ class Switchboard(watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaul
|
||||
connection
|
||||
case None =>
|
||||
log.info(s"connecting to $remoteNodeId @ $address")
|
||||
val connection = context.actorOf(Client.props(self, address, remoteNodeId, sender))
|
||||
context watch(connection)
|
||||
val connection = context.actorOf(Client.props(nodeParams, self, address, remoteNodeId, sender))
|
||||
context watch (connection)
|
||||
connection
|
||||
}
|
||||
val peer = peers.get(remoteNodeId) match {
|
||||
@ -74,13 +74,13 @@ class Switchboard(watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaul
|
||||
|
||||
def createPeer(remoteNodeId: PublicKey, address_opt: Option[InetSocketAddress]) = {
|
||||
peerDb.put(remoteNodeId, PeerRecord(remoteNodeId, address_opt))
|
||||
context.actorOf(Peer.props(remoteNodeId, address_opt, watcher, router, relayer, defaultFinalScriptPubKey, db), name = s"peer-$remoteNodeId")
|
||||
context.actorOf(Peer.props(nodeParams, remoteNodeId, address_opt, watcher, router, relayer, defaultFinalScriptPubKey, db), name = s"peer-$remoteNodeId")
|
||||
}
|
||||
}
|
||||
|
||||
object Switchboard {
|
||||
|
||||
def props(watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) = Props(classOf[Switchboard], watcher, router, relayer, defaultFinalScriptPubKey, db)
|
||||
def props(nodeParams: NodeParams, watcher: ActorRef, router: ActorRef, relayer: ActorRef, defaultFinalScriptPubKey: BinaryData, db: SimpleDb) = Props(new Switchboard(nodeParams, watcher, router, relayer, defaultFinalScriptPubKey, db))
|
||||
|
||||
// @formatter:off
|
||||
case class NewChannel(fundingSatoshis: Satoshi, pushMsat: MilliSatoshi)
|
||||
|
@ -2,11 +2,12 @@ package fr.acinq.eclair.payment
|
||||
|
||||
import akka.actor.{Actor, ActorLogging, ActorRef, Props}
|
||||
import fr.acinq.bitcoin.BinaryData
|
||||
import fr.acinq.bitcoin.Crypto.PublicKey
|
||||
|
||||
/**
|
||||
* Created by PM on 29/08/2016.
|
||||
*/
|
||||
class PaymentInitiator(sourceNodeId: BinaryData, router: ActorRef) extends Actor with ActorLogging {
|
||||
class PaymentInitiator(sourceNodeId: PublicKey, router: ActorRef) extends Actor with ActorLogging {
|
||||
|
||||
override def receive: Receive = {
|
||||
case c: CreatePayment =>
|
||||
@ -17,5 +18,5 @@ class PaymentInitiator(sourceNodeId: BinaryData, router: ActorRef) extends Actor
|
||||
}
|
||||
|
||||
object PaymentInitiator {
|
||||
def props(sourceNodeId: BinaryData, router: ActorRef) = Props(classOf[PaymentInitiator], sourceNodeId, router)
|
||||
def props(sourceNodeId: PublicKey, router: ActorRef) = Props(classOf[PaymentInitiator], sourceNodeId, router)
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ case object WAITING_FOR_PAYMENT_COMPLETE extends State
|
||||
/**
|
||||
* Created by PM on 26/08/2016.
|
||||
*/
|
||||
class PaymentLifecycle(sourceNodeId: BinaryData, router: ActorRef) extends LoggingFSM[State, Data] {
|
||||
class PaymentLifecycle(sourceNodeId: PublicKey, router: ActorRef) extends LoggingFSM[State, Data] {
|
||||
|
||||
import PaymentLifecycle._
|
||||
|
||||
@ -76,7 +76,7 @@ class PaymentLifecycle(sourceNodeId: BinaryData, router: ActorRef) extends Loggi
|
||||
|
||||
object PaymentLifecycle {
|
||||
|
||||
def props(sourceNodeId: BinaryData, router: ActorRef) = Props(classOf[PaymentLifecycle], sourceNodeId, router)
|
||||
def props(sourceNodeId: PublicKey, router: ActorRef) = Props(classOf[PaymentLifecycle], sourceNodeId, router)
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -1,9 +1,10 @@
|
||||
package fr.acinq.eclair
|
||||
|
||||
import fr.acinq.bitcoin.{Base58Check, Crypto, OP_0, OP_PUSHDATA, Script}
|
||||
import fr.acinq.bitcoin.Crypto.{PrivateKey, Scalar}
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.transactions.Scripts
|
||||
import java.net.InetSocketAddress
|
||||
|
||||
import fr.acinq.bitcoin.Crypto.PrivateKey
|
||||
import fr.acinq.bitcoin.{BinaryData, DeterministicWallet, Script}
|
||||
import fr.acinq.eclair.io.Peer
|
||||
|
||||
/**
|
||||
* Created by PM on 26/04/2016.
|
||||
@ -13,46 +14,72 @@ object TestConstants {
|
||||
val pushMsat = 200000000L
|
||||
|
||||
object Alice {
|
||||
val id = randomKey.publicKey
|
||||
val channelParams = LocalParams(
|
||||
val seed = BinaryData("01" * 32)
|
||||
val master = DeterministicWallet.generate(seed)
|
||||
val extendedPrivateKey = DeterministicWallet.derivePrivateKey(master, DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil)
|
||||
val nodeParams = NodeParams(
|
||||
extendedPrivateKey = extendedPrivateKey,
|
||||
privateKey = extendedPrivateKey.privateKey,
|
||||
alias = "alice",
|
||||
color = (1: Byte, 2: Byte, 3: Byte),
|
||||
address = new InetSocketAddress("localhost", 9731),
|
||||
globalFeatures = "",
|
||||
localFeatures = "00", // no announcement
|
||||
dustLimitSatoshis = 542,
|
||||
maxHtlcValueInFlightMsat = 150000000,
|
||||
channelReserveSatoshis = 10000, // Bob will need to keep that much satoshis as direct payment
|
||||
htlcMinimumMsat = 0,
|
||||
feeratePerKw = 10000,
|
||||
toSelfDelay = 144,
|
||||
maxAcceptedHtlcs = 100,
|
||||
fundingPrivKey = PrivateKey(Array.fill[Byte](32)(1), compressed = true),
|
||||
revocationSecret = PrivateKey(Array.fill[Byte](32)(2), compressed = true),
|
||||
paymentKey = PrivateKey(Array.fill[Byte](32)(3), compressed = true),
|
||||
delayedPaymentKey = PrivateKey(Array.fill[Byte](32)(4), compressed = true),
|
||||
expiryDeltaBlocks = 144,
|
||||
htlcMinimumMsat = 0,
|
||||
minDepthBlocks = 3,
|
||||
delayBlocks = 144,
|
||||
feeratePerKw = 10000,
|
||||
feeBaseMsat = 546000,
|
||||
feeProportionalMillionth = 10,
|
||||
reserveToFundingRatio = 0.01, // note: not used (overriden below)
|
||||
maxReserveToFundingRatio = 0.05)
|
||||
val id = nodeParams.privateKey.publicKey
|
||||
val channelParams = Peer.makeChannelParams(
|
||||
nodeParams = nodeParams,
|
||||
keyIndex = 1,
|
||||
defaultFinalScriptPubKey = Script.write(Script.pay2wpkh(PrivateKey(Array.fill[Byte](32)(5), compressed = true).publicKey)),
|
||||
shaSeed = Crypto.sha256("alice-seed".getBytes()),
|
||||
isFunder = true,
|
||||
globalFeatures = "",
|
||||
localFeatures = "00" // no announcement
|
||||
fundingSatoshis).copy(
|
||||
channelReserveSatoshis = 10000 // Bob will need to keep that much satoshis as direct payment
|
||||
)
|
||||
}
|
||||
|
||||
object Bob {
|
||||
val id = randomKey.publicKey
|
||||
val channelParams = LocalParams(
|
||||
val seed = BinaryData("02" * 32)
|
||||
val master = DeterministicWallet.generate(seed)
|
||||
val extendedPrivateKey = DeterministicWallet.derivePrivateKey(master, DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil)
|
||||
val nodeParams = NodeParams(
|
||||
extendedPrivateKey = extendedPrivateKey,
|
||||
privateKey = extendedPrivateKey.privateKey,
|
||||
alias = "bob",
|
||||
color = (4: Byte, 5: Byte, 6: Byte),
|
||||
address = new InetSocketAddress("localhost", 9732),
|
||||
globalFeatures = "",
|
||||
localFeatures = "00", // no announcement
|
||||
dustLimitSatoshis = 542,
|
||||
maxHtlcValueInFlightMsat = Long.MaxValue, // Bob has no limit on the combined max value of in-flight htlcs
|
||||
channelReserveSatoshis = 20000, // Alice will need to keep that much satoshis as direct payment
|
||||
htlcMinimumMsat = 1000,
|
||||
feeratePerKw = 10000,
|
||||
toSelfDelay = 144,
|
||||
maxAcceptedHtlcs = 30,
|
||||
fundingPrivKey = PrivateKey(Array.fill[Byte](32)(11), compressed = true),
|
||||
revocationSecret = PrivateKey(Array.fill[Byte](32)(12), compressed = true),
|
||||
paymentKey = PrivateKey(Array.fill[Byte](32)(13), compressed = true),
|
||||
delayedPaymentKey = PrivateKey(Array.fill[Byte](32)(14), compressed = true),
|
||||
expiryDeltaBlocks = 144,
|
||||
htlcMinimumMsat = 1000,
|
||||
minDepthBlocks = 3,
|
||||
delayBlocks = 144,
|
||||
feeratePerKw = 10000,
|
||||
feeBaseMsat = 546000,
|
||||
feeProportionalMillionth = 10,
|
||||
reserveToFundingRatio = 0.01, // note: not used (overriden below)
|
||||
maxReserveToFundingRatio = 0.05)
|
||||
val id = nodeParams.privateKey.publicKey
|
||||
val channelParams = Peer.makeChannelParams(
|
||||
nodeParams = nodeParams,
|
||||
keyIndex = 1,
|
||||
defaultFinalScriptPubKey = Script.write(Script.pay2wpkh(PrivateKey(Array.fill[Byte](32)(15), compressed = true).publicKey)),
|
||||
shaSeed = Crypto.sha256("alice-seed".getBytes()),
|
||||
isFunder = false,
|
||||
globalFeatures = "",
|
||||
localFeatures = "00" // no announcement
|
||||
fundingSatoshis).copy(
|
||||
channelReserveSatoshis = 20000 // Alice will need to keep that much satoshis as direct payment
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,10 @@ class ThroughputSpec extends FunSuite {
|
||||
context.become(run(h2r - htlc.paymentHash))
|
||||
}
|
||||
}), "payment-handler")
|
||||
val relayer = system.actorOf(Relayer.props(Globals.Node.privateKey, paymentHandler))
|
||||
val alice = system.actorOf(Channel.props(pipe, blockchain, ???, relayer, new DummyDb()), "a")
|
||||
val bob = system.actorOf(Channel.props(pipe, blockchain, ???, relayer, new DummyDb()), "b")
|
||||
val relayerA = system.actorOf(Relayer.props(Alice.nodeParams.privateKey, paymentHandler))
|
||||
val relayerB = system.actorOf(Relayer.props(Bob.nodeParams.privateKey, paymentHandler))
|
||||
val alice = system.actorOf(Channel.props(Alice.nodeParams, pipe, blockchain, ???, relayerA, new DummyDb()), "a")
|
||||
val bob = system.actorOf(Channel.props(Bob.nodeParams, pipe, blockchain, ???, relayerB, new DummyDb()), "b")
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
alice ! INPUT_INIT_FUNDER(Bob.id, 0, TestConstants.fundingSatoshis, TestConstants.pushMsat, Alice.channelParams, bobInit)
|
||||
|
@ -33,11 +33,11 @@ class FuzzySpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
val bob2blockchain = TestProbe()
|
||||
val paymentHandlerA = system.actorOf(Props(new LocalPaymentHandler()), name = "payment-handler-a")
|
||||
val paymentHandlerB = system.actorOf(Props(new LocalPaymentHandler()), name = "payment-handler-b")
|
||||
val relayerA = system.actorOf(Relayer.props(Globals.Node.privateKey, paymentHandlerA), "relayer-a")
|
||||
val relayerB = system.actorOf(Relayer.props(Globals.Node.privateKey, paymentHandlerB), "relayer-b")
|
||||
val relayerA = system.actorOf(Relayer.props(Alice.nodeParams.privateKey, paymentHandlerA), "relayer-a")
|
||||
val relayerB = system.actorOf(Relayer.props(Bob.nodeParams.privateKey, paymentHandlerB), "relayer-b")
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, alice2blockchain.ref, router.ref, relayerA, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, bob2blockchain.ref, router.ref, relayerB, new DummyDb()))
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(Alice.nodeParams, pipe, alice2blockchain.ref, router.ref, relayerA, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(Bob.nodeParams, pipe, bob2blockchain.ref, router.ref, relayerB, new DummyDb()))
|
||||
within(30 seconds) {
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
@ -66,7 +66,7 @@ class FuzzySpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
def buildCmdAdd(paymentHash: BinaryData) = {
|
||||
val channelUpdate_ab = ChannelUpdate("00" * 64, 0, 0, "0000", cltvExpiryDelta = 4, feeBaseMsat = 642000, feeProportionalMillionths = 7, htlcMinimumMsat = 0)
|
||||
val hops = Hop(Globals.Node.publicKey, Globals.Node.publicKey, channelUpdate_ab) :: Nil
|
||||
val hops = Hop(Alice.nodeParams.privateKey.publicKey, Bob.nodeParams.privateKey.publicKey, channelUpdate_ab) :: Nil
|
||||
// we don't want to be below htlcMinimumMsat
|
||||
val amount = Random.nextInt(1000000) + 1000
|
||||
PaymentLifecycle.buildCommand(amount, paymentHash, hops, 444000)
|
||||
|
@ -1,13 +1,14 @@
|
||||
package fr.acinq.eclair.channel.states
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.testkit.{TestFSMRef, TestKitBase, TestProbe}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto}
|
||||
import fr.acinq.eclair.TestConstants
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.wire._
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants}
|
||||
|
||||
import scala.util.Random
|
||||
|
||||
@ -16,6 +17,31 @@ import scala.util.Random
|
||||
*/
|
||||
trait StateTestsHelperMethods extends TestKitBase {
|
||||
|
||||
case class Setup(alice: TestFSMRef[State, Data, Channel],
|
||||
bob: TestFSMRef[State, Data, Channel],
|
||||
alice2bob: TestProbe,
|
||||
bob2alice: TestProbe,
|
||||
blockchainA: ActorRef,
|
||||
alice2blockchain: TestProbe,
|
||||
bob2blockchain: TestProbe,
|
||||
router: TestProbe,
|
||||
relayer: TestProbe)
|
||||
|
||||
def init(): Setup = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val nodeParamsA = TestConstants.Alice.nodeParams
|
||||
val nodeParamsB = TestConstants.Bob.nodeParams
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(nodeParamsA, alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(nodeParamsB, bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
Setup(alice, bob, alice2bob, bob2alice, blockchainA, alice2blockchain, bob2blockchain, router, relayer)
|
||||
}
|
||||
|
||||
def reachNormal(alice: TestFSMRef[State, Data, Channel],
|
||||
bob: TestFSMRef[State, Data, Channel],
|
||||
alice2bob: TestProbe,
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.acinq.eclair.channel.states.a
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain.PeerWatcher
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.channel.{WAIT_FOR_FUNDING_INTERNAL, _}
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.wire.{AcceptChannel, Error, Init, OpenChannel}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -17,20 +17,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForAcceptChannelStateSpec extends TestkitBaseClass {
|
||||
class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple5[TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, ActorRef]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
within(30 seconds) {
|
||||
|
@ -4,6 +4,7 @@ import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire.{Error, Init, OpenChannel}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
@ -15,19 +16,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForOpenChannelStateSpec extends TestkitBaseClass {
|
||||
class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple4[TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
within(30 seconds) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.acinq.eclair.channel.states.b
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain.{MakeFundingTx, PeerWatcher}
|
||||
import fr.acinq.eclair.blockchain.MakeFundingTx
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire._
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -17,20 +17,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForFundingCreatedInternalStateSpec extends TestkitBaseClass {
|
||||
class WaitForFundingCreatedInternalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple5[TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, ActorRef]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
within(30 seconds) {
|
||||
|
@ -1,13 +1,12 @@
|
||||
package fr.acinq.eclair.channel.states.b
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain.{PeerWatcher, WatchConfirmed, WatchSpent}
|
||||
import fr.acinq.eclair.blockchain.{MakeFundingTx, WatchConfirmed, WatchSpent}
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire._
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -17,19 +16,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForFundingCreatedStateSpec extends TestkitBaseClass {
|
||||
class WaitForFundingCreatedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple4[TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, blockchainA, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
within(30 seconds) {
|
||||
@ -39,6 +32,8 @@ class WaitForFundingCreatedStateSpec extends TestkitBaseClass {
|
||||
alice2bob.forward(bob)
|
||||
bob2alice.expectMsgType[AcceptChannel]
|
||||
bob2alice.forward(alice)
|
||||
alice2blockchain.expectMsgType[MakeFundingTx]
|
||||
alice2blockchain.forward(blockchainA)
|
||||
awaitCond(bob.stateName == WAIT_FOR_FUNDING_CREATED)
|
||||
}
|
||||
test((bob, alice2bob, bob2alice, bob2blockchain))
|
||||
|
@ -1,14 +1,14 @@
|
||||
package fr.acinq.eclair.channel.states.b
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.bitcoin.BinaryData
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire.{AcceptChannel, Error, FundingCreated, FundingSigned, Init, OpenChannel}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -18,20 +18,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForFundingSignedStateSpec extends TestkitBaseClass {
|
||||
class WaitForFundingSignedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple5[TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, ActorRef]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
within(30 seconds) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.acinq.eclair.channel.states.c
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire._
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -17,20 +17,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForAnnSignaturesStateSpec extends TestkitBaseClass {
|
||||
class WaitForAnnSignaturesStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple7[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, ActorRef, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val (aliceParams, bobParams) = (Alice.channelParams.copy(localFeatures = "01"), Bob.channelParams.copy(localFeatures = "01"))
|
||||
val aliceInit = Init(aliceParams.globalFeatures, aliceParams.localFeatures)
|
||||
val bobInit = Init(bobParams.globalFeatures, bobParams.localFeatures)
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.acinq.eclair.channel.states.c
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire.{AcceptChannel, Error, FundingCreated, FundingLocked, FundingSigned, Init, OpenChannel}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -17,20 +17,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForFundingConfirmedStateSpec extends TestkitBaseClass {
|
||||
class WaitForFundingConfirmedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple6[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, ActorRef]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
within(30 seconds) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
package fr.acinq.eclair.channel.states.c
|
||||
|
||||
import akka.actor.{ActorRef, Props}
|
||||
import akka.actor.ActorRef
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel._
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.wire._
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.Tag
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -18,20 +18,13 @@ import scala.concurrent.duration._
|
||||
* Created by PM on 05/07/2016.
|
||||
*/
|
||||
@RunWith(classOf[JUnitRunner])
|
||||
class WaitForFundingLockedStateSpec extends TestkitBaseClass {
|
||||
class WaitForFundingLockedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
|
||||
type FixtureParam = Tuple7[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, ActorRef, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
val (aliceParams, bobParams) = if (test.tags.contains("public")) {
|
||||
(Alice.channelParams.copy(localFeatures = "01"), Bob.channelParams.copy(localFeatures = "01"))
|
||||
} else {
|
||||
|
@ -1,19 +1,17 @@
|
||||
package fr.acinq.eclair.channel.states.e
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.bitcoin.Crypto.Scalar
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Satoshi, Script, ScriptFlags, Transaction}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Satoshi, ScriptFlags, Transaction}
|
||||
import fr.acinq.eclair.TestConstants.Bob
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.blockchain.peer.CurrentBlockCount
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.channel.{Data, State, _}
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.payment.{Bind, Local, Relayed}
|
||||
import fr.acinq.eclair.transactions.{IN, OUT}
|
||||
import fr.acinq.eclair.wire.{ClosingSigned, CommitSig, Error, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFulfillHtlc}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestConstants, TestkitBaseClass}
|
||||
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -28,15 +26,8 @@ class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
type FixtureParam = Tuple7[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, TestProbe, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
within(30 seconds) {
|
||||
reachNormal(alice, bob, alice2bob, bob2alice, blockchainA, alice2blockchain, bob2blockchain)
|
||||
awaitCond(alice.stateName == NORMAL)
|
||||
|
@ -1,14 +1,11 @@
|
||||
package fr.acinq.eclair.channel.states.e
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.bitcoin.BinaryData
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.TestkitBaseClass
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.channel.{Data, State, _}
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.wire.{CommitSig, RevokeAndAck, UpdateAddHtlc}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestkitBaseClass}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
|
||||
@ -23,15 +20,8 @@ class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
type FixtureParam = Tuple7[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, TestProbe, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
within(30 seconds) {
|
||||
reachNormal(alice, bob, alice2bob, bob2alice, blockchainA, alice2blockchain, bob2blockchain)
|
||||
awaitCond(alice.stateName == NORMAL)
|
||||
|
@ -1,16 +1,13 @@
|
||||
package fr.acinq.eclair.channel.states.f
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.bitcoin.Crypto.Scalar
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Satoshi, ScriptFlags, Transaction}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestkitBaseClass}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.TestkitBaseClass
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.blockchain.peer.CurrentBlockCount
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.channel.{Data, State, _}
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.wire.{CommitSig, Error, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFulfillHtlc}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -26,16 +23,9 @@ class ShutdownStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
type FixtureParam = Tuple6[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
within(35 seconds) {
|
||||
val setup = init()
|
||||
import setup._
|
||||
within(30 seconds) {
|
||||
reachNormal(alice, bob, alice2bob, bob2alice, blockchainA, alice2blockchain, bob2blockchain)
|
||||
val sender = TestProbe()
|
||||
// alice sends an HTLC to bob
|
||||
|
@ -1,13 +1,10 @@
|
||||
package fr.acinq.eclair.channel.states.g
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.eclair.{TestBitcoinClient, TestkitBaseClass}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.TestkitBaseClass
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.channel.{Data, State, _}
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.wire.{ClosingSigned, Error, Shutdown}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -23,16 +20,9 @@ class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods
|
||||
type FixtureParam = Tuple6[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, TestProbe]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val setup = init()
|
||||
import setup._
|
||||
// note that alice.initialFeeRate != bob.initialFeeRate
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
within(30 seconds) {
|
||||
reachNormal(alice, bob, alice2bob, bob2alice, blockchainA, alice2blockchain, bob2blockchain)
|
||||
val sender = TestProbe()
|
||||
|
@ -1,14 +1,11 @@
|
||||
package fr.acinq.eclair.channel.states.h
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.{TestFSMRef, TestProbe}
|
||||
import fr.acinq.bitcoin.Transaction
|
||||
import fr.acinq.eclair.{Globals, TestBitcoinClient, TestkitBaseClass}
|
||||
import fr.acinq.eclair.TestConstants.{Alice, Bob}
|
||||
import fr.acinq.eclair.TestkitBaseClass
|
||||
import fr.acinq.eclair.blockchain._
|
||||
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
|
||||
import fr.acinq.eclair.channel.{Data, State, _}
|
||||
import fr.acinq.eclair.db.DummyDb
|
||||
import fr.acinq.eclair.wire._
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -24,15 +21,8 @@ class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
|
||||
type FixtureParam = Tuple7[TestFSMRef[State, Data, Channel], TestFSMRef[State, Data, Channel], TestProbe, TestProbe, TestProbe, TestProbe, List[Transaction]]
|
||||
|
||||
override def withFixture(test: OneArgTest) = {
|
||||
val alice2bob = TestProbe()
|
||||
val bob2alice = TestProbe()
|
||||
val alice2blockchain = TestProbe()
|
||||
val blockchainA = system.actorOf(Props(new PeerWatcher(new TestBitcoinClient())))
|
||||
val bob2blockchain = TestProbe()
|
||||
val relayer = TestProbe()
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(alice2bob.ref, alice2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(bob2alice.ref, bob2blockchain.ref, router.ref, relayer.ref, new DummyDb()))
|
||||
val setup = init()
|
||||
import setup._
|
||||
within(30 seconds) {
|
||||
reachNormal(alice, bob, alice2bob, bob2alice, blockchainA, alice2blockchain, bob2blockchain)
|
||||
|
||||
|
@ -37,8 +37,8 @@ class RustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with fix
|
||||
// we just bypass the relayer for this test
|
||||
val relayer = paymentHandler
|
||||
val router = TestProbe()
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, blockchainA, router.ref, relayer, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(pipe, blockchainB, router.ref, relayer, new DummyDb()))
|
||||
val alice: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(Alice.nodeParams, pipe, blockchainA, router.ref, relayer, new DummyDb()))
|
||||
val bob: TestFSMRef[State, Data, Channel] = TestFSMRef(new Channel(Bob.nodeParams, pipe, blockchainB, router.ref, relayer, new DummyDb()))
|
||||
val aliceInit = Init(Alice.channelParams.globalFeatures, Alice.channelParams.localFeatures)
|
||||
val bobInit = Init(Bob.channelParams.globalFeatures, Bob.channelParams.localFeatures)
|
||||
// alice and bob will both have 1 000 000 sat
|
||||
|
@ -1,7 +1,8 @@
|
||||
package fr.acinq.eclair.router
|
||||
|
||||
import fr.acinq.eclair.TestConstants.Alice
|
||||
import fr.acinq.eclair._
|
||||
import fr.acinq.eclair.router.Announcements._
|
||||
import fr.acinq.eclair.{Globals, _}
|
||||
import org.junit.runner.RunWith
|
||||
import org.scalatest.FunSuite
|
||||
import org.scalatest.junit.JUnitRunner
|
||||
@ -24,16 +25,14 @@ class AnnouncementsSpec extends FunSuite {
|
||||
}
|
||||
|
||||
test("create valid signed node announcement") {
|
||||
val key = randomKey
|
||||
val ann = makeNodeAnnouncement(key, Globals.Node.alias, Globals.Node.color, Globals.Node.address :: Nil, Platform.currentTime / 1000)
|
||||
val ann = makeNodeAnnouncement(Alice.nodeParams.privateKey, Alice.nodeParams.alias, Alice.nodeParams.color, Alice.nodeParams.address :: Nil, Platform.currentTime / 1000)
|
||||
assert(checkSig(ann))
|
||||
assert(checkSig(ann.copy(timestamp = 153)) === false)
|
||||
}
|
||||
|
||||
test("create valid signed channel update announcement") {
|
||||
val key = randomKey
|
||||
val ann = makeChannelUpdate(key, randomKey.publicKey, 45561, Globals.expiry_delta_blocks, Globals.htlc_minimum_msat, Globals.fee_base_msat, Globals.fee_proportional_millionth, Platform.currentTime / 1000)
|
||||
assert(checkSig(ann, key.publicKey))
|
||||
val ann = makeChannelUpdate(Alice.nodeParams.privateKey, randomKey.publicKey, 45561, Alice.nodeParams.expiryDeltaBlocks, Alice.nodeParams.htlcMinimumMsat, Alice.nodeParams.feeBaseMsat, Alice.nodeParams.feeProportionalMillionth, Platform.currentTime / 1000)
|
||||
assert(checkSig(ann, Alice.nodeParams.privateKey.publicKey))
|
||||
assert(checkSig(ann, randomKey.publicKey) === false)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user