mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-01-18 21:34:39 +01:00
Bump Eclair version (#2405)
* Bump Eclair version * cleanup * Bump JVM version for CI * Update docs * Fix docs
This commit is contained in:
parent
0d07d558c4
commit
05e21b1200
4
.github/workflows/Linux_2.12_RPC_Tests.yml
vendored
4
.github/workflows/Linux_2.12_RPC_Tests.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Linux 2.13 bitcoind and eclair rpc tests
|
||||
name: Linux 2.12 bitcoind and eclair rpc tests
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
||||
|
||||
@ -14,6 +14,8 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Scala
|
||||
uses: olafurpg/setup-scala@v10
|
||||
with:
|
||||
java-version: adopt@1.11
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
|
2
.github/workflows/Linux_2.13_RPC_Tests.yml
vendored
2
.github/workflows/Linux_2.13_RPC_Tests.yml
vendored
@ -14,6 +14,8 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Scala
|
||||
uses: olafurpg/setup-scala@v10
|
||||
with:
|
||||
java-version: adopt@1.11
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
|
2
.github/workflows/Mac_2.13_RPC_Tests.yml
vendored
2
.github/workflows/Mac_2.13_RPC_Tests.yml
vendored
@ -14,6 +14,8 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Scala
|
||||
uses: olafurpg/setup-scala@v10
|
||||
with:
|
||||
java-version: adopt@1.11
|
||||
- name: Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
|
@ -1,30 +1,24 @@
|
||||
package org.bitcoins.commons.jsonmodels.eclair
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
|
||||
import org.bitcoins.commons.serializers.JsonReaders._
|
||||
import org.bitcoins.core.config.BitcoinNetwork
|
||||
import org.bitcoins.core.currency.Satoshis
|
||||
import org.bitcoins.core.protocol.ln.channel.{ChannelState, FundedChannelId}
|
||||
import org.bitcoins.core.protocol.ln.channel.{
|
||||
ChannelId,
|
||||
ChannelState,
|
||||
FundedChannelId,
|
||||
ShortChannelId
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.fee.FeeProportionalMillionths
|
||||
import org.bitcoins.core.protocol.ln.node.{Feature, FeatureSupport, NodeId}
|
||||
import org.bitcoins.core.protocol.ln.{
|
||||
LnHumanReadablePart,
|
||||
PaymentPreimage,
|
||||
ShortChannelId
|
||||
}
|
||||
import org.bitcoins.crypto.{
|
||||
DoubleSha256Digest,
|
||||
DoubleSha256DigestBE,
|
||||
ECDigitalSignature,
|
||||
Sha256Digest,
|
||||
StringFactory
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.{LnHumanReadablePart, PaymentPreimage}
|
||||
import org.bitcoins.crypto._
|
||||
import play.api.libs.json.JsObject
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
sealed abstract class EclairModels
|
||||
@ -51,6 +45,23 @@ case class ChannelCommandResult(
|
||||
Either[ShortChannelId, FundedChannelId],
|
||||
State]
|
||||
)
|
||||
|
||||
case class UpdateRelayFeeResult(
|
||||
results: Map[Either[ShortChannelId, FundedChannelId], UpdateRelayFee])
|
||||
|
||||
sealed trait UpdateRelayFee
|
||||
|
||||
object UpdateRelayFee {
|
||||
|
||||
case class OK(
|
||||
channelId: ChannelId,
|
||||
feeBaseMsat: MilliSatoshis,
|
||||
feeProportionalMillionths: Long)
|
||||
extends UpdateRelayFee
|
||||
|
||||
case class Error(message: String) extends UpdateRelayFee
|
||||
}
|
||||
|
||||
sealed trait State
|
||||
|
||||
object ChannelCommandResult extends StringFactory[State] {
|
||||
@ -343,7 +354,8 @@ object OutgoingPaymentStatus {
|
||||
completedAt: Instant //milliseconds
|
||||
) extends OutgoingPaymentStatus
|
||||
|
||||
case class Failed(failures: Seq[PaymentFailure]) extends OutgoingPaymentStatus
|
||||
case class Failed(failures: Seq[PaymentFailure], completedAt: Instant)
|
||||
extends OutgoingPaymentStatus
|
||||
}
|
||||
|
||||
case class PaymentFailure(
|
||||
|
@ -1,11 +1,5 @@
|
||||
package org.bitcoins.commons.serializers
|
||||
|
||||
import java.io.File
|
||||
import java.net.{InetAddress, InetSocketAddress, URI}
|
||||
import java.nio.file.Path
|
||||
import java.time._
|
||||
import java.util.UUID
|
||||
|
||||
import org.bitcoins.commons.jsonmodels._
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind.RpcOpts.LabelPurpose
|
||||
import org.bitcoins.commons.jsonmodels.bitcoind._
|
||||
@ -41,6 +35,11 @@ import org.bitcoins.core.wallet.fee.{BitcoinFeeUnit, SatoshisPerByte}
|
||||
import org.bitcoins.crypto._
|
||||
import play.api.libs.json._
|
||||
|
||||
import java.io.File
|
||||
import java.net.{InetAddress, InetSocketAddress, URI}
|
||||
import java.nio.file.Path
|
||||
import java.time._
|
||||
import java.util.UUID
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
||||
@ -910,6 +909,35 @@ object JsonReaders {
|
||||
SerializerUtil.buildJsErrorMsg("jsobject", err)
|
||||
}
|
||||
|
||||
implicit val updateRelayFeeResultReads: Reads[UpdateRelayFeeResult] =
|
||||
Reads {
|
||||
case obj: JsObject =>
|
||||
JsSuccess(UpdateRelayFeeResult(obj.value.map { x =>
|
||||
val channelId = Try(FundedChannelId.fromHex(x._1)) match {
|
||||
case Success(id) => Right(id)
|
||||
case Failure(_) =>
|
||||
Left(ShortChannelId.fromHumanReadableString(x._1))
|
||||
}
|
||||
val result = Try(
|
||||
UpdateRelayFee.OK(
|
||||
channelId = FundedChannelId.fromHex(
|
||||
(x._2 \ "channelId").validate[String].get),
|
||||
feeBaseMsat =
|
||||
(x._2 \ "cmd" \ "feeBase").validate[MilliSatoshis].get,
|
||||
feeProportionalMillionths =
|
||||
(x._2 \ "cmd" \ "feeProportionalMillionths").validate[Long].get
|
||||
)) match {
|
||||
case Success(ok) => ok
|
||||
case Failure(_) => UpdateRelayFee.Error(x._2.toString())
|
||||
}
|
||||
(channelId, result)
|
||||
}.toMap))
|
||||
|
||||
case err @ (JsNull | _: JsBoolean | _: JsString | _: JsArray |
|
||||
_: JsNumber) =>
|
||||
SerializerUtil.buildJsErrorMsg("jsobject", err)
|
||||
}
|
||||
|
||||
implicit val channelUpdateReads: Reads[ChannelUpdate] = {
|
||||
Reads { jsValue =>
|
||||
for {
|
||||
@ -998,7 +1026,7 @@ object JsonReaders {
|
||||
|
||||
implicit val paymentFailureTypeReads: Reads[PaymentFailure.Type] = Reads {
|
||||
jsValue =>
|
||||
(jsValue \ "name")
|
||||
jsValue
|
||||
.validate[String]
|
||||
.flatMap { s =>
|
||||
s.toLowerCase match {
|
||||
@ -1251,10 +1279,13 @@ object JsonReaders {
|
||||
for {
|
||||
id <- (js \ "id").validate[PaymentId]
|
||||
paymentHash <- (js \ "paymentHash").validate[Sha256Digest]
|
||||
failures <- (js \ "failures").validate[Vector[String]]
|
||||
failures <- (js \ "failures").validate[Vector[JsObject]]
|
||||
timestamp <- (js \ "timestamp")
|
||||
.validate[Instant](instantReadsMilliseconds)
|
||||
} yield WebSocketEvent.PaymentFailed(id, paymentHash, failures, timestamp)
|
||||
} yield WebSocketEvent.PaymentFailed(id,
|
||||
paymentHash,
|
||||
failures.map(_.toString()),
|
||||
timestamp)
|
||||
}
|
||||
|
||||
implicit val paymentSentEventPartReads: Reads[
|
||||
|
@ -5,6 +5,7 @@ import org.bitcoins.core.protocol.ln.LnParams.{
|
||||
LnBitcoinMainNet,
|
||||
LnBitcoinTestNet
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.channel.ShortChannelId
|
||||
import org.bitcoins.core.protocol.ln.currency.{
|
||||
MicroBitcoins,
|
||||
MilliBitcoins,
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.bitcoins.core.protocol.ln
|
||||
package org.bitcoins.core.protocol.ln.channel
|
||||
|
||||
import org.bitcoins.testkit.util.BitcoinSUnitTest
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.bitcoins.core.protocol.ln
|
||||
package org.bitcoins.core.protocol.ln.channel
|
||||
|
||||
import org.bitcoins.core.number.UInt64
|
||||
import org.bitcoins.crypto.{Factory, NetworkElement}
|
@ -1,9 +1,7 @@
|
||||
package org.bitcoins.core.protocol.ln.routing
|
||||
|
||||
import java.math.BigInteger
|
||||
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.protocol.ln.ShortChannelId
|
||||
import org.bitcoins.core.protocol.ln.channel.ShortChannelId
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.fee.{
|
||||
FeeBaseMSat,
|
||||
@ -13,6 +11,8 @@ import org.bitcoins.core.util.BytesUtil
|
||||
import org.bitcoins.crypto.{ECPublicKey, NetworkElement}
|
||||
import scodec.bits.ByteVector
|
||||
|
||||
import java.math.BigInteger
|
||||
|
||||
/**
|
||||
* Indicates a node to route through with specific options on the Lightning Network
|
||||
* For more details on these settings please see
|
||||
|
@ -0,0 +1,13 @@
|
||||
package org.bitcoins.core.protocol.ln.routing
|
||||
|
||||
import org.bitcoins.core.protocol.ln.channel.ShortChannelId
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
|
||||
/**
|
||||
* Represent differet types of LN routes. Supports node and channel routes.
|
||||
*/
|
||||
sealed trait Route
|
||||
|
||||
case class NodeRoute(ids: Vector[NodeId]) extends Route
|
||||
|
||||
case class ChannelRoute(ids: Vector[ShortChannelId]) extends Route
|
@ -5,7 +5,7 @@ title: Eclair
|
||||
|
||||
This is a RPC client for [Eclair](https://github.com/acinq/eclair). It assumes that a bitcoind instance is running.
|
||||
|
||||
Currently this RPC client is written for [v0.4.1](https://github.com/ACINQ/eclair/releases/tag/v0.4.1) version of Eclair.
|
||||
Currently this RPC client is written for [v0.5.0](https://github.com/ACINQ/eclair/releases/tag/v0.5.0) version of Eclair.
|
||||
|
||||
## Configuration of Eclair
|
||||
|
||||
@ -16,12 +16,12 @@ You can find the configuration we use for our testing infrastrture for eclair [h
|
||||
|
||||
## Starting Eclair
|
||||
|
||||
You need to download the jar from the [eclair's github](https://github.com/ACINQ/eclair/releases/tag/v0.4.1).
|
||||
You need to download the jar from the [eclair's github](https://github.com/ACINQ/eclair/releases/tag/v0.5.0).
|
||||
|
||||
To run Eclair by unzipping the `eclair-node-0.4.1-e5fb281-bin.zip` and then running
|
||||
To run Eclair by unzipping the `eclair-node-0.5.0-ac08560-bin.zip` and then running
|
||||
|
||||
```bash
|
||||
$ ./eclair-node-0.4-69c538e/bin/eclair-node.sh
|
||||
$ ./eclair-node-0.5.0-ac08560/bin/eclair-node.sh
|
||||
```
|
||||
|
||||
If you wish to start Eclair from the RPC client, you can do one of the following:
|
||||
@ -46,7 +46,7 @@ implicit val system = ActorSystem(s"eclair-rpc-${System.currentTimeMillis}")
|
||||
implicit val ec = system.dispatcher
|
||||
|
||||
val datadirPath = Paths.get("path", "to", "datadir")
|
||||
val binaryPath = Paths.get("path", "to", "eclair-node-0.3.3-12ac145.jar")
|
||||
val binaryPath = Paths.get("path", "to", "eclair-node-0.5.0-ac08560", "bin", "eclair-node.sh")
|
||||
val instance = EclairInstance.fromDatadir(datadirPath.toFile,None)
|
||||
val client = new EclairRpcClient(instance, Some(binaryPath.toFile))
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.bitcoins.eclair.rpc
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
import org.bitcoins.commons.jsonmodels.eclair._
|
||||
import org.bitcoins.core.config.RegTest
|
||||
import org.bitcoins.core.currency.{CurrencyUnits, Satoshis}
|
||||
@ -30,6 +28,8 @@ import org.bitcoins.testkit.eclair.rpc.{EclairNodes4, EclairRpcTestUtil}
|
||||
import org.bitcoins.testkit.util.{BitcoinSAsyncTest, EclairRpcTestClient}
|
||||
import org.scalatest.Assertion
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
import scala.concurrent._
|
||||
import scala.concurrent.duration.{DurationInt, _}
|
||||
|
||||
@ -64,38 +64,29 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||
}
|
||||
|
||||
lazy val eclairNodesF: Future[EclairNodes4] = {
|
||||
bitcoindRpcClientF.flatMap { bitcoindRpcClient =>
|
||||
val nodesF = EclairRpcTestUtil.createNodeLink(bitcoindRpcClient)
|
||||
|
||||
val addedF = nodesF.map { nodes =>
|
||||
clients ++= List(nodes.c1, nodes.c2, nodes.c3, nodes.c4)
|
||||
}
|
||||
|
||||
addedF.flatMap(_ => nodesF)
|
||||
for {
|
||||
bitcoindRpcClient <- bitcoindRpcClientF
|
||||
nodes <- EclairRpcTestUtil.createNodeLink(bitcoindRpcClient)
|
||||
} yield {
|
||||
clients ++= List(nodes.c1, nodes.c2, nodes.c3, nodes.c4)
|
||||
nodes
|
||||
}
|
||||
}
|
||||
|
||||
lazy val firstClientF = eclairNodesF.map(_.c1)
|
||||
lazy val firstClientF: Future[EclairRpcClient] = eclairNodesF.map(_.c1)
|
||||
|
||||
lazy val secondClientF = eclairNodesF.map(_.c2)
|
||||
lazy val secondClientF: Future[EclairRpcClient] = eclairNodesF.map(_.c2)
|
||||
|
||||
lazy val thirdClientF = eclairNodesF.map(_.c3)
|
||||
lazy val thirdClientF: Future[EclairRpcClient] = eclairNodesF.map(_.c3)
|
||||
|
||||
lazy val fourthClientF = eclairNodesF.map(_.c4)
|
||||
lazy val fourthClientF: Future[EclairRpcClient] = eclairNodesF.map(_.c4)
|
||||
|
||||
/** There is specific cases where we just need two clients,
|
||||
* so this is a helper val that pairs two connected
|
||||
* clients together with an open channel
|
||||
*/
|
||||
lazy val clientOtherClientF = {
|
||||
|
||||
//use second and third client above since they
|
||||
//aren't really being used in the tests that use eclairNodesF
|
||||
secondClientF.flatMap(s => thirdClientF.map(t => (s, t)))
|
||||
}
|
||||
|
||||
lazy val clientF = clientOtherClientF.map(_._1)
|
||||
lazy val otherClientF = clientOtherClientF.map(_._2)
|
||||
lazy val clientF: Future[EclairRpcClient] = secondClientF
|
||||
lazy val otherClientF: Future[EclairRpcClient] = thirdClientF
|
||||
|
||||
private val clients =
|
||||
Vector.newBuilder[EclairRpcClient]
|
||||
@ -177,7 +168,7 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||
.exists(_.endsWith(".onion")))
|
||||
route <- client1.findRoute(invoice, None)
|
||||
} yield {
|
||||
route.size == 4
|
||||
route.ids.size == 4
|
||||
}).recover {
|
||||
case err: RuntimeException
|
||||
if err.getMessage.contains("route not found") =>
|
||||
@ -196,7 +187,7 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||
.flatMap(_.getInfo)
|
||||
.flatMap(info =>
|
||||
firstClientF.flatMap(_.findRoute(info.nodeId, MilliSatoshis(100))))
|
||||
.map(route => route.length == 4)
|
||||
.map(route => route.ids.length == 4)
|
||||
.recover {
|
||||
case err: RuntimeException
|
||||
if err.getMessage.contains("route not found") =>
|
||||
@ -1026,18 +1017,23 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||
|
||||
it should "update the relay fee of a channel" in {
|
||||
val channelAndFeeF = for {
|
||||
channel <- EclairRpcTestUtil.openAndConfirmChannel(clientF, otherClientF)
|
||||
feeOpt <- clientF.flatMap(_.channel(channel).map(_.feeBaseMsat))
|
||||
channelId <-
|
||||
EclairRpcTestUtil.openAndConfirmChannel(clientF, otherClientF)
|
||||
client <- clientF
|
||||
channel <- client.channel(channelId)
|
||||
feeOpt = channel.feeBaseMsat
|
||||
} yield {
|
||||
assert(feeOpt.isDefined)
|
||||
assert(feeOpt.get > MilliSatoshis.zero)
|
||||
(channel, feeOpt.get)
|
||||
(channelId, feeOpt.get)
|
||||
}
|
||||
|
||||
for {
|
||||
(channel, oldFee) <- channelAndFeeF
|
||||
_ <- clientF.flatMap(_.updateRelayFee(channel, oldFee * 2, 1))
|
||||
newFeeOpt <- clientF.flatMap(_.channel(channel).map(_.feeBaseMsat))
|
||||
(channelId, oldFee) <- channelAndFeeF
|
||||
client <- clientF
|
||||
_ <- client.updateRelayFee(channelId, oldFee * 2, 1)
|
||||
channel <- client.channel(channelId)
|
||||
newFeeOpt = channel.feeBaseMsat
|
||||
} yield {
|
||||
assert(newFeeOpt.isDefined)
|
||||
assert(newFeeOpt.get == oldFee * 2)
|
||||
@ -1058,9 +1054,11 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||
}
|
||||
|
||||
for {
|
||||
client <- clientF
|
||||
(channelId, shortChannelId, oldFee) <- channelAndFeeF
|
||||
_ <- clientF.flatMap(_.updateRelayFee(shortChannelId, oldFee * 4, 1))
|
||||
newFeeOpt <- clientF.flatMap(_.channel(channelId).map(_.feeBaseMsat))
|
||||
_ <- client.updateRelayFee(shortChannelId, oldFee * 4, 1)
|
||||
channel <- client.channel(channelId)
|
||||
newFeeOpt = channel.feeBaseMsat
|
||||
} yield {
|
||||
assert(newFeeOpt.isDefined)
|
||||
assert(newFeeOpt.get == oldFee * 4)
|
||||
@ -1192,7 +1190,7 @@ class EclairRpcClientTest extends BitcoinSAsyncTest {
|
||||
pending <- c.listPendingInvoices(from = None, to = None)
|
||||
} yield {
|
||||
assert(res.nonEmpty)
|
||||
assert(pending.exists(_ == i))
|
||||
assert(pending.contains(i))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,8 @@ TaskKeys.downloadEclair := {
|
||||
Files.createDirectories(binaryDir)
|
||||
}
|
||||
|
||||
val version = "0.4.1"
|
||||
val commit = "e5fb281"
|
||||
val version = "0.5.0"
|
||||
val commit = "ac08560"
|
||||
|
||||
logger.debug(s"(Maybe) downloading Eclair binaries for version: $version")
|
||||
|
||||
|
@ -1,25 +1,24 @@
|
||||
package org.bitcoins.eclair.rpc.api
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import java.time.Instant
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.eclair._
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
||||
import org.bitcoins.core.protocol.ln.channel.{ChannelId, FundedChannelId}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.protocol.ln.{
|
||||
LnInvoice,
|
||||
LnParams,
|
||||
PaymentPreimage,
|
||||
import org.bitcoins.core.protocol.ln.channel.{
|
||||
ChannelId,
|
||||
FundedChannelId,
|
||||
ShortChannelId
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.protocol.ln.routing.{NodeRoute, Route}
|
||||
import org.bitcoins.core.protocol.ln.{LnInvoice, LnParams, PaymentPreimage}
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.{Address, BitcoinAddress}
|
||||
import org.bitcoins.core.wallet.fee.SatoshisPerByte
|
||||
import org.bitcoins.crypto.{DoubleSha256DigestBE, Sha256Digest}
|
||||
import org.bitcoins.eclair.rpc.network.NodeUri
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import java.time.Instant
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
@ -77,15 +76,13 @@ trait EclairApi {
|
||||
|
||||
def close(id: ChannelId, spk: ScriptPubKey): Future[ChannelCommandResult]
|
||||
|
||||
def findRoute(
|
||||
nodeId: NodeId,
|
||||
amountMsat: MilliSatoshis): Future[Vector[NodeId]]
|
||||
def findRoute(nodeId: NodeId, amountMsat: MilliSatoshis): Future[NodeRoute]
|
||||
|
||||
def findRoute(invoice: LnInvoice): Future[Vector[NodeId]]
|
||||
def findRoute(invoice: LnInvoice): Future[NodeRoute]
|
||||
|
||||
def findRoute(
|
||||
invoice: LnInvoice,
|
||||
amountMsat: MilliSatoshis): Future[Vector[NodeId]]
|
||||
amountMsat: MilliSatoshis): Future[NodeRoute]
|
||||
|
||||
def forceClose(channelId: ChannelId): Future[ChannelCommandResult]
|
||||
|
||||
@ -102,13 +99,13 @@ trait EclairApi {
|
||||
def updateRelayFee(
|
||||
channelId: ChannelId,
|
||||
feeBaseMsat: MilliSatoshis,
|
||||
feePropertionalMillionths: Long): Future[ChannelCommandResult]
|
||||
feeProportionalMillionths: Long): Future[UpdateRelayFeeResult]
|
||||
|
||||
def updateRelayFee(
|
||||
shortChannelId: ShortChannelId,
|
||||
feeBaseMsat: MilliSatoshis,
|
||||
feePropertionalMillionths: Long
|
||||
): Future[ChannelCommandResult]
|
||||
): Future[UpdateRelayFeeResult]
|
||||
|
||||
def open(
|
||||
nodeId: NodeId,
|
||||
@ -264,7 +261,7 @@ trait EclairApi {
|
||||
*/
|
||||
def sendToRoute(
|
||||
invoice: LnInvoice,
|
||||
route: scala.collection.immutable.Seq[NodeId],
|
||||
route: Route,
|
||||
amountMsat: MilliSatoshis,
|
||||
paymentHash: Sha256Digest,
|
||||
finalCltvExpiry: Long,
|
||||
|
@ -1,10 +1,5 @@
|
||||
package org.bitcoins.eclair.rpc.client
|
||||
|
||||
import java.io.File
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.file.NoSuchFileException
|
||||
import java.time.Instant
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import akka.Done
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.javadsl.model.headers.HttpCredentials
|
||||
@ -17,15 +12,15 @@ import akka.util.ByteString
|
||||
import org.bitcoins.commons.jsonmodels.eclair._
|
||||
import org.bitcoins.commons.serializers.JsonReaders._
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, Satoshis}
|
||||
import org.bitcoins.core.protocol.ln.channel.{ChannelId, FundedChannelId}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.protocol.ln.{
|
||||
LnInvoice,
|
||||
LnParams,
|
||||
PaymentPreimage,
|
||||
import org.bitcoins.core.protocol.ln.channel.{
|
||||
ChannelId,
|
||||
FundedChannelId,
|
||||
ShortChannelId
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.protocol.ln.routing.{ChannelRoute, NodeRoute, Route}
|
||||
import org.bitcoins.core.protocol.ln.{LnInvoice, LnParams, PaymentPreimage}
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.{Address, BitcoinAddress}
|
||||
import org.bitcoins.core.util.{BytesUtil, FutureUtil, StartStopAsync}
|
||||
@ -39,6 +34,11 @@ import org.bitcoins.rpc.util.AsyncUtil
|
||||
import org.slf4j.LoggerFactory
|
||||
import play.api.libs.json._
|
||||
|
||||
import java.io.File
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.file.NoSuchFileException
|
||||
import java.time.Instant
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import scala.concurrent.duration.{DurationInt, FiniteDuration}
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
import scala.sys.process._
|
||||
@ -148,29 +148,30 @@ class EclairRpcClient(
|
||||
|
||||
override def findRoute(
|
||||
nodeId: NodeId,
|
||||
amountMsat: MilliSatoshis): Future[Vector[NodeId]] = {
|
||||
eclairCall[Vector[NodeId]]("findroutetonode",
|
||||
"nodeId" -> nodeId.toString,
|
||||
"amountMsat" -> amountMsat.toBigDecimal.toString)
|
||||
amountMsat: MilliSatoshis): Future[NodeRoute] = {
|
||||
eclairCall[Vector[NodeId]](
|
||||
"findroutetonode",
|
||||
"nodeId" -> nodeId.toString,
|
||||
"amountMsat" -> amountMsat.toBigDecimal.toString).map(NodeRoute.apply)
|
||||
}
|
||||
|
||||
override def findRoute(invoice: LnInvoice): Future[Vector[NodeId]] = {
|
||||
override def findRoute(invoice: LnInvoice): Future[NodeRoute] = {
|
||||
findRoute(invoice, None)
|
||||
}
|
||||
|
||||
override def findRoute(
|
||||
invoice: LnInvoice,
|
||||
amount: MilliSatoshis): Future[Vector[NodeId]] = {
|
||||
amount: MilliSatoshis): Future[NodeRoute] = {
|
||||
findRoute(invoice, Some(amount))
|
||||
}
|
||||
|
||||
def findRoute(
|
||||
invoice: LnInvoice,
|
||||
amountMsat: Option[MilliSatoshis]): Future[Vector[NodeId]] = {
|
||||
amountMsat: Option[MilliSatoshis]): Future[NodeRoute] = {
|
||||
val params = Seq(
|
||||
Some("invoice" -> invoice.toString),
|
||||
amountMsat.map(x => "amountMsat" -> x.toBigDecimal.toString)).flatten
|
||||
eclairCall[Vector[NodeId]]("findroute", params: _*)
|
||||
eclairCall[Vector[NodeId]]("findroute", params: _*).map(NodeRoute.apply)
|
||||
}
|
||||
|
||||
override def forceClose(
|
||||
@ -511,16 +512,20 @@ class EclairRpcClient(
|
||||
|
||||
def sendToRoute(
|
||||
invoice: LnInvoice,
|
||||
route: scala.collection.immutable.Seq[NodeId],
|
||||
route: Route,
|
||||
amountMsat: MilliSatoshis,
|
||||
paymentHash: Sha256Digest,
|
||||
finalCltvExpiry: Long,
|
||||
recipientAmountMsat: Option[MilliSatoshis],
|
||||
parentId: Option[PaymentId],
|
||||
externalId: Option[String]): Future[SendToRouteResult] = {
|
||||
val ids = route match {
|
||||
case NodeRoute(ids) => "nodeIds" -> ids.mkString(",")
|
||||
case ChannelRoute(ids) => "shortChannelIds" -> ids.mkString(",")
|
||||
}
|
||||
val params = Seq(
|
||||
"invoice" -> invoice.toString,
|
||||
"route" -> route.iterator.mkString(","),
|
||||
ids,
|
||||
"amountMsat" -> amountMsat.toBigDecimal.toString,
|
||||
"paymentHash" -> paymentHash.hex,
|
||||
"finalCltvExpiry" -> finalCltvExpiry.toString
|
||||
@ -533,8 +538,8 @@ class EclairRpcClient(
|
||||
override def updateRelayFee(
|
||||
channelId: ChannelId,
|
||||
feeBaseMsat: MilliSatoshis,
|
||||
feeProportionalMillionths: Long): Future[ChannelCommandResult] = {
|
||||
eclairCall[ChannelCommandResult](
|
||||
feeProportionalMillionths: Long): Future[UpdateRelayFeeResult] = {
|
||||
eclairCall[UpdateRelayFeeResult](
|
||||
"updaterelayfee",
|
||||
"channelId" -> channelId.hex,
|
||||
"feeBaseMsat" -> feeBaseMsat.toLong.toString,
|
||||
@ -545,8 +550,8 @@ class EclairRpcClient(
|
||||
override def updateRelayFee(
|
||||
shortChannelId: ShortChannelId,
|
||||
feeBaseMsat: MilliSatoshis,
|
||||
feeProportionalMillionths: Long): Future[ChannelCommandResult] = {
|
||||
eclairCall[ChannelCommandResult](
|
||||
feeProportionalMillionths: Long): Future[UpdateRelayFeeResult] = {
|
||||
eclairCall[UpdateRelayFeeResult](
|
||||
"updaterelayfee",
|
||||
"shortChannelId" -> shortChannelId.toHumanReadableString,
|
||||
"feeBaseMsat" -> feeBaseMsat.toLong.toString,
|
||||
@ -904,11 +909,16 @@ class EclairRpcClient(
|
||||
val incoming: Sink[Message, Future[Done]] =
|
||||
Sink.foreach[Message] {
|
||||
case message: TextMessage.Strict =>
|
||||
val parsed: JsValue = Json.parse(message.text)
|
||||
val validated: JsResult[WebSocketEvent] =
|
||||
parsed.validate[WebSocketEvent]
|
||||
val event = parseResult[WebSocketEvent](validated, parsed, "ws")
|
||||
eventHandler(event)
|
||||
try {
|
||||
val parsed: JsValue = Json.parse(message.text)
|
||||
val validated: JsResult[WebSocketEvent] =
|
||||
parsed.validate[WebSocketEvent]
|
||||
val event = parseResult[WebSocketEvent](validated, parsed, "ws")
|
||||
eventHandler(event)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
logger.error("Cannot process web-socket event", e)
|
||||
}
|
||||
case _: Message => ()
|
||||
}
|
||||
|
||||
@ -957,7 +967,7 @@ object EclairRpcClient {
|
||||
def apply(
|
||||
instance: EclairInstance,
|
||||
binary: Option[File] = None): EclairRpcClient = {
|
||||
implicit val systme = ActorSystem.create(ActorSystemName)
|
||||
implicit val system = ActorSystem.create(ActorSystemName)
|
||||
withActorSystem(instance, binary)
|
||||
}
|
||||
|
||||
@ -969,10 +979,10 @@ object EclairRpcClient {
|
||||
implicit system: ActorSystem) = new EclairRpcClient(instance, binary)
|
||||
|
||||
/** The current commit we support of Eclair */
|
||||
private[bitcoins] val commit = "e5fb281"
|
||||
private[bitcoins] val commit = "ac08560"
|
||||
|
||||
/** The current version we support of Eclair */
|
||||
private[bitcoins] val version = "0.4.1"
|
||||
private[bitcoins] val version = "0.5.0"
|
||||
|
||||
/** The bitcoind version that eclair is officially tested & supported with by ACINQ
|
||||
* @see https://github.com/ACINQ/eclair/releases/tag/v0.4
|
||||
|
@ -1,24 +1,16 @@
|
||||
package org.bitcoins.node
|
||||
|
||||
import akka.actor.Cancellable
|
||||
import org.bitcoins.core.protocol.blockchain.Block
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.crypto.DoubleSha256DigestBE
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion
|
||||
import org.bitcoins.rpc.util.RpcUtil
|
||||
import org.bitcoins.server.BitcoinSAppConfig
|
||||
import org.bitcoins.testkit.BitcoinSTestAppConfig
|
||||
import org.bitcoins.testkit.fixtures.UsesExperimentalBitcoind
|
||||
import org.bitcoins.testkit.node.fixture.NeutrinoNodeConnectedWithBitcoind
|
||||
import org.bitcoins.testkit.node.{
|
||||
NeutrinoNodeFundedWalletBitcoind,
|
||||
NodeTestUtil,
|
||||
NodeUnitTest
|
||||
}
|
||||
import org.bitcoins.testkit.node.{NodeTestUtil, NodeUnitTest}
|
||||
import org.scalatest.FutureOutcome
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.concurrent.{Future, Promise}
|
||||
import scala.concurrent.Future
|
||||
|
||||
class NeutrinoNodeTest extends NodeUnitTest {
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
package org.bitcoins.testkit.core.gen.ln
|
||||
|
||||
import org.bitcoins.testkit.core.gen.{CryptoGenerators, NumberGenerator}
|
||||
import org.bitcoins.core.protocol.ln.ShortChannelId
|
||||
import org.bitcoins.core.protocol.ln.channel.ShortChannelId
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.fee.{
|
||||
FeeBaseMSat,
|
||||
FeeProportionalMillionths
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.routing.LnRoute
|
||||
import org.bitcoins.testkit.core.gen.{CryptoGenerators, NumberGenerator}
|
||||
import org.scalacheck.Gen
|
||||
|
||||
trait LnRouteGen {
|
||||
|
@ -139,7 +139,9 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
||||
"eclair.to-remote-delay-blocks" -> 144,
|
||||
"eclair.db.regtest.url" -> "jdbc:sqlite:regtest/",
|
||||
"eclair.max-payment-fee" -> 10, // avoid complaints about too high fees
|
||||
"eclair.alias" -> "suredbits"
|
||||
"eclair.alias" -> "suredbits",
|
||||
"eclair.fulfill-safety-before-timeout-blocks" -> 1,
|
||||
"eclair.min-final-expiry-delta-blocks" -> 2
|
||||
)
|
||||
}
|
||||
val c = ConfigFactory.parseMap(configMap.asJava)
|
||||
|
@ -19,7 +19,7 @@ You can find the configuration we use for our testing infrastrture for eclair [h
|
||||
|
||||
You need to download the jar from the [eclair's github](https://github.com/ACINQ/eclair/releases/tag/v0.4.1).
|
||||
|
||||
To run Eclair by unzipping the `eclair-node-0.4.1-e5fb281-bin.zip` and then running
|
||||
To run Eclair by unzipping the `eclair-node-0.5.0-ac08560-bin.zip` and then running
|
||||
|
||||
```bash
|
||||
$ ./eclair-node-0.4-69c538e/bin/eclair-node.sh
|
||||
|
Loading…
Reference in New Issue
Block a user