mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-21 22:21:53 +01:00
Reduce number of requests we send to eclair in testkits, add commandN… (#343)
* Reduce number of requests we send to eclair in testkits, add commandName param to parseResult in EclairRpcClient * Factor our EclairRpcClient error message * Make jvm opts more sane, refactor error message code again * Add error message on EclairRpcTestUtil.sendPayments, scalafmt
This commit is contained in:
parent
abc6f55a08
commit
88e6450c5a
4 changed files with 293 additions and 226 deletions
1
.jvmopts
1
.jvmopts
|
@ -1,2 +1 @@
|
|||
-Xmx1024m
|
||||
-Xms1024m
|
||||
|
|
|
@ -7,7 +7,11 @@ import org.bitcoins.core.config.RegTest
|
|||
import org.bitcoins.core.currency.{CurrencyUnit, CurrencyUnits, Satoshis}
|
||||
import org.bitcoins.core.number.Int64
|
||||
import org.bitcoins.core.protocol.ln.LnParams.LnBitcoinRegTest
|
||||
import org.bitcoins.core.protocol.ln.channel.{ChannelId, ChannelState, FundedChannelId}
|
||||
import org.bitcoins.core.protocol.ln.channel.{
|
||||
ChannelId,
|
||||
ChannelState,
|
||||
FundedChannelId
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.currency._
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.util.BitcoinSLogger
|
||||
|
@ -41,7 +45,6 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
blocksF.flatMap(_ => cliF)
|
||||
}
|
||||
|
||||
|
||||
val eclairNodesF: Future[EclairNodes4] = {
|
||||
bitcoindRpcClientF.flatMap { bitcoindRpcClient =>
|
||||
val nodesF = EclairRpcTestUtil.createNodeLink(bitcoindRpcClient)
|
||||
|
@ -62,7 +65,6 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
lazy val fourthClientF = 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
|
||||
|
@ -71,7 +73,7 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
//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)))
|
||||
secondClientF.flatMap(s => thirdClientF.map(t => (s, t)))
|
||||
}
|
||||
|
||||
lazy val clientF = clientOtherClientF.map(_._1)
|
||||
|
@ -86,21 +88,22 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
* @tparam T
|
||||
* @return
|
||||
*/
|
||||
def executeWithClientOtherClient[T](test: (EclairRpcClient,EclairRpcClient) => Future[T]): Future[T] = {
|
||||
def executeWithClientOtherClient[T](
|
||||
test: (EclairRpcClient, EclairRpcClient) => Future[T]): Future[T] = {
|
||||
|
||||
executeSpecificClients(clientF = clientF,
|
||||
otherClientF = otherClientF,
|
||||
test = test)
|
||||
otherClientF = otherClientF,
|
||||
test = test)
|
||||
}
|
||||
|
||||
|
||||
/** Executes the test with the clients passed as a parameter */
|
||||
def executeSpecificClients[T](clientF: Future[EclairRpcClient],
|
||||
otherClientF: Future[EclairRpcClient],
|
||||
test: (EclairRpcClient,EclairRpcClient) => Future[T]): Future[T] = {
|
||||
def executeSpecificClients[T](
|
||||
clientF: Future[EclairRpcClient],
|
||||
otherClientF: Future[EclairRpcClient],
|
||||
test: (EclairRpcClient, EclairRpcClient) => Future[T]): Future[T] = {
|
||||
clientF.flatMap { c1 =>
|
||||
otherClientF.flatMap { other =>
|
||||
test(c1,other)
|
||||
test(c1, other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,43 +115,43 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val changeAddrF = bitcoindRpcClientF.flatMap(_.getNewAddress())
|
||||
val result: Future[Assertion] = {
|
||||
val isOpenedF: Future[(ChannelId, Assertion)] = {
|
||||
val getChannelId = (client: EclairRpcClient, otherClient: EclairRpcClient) => {
|
||||
otherClient.getInfo.flatMap { info =>
|
||||
val amt = Satoshis(Int64(100000))
|
||||
val openedChanF = clientF.flatMap(_.open(info.nodeId, amt))
|
||||
val getChannelId =
|
||||
(client: EclairRpcClient, otherClient: EclairRpcClient) => {
|
||||
otherClient.getInfo.flatMap { info =>
|
||||
val amt = Satoshis(Int64(100000))
|
||||
val openedChanF = clientF.flatMap(_.open(info.nodeId, amt))
|
||||
|
||||
openedChanF.flatMap { channelId =>
|
||||
val exists = hasChannel(client, channelId)
|
||||
exists.map(e => (channelId, e))
|
||||
openedChanF.flatMap { channelId =>
|
||||
val exists = hasChannel(client, channelId)
|
||||
exists.map(e => (channelId, e))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
executeWithClientOtherClient[(ChannelId,Assertion)](getChannelId)
|
||||
executeWithClientOtherClient[(ChannelId, Assertion)](getChannelId)
|
||||
}
|
||||
|
||||
val isConfirmedF: Future[(ChannelId, Assertion)] = {
|
||||
val getIsConfirmed = {
|
||||
(client: EclairRpcClient, _: EclairRpcClient) =>
|
||||
isOpenedF.flatMap {
|
||||
case (chanId, assertion) =>
|
||||
val generatedF = bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
val normalF = generatedF.flatMap { _ =>
|
||||
EclairRpcTestUtil.awaitUntilChannelNormal(
|
||||
client = client,
|
||||
chanId = chanId
|
||||
)
|
||||
}
|
||||
val getIsConfirmed = { (client: EclairRpcClient, _: EclairRpcClient) =>
|
||||
isOpenedF.flatMap {
|
||||
case (chanId, assertion) =>
|
||||
val generatedF = bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
val normalF = generatedF.flatMap { _ =>
|
||||
EclairRpcTestUtil.awaitUntilChannelNormal(
|
||||
client = client,
|
||||
chanId = chanId
|
||||
)
|
||||
}
|
||||
|
||||
normalF.map(_ => (chanId, assertion))
|
||||
}
|
||||
normalF.map(_ => (chanId, assertion))
|
||||
}
|
||||
}
|
||||
|
||||
executeWithClientOtherClient(getIsConfirmed)
|
||||
}
|
||||
|
||||
val isClosedF = {
|
||||
val getIsClosed = {
|
||||
(client: EclairRpcClient, _: EclairRpcClient) => isConfirmedF.flatMap {
|
||||
val getIsClosed = { (client: EclairRpcClient, _: EclairRpcClient) =>
|
||||
isConfirmedF.flatMap {
|
||||
case (chanId, assertion) =>
|
||||
val closedF = changeAddrF.flatMap { addr =>
|
||||
val closedF = client.close(chanId, addr.scriptPubKey)
|
||||
|
@ -159,7 +162,6 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
}
|
||||
|
||||
closedF.flatMap { _ =>
|
||||
|
||||
val chanF = client.channel(chanId)
|
||||
chanF.map { chan =>
|
||||
assert(chan.state == ChannelState.CLOSING)
|
||||
|
@ -177,7 +179,7 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val amountF =
|
||||
bitcoindRpcClientF.flatMap { bitcoindRpcClient =>
|
||||
bitcoindRpcClient.getReceivedByAddress(address = addr,
|
||||
minConfirmations = 0)
|
||||
minConfirmations = 0)
|
||||
}
|
||||
amountF.map(amt => assert(amt > CurrencyUnits.zero))
|
||||
}
|
||||
|
@ -199,28 +201,23 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
executeWithClientOtherClient[EclairAuthCredentials](getAuthCredentials)
|
||||
}
|
||||
|
||||
|
||||
val badCredentialsF = goodCredentialsF.map { good =>
|
||||
EclairAuthCredentials("bad_password",
|
||||
good.bitcoinAuthOpt,
|
||||
good.port)
|
||||
EclairAuthCredentials("bad_password", good.bitcoinAuthOpt, good.port)
|
||||
}
|
||||
|
||||
val badInstanceF = badCredentialsF.flatMap { badCredentials =>
|
||||
val getBadInstance = (client: EclairRpcClient, _: EclairRpcClient) => {
|
||||
val instance = EclairInstance(network = client.instance.network,
|
||||
uri = client.instance.uri,
|
||||
rpcUri = client.instance.rpcUri,
|
||||
authCredentials = badCredentials)
|
||||
uri = client.instance.uri,
|
||||
rpcUri = client.instance.rpcUri,
|
||||
authCredentials = badCredentials)
|
||||
|
||||
Future.successful(instance)
|
||||
}
|
||||
|
||||
|
||||
executeWithClientOtherClient(getBadInstance)
|
||||
}
|
||||
|
||||
|
||||
val badClientF = badInstanceF.map(new EclairRpcClient(_))
|
||||
|
||||
badClientF.flatMap { badClient =>
|
||||
|
@ -228,13 +225,11 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
it should "be able to list an existing peer and isConnected must be true" in {
|
||||
//test assumes that a connection to a peer was made in `beforeAll`
|
||||
val otherClientNodeIdF = {
|
||||
val getOtherClientNodeId = {
|
||||
(_:EclairRpcClient, otherClient: EclairRpcClient) =>
|
||||
(_: EclairRpcClient, otherClient: EclairRpcClient) =>
|
||||
otherClient.getInfo.map(_.nodeId)
|
||||
}
|
||||
|
||||
|
@ -247,26 +242,28 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
it should "ble able to pay to a hash" in {
|
||||
val amt = MilliSatoshis(50)
|
||||
val getPayment = {
|
||||
(client: EclairRpcClient,otherClient: EclairRpcClient) => {
|
||||
for {
|
||||
channelId <- openAndConfirmChannel(clientF, otherClientF)
|
||||
otherClientNodeId <- otherClient.getInfo.map(_.nodeId)
|
||||
channels <- client.channels(otherClientNodeId)
|
||||
// without this we've been getting "route not found"
|
||||
// probably an async issue, this is more elegant than Thread.sleep
|
||||
_ = assert(channels.exists(_.state == ChannelState.NORMAL), "Nodes did not have open channel!")
|
||||
invoice <- otherClient.receive(amt.toLnCurrencyUnit)
|
||||
payment <- client.send(amt.toLnCurrencyUnit,
|
||||
invoice.lnTags.paymentHash.hash,
|
||||
otherClientNodeId)
|
||||
_ <- client.close(channelId)
|
||||
_ <- bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
} yield {
|
||||
assert(payment.isInstanceOf[PaymentSucceeded])
|
||||
val succeeded = payment.asInstanceOf[PaymentSucceeded]
|
||||
assert(succeeded.amountMsat == amt)
|
||||
(client: EclairRpcClient, otherClient: EclairRpcClient) =>
|
||||
{
|
||||
for {
|
||||
channelId <- openAndConfirmChannel(clientF, otherClientF)
|
||||
otherClientNodeId <- otherClient.getInfo.map(_.nodeId)
|
||||
channels <- client.channels(otherClientNodeId)
|
||||
// without this we've been getting "route not found"
|
||||
// probably an async issue, this is more elegant than Thread.sleep
|
||||
_ = assert(channels.exists(_.state == ChannelState.NORMAL),
|
||||
"Nodes did not have open channel!")
|
||||
invoice <- otherClient.receive(amt.toLnCurrencyUnit)
|
||||
payment <- client.send(amt.toLnCurrencyUnit,
|
||||
invoice.lnTags.paymentHash.hash,
|
||||
otherClientNodeId)
|
||||
_ <- client.close(channelId)
|
||||
_ <- bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
} yield {
|
||||
assert(payment.isInstanceOf[PaymentSucceeded])
|
||||
val succeeded = payment.asInstanceOf[PaymentSucceeded]
|
||||
assert(succeeded.amountMsat == amt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
executeWithClientOtherClient(getPayment)
|
||||
|
@ -277,19 +274,20 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val amt = MilliSatoshis(50)
|
||||
|
||||
val getPaymentWithAmount = {
|
||||
(client: EclairRpcClient, otherClient: EclairRpcClient) => {
|
||||
for {
|
||||
channelId <- openAndConfirmChannel(clientF, otherClientF)
|
||||
invoice <- otherClient.receive(amt.toLnCurrencyUnit)
|
||||
payment <- client.send(invoice)
|
||||
_ <- client.close(channelId)
|
||||
_ <- bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
} yield {
|
||||
assert(payment.isInstanceOf[PaymentSucceeded])
|
||||
val succeeded = payment.asInstanceOf[PaymentSucceeded]
|
||||
assert(succeeded.amountMsat == amt)
|
||||
(client: EclairRpcClient, otherClient: EclairRpcClient) =>
|
||||
{
|
||||
for {
|
||||
channelId <- openAndConfirmChannel(clientF, otherClientF)
|
||||
invoice <- otherClient.receive(amt.toLnCurrencyUnit)
|
||||
payment <- client.send(invoice)
|
||||
_ <- client.close(channelId)
|
||||
_ <- bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
} yield {
|
||||
assert(payment.isInstanceOf[PaymentSucceeded])
|
||||
val succeeded = payment.asInstanceOf[PaymentSucceeded]
|
||||
assert(succeeded.amountMsat == amt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
executeWithClientOtherClient(getPaymentWithAmount)
|
||||
|
@ -298,19 +296,20 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
it should "be able to generate an invoice without amount and pay it" in {
|
||||
val amt = MilliSatoshis(50)
|
||||
val getPaymentNoAmount = {
|
||||
(client: EclairRpcClient, otherClient: EclairRpcClient) => {
|
||||
for {
|
||||
channelId <- openAndConfirmChannel(clientF, otherClientF)
|
||||
invoice <- otherClient.receive("no amount")
|
||||
payment <- client.send(invoice, amt.toLnCurrencyUnit)
|
||||
_ <- client.close(channelId)
|
||||
_ <- bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
} yield {
|
||||
assert(payment.isInstanceOf[PaymentSucceeded])
|
||||
val succeeded = payment.asInstanceOf[PaymentSucceeded]
|
||||
assert(succeeded.amountMsat == amt)
|
||||
(client: EclairRpcClient, otherClient: EclairRpcClient) =>
|
||||
{
|
||||
for {
|
||||
channelId <- openAndConfirmChannel(clientF, otherClientF)
|
||||
invoice <- otherClient.receive("no amount")
|
||||
payment <- client.send(invoice, amt.toLnCurrencyUnit)
|
||||
_ <- client.close(channelId)
|
||||
_ <- bitcoindRpcClientF.flatMap(_.generate(6))
|
||||
} yield {
|
||||
assert(payment.isInstanceOf[PaymentSucceeded])
|
||||
val succeeded = payment.asInstanceOf[PaymentSucceeded]
|
||||
assert(succeeded.amountMsat == amt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
executeWithClientOtherClient(getPaymentNoAmount)
|
||||
|
@ -321,9 +320,10 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val description = "bitcoin-s test case"
|
||||
val expiry = (System.currentTimeMillis() / 1000)
|
||||
|
||||
val invoiceF = clientF.flatMap(_.receive(description = description,
|
||||
amountMsat = amt,
|
||||
expirySeconds = expiry))
|
||||
val invoiceF = clientF.flatMap(
|
||||
_.receive(description = description,
|
||||
amountMsat = amt,
|
||||
expirySeconds = expiry))
|
||||
|
||||
val assert0: Future[Assertion] = {
|
||||
invoiceF.map { i =>
|
||||
|
@ -334,9 +334,10 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
}
|
||||
|
||||
val amt1 = NanoBitcoins.one
|
||||
val invoice1F = clientF.flatMap(_.receive(description = description,
|
||||
amountMsat = amt1,
|
||||
expirySeconds = expiry))
|
||||
val invoice1F = clientF.flatMap(
|
||||
_.receive(description = description,
|
||||
amountMsat = amt1,
|
||||
expirySeconds = expiry))
|
||||
|
||||
val assert1 = {
|
||||
invoice1F.map { i =>
|
||||
|
@ -347,9 +348,10 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
}
|
||||
|
||||
val amt2 = MicroBitcoins.one
|
||||
val invoice2F = clientF.flatMap(_.receive(description = description,
|
||||
amountMsat = amt2,
|
||||
expirySeconds = expiry))
|
||||
val invoice2F = clientF.flatMap(
|
||||
_.receive(description = description,
|
||||
amountMsat = amt2,
|
||||
expirySeconds = expiry))
|
||||
|
||||
val assert2 = {
|
||||
invoice2F.map { i =>
|
||||
|
@ -362,9 +364,10 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
val amt3 = MilliBitcoins.one
|
||||
|
||||
val invoice3F = clientF.flatMap(_.receive(description = description,
|
||||
amountMsat = amt3,
|
||||
expirySeconds = expiry))
|
||||
val invoice3F = clientF.flatMap(
|
||||
_.receive(description = description,
|
||||
amountMsat = amt3,
|
||||
expirySeconds = expiry))
|
||||
|
||||
val assert3 = {
|
||||
invoice3F.map { i =>
|
||||
|
@ -385,9 +388,10 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val description = "bitcoin-s test case"
|
||||
val expiry = (System.currentTimeMillis() / 1000)
|
||||
|
||||
val invoiceF = clientF.flatMap(_.receive(description = description,
|
||||
amountMsat = amt,
|
||||
expirySeconds = expiry))
|
||||
val invoiceF = clientF.flatMap(
|
||||
_.receive(description = description,
|
||||
amountMsat = amt,
|
||||
expirySeconds = expiry))
|
||||
|
||||
val paymentRequestF: Future[PaymentRequest] = invoiceF.flatMap { i =>
|
||||
clientF.flatMap(_.checkInvoice(i))
|
||||
|
@ -404,7 +408,8 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
val paymentAmount = NanoBitcoins(100000)
|
||||
val invoiceF =
|
||||
openChannelIdF.flatMap(_ => otherClientF.flatMap(_.receive(paymentAmount)))
|
||||
openChannelIdF.flatMap(_ =>
|
||||
otherClientF.flatMap(_.receive(paymentAmount)))
|
||||
|
||||
val paymentF = invoiceF.flatMap(i => clientF.flatMap(_.send(i)))
|
||||
|
||||
|
@ -451,14 +456,17 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
val paymentAmount = NanoBitcoins(100000)
|
||||
val invoiceF =
|
||||
openChannelIdF.flatMap(_ => otherClientF.flatMap(_.receive(paymentAmount)))
|
||||
openChannelIdF.flatMap(_ =>
|
||||
otherClientF.flatMap(_.receive(paymentAmount)))
|
||||
|
||||
val isPaid1F = invoiceF.flatMap(i => otherClientF.flatMap(_.checkPayment(Left(i))))
|
||||
val isPaid1F =
|
||||
invoiceF.flatMap(i => otherClientF.flatMap(_.checkPayment(Left(i))))
|
||||
|
||||
val isNotPaidAssertF = isPaid1F.map(isPaid => assert(!isPaid))
|
||||
|
||||
//send the payment now
|
||||
val paidF: Future[PaymentResult] = invoiceF.flatMap(i => clientF.flatMap(_.send(i)))
|
||||
val paidF: Future[PaymentResult] =
|
||||
invoiceF.flatMap(i => clientF.flatMap(_.send(i)))
|
||||
|
||||
val isPaid2F: Future[Boolean] = paidF.flatMap { p =>
|
||||
val succeed = p.asInstanceOf[PaymentSucceeded]
|
||||
|
@ -481,9 +489,11 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
val paymentAmount = NanoBitcoins(100000)
|
||||
val invoiceF =
|
||||
openChannelIdF.flatMap(_ => otherClientF.flatMap(_.receive(paymentAmount)))
|
||||
openChannelIdF.flatMap(_ =>
|
||||
otherClientF.flatMap(_.receive(paymentAmount)))
|
||||
//send the payment now
|
||||
val paidF: Future[PaymentResult] = invoiceF.flatMap(i => clientF.flatMap(_.send(i)))
|
||||
val paidF: Future[PaymentResult] =
|
||||
invoiceF.flatMap(i => clientF.flatMap(_.send(i)))
|
||||
|
||||
val isPaidF: Future[Boolean] = paidF.flatMap { p =>
|
||||
val succeed = p.asInstanceOf[PaymentSucceeded]
|
||||
|
@ -493,7 +503,8 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val isPaidAssertF = isPaidF.map(isPaid => assert(isPaid))
|
||||
|
||||
isPaidAssertF.flatMap { isPaid =>
|
||||
val invoice2F = openChannelIdF.flatMap(_ => clientF.flatMap(_.receive(paymentAmount)))
|
||||
val invoice2F =
|
||||
openChannelIdF.flatMap(_ => clientF.flatMap(_.receive(paymentAmount)))
|
||||
//send the payment now
|
||||
val paid2F: Future[PaymentResult] =
|
||||
invoice2F.flatMap((i => otherClientF.flatMap(_.send(i))))
|
||||
|
@ -520,7 +531,8 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
for {
|
||||
(channel, oldFee) <- channelAndFeeF
|
||||
_ <- clientF.flatMap(_.updateRelayFee(channel, MilliSatoshis(oldFee.toLong * 2), 1))
|
||||
_ <- clientF.flatMap(
|
||||
_.updateRelayFee(channel, MilliSatoshis(oldFee.toLong * 2), 1))
|
||||
newFeeOpt <- clientF.flatMap(_.channel(channel).map(_.feeBaseMsat))
|
||||
} yield {
|
||||
assert(newFeeOpt.isDefined)
|
||||
|
@ -540,7 +552,8 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
it should "get a route to a node ID" in {
|
||||
val hasRoute = () => {
|
||||
fourthClientF.flatMap(_.getInfo)
|
||||
fourthClientF
|
||||
.flatMap(_.getInfo)
|
||||
.flatMap(info => firstClientF.flatMap(_.findRoute(info.nodeId)))
|
||||
.map(route => route.length == 4)
|
||||
.recover {
|
||||
|
@ -559,14 +572,15 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
it should "get a route to an invoice" in {
|
||||
val hasRoute = () => {
|
||||
fourthClientF.flatMap { fourthClient =>
|
||||
fourthClient.receive("foo")
|
||||
fourthClient
|
||||
.receive("foo")
|
||||
.flatMap { invoice =>
|
||||
firstClientF.flatMap(_.findRoute(invoice))
|
||||
}
|
||||
.map(route => route.length == 4)
|
||||
.recover {
|
||||
case err: RuntimeException
|
||||
if err.getMessage.contains("route not found") =>
|
||||
if err.getMessage.contains("route not found") =>
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -581,14 +595,21 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
|
||||
it should "send some payments and get the audit info" in {
|
||||
for {
|
||||
invoice <- fourthClientF.flatMap(_.receive(MilliSatoshis(50000).toLnCurrencyUnit))
|
||||
_ <- firstClientF.flatMap(_.send(invoice)
|
||||
.map(payment => assert(payment.isInstanceOf[PaymentSucceeded])))
|
||||
invoice <- fourthClientF.flatMap(
|
||||
_.receive(MilliSatoshis(50000).toLnCurrencyUnit))
|
||||
_ <- firstClientF.flatMap(
|
||||
_.send(invoice)
|
||||
.map(payment => assert(payment.isInstanceOf[PaymentSucceeded])))
|
||||
|
||||
received <- fourthClientF.flatMap(_.audit())
|
||||
received <- fourthClientF
|
||||
.flatMap(_.audit())
|
||||
.map(_.received) // check for received payments
|
||||
relayed <- secondClientF.flatMap(_.audit()).map(_.relayed) // check for relayed payments
|
||||
sent <- firstClientF.flatMap(_.audit()).map(_.sent) // check for sent payments
|
||||
relayed <- secondClientF
|
||||
.flatMap(_.audit())
|
||||
.map(_.relayed) // check for relayed payments
|
||||
sent <- firstClientF
|
||||
.flatMap(_.audit())
|
||||
.map(_.sent) // check for sent payments
|
||||
} yield {
|
||||
assert(received.nonEmpty)
|
||||
assert(relayed.nonEmpty)
|
||||
|
@ -601,57 +622,66 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
// to them
|
||||
it should "get all channel updates for a given node ID" in {
|
||||
val freshClients1F = bitcoindRpcClientF.flatMap { bitcoindRpcClient =>
|
||||
EclairRpcTestUtil.createNodePair(Some(bitcoindRpcClient))
|
||||
}
|
||||
|
||||
|
||||
val freshClients2F = bitcoindRpcClientF.flatMap { bitcoindRpcClient =>
|
||||
EclairRpcTestUtil.createNodePair(Some(bitcoindRpcClient))
|
||||
}
|
||||
|
||||
val freshClients2F = bitcoindRpcClientF.flatMap { _ =>
|
||||
thirdClientF.flatMap(t => fourthClientF.map(f => (t, f)))
|
||||
}
|
||||
|
||||
val connectedClientsF: Future[EclairNodes4] = {
|
||||
freshClients1F.flatMap { case (freshClient1, freshClient2) =>
|
||||
freshClients2F.flatMap { case (freshClient3,freshClient4) =>
|
||||
freshClients1F.flatMap {
|
||||
case (freshClient1, freshClient2) =>
|
||||
freshClients2F.flatMap {
|
||||
case (freshClient3, freshClient4) =>
|
||||
clients ++= List(freshClient1,
|
||||
freshClient2,
|
||||
freshClient3,
|
||||
freshClient4)
|
||||
|
||||
clients ++= List(freshClient1,
|
||||
freshClient2,
|
||||
freshClient3,
|
||||
freshClient4)
|
||||
|
||||
val connect1And3 = EclairRpcTestUtil.connectLNNodes(freshClient1, freshClient3)
|
||||
val connect1And4 = EclairRpcTestUtil.connectLNNodes(freshClient1, freshClient4)
|
||||
connect1And3.flatMap { _ =>
|
||||
connect1And4.map { _ =>
|
||||
EclairNodes4(freshClient1, freshClient2, freshClient3, freshClient4)
|
||||
}
|
||||
val connect1And3 =
|
||||
EclairRpcTestUtil.connectLNNodes(freshClient1, freshClient3)
|
||||
val connect1And4 = connect1And3.flatMap(_ =>
|
||||
EclairRpcTestUtil.connectLNNodes(freshClient1, freshClient4))
|
||||
connect1And3.flatMap { _ =>
|
||||
connect1And4.map { _ =>
|
||||
EclairNodes4(freshClient1,
|
||||
freshClient2,
|
||||
freshClient3,
|
||||
freshClient4)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def openChannel(c1: EclairRpcClient, c2: EclairRpcClient): Future[FundedChannelId] = {
|
||||
def openChannel(
|
||||
c1: EclairRpcClient,
|
||||
c2: EclairRpcClient): Future[FundedChannelId] = {
|
||||
EclairRpcTestUtil
|
||||
.openChannel(c1, c2, Satoshis(Int64(500000)), MilliSatoshis(500000))
|
||||
}
|
||||
|
||||
val openedChannelsF: Future[(ChannelId, ChannelId)] = {
|
||||
connectedClientsF.flatMap { case nodes4: EclairNodes4 =>
|
||||
val chan1F = openChannel(nodes4.c1, nodes4.c2)
|
||||
val chan2F = openChannel(nodes4.c3, nodes4.c4)
|
||||
chan1F.flatMap(chanId1 => chan2F.map(chanId2 => (chanId1,chanId2)))
|
||||
connectedClientsF.flatMap {
|
||||
case nodes4: EclairNodes4 =>
|
||||
val chan1F = openChannel(nodes4.c1, nodes4.c2)
|
||||
val chan2F = openChannel(nodes4.c3, nodes4.c4)
|
||||
chan1F.flatMap(chanId1 => chan2F.map(chanId2 => (chanId1, chanId2)))
|
||||
}
|
||||
}
|
||||
|
||||
val gen10F = openedChannelsF.flatMap(_ => bitcoindRpcClientF.flatMap(_.generate(10)))
|
||||
val gen10F =
|
||||
openedChannelsF.flatMap(_ => bitcoindRpcClientF.flatMap(_.generate(10)))
|
||||
|
||||
val nodesReadyForPayments = gen10F.flatMap(_ => connectedClientsF)
|
||||
|
||||
val sendPaymentsF = nodesReadyForPayments.flatMap { n4 =>
|
||||
val p1F =
|
||||
EclairRpcTestUtil.sendPayments(c1 = n4.c1, c2 = n4.c2, numPayments = 2)
|
||||
val p2F =
|
||||
EclairRpcTestUtil.sendPayments(c1 = n4.c3, c2 = n4.c4, numPayments = 2)
|
||||
|
||||
val p1F = EclairRpcTestUtil.sendPayments(n4.c1, n4.c2)
|
||||
val p2F = EclairRpcTestUtil.sendPayments(n4.c3, n4.c4)
|
||||
p1F.flatMap(_ => p2F)
|
||||
}
|
||||
|
||||
|
@ -677,10 +707,9 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
val client2F = connectedClientsF.map(_.c2)
|
||||
|
||||
sendPaymentsF.flatMap { _ =>
|
||||
|
||||
executeSpecificClients(clientF = client1F,
|
||||
otherClientF = client2F,
|
||||
test = getChannelUpdates)
|
||||
otherClientF = client2F,
|
||||
test = getChannelUpdates)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -692,29 +721,27 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
//about the channels for future fee calculations
|
||||
val sentPaymentF = secondClientF.flatMap { c1 =>
|
||||
thirdClientF.flatMap { c2 =>
|
||||
EclairRpcTestUtil.sendPayments(c1,c2)
|
||||
EclairRpcTestUtil.sendPayments(c1, c2)
|
||||
}
|
||||
}
|
||||
|
||||
val gossipFromPeerWithNoChannel = {
|
||||
(client: EclairRpcClient, nonPeer: EclairRpcClient) =>
|
||||
|
||||
sentPaymentF.flatMap { _ =>
|
||||
val nodeIdF = client.getNodeURI.map(_.nodeId)
|
||||
def ourUpdates = nodeIdF.flatMap(nonPeer.allUpdates(_))
|
||||
def allUpdates = nonPeer.allUpdates()
|
||||
def checkUpdates() : Future[Boolean] = {
|
||||
ourUpdates.flatMap( our =>
|
||||
def checkUpdates(): Future[Boolean] = {
|
||||
ourUpdates.flatMap(our =>
|
||||
allUpdates.map { all =>
|
||||
our != all
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
val checkedUpatesF: Future[Unit] = AsyncUtil.retryUntilSatisfiedF(
|
||||
checkUpdates,
|
||||
duration = 5.seconds,
|
||||
maxTries = 15)
|
||||
val checkedUpatesF: Future[Unit] =
|
||||
AsyncUtil.retryUntilSatisfiedF(checkUpdates,
|
||||
duration = 5.seconds,
|
||||
maxTries = 15)
|
||||
|
||||
val hasUpdateP = Promise[Assertion]()
|
||||
checkedUpatesF.onComplete { t =>
|
||||
|
@ -795,7 +822,8 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
genF.flatMap { _ =>
|
||||
//wait until our peer has put the channel in the
|
||||
//NORMAL state so we can route payments to them
|
||||
val normalF = client2F.flatMap(c2 => EclairRpcTestUtil.awaitUntilChannelNormal(c2, cid))
|
||||
val normalF = client2F.flatMap(c2 =>
|
||||
EclairRpcTestUtil.awaitUntilChannelNormal(c2, cid))
|
||||
|
||||
normalF.map(_ => cid)
|
||||
|
||||
|
@ -804,7 +832,7 @@ class EclairRpcClientTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
}
|
||||
|
||||
private def updateIsInChannels(channels: Seq[OpenChannelInfo])(
|
||||
update: ChannelUpdate): Boolean = {
|
||||
update: ChannelUpdate): Boolean = {
|
||||
channels.exists(_.shortChannelId == update.shortChannelId)
|
||||
}
|
||||
|
||||
|
|
|
@ -476,7 +476,7 @@ class EclairRpcClient(val instance: EclairInstance)(
|
|||
val payloadF: Future[JsValue] = responseF.flatMap(getPayload)
|
||||
payloadF.map { payload =>
|
||||
val validated: JsResult[T] = (payload \ resultKey).validate[T]
|
||||
val parsed: T = parseResult(validated, payload)
|
||||
val parsed: T = parseResult(validated, payload, command)
|
||||
parsed
|
||||
}
|
||||
}
|
||||
|
@ -484,16 +484,19 @@ class EclairRpcClient(val instance: EclairInstance)(
|
|||
case class RpcError(code: Int, message: String)
|
||||
implicit val rpcErrorReads: Reads[RpcError] = Json.reads[RpcError]
|
||||
|
||||
private def parseResult[T](result: JsResult[T], json: JsValue): T = {
|
||||
private def parseResult[T](result: JsResult[T], json: JsValue, commandName: String): T = {
|
||||
result match {
|
||||
case res: JsSuccess[T] =>
|
||||
res.value
|
||||
case res: JsError =>
|
||||
(json \ errorKey).validate[RpcError] match {
|
||||
case err: JsSuccess[RpcError] =>
|
||||
logger.error(s"Error ${err.value.code}: ${err.value.message}")
|
||||
throw new RuntimeException(
|
||||
s"Error ${err.value.code}: ${err.value.message}")
|
||||
val datadirMsg = instance.authCredentials.datadir
|
||||
.map(d => s"datadir=${d}")
|
||||
.getOrElse("")
|
||||
val errMsg = s"Error for command=${commandName} ${datadirMsg}, ${err.value.code}=${err.value.message}"
|
||||
logger.error(errMsg)
|
||||
throw new RuntimeException(errMsg)
|
||||
case _: JsError =>
|
||||
logger.error(JsError.toJson(res).toString())
|
||||
throw new IllegalArgumentException(
|
||||
|
|
|
@ -7,8 +7,13 @@ import akka.actor.ActorSystem
|
|||
import com.typesafe.config.{Config, ConfigFactory}
|
||||
import org.bitcoins.core.config.RegTest
|
||||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.protocol.ln.channel.{ChannelId, ChannelState, FundedChannelId}
|
||||
import org.bitcoins.core.protocol.ln.channel.{
|
||||
ChannelId,
|
||||
ChannelState,
|
||||
FundedChannelId
|
||||
}
|
||||
import org.bitcoins.core.protocol.ln.currency.MilliSatoshis
|
||||
import org.bitcoins.core.protocol.ln.node.NodeId
|
||||
import org.bitcoins.core.util.BitcoinSLogger
|
||||
import org.bitcoins.eclair.rpc.client.EclairRpcClient
|
||||
import org.bitcoins.eclair.rpc.config.EclairInstance
|
||||
|
@ -21,6 +26,7 @@ import org.bitcoins.util.AsyncUtil
|
|||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
/**
|
||||
* @define nodeLinkDoc
|
||||
|
@ -217,7 +223,8 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
}(system.dispatcher)
|
||||
}
|
||||
|
||||
AsyncUtil.retryUntilSatisfiedF(conditionF = () => isState(), duration = 1.seconds)
|
||||
AsyncUtil.retryUntilSatisfiedF(conditionF = () => isState(),
|
||||
duration = 1.seconds)
|
||||
}
|
||||
|
||||
private def createNodeLink(
|
||||
|
@ -237,7 +244,7 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
internalBitcoindF.flatMap(b => createNodePair(Some(b)))
|
||||
}
|
||||
|
||||
val pair2: Future[(EclairRpcClient,EclairRpcClient)] = {
|
||||
val pair2: Future[(EclairRpcClient, EclairRpcClient)] = {
|
||||
internalBitcoindF.flatMap(b => createNodePair(Some(b)))
|
||||
}
|
||||
|
||||
|
@ -251,32 +258,30 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
}
|
||||
|
||||
val nodeVecF: Future[Vector[EclairRpcClient]] = {
|
||||
pair1.flatMap { case (first,second) =>
|
||||
pair2.flatMap {
|
||||
case (third,fourth) =>
|
||||
pair1.flatMap {
|
||||
case (first, second) =>
|
||||
pair2.flatMap {
|
||||
case (third, fourth) =>
|
||||
// we need to make sure the second and third nodes are connected
|
||||
val connected = EclairRpcTestUtil.connectLNNodes(second, third)
|
||||
connected.map { _ =>
|
||||
Vector(first, second, third, fourth)
|
||||
}
|
||||
|
||||
// we need to make sure the second and third nodes are connected
|
||||
val connected = EclairRpcTestUtil.connectLNNodes(second, third)
|
||||
connected.map { _ =>
|
||||
Vector(first,second,third,fourth)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
val openChannelsFNested: Future[List[Future[FundedChannelId]]] = {
|
||||
nodeVecF.map { nodeVec =>
|
||||
List(open(nodeVec.head, nodeVec(1)),
|
||||
open(nodeVec(1), nodeVec(2)),
|
||||
open(nodeVec(2), nodeVec(3)))
|
||||
open(nodeVec(1), nodeVec(2)),
|
||||
open(nodeVec(2), nodeVec(3)))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val openChannelsF :Future[List[FundedChannelId]] = {
|
||||
val openChannelsF: Future[List[FundedChannelId]] = {
|
||||
openChannelsFNested.flatMap(Future.sequence(_))
|
||||
}
|
||||
|
||||
|
@ -322,7 +327,8 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
* @return A 4-tuple of the created nodes' respective
|
||||
* [[org.bitcoins.eclair.rpc.client.EclairRpcClient EclairRpcClient]]
|
||||
*/
|
||||
def createNodeLink()(implicit actorSystem: ActorSystem): Future[EclairNodes4] = {
|
||||
def createNodeLink()(
|
||||
implicit actorSystem: ActorSystem): Future[EclairNodes4] = {
|
||||
createNodeLink(None, DEFAULT_CHANNEL_MSAT_AMT)
|
||||
}
|
||||
|
||||
|
@ -343,7 +349,8 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
* respective [[org.bitcoins.eclair.rpc.client.EclairRpcClient EclairRpcClient]]s
|
||||
*/
|
||||
def createNodePair(bitcoindRpcClientOpt: Option[BitcoindRpcClient])(
|
||||
implicit system: ActorSystem): Future[(EclairRpcClient, EclairRpcClient)] = {
|
||||
implicit system: ActorSystem): Future[
|
||||
(EclairRpcClient, EclairRpcClient)] = {
|
||||
import system.dispatcher
|
||||
val bitcoindRpcClientF: Future[BitcoindRpcClient] = {
|
||||
|
||||
|
@ -354,8 +361,10 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
}
|
||||
}
|
||||
|
||||
val e1InstanceF = bitcoindRpcClientF.map(EclairRpcTestUtil.eclairInstance(_))
|
||||
val e2InstanceF = bitcoindRpcClientF.map(EclairRpcTestUtil.eclairInstance(_))
|
||||
val e1InstanceF =
|
||||
bitcoindRpcClientF.map(EclairRpcTestUtil.eclairInstance(_))
|
||||
val e2InstanceF =
|
||||
bitcoindRpcClientF.map(EclairRpcTestUtil.eclairInstance(_))
|
||||
|
||||
val clientF = e1InstanceF.flatMap { e1 =>
|
||||
val e = new EclairRpcClient(e1)
|
||||
|
@ -372,14 +381,15 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
|
||||
logger.debug(s"Both clients started")
|
||||
|
||||
val connectedLnF: Future[(EclairRpcClient, EclairRpcClient)] = clientF.flatMap { c1 =>
|
||||
otherClientF.flatMap { c2 =>
|
||||
val connectedF = connectLNNodes(c1, c2)
|
||||
connectedF.map { _ =>
|
||||
(c1,c2)
|
||||
val connectedLnF: Future[(EclairRpcClient, EclairRpcClient)] =
|
||||
clientF.flatMap { c1 =>
|
||||
otherClientF.flatMap { c2 =>
|
||||
val connectedF = connectLNNodes(c1, c2)
|
||||
connectedF.map { _ =>
|
||||
(c1, c2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectedLnF
|
||||
}
|
||||
|
@ -389,13 +399,13 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
system: ActorSystem): Future[Unit] = {
|
||||
implicit val dispatcher = system.dispatcher
|
||||
val infoF = otherClient.getInfo
|
||||
|
||||
val nodeIdF = infoF.map(_.nodeId)
|
||||
val connection: Future[String] = infoF.flatMap { info =>
|
||||
client.connect(info.nodeId, "localhost", info.port)
|
||||
}
|
||||
|
||||
def isConnected(): Future[Boolean] = {
|
||||
val nodeIdF = infoF.map(_.nodeId)
|
||||
|
||||
nodeIdF.flatMap { nodeId =>
|
||||
connection.flatMap { _ =>
|
||||
val connected: Future[Boolean] = client.isConnected(nodeId)
|
||||
|
@ -405,9 +415,9 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
}
|
||||
|
||||
logger.debug(s"Awaiting connection between clients")
|
||||
val connected = RpcUtil.retryUntilSatisfiedF(
|
||||
conditionF = () => isConnected(),
|
||||
duration = 1.second)
|
||||
val connected = RpcUtil.retryUntilSatisfiedF(conditionF =
|
||||
() => isConnected(),
|
||||
duration = 1.second)
|
||||
|
||||
connected.map(_ => logger.debug(s"Successfully connected two clients"))
|
||||
|
||||
|
@ -424,8 +434,8 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
def sendPayments(
|
||||
c1: EclairRpcClient,
|
||||
c2: EclairRpcClient,
|
||||
numPayments: Int = 10)(
|
||||
implicit ec: ExecutionContext): Future[Seq[PaymentResult]] = {
|
||||
numPayments: Int = 5)(
|
||||
implicit ec: ExecutionContext): Future[Vector[PaymentResult]] = {
|
||||
val payments = (1 to numPayments)
|
||||
.map(MilliSatoshis(_))
|
||||
.map(
|
||||
|
@ -434,7 +444,22 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
.flatMap(invoice => c2.send(invoice, sats.toLnCurrencyUnit))
|
||||
)
|
||||
|
||||
Future.sequence(payments)
|
||||
val resultF = Future.sequence(payments).map(_.toVector)
|
||||
|
||||
resultF.onComplete {
|
||||
case Success(_) =>
|
||||
case Failure(_) =>
|
||||
val nodeId1F = c1.nodeId()
|
||||
val nodeId2F = c2.nodeId()
|
||||
nodeId1F.flatMap { nid1 =>
|
||||
nodeId2F.map { nid2 =>
|
||||
logger.error(
|
||||
s"Failed to send payments from ${nid1.hex} -> ${nid2.hex}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultF
|
||||
}
|
||||
|
||||
private val DEFAULT_CHANNEL_MSAT_AMT = MilliSatoshis(500000000L)
|
||||
|
@ -450,23 +475,30 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
|
||||
val bitcoindRpcClient = getBitcoindRpc(n1)
|
||||
implicit val ec = system.dispatcher
|
||||
val fundedChannelIdF: Future[FundedChannelId] = {
|
||||
n2.nodeId.flatMap { nodeId =>
|
||||
n1.getInfo.map { info =>
|
||||
logger.debug(
|
||||
s"Opening a channel from ${info.nodeId} -> ${nodeId} with amount ${amt}")
|
||||
|
||||
}
|
||||
n1.open(nodeId = nodeId,
|
||||
fundingSatoshis = amt,
|
||||
pushMsat = Some(pushMSat),
|
||||
feerateSatPerByte = None,
|
||||
channelFlags = None)
|
||||
val n1NodeIdF = n1.nodeId()
|
||||
val n2NodeIdF = n2.nodeId()
|
||||
|
||||
val nodeIdsF: Future[(NodeId, NodeId)] = {
|
||||
n1NodeIdF.flatMap(n1 => n2NodeIdF.map(n2 => (n1, n2)))
|
||||
}
|
||||
|
||||
val fundedChannelIdF: Future[FundedChannelId] = {
|
||||
nodeIdsF.flatMap {
|
||||
case (nodeId1, nodeId2) =>
|
||||
logger.debug(
|
||||
s"Opening a channel from ${nodeId1} -> ${nodeId2} with amount ${amt}")
|
||||
n1.open(nodeId = nodeId2,
|
||||
fundingSatoshis = amt,
|
||||
pushMsat = Some(pushMSat),
|
||||
feerateSatPerByte = None,
|
||||
channelFlags = None)
|
||||
}
|
||||
}
|
||||
|
||||
val gen = fundedChannelIdF.flatMap(_ => bitcoindRpcClient.generate(6))
|
||||
|
||||
val opened = {
|
||||
val openedF = {
|
||||
gen.flatMap { _ =>
|
||||
fundedChannelIdF.flatMap { fcid =>
|
||||
val chanOpenF = awaitChannelOpened(n1, fcid)
|
||||
|
@ -474,12 +506,17 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
|
|||
}
|
||||
}
|
||||
}
|
||||
opened.map {
|
||||
|
||||
openedF.flatMap {
|
||||
case _ =>
|
||||
logger.debug(
|
||||
s"Channel successfully opened ${n1.getNodeURI} -> ${n2.getNodeURI} with amount $amt")
|
||||
nodeIdsF.map {
|
||||
case (nodeId1, nodeId2) =>
|
||||
logger.debug(
|
||||
s"Channel successfully opened ${nodeId1} -> ${nodeId2} with amount $amt")
|
||||
}
|
||||
}
|
||||
opened
|
||||
|
||||
openedF
|
||||
}
|
||||
|
||||
def awaitChannelOpened(client1: EclairRpcClient, chanId: ChannelId)(
|
||||
|
|
Loading…
Add table
Reference in a new issue