mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-23 14:40:34 +01:00
use Satoshi explicitely instead of Long when specifying amounts, add an "Amount" field to
our "Open Channel" dialog box
This commit is contained in:
parent
c7145d6dbc
commit
bdc66ff4ce
11 changed files with 147 additions and 66 deletions
|
@ -15,7 +15,7 @@ import grizzled.slf4j.Logging
|
|||
|
||||
import scala.concurrent.{Await, ExecutionContext}
|
||||
import scala.concurrent.duration._
|
||||
import fr.acinq.bitcoin.BitcoinJsonRPCClient
|
||||
import fr.acinq.bitcoin.{BitcoinJsonRPCClient, Satoshi}
|
||||
import fr.acinq.eclair.gui.MainWindow
|
||||
import fr.acinq.eclair.router.IRCRouter
|
||||
|
||||
|
@ -35,22 +35,22 @@ class Setup extends Logging {
|
|||
logger.info(s"nodeid=${Globals.Node.publicKey}")
|
||||
val config = ConfigFactory.load()
|
||||
|
||||
implicit lazy val system = ActorSystem()
|
||||
implicit val materializer = ActorMaterializer()
|
||||
implicit val timeout = Timeout(30 seconds)
|
||||
implicit val formats = org.json4s.DefaultFormats
|
||||
implicit val ec = ExecutionContext.Implicits.global
|
||||
|
||||
val bitcoin_client = new BitcoinJsonRPCClient(
|
||||
user = config.getString("eclair.bitcoind.rpcuser"),
|
||||
password = config.getString("eclair.bitcoind.rpcpassword"),
|
||||
host = config.getString("eclair.bitcoind.host"),
|
||||
port = config.getInt("eclair.bitcoind.port"))
|
||||
|
||||
implicit val formats = org.json4s.DefaultFormats
|
||||
implicit val ec = ExecutionContext.Implicits.global
|
||||
val chain = Await.result(bitcoin_client.invoke("getblockchaininfo").map(json => (json \ "chain").extract[String]), 10 seconds)
|
||||
assert(chain == "testnet" || chain == "regtest" || chain == "segnet4", "you should be on testnet or regtest or segnet4")
|
||||
val bitcoinVersion = Await.result(bitcoin_client.invoke("getinfo").map(json => (json \ "version").extract[String]), 10 seconds)
|
||||
|
||||
implicit lazy val system = ActorSystem()
|
||||
implicit val materializer = ActorMaterializer()
|
||||
implicit val timeout = Timeout(30 seconds)
|
||||
|
||||
val blockchain = system.actorOf(Props(new PollingWatcher(new ExtendedBitcoinClient(bitcoin_client))), name = "blockchain")
|
||||
val paymentHandler = config.getString("eclair.payment-handler") match {
|
||||
case "local" => system.actorOf(Props[LocalPaymentHandler], name = "payment-handler")
|
||||
|
@ -67,7 +67,7 @@ class Setup extends Logging {
|
|||
|
||||
override def paymentHandler: ActorRef = _setup.paymentHandler
|
||||
|
||||
override def connect(host: String, port: Int, amount: Long): Unit = system.actorOf(Client.props(host, port, amount, register))
|
||||
override def connect(host: String, port: Int, amount: Satoshi): Unit = system.actorOf(Client.props(host, port, amount, register))
|
||||
}
|
||||
Http().bindAndHandle(api.route, config.getString("eclair.api.host"), config.getInt("eclair.api.port"))
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import akka.http.scaladsl.model.headers.RawHeader
|
|||
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpResponse, StatusCodes}
|
||||
import akka.util.Timeout
|
||||
import akka.http.scaladsl.server.Directives._
|
||||
import fr.acinq.bitcoin.BinaryData
|
||||
import fr.acinq.bitcoin.{BinaryData, Satoshi}
|
||||
import fr.acinq.eclair._
|
||||
import fr.acinq.eclair.channel._
|
||||
import grizzled.slf4j.Logging
|
||||
|
@ -42,7 +42,7 @@ trait Service extends Logging {
|
|||
implicit val formats = org.json4s.DefaultFormats + new BinaryDataSerializer + new StateSerializer + new Sha256Serializer + new ShaChainSerializer
|
||||
implicit val timeout = Timeout(30 seconds)
|
||||
|
||||
def connect(host: String, port: Int, amount: Long): Unit
|
||||
def connect(host: String, port: Int, amount: Satoshi): Unit
|
||||
|
||||
def register: ActorRef
|
||||
|
||||
|
@ -64,7 +64,7 @@ trait Service extends Logging {
|
|||
val json = parse(body).extract[JsonRPCBody]
|
||||
val f_res: Future[AnyRef] = json match {
|
||||
case JsonRPCBody(_, _, "connect", JString(host) :: JInt(port) :: JInt(anchor_amount) :: Nil) =>
|
||||
connect(host, port.toInt, anchor_amount.toLong)
|
||||
connect(host, port.toInt, Satoshi(anchor_amount.toLong))
|
||||
Future.successful("ok")
|
||||
case JsonRPCBody(_, _, "info", _) =>
|
||||
Future.successful(Status(Globals.Node.id))
|
||||
|
|
|
@ -44,9 +44,9 @@ class ExtendedBitcoinClient(val client: BitcoinJsonRPCClient) {
|
|||
* @return a Future[txid] where txid (a String) is the is of the tx that sends the bitcoins
|
||||
*/
|
||||
def sendFromAccount(account: String, destination: String, amount: Double)(implicit ec: ExecutionContext): Future[String] =
|
||||
client.invoke("sendfrom", account, destination, amount) collect {
|
||||
case JString(txid) => txid
|
||||
}
|
||||
client.invoke("sendfrom", account, destination, amount) collect {
|
||||
case JString(txid) => txid
|
||||
}
|
||||
|
||||
def getRawTransaction(txId: String)(implicit ec: ExecutionContext): Future[String] =
|
||||
client.invoke("getrawtransaction", txId) collect {
|
||||
|
@ -110,9 +110,9 @@ class ExtendedBitcoinClient(val client: BitcoinJsonRPCClient) {
|
|||
} yield tx
|
||||
}
|
||||
|
||||
def makeAnchorTx(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Long)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
def makeAnchorTx(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Satoshi)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
val anchorOutputScript = channel.Scripts.anchorPubkeyScript(ourCommitPub, theirCommitPub)
|
||||
val tx = Transaction(version = 2, txIn = Seq.empty[TxIn], txOut = TxOut(Satoshi(amount), anchorOutputScript) :: Nil, lockTime = 0)
|
||||
val tx = Transaction(version = 2, txIn = Seq.empty[TxIn], txOut = TxOut(amount, anchorOutputScript) :: Nil, lockTime = 0)
|
||||
val future = for {
|
||||
FundTransactionResponse(tx1, changepos, fee) <- fundTransaction(tx)
|
||||
SignTransactionResponse(anchorTx, true) <- signTransaction(tx1)
|
||||
|
@ -151,7 +151,7 @@ class ExtendedBitcoinClient(val client: BitcoinJsonRPCClient) {
|
|||
* @return the current number of blocks in the active chain
|
||||
*/
|
||||
def getBlockCount(implicit ec: ExecutionContext): Future[Long] =
|
||||
client.invoke("getblockcount") collect {
|
||||
case JInt(count) => count.toLong
|
||||
}
|
||||
client.invoke("getblockcount") collect {
|
||||
case JInt(count) => count.toLong
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package fr.acinq.eclair.blockchain
|
||||
|
||||
import akka.actor.ActorRef
|
||||
import fr.acinq.bitcoin.{Transaction, TxOut, BinaryData}
|
||||
import fr.acinq.bitcoin.{BinaryData, Satoshi, Transaction, TxOut}
|
||||
import fr.acinq.eclair.channel.BlockchainEvent
|
||||
|
||||
/**
|
||||
|
@ -13,10 +13,17 @@ import fr.acinq.eclair.channel.BlockchainEvent
|
|||
trait Watch {
|
||||
def channel: ActorRef
|
||||
}
|
||||
|
||||
final case class WatchConfirmed(channel: ActorRef, txId: BinaryData, minDepth: Int, event: BlockchainEvent) extends Watch
|
||||
|
||||
final case class WatchSpent(channel: ActorRef, txId: BinaryData, outputIndex: Int, minDepth: Int, event: BlockchainEvent) extends Watch
|
||||
final case class WatchLost(channel: ActorRef, txId: BinaryData, minDepth: Int, event: BlockchainEvent) extends Watch // notify me if confirmation number gets below minDepth
|
||||
|
||||
final case class WatchLost(channel: ActorRef, txId: BinaryData, minDepth: Int, event: BlockchainEvent) extends Watch
|
||||
|
||||
// notify me if confirmation number gets below minDepth
|
||||
|
||||
final case class Publish(tx: Transaction)
|
||||
final case class MakeAnchor(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Long)
|
||||
|
||||
final case class MakeAnchor(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Satoshi)
|
||||
|
||||
// @formatter:on
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package fr.acinq.eclair.channel
|
||||
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Transaction}
|
||||
import fr.acinq.bitcoin.{BinaryData, Crypto, Satoshi, Transaction}
|
||||
import lightning._
|
||||
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
@ -23,23 +23,41 @@ import scala.concurrent.duration.FiniteDuration
|
|||
"Y8888P" 888 d88P 888 888 8888888888 "Y8888P"
|
||||
*/
|
||||
sealed trait State
|
||||
|
||||
case object INIT_NOANCHOR extends State
|
||||
|
||||
case object INIT_WITHANCHOR extends State
|
||||
|
||||
case object OPEN_WAIT_FOR_OPEN_NOANCHOR extends State
|
||||
|
||||
case object OPEN_WAIT_FOR_OPEN_WITHANCHOR extends State
|
||||
|
||||
case object OPEN_WAIT_FOR_ANCHOR extends State
|
||||
|
||||
case object OPEN_WAIT_FOR_COMMIT_SIG extends State
|
||||
|
||||
case object OPEN_WAITING_THEIRANCHOR extends State
|
||||
|
||||
case object OPEN_WAITING_OURANCHOR extends State
|
||||
|
||||
case object OPEN_WAIT_FOR_COMPLETE_OURANCHOR extends State
|
||||
|
||||
case object OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR extends State
|
||||
|
||||
case object NORMAL extends State
|
||||
|
||||
case object CLEARING extends State
|
||||
|
||||
case object NEGOTIATING extends State
|
||||
|
||||
case object CLOSING extends State
|
||||
|
||||
case object CLOSED extends State
|
||||
|
||||
case object ERR_ANCHOR_LOST extends State
|
||||
|
||||
case object ERR_ANCHOR_TIMEOUT extends State
|
||||
|
||||
case object ERR_INFORMATION_LEAK extends State
|
||||
|
||||
/*
|
||||
|
@ -54,18 +72,28 @@ case object ERR_INFORMATION_LEAK extends State
|
|||
*/
|
||||
|
||||
case object INPUT_NO_MORE_HTLCS
|
||||
|
||||
// when requesting a mutual close, we wait for as much as this timeout, then unilateral close
|
||||
case object INPUT_CLOSE_COMPLETE_TIMEOUT
|
||||
|
||||
sealed trait BlockchainEvent
|
||||
|
||||
case object BITCOIN_ANCHOR_DEPTHOK extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_ANCHOR_LOST extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_ANCHOR_TIMEOUT extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_ANCHOR_SPENT extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_ANCHOR_OURCOMMIT_DELAYPASSED extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_SPEND_THEIRS_DONE extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_SPEND_OURS_DONE extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_STEAL_DONE extends BlockchainEvent
|
||||
|
||||
case object BITCOIN_CLOSE_DONE extends BlockchainEvent
|
||||
|
||||
/*
|
||||
|
@ -80,17 +108,26 @@ case object BITCOIN_CLOSE_DONE extends BlockchainEvent
|
|||
*/
|
||||
|
||||
sealed trait Command
|
||||
|
||||
/**
|
||||
* @param id should only be provided in tests otherwise it will be assigned automatically
|
||||
*/
|
||||
final case class CMD_ADD_HTLC(amountMsat: Int, rHash: sha256_hash, expiry: locktime, payment_route: route = route(route_step(0, next = route_step.Next.End(true)) :: Nil), originChannelId: Option[BinaryData] = None, id: Option[Long] = None, commit: Boolean = false) extends Command
|
||||
|
||||
final case class CMD_FULFILL_HTLC(id: Long, r: rval, commit: Boolean = false) extends Command
|
||||
|
||||
final case class CMD_FAIL_HTLC(id: Long, reason: String, commit: Boolean = false) extends Command
|
||||
|
||||
case object CMD_SIGN extends Command
|
||||
|
||||
final case class CMD_CLOSE(scriptPubKey: Option[BinaryData]) extends Command
|
||||
|
||||
case object CMD_GETSTATE extends Command
|
||||
|
||||
case object CMD_GETSTATEDATA extends Command
|
||||
|
||||
case object CMD_GETINFO extends Command
|
||||
|
||||
final case class RES_GETINFO(nodeid: BinaryData, channelid: BinaryData, state: State, data: Data)
|
||||
|
||||
/*
|
||||
|
@ -105,23 +142,29 @@ final case class RES_GETINFO(nodeid: BinaryData, channelid: BinaryData, state: S
|
|||
*/
|
||||
|
||||
sealed trait Data
|
||||
|
||||
case object Nothing extends Data
|
||||
final case class OurChannelParams(delay: locktime, commitPrivKey: BinaryData, finalPrivKey: BinaryData, minDepth: Int, initialFeeRate: Long, shaSeed: BinaryData, anchorAmount: Option[Long], autoSignInterval: Option[FiniteDuration] = None) {
|
||||
|
||||
final case class OurChannelParams(delay: locktime, commitPrivKey: BinaryData, finalPrivKey: BinaryData, minDepth: Int, initialFeeRate: Long, shaSeed: BinaryData, anchorAmount: Option[Satoshi], autoSignInterval: Option[FiniteDuration] = None) {
|
||||
val commitPubKey: BinaryData = Crypto.publicKeyFromPrivateKey(commitPrivKey)
|
||||
val finalPubKey: BinaryData = Crypto.publicKeyFromPrivateKey(finalPrivKey)
|
||||
}
|
||||
|
||||
final case class TheirChannelParams(delay: locktime, commitPubKey: BinaryData, finalPubKey: BinaryData, minDepth: Option[Int], initialFeeRate: Long)
|
||||
|
||||
object TheirChannelParams {
|
||||
def apply(params: OurChannelParams) = new TheirChannelParams(params.delay, params.commitPubKey, params.finalPubKey, Some(params.minDepth), params.initialFeeRate)
|
||||
}
|
||||
|
||||
sealed trait Direction
|
||||
|
||||
case object IN extends Direction
|
||||
|
||||
case object OUT extends Direction
|
||||
|
||||
case class Htlc(direction: Direction, add: update_add_htlc, val previousChannelId: Option[BinaryData])
|
||||
|
||||
final case class CommitmentSpec(htlcs: Set[Htlc], feeRate: Long, initial_amount_us_msat : Long, initial_amount_them_msat: Long, amount_us_msat: Long, amount_them_msat: Long) {
|
||||
final case class CommitmentSpec(htlcs: Set[Htlc], feeRate: Long, initial_amount_us_msat: Long, initial_amount_them_msat: Long, amount_us_msat: Long, amount_them_msat: Long) {
|
||||
val totalFunds = amount_us_msat + amount_them_msat + htlcs.toSeq.map(_.add.amountMsat).sum
|
||||
}
|
||||
|
||||
|
@ -131,25 +174,33 @@ trait HasCommitments {
|
|||
def commitments: Commitments
|
||||
}
|
||||
|
||||
final case class DATA_OPEN_WAIT_FOR_OPEN (ourParams: OurChannelParams) extends Data
|
||||
final case class DATA_OPEN_WAIT_FOR_OPEN(ourParams: OurChannelParams) extends Data
|
||||
|
||||
final case class DATA_OPEN_WITH_ANCHOR_WAIT_FOR_ANCHOR(ourParams: OurChannelParams, theirParams: TheirChannelParams, theirRevocationHash: BinaryData, theirNextRevocationHash: sha256_hash) extends Data
|
||||
final case class DATA_OPEN_WAIT_FOR_ANCHOR (ourParams: OurChannelParams, theirParams: TheirChannelParams, theirRevocationHash: sha256_hash, theirNextRevocationHash: sha256_hash) extends Data
|
||||
final case class DATA_OPEN_WAIT_FOR_COMMIT_SIG (ourParams: OurChannelParams, theirParams: TheirChannelParams, anchorTx: Transaction, anchorOutputIndex: Int, initialCommitment: TheirCommit, theirNextRevocationHash: sha256_hash) extends Data
|
||||
final case class DATA_OPEN_WAITING (commitments: Commitments, deferred: Option[open_complete]) extends Data with HasCommitments
|
||||
final case class DATA_NORMAL (commitments: Commitments,
|
||||
ourClearing: Option[close_clearing],
|
||||
downstreams: Map[Long, Option[BinaryData]]) extends Data with HasCommitments
|
||||
final case class DATA_CLEARING (commitments: Commitments,
|
||||
ourClearing: close_clearing, theirClearing: close_clearing,
|
||||
downstreams: Map[Long, Option[BinaryData]]) extends Data with HasCommitments
|
||||
final case class DATA_NEGOTIATING (commitments: Commitments,
|
||||
ourClearing: close_clearing, theirClearing: close_clearing, ourSignature: close_signature) extends Data with HasCommitments
|
||||
final case class DATA_CLOSING (commitments: Commitments,
|
||||
ourSignature: Option[close_signature] = None,
|
||||
mutualClosePublished: Option[Transaction] = None,
|
||||
ourCommitPublished: Option[Transaction] = None,
|
||||
theirCommitPublished: Option[Transaction] = None,
|
||||
revokedPublished: Seq[Transaction] = Seq()) extends Data with HasCommitments {
|
||||
|
||||
final case class DATA_OPEN_WAIT_FOR_ANCHOR(ourParams: OurChannelParams, theirParams: TheirChannelParams, theirRevocationHash: sha256_hash, theirNextRevocationHash: sha256_hash) extends Data
|
||||
|
||||
final case class DATA_OPEN_WAIT_FOR_COMMIT_SIG(ourParams: OurChannelParams, theirParams: TheirChannelParams, anchorTx: Transaction, anchorOutputIndex: Int, initialCommitment: TheirCommit, theirNextRevocationHash: sha256_hash) extends Data
|
||||
|
||||
final case class DATA_OPEN_WAITING(commitments: Commitments, deferred: Option[open_complete]) extends Data with HasCommitments
|
||||
|
||||
final case class DATA_NORMAL(commitments: Commitments,
|
||||
ourClearing: Option[close_clearing],
|
||||
downstreams: Map[Long, Option[BinaryData]]) extends Data with HasCommitments
|
||||
|
||||
final case class DATA_CLEARING(commitments: Commitments,
|
||||
ourClearing: close_clearing, theirClearing: close_clearing,
|
||||
downstreams: Map[Long, Option[BinaryData]]) extends Data with HasCommitments
|
||||
|
||||
final case class DATA_NEGOTIATING(commitments: Commitments,
|
||||
ourClearing: close_clearing, theirClearing: close_clearing, ourSignature: close_signature) extends Data with HasCommitments
|
||||
|
||||
final case class DATA_CLOSING(commitments: Commitments,
|
||||
ourSignature: Option[close_signature] = None,
|
||||
mutualClosePublished: Option[Transaction] = None,
|
||||
ourCommitPublished: Option[Transaction] = None,
|
||||
theirCommitPublished: Option[Transaction] = None,
|
||||
revokedPublished: Seq[Transaction] = Seq()) extends Data with HasCommitments {
|
||||
assert(mutualClosePublished.isDefined || ourCommitPublished.isDefined || theirCommitPublished.isDefined || revokedPublished.size > 0, "there should be at least one tx published in this state")
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package fr.acinq.eclair.channel
|
|||
|
||||
import akka.actor._
|
||||
import akka.util.Timeout
|
||||
import fr.acinq.bitcoin.{BinaryData, DeterministicWallet}
|
||||
import fr.acinq.bitcoin.{BinaryData, DeterministicWallet, Satoshi}
|
||||
import fr.acinq.eclair.io.AuthHandler
|
||||
import fr.acinq.eclair.Globals
|
||||
|
||||
|
@ -58,7 +58,7 @@ object Register {
|
|||
def props(blockchain: ActorRef, paymentHandler: ActorRef) = Props(classOf[Register], blockchain, paymentHandler)
|
||||
|
||||
// @formatter:off
|
||||
case class CreateChannel(connection: ActorRef, anchorAmount: Option[Long])
|
||||
case class CreateChannel(connection: ActorRef, anchorAmount: Option[Satoshi])
|
||||
|
||||
case class ListChannels()
|
||||
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
package fr.acinq.eclair.gui
|
||||
|
||||
import javafx.collections.FXCollections
|
||||
import javafx.event.{ActionEvent, EventHandler}
|
||||
import javafx.geometry.{Insets, Pos}
|
||||
import javafx.scene.{Node, Scene}
|
||||
import javafx.scene.control.{Button, Label, TextField}
|
||||
import javafx.scene.input.{KeyCode, KeyEvent}
|
||||
import javafx.scene.control.{Button, ComboBox, Label, TextField}
|
||||
import javafx.scene.layout.GridPane
|
||||
import javafx.scene.{Node, Scene}
|
||||
import javafx.stage.{Modality, Stage, StageStyle}
|
||||
|
||||
import fr.acinq.bitcoin.Satoshi
|
||||
|
||||
/**
|
||||
* Created by PM on 16/08/2016.
|
||||
*/
|
||||
|
@ -15,12 +17,12 @@ class DialogOpen(primaryStage: Stage, handlers: Handlers) extends Stage() {
|
|||
initModality(Modality.WINDOW_MODAL)
|
||||
initStyle(StageStyle.UTILITY)
|
||||
initOwner(primaryStage)
|
||||
setWidth(300)
|
||||
setHeight(100)
|
||||
setWidth(500)
|
||||
setHeight(300)
|
||||
// center on parent
|
||||
setX(primaryStage.getX() + primaryStage.getWidth() / 2 - getWidth() / 2)
|
||||
setY(primaryStage.getY() + primaryStage.getHeight() / 2 - getHeight() / 2)
|
||||
setTitle("Open a new channel")
|
||||
setTitle("Create a new channel")
|
||||
setResizable(false)
|
||||
|
||||
val grid = new GridPane()
|
||||
|
@ -35,16 +37,37 @@ class DialogOpen(primaryStage: Stage, handlers: Handlers) extends Stage() {
|
|||
val textFieldHostPort = new TextField()
|
||||
grid.add(textFieldHostPort, 1, 0)
|
||||
|
||||
val btn = new Button("Connect")
|
||||
val labelAmount = new Label("Amount (msat)")
|
||||
grid.add(labelAmount, 0, 1)
|
||||
|
||||
val textFieldAmount = new TextField("10")
|
||||
grid.add(textFieldAmount, 1, 1)
|
||||
|
||||
val units = FXCollections.observableArrayList(
|
||||
"milliBTC",
|
||||
"Satoshi",
|
||||
"milliSatoshi"
|
||||
)
|
||||
val unitChooser = new ComboBox(units)
|
||||
unitChooser.setValue(units.get(0))
|
||||
grid.add(unitChooser, 2, 1)
|
||||
|
||||
val btn = new Button("Create channel")
|
||||
btn.setOnAction(new EventHandler[ActionEvent] {
|
||||
override def handle(event: ActionEvent): Unit = {
|
||||
handlers.open(textFieldHostPort.getText)
|
||||
val raw = textFieldAmount.getText.toLong
|
||||
val amount = unitChooser.getValue match {
|
||||
case "milliBTC" => Satoshi(raw * 100000L)
|
||||
case "Satoshi" => Satoshi(raw)
|
||||
case "milliSatoshi" => Satoshi(raw / 1000L)
|
||||
}
|
||||
handlers.open(textFieldHostPort.getText, amount)
|
||||
event.getSource.asInstanceOf[Node].getScene.getWindow.hide()
|
||||
}
|
||||
})
|
||||
// click on enter
|
||||
btn.defaultButtonProperty().bind(btn.focusedProperty())
|
||||
grid.add(btn, 1, 1)
|
||||
grid.add(btn, 1, 2)
|
||||
|
||||
val scene = new Scene(grid)
|
||||
setScene(scene)
|
||||
|
|
|
@ -4,7 +4,7 @@ package fr.acinq.eclair.gui
|
|||
import javafx.application.Platform
|
||||
import javafx.scene.control.{TextArea, TextField}
|
||||
|
||||
import fr.acinq.bitcoin.BinaryData
|
||||
import fr.acinq.bitcoin.{BinaryData, Satoshi}
|
||||
import fr.acinq.eclair.io.Client
|
||||
import fr.acinq.eclair.router.CreatePayment
|
||||
import fr.acinq.eclair._
|
||||
|
@ -17,12 +17,11 @@ class Handlers(setup: Setup) extends Logging {
|
|||
|
||||
import setup._
|
||||
|
||||
def open(hostPort: String) = {
|
||||
def open(hostPort: String, amount: Satoshi) = {
|
||||
val regex = "([a-zA-Z0-9\\.\\-_]+):([0-9]+)".r
|
||||
hostPort match {
|
||||
case regex(host, port) =>
|
||||
logger.info(s"connecting to $host:$port")
|
||||
val amount = 1000000L
|
||||
system.actorOf(Client.props(host, port.toInt, amount, register))
|
||||
case _ => {}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@ import java.net.InetSocketAddress
|
|||
|
||||
import akka.actor._
|
||||
import akka.io.{IO, Tcp}
|
||||
import fr.acinq.bitcoin.Satoshi
|
||||
import fr.acinq.eclair.channel.Register.CreateChannel
|
||||
|
||||
/**
|
||||
* Created by PM on 27/10/2015.
|
||||
*/
|
||||
class Client(remote: InetSocketAddress, amount: Long, register: ActorRef) extends Actor with ActorLogging {
|
||||
* Created by PM on 27/10/2015.
|
||||
*/
|
||||
class Client(remote: InetSocketAddress, amount: Satoshi, register: ActorRef) extends Actor with ActorLogging {
|
||||
|
||||
import Tcp._
|
||||
import context.system
|
||||
|
@ -23,14 +24,14 @@ class Client(remote: InetSocketAddress, amount: Long, register: ActorRef) extend
|
|||
log.info(s"connected to $remote")
|
||||
val connection = sender()
|
||||
register ! CreateChannel(connection, Some(amount))
|
||||
// TODO : kill this actor ?
|
||||
// TODO : kill this actor ?
|
||||
}
|
||||
}
|
||||
|
||||
object Client extends App {
|
||||
|
||||
def props(address: InetSocketAddress, amount: Long, register: ActorRef): Props = Props(classOf[Client], address, register)
|
||||
def props(address: InetSocketAddress, amount: Satoshi, register: ActorRef): Props = Props(classOf[Client], address, amount, register)
|
||||
|
||||
def props(host: String, port: Int, amount: Long, register: ActorRef): Props = Props(classOf[Client], new InetSocketAddress(host, port), amount, register)
|
||||
def props(host: String, port: Int, amount: Satoshi, register: ActorRef): Props = Props(classOf[Client], new InetSocketAddress(host, port), amount, register)
|
||||
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ class TestBitcoinClient extends ExtendedBitcoinClient(new BitcoinJsonRPCClient("
|
|||
|
||||
client.client.close()
|
||||
|
||||
override def makeAnchorTx(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Long)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
override def makeAnchorTx(ourCommitPub: BinaryData, theirCommitPub: BinaryData, amount: Satoshi)(implicit ec: ExecutionContext): Future[(Transaction, Int)] = {
|
||||
val anchorTx = Transaction(version = 1,
|
||||
txIn = Seq.empty[TxIn],
|
||||
txOut = TxOut(Satoshi(amount), Scripts.anchorPubkeyScript(ourCommitPub, theirCommitPub)) :: Nil,
|
||||
txOut = TxOut(amount, Scripts.anchorPubkeyScript(ourCommitPub, theirCommitPub)) :: Nil,
|
||||
lockTime = 0
|
||||
)
|
||||
Future.successful((anchorTx, 0))
|
||||
|
|
|
@ -19,7 +19,7 @@ object TestConstants {
|
|||
object Alice {
|
||||
val (Base58.Prefix.SecretKeyTestnet, commitPrivKey) = Base58Check.decode("cQPmcNr6pwBQPyGfab3SksE9nTCtx9ism9T4dkS9dETNU2KKtJHk")
|
||||
val (Base58.Prefix.SecretKeyTestnet, finalPrivKey) = Base58Check.decode("cUrAtLtV7GGddqdkhUxnbZVDWGJBTducpPoon3eKp9Vnr1zxs6BG")
|
||||
val channelParams = OurChannelParams(locktime(Blocks(4)), commitPrivKey, finalPrivKey, 1, 10000, Crypto.sha256("alice-seed".getBytes()), Some(anchorAmount))
|
||||
val channelParams = OurChannelParams(locktime(Blocks(4)), commitPrivKey, finalPrivKey, 1, 10000, Crypto.sha256("alice-seed".getBytes()), Some(Satoshi(anchorAmount)))
|
||||
val finalPubKey = channelParams.finalPubKey
|
||||
|
||||
def revocationHash(index: Long) = Helpers.revocationHash(channelParams.shaSeed, index)
|
||||
|
|
Loading…
Add table
Reference in a new issue