1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-02-23 22:46:44 +01:00

Use bitcoin 0.18.1 in the test (#1148)

* Use bitcoin 0.18.1 during test
This commit is contained in:
araspitzu 2019-10-03 09:23:31 +02:00 committed by GitHub
parent 320af437d7
commit 37cc5262b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 88 additions and 96 deletions

View file

@ -79,10 +79,10 @@
<activeByDefault>true</activeByDefault> <activeByDefault>true</activeByDefault>
</activation> </activation>
<properties> <properties>
<bitcoind.url>https://bitcoin.org/bin/bitcoin-core-0.17.1/bitcoin-0.17.1-x86_64-linux-gnu.tar.gz <bitcoind.url>https://bitcoin.org/bin/bitcoin-core-0.18.1/bitcoin-0.18.1-x86_64-linux-gnu.tar.gz
</bitcoind.url> </bitcoind.url>
<bitcoind.md5>724043999e2b5ed0c088e8db34f15d43</bitcoind.md5> <bitcoind.md5>d3159a28702ca0cba2e0459e83219dfb</bitcoind.md5>
<bitcoind.sha1>546ee35d4089c7ccc040a01cdff3362599b8bc53</bitcoind.sha1> <bitcoind.sha1>969020835c1f0c759032def0d7b99669db06d8f7</bitcoind.sha1>
</properties> </properties>
</profile> </profile>
<profile> <profile>
@ -93,10 +93,10 @@
</os> </os>
</activation> </activation>
<properties> <properties>
<bitcoind.url>https://bitcoin.org/bin/bitcoin-core-0.17.1/bitcoin-0.17.1-osx64.tar.gz <bitcoind.url>https://bitcoin.org/bin/bitcoin-core-0.18.1/bitcoin-0.18.1-osx64.tar.gz
</bitcoind.url> </bitcoind.url>
<bitcoind.md5>b5a792c6142995faa42b768273a493bd</bitcoind.md5> <bitcoind.md5>0334b1024f28e83341c89df14e622bb6</bitcoind.md5>
<bitcoind.sha1>8bd51c7024d71de07df381055993e9f472013db8</bitcoind.sha1> <bitcoind.sha1>80354b40b409f342f5d35acd6b2c0e71f689285b</bitcoind.sha1>
</properties> </properties>
</profile> </profile>
<profile> <profile>
@ -107,9 +107,9 @@
</os> </os>
</activation> </activation>
<properties> <properties>
<bitcoind.url>https://bitcoin.org/bin/bitcoin-core-0.17.1/bitcoin-0.17.1-win64.zip</bitcoind.url> <bitcoind.url>https://bitcoin.org/bin/bitcoin-core-0.18.1/bitcoin-0.18.1-win64.zip</bitcoind.url>
<bitcoind.md5>b0e824e9dd02580b5b01f073f3c89858</bitcoind.md5> <bitcoind.md5>637776ca50b4354ca2f523bdee576bdb</bitcoind.md5>
<bitcoind.sha1>4e17bad7d08c465b444143a93cd6eb1c95076e3f</bitcoind.sha1> <bitcoind.sha1>44771cc2161853b5230a7a159278dc8f27e7d4c2</bitcoind.sha1>
</properties> </properties>
</profile> </profile>
</profiles> </profiles>

View file

@ -26,10 +26,10 @@ import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.blockchain.bitcoind.BitcoinCoreWallet.FundTransactionResponse import fr.acinq.eclair.blockchain.bitcoind.BitcoinCoreWallet.FundTransactionResponse
import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, JsonRPCError} import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, JsonRPCError}
import fr.acinq.eclair.transactions.Scripts import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.{LongToBtcAmount, addressToPublicKeyScript, randomKey} import fr.acinq.eclair.{LongToBtcAmount, TestConstants, addressToPublicKeyScript, randomKey}
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
import org.json4s.JsonAST._ import org.json4s.JsonAST.{JString, _}
import org.json4s.{DefaultFormats, JString} import org.json4s.DefaultFormats
import org.scalatest.{BeforeAndAfterAll, FunSuiteLike} import org.scalatest.{BeforeAndAfterAll, FunSuiteLike}
import scala.collection.JavaConversions._ import scala.collection.JavaConversions._
@ -275,8 +275,7 @@ class BitcoinCoreWalletSpec extends TestKit(ActorSystem("test")) with BitcoindSe
wallet.doubleSpent(tx1).pipeTo(sender.ref) wallet.doubleSpent(tx1).pipeTo(sender.ref)
sender.expectMsg(false) sender.expectMsg(false)
// let's confirm tx2 // let's confirm tx2
sender.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
sender.expectMsgType[JValue](10 seconds)
// this time tx1 has been double spent // this time tx1 has been double spent
wallet.doubleSpent(tx1).pipeTo(sender.ref) wallet.doubleSpent(tx1).pipeTo(sender.ref)
sender.expectMsg(true) sender.expectMsg(true)

View file

@ -53,7 +53,7 @@ trait BitcoindService extends Logging {
val INTEGRATION_TMP_DIR = new File(TestUtils.BUILD_DIRECTORY, s"integration-${UUID.randomUUID()}") val INTEGRATION_TMP_DIR = new File(TestUtils.BUILD_DIRECTORY, s"integration-${UUID.randomUUID()}")
logger.info(s"using tmp dir: $INTEGRATION_TMP_DIR") logger.info(s"using tmp dir: $INTEGRATION_TMP_DIR")
val PATH_BITCOIND = new File(TestUtils.BUILD_DIRECTORY, "bitcoin-0.17.1/bin/bitcoind") val PATH_BITCOIND = new File(TestUtils.BUILD_DIRECTORY, "bitcoin-0.18.1/bin/bitcoind")
val PATH_BITCOIND_DATADIR = new File(INTEGRATION_TMP_DIR, "datadir-bitcoin") val PATH_BITCOIND_DATADIR = new File(INTEGRATION_TMP_DIR, "datadir-bitcoin")
var bitcoind: Process = null var bitcoind: Process = null
@ -107,9 +107,7 @@ trait BitcoindService extends Logging {
} }
}, max = 3 minutes, interval = 2 seconds) }, max = 3 minutes, interval = 2 seconds)
logger.info(s"generating initial blocks...") logger.info(s"generating initial blocks...")
sender.send(bitcoincli, BitcoinReq("generate", 150)) generateBlocks(bitcoincli, 150)
val JArray(res) = sender.expectMsgType[JValue](3 minutes)
assert(res.size == 150)
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("getbalance")) sender.send(bitcoincli, BitcoinReq("getbalance"))
val JDecimal(balance) = sender.expectMsgType[JDecimal](30 seconds) val JDecimal(balance) = sender.expectMsgType[JDecimal](30 seconds)
@ -117,4 +115,18 @@ trait BitcoindService extends Logging {
}, max = 3 minutes, interval = 2 second) }, max = 3 minutes, interval = 2 second)
} }
def generateBlocks(bitcoinCli: ActorRef, blockCount: Int, address: Option[String] = None, timeout: FiniteDuration = 10 seconds)(implicit system: ActorSystem): Unit = {
val sender = TestProbe()
val addressToUse = address match {
case Some(addr) => addr
case None =>
sender.send(bitcoinCli, BitcoinReq("getnewaddress"))
val JString(address) = sender.expectMsgType[JValue](timeout)
address
}
sender.send(bitcoinCli, BitcoinReq("generatetoaddress", blockCount, addressToUse))
val JArray(blocks) = sender.expectMsgType[JValue](timeout)
assert(blocks.size == blockCount)
}
} }

View file

@ -24,8 +24,8 @@ import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.Transaction import fr.acinq.bitcoin.Transaction
import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, ExtendedBitcoinClient} import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, ExtendedBitcoinClient}
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
import org.json4s.JsonAST._ import org.json4s.JsonAST.{JString, _}
import org.json4s.{DefaultFormats, JString} import org.json4s.{DefaultFormats}
import org.scalatest.{BeforeAndAfterAll, FunSuiteLike} import org.scalatest.{BeforeAndAfterAll, FunSuiteLike}
import scala.collection.JavaConversions._ import scala.collection.JavaConversions._
@ -88,7 +88,9 @@ class ExtendedBitcoinClientSpec extends TestKit(ActorSystem("test")) with Bitcoi
client.publishTransaction(tx).pipeTo(sender.ref) client.publishTransaction(tx).pipeTo(sender.ref)
sender.expectMsg(txid) sender.expectMsg(txid)
// let's confirm the tx // let's confirm the tx
bitcoinClient.invoke("generate", 1).pipeTo(sender.ref) sender.send(bitcoincli, BitcoinReq("getnewaddress"))
val JString(generatingAddress) = sender.expectMsgType[JValue]
bitcoinClient.invoke("generatetoaddress", 1, generatingAddress).pipeTo(sender.ref)
sender.expectMsgType[JValue] sender.expectMsgType[JValue]
// and publish the tx a third time to test idempotence // and publish the tx a third time to test idempotence
client.publishTransaction(tx).pipeTo(sender.ref) client.publishTransaction(tx).pipeTo(sender.ref)
@ -110,7 +112,7 @@ class ExtendedBitcoinClientSpec extends TestKit(ActorSystem("test")) with Bitcoi
client.publishTransaction(tx).pipeTo(sender.ref) client.publishTransaction(tx).pipeTo(sender.ref)
sender.expectMsg(txid) sender.expectMsg(txid)
// let's confirm the tx // let's confirm the tx
bitcoinClient.invoke("generate", 1).pipeTo(sender.ref) bitcoinClient.invoke("generatetoaddress", 1, generatingAddress).pipeTo(sender.ref)
sender.expectMsgType[JValue] sender.expectMsgType[JValue]
// and publish the tx a fifth time to test idempotence // and publish the tx a fifth time to test idempotence
client.publishTransaction(tx).pipeTo(sender.ref) client.publishTransaction(tx).pipeTo(sender.ref)

View file

@ -84,8 +84,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
sender.receiveOne(5 second).isInstanceOf[JValue] sender.receiveOne(5 second).isInstanceOf[JValue]
}, max = 30 seconds, interval = 500 millis) }, max = 30 seconds, interval = 500 millis)
logger.info(s"generating initial blocks...") logger.info(s"generating initial blocks...")
sender.send(bitcoincli, BitcoinReq("generate", 150)) generateBlocks(bitcoincli, 150, timeout = 30 seconds)
sender.expectMsgType[JValue](30 seconds)
DockerReadyChecker.LogLineContains("INFO:BlockProcessor:height: 151").looped(attempts = 15, delay = 1 second) DockerReadyChecker.LogLineContains("INFO:BlockProcessor:height: 151").looped(attempts = 15, delay = 1 second)
} }
@ -119,9 +118,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// confirm our tx // confirm our tx
probe.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
val GetBalanceResponse(confirmed1, unconfirmed1) = getBalance(probe) val GetBalanceResponse(confirmed1, unconfirmed1) = getBalance(probe)
confirmed1 == confirmed + 100000000.sat confirmed1 == confirmed + 100000000.sat
@ -135,9 +132,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
logger.info(s"sending 0.5 btc to $address1") logger.info(s"sending 0.5 btc to $address1")
probe.send(bitcoincli, BitcoinReq("sendtoaddress", address1, 0.5)) probe.send(bitcoincli, BitcoinReq("sendtoaddress", address1, 0.5))
probe.expectMsgType[JValue] probe.expectMsgType[JValue]
generateBlocks(bitcoincli, 1)
probe.send(bitcoincli, BitcoinReq("generate", 1))
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
val GetBalanceResponse(confirmed1, _) = getBalance(probe) val GetBalanceResponse(confirmed1, _) = getBalance(probe)
@ -172,9 +167,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
unconfirmed1 == unconfirmed + amount + amount unconfirmed1 == unconfirmed + amount + amount
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
probe.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
val GetBalanceResponse(confirmed1, _) = getBalance(probe) val GetBalanceResponse(confirmed1, _) = getBalance(probe)
confirmed1 == confirmed + amount + amount confirmed1 == confirmed + amount + amount
@ -204,9 +197,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
assert(received === 100000000.sat) assert(received === 100000000.sat)
logger.info("generating a new block") logger.info("generating a new block")
probe.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
val GetBalanceResponse(confirmed1, _) = getBalance(probe) val GetBalanceResponse(confirmed1, _) = getBalance(probe)
confirmed1 - confirmed === 100000000.sat confirmed1 - confirmed === 100000000.sat
@ -237,8 +228,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
probe.send(wallet, BroadcastTransaction(tx1)) probe.send(wallet, BroadcastTransaction(tx1))
val BroadcastTransactionResponse(_, None) = probe.expectMsgType[BroadcastTransactionResponse] val BroadcastTransactionResponse(_, None) = probe.expectMsgType[BroadcastTransactionResponse]
probe.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
probe.send(bitcoincli, BitcoinReq("getreceivedbyaddress", address)) probe.send(bitcoincli, BitcoinReq("getreceivedbyaddress", address))
@ -270,8 +260,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
probe.send(wallet, BroadcastTransaction(tx1)) probe.send(wallet, BroadcastTransaction(tx1))
val BroadcastTransactionResponse(_, None) = probe.expectMsgType[BroadcastTransactionResponse] val BroadcastTransactionResponse(_, None) = probe.expectMsgType[BroadcastTransactionResponse]
probe.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
val GetBalanceResponse(confirmed1, _) = getBalance(probe) val GetBalanceResponse(confirmed1, _) = getBalance(probe)
@ -328,8 +317,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
probe.send(wallet, IsDoubleSpent(tx2)) probe.send(wallet, IsDoubleSpent(tx2))
probe.expectMsg(IsDoubleSpentResponse(tx2, false)) probe.expectMsg(IsDoubleSpentResponse(tx2, false))
probe.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2)
probe.expectMsgType[JValue]
awaitCond({ awaitCond({
probe.send(wallet, GetData) probe.send(wallet, GetData)

View file

@ -30,6 +30,7 @@ import fr.acinq.eclair.blockchain.electrum.ElectrumClientPool.ElectrumServerAddr
import fr.acinq.eclair.blockchain._ import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT} import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT}
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
import org.json4s
import org.json4s.JsonAST.{JArray, JString, JValue} import org.json4s.JsonAST.{JArray, JString, JValue}
import org.scalatest.{BeforeAndAfterAll, FunSuiteLike} import org.scalatest.{BeforeAndAfterAll, FunSuiteLike}
import scodec.bits._ import scodec.bits._
@ -72,9 +73,7 @@ class ElectrumWatcherSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
val listener = TestProbe() val listener = TestProbe()
probe.send(watcher, WatchConfirmed(listener.ref, tx.txid, tx.txOut(0).publicKeyScript, 4, BITCOIN_FUNDING_DEPTHOK)) probe.send(watcher, WatchConfirmed(listener.ref, tx.txid, tx.txOut(0).publicKeyScript, 4, BITCOIN_FUNDING_DEPTHOK))
probe.send(bitcoincli, BitcoinReq("generate", 3)) generateBlocks(bitcoincli, 5)
listener.expectNoMsg(1 second)
probe.send(bitcoincli, BitcoinReq("generate", 2))
val confirmed = listener.expectMsgType[WatchEventConfirmed](20 seconds) val confirmed = listener.expectMsgType[WatchEventConfirmed](20 seconds)
assert(confirmed.tx.txid.toHex === txid) assert(confirmed.tx.txid.toHex === txid)
system.stop(watcher) system.stop(watcher)
@ -119,10 +118,8 @@ class ElectrumWatcherSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
listener.expectNoMsg(1 second) listener.expectNoMsg(1 second)
probe.send(bitcoincli, BitcoinReq("sendrawtransaction", spendingTx.toString)) probe.send(bitcoincli, BitcoinReq("sendrawtransaction", spendingTx.toString))
probe.expectMsgType[JValue] probe.expectMsgType[JValue]
probe.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2)
val blocks = probe.expectMsgType[JValue] listener.expectMsgType[WatchEventSpent](20 seconds)
val JArray(List(JString(block1), JString(block2))) = blocks
val spent = listener.expectMsgType[WatchEventSpent](20 seconds)
system.stop(watcher) system.stop(watcher)
} }

View file

@ -43,10 +43,10 @@ import fr.acinq.eclair.router.{Announcements, AnnouncementsBatchValidationSpec,
import fr.acinq.eclair.transactions.Transactions import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.transactions.Transactions.{HtlcSuccessTx, HtlcTimeoutTx} import fr.acinq.eclair.transactions.Transactions.{HtlcSuccessTx, HtlcTimeoutTx}
import fr.acinq.eclair.wire._ import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiryDelta, Kit, LongToBtcAmount, MilliSatoshi, Setup, ShortChannelId, randomBytes32} import fr.acinq.eclair.{CltvExpiryDelta, Kit, LongToBtcAmount, MilliSatoshi, Setup, ShortChannelId, TestConstants, randomBytes32}
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
import org.json4s.JsonAST.JValue import org.json4s.JsonAST.{JString, JValue}
import org.json4s.{DefaultFormats, JString} import org.json4s.DefaultFormats
import org.scalatest.{BeforeAndAfterAll, FunSuiteLike} import org.scalatest.{BeforeAndAfterAll, FunSuiteLike}
import scodec.bits.ByteVector import scodec.bits.ByteVector
@ -115,8 +115,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.receiveOne(5 second).isInstanceOf[JValue] sender.receiveOne(5 second).isInstanceOf[JValue]
}, max = 30 seconds, interval = 500 millis) }, max = 30 seconds, interval = 500 millis)
logger.info(s"generating initial blocks...") logger.info(s"generating initial blocks...")
sender.send(bitcoincli, BitcoinReq("generate", 150)) generateBlocks(bitcoincli, 150, timeout = 30 seconds)
sender.expectMsgType[JValue](30 seconds)
} }
def instantiateEclairNode(name: String, config: Config) = { def instantiateEclairNode(name: String, config: Config) = {
@ -214,8 +213,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
}, max = 20 seconds, interval = 1 second) }, max = 20 seconds, interval = 1 second)
// confirming the funding tx // confirming the funding tx
sender.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2)
sender.expectMsgType[JValue](10 seconds)
within(60 seconds) { within(60 seconds) {
var count = 0 var count = 0
@ -247,8 +245,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
test("wait for network announcements") { test("wait for network announcements") {
val sender = TestProbe() val sender = TestProbe()
// generating more blocks so that all funding txes are buried under at least 6 blocks // generating more blocks so that all funding txes are buried under at least 6 blocks
sender.send(bitcoincli, BitcoinReq("generate", 4)) generateBlocks(bitcoincli, 4)
sender.expectMsgType[JValue]
// A requires private channels, as a consequence: // A requires private channels, as a consequence:
// - only A and B know about channel A-B (and there is no channel_announcement) // - only A and B know about channel A-B (and there is no channel_announcement)
// - A is not announced (no node_announcement) // - A is not announced (no node_announcement)
@ -500,8 +497,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
// we then fulfill the htlc, which will make F redeem it on-chain // we then fulfill the htlc, which will make F redeem it on-chain
sender.send(nodes("F1").register, Forward(htlc.channelId, CMD_FULFILL_HTLC(htlc.id, preimage))) sender.send(nodes("F1").register, Forward(htlc.channelId, CMD_FULFILL_HTLC(htlc.id, preimage)))
// we then generate one block so that the htlc success tx gets written to the blockchain // we then generate one block so that the htlc success tx gets written to the blockchain
sender.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1)
sender.expectMsgType[JValue](10 seconds)
// C will extract the preimage from the blockchain and fulfill the payment upstream // C will extract the preimage from the blockchain and fulfill the payment upstream
paymentSender.expectMsgType[PaymentSent](30 seconds) paymentSender.expectMsgType[PaymentSent](30 seconds)
// at this point F should have 1 recv transactions: the redeemed htlc // at this point F should have 1 recv transactions: the redeemed htlc
@ -511,8 +507,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
res.filter(_ \ "address" == JString(finalAddressF)).flatMap(_ \ "txids" \\ classOf[JString]).size == 1 res.filter(_ \ "address" == JString(finalAddressF)).flatMap(_ \ "txids" \\ classOf[JString]).size == 1
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// we then generate enough blocks so that C gets its main delayed output // we then generate enough blocks so that C gets its main delayed output
sender.send(bitcoincli, BitcoinReq("generate", 145)) generateBlocks(bitcoincli, 145)
sender.expectMsgType[JValue](10 seconds)
// and C will have its main output // and C will have its main output
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0)) sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0))
@ -521,8 +516,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
(receivedByC diff previouslyReceivedByC).size == 1 (receivedByC diff previouslyReceivedByC).size == 1
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// we generate blocks to make tx confirm // we generate blocks to make tx confirm
sender.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2)
sender.expectMsgType[JValue](10 seconds)
// and we wait for C'channel to close // and we wait for C'channel to close
awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds) awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds)
awaitAnnouncements(nodes.filterKeys(_ == "A"), 9, 11, 24) awaitAnnouncements(nodes.filterKeys(_ == "A"), 9, 11, 24)
@ -582,14 +576,14 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
// we then fulfill the htlc (it won't be sent to C, and will be used to pull funds on-chain) // we then fulfill the htlc (it won't be sent to C, and will be used to pull funds on-chain)
sender.send(nodes("F2").register, Forward(htlc.channelId, CMD_FULFILL_HTLC(htlc.id, preimage))) sender.send(nodes("F2").register, Forward(htlc.channelId, CMD_FULFILL_HTLC(htlc.id, preimage)))
// we then generate one block so that the htlc success tx gets written to the blockchain // we then generate one block so that the htlc success tx gets written to the blockchain
sender.send(bitcoincli, BitcoinReq("generate", 1)) sender.send(bitcoincli, BitcoinReq("getnewaddress"))
sender.expectMsgType[JValue](10 seconds) val JString(address) = sender.expectMsgType[JValue]
generateBlocks(bitcoincli, 1, Some(address))
// C will extract the preimage from the blockchain and fulfill the payment upstream // C will extract the preimage from the blockchain and fulfill the payment upstream
paymentSender.expectMsgType[PaymentSent](30 seconds) paymentSender.expectMsgType[PaymentSent](30 seconds)
// at this point F should have 1 recv transactions: the redeemed htlc // at this point F should have 1 recv transactions: the redeemed htlc
// we then generate enough blocks so that F gets its htlc-success delayed output // we then generate enough blocks so that F gets its htlc-success delayed output
sender.send(bitcoincli, BitcoinReq("generate", 145)) generateBlocks(bitcoincli, 145, Some(address))
sender.expectMsgType[JValue](10 seconds)
// at this point F should have 1 recv transactions: the redeemed htlc // at this point F should have 1 recv transactions: the redeemed htlc
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0)) sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0))
@ -604,8 +598,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
(receivedByC diff previouslyReceivedByC).size == 1 (receivedByC diff previouslyReceivedByC).size == 1
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// we generate blocks to make tx confirm // we generate blocks to make tx confirm
sender.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2, Some(address))
sender.expectMsgType[JValue](10 seconds)
// and we wait for C'channel to close // and we wait for C'channel to close
awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds) awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds)
awaitAnnouncements(nodes.filterKeys(_ == "A"), 8, 10, 22) awaitAnnouncements(nodes.filterKeys(_ == "A"), 8, 10, 22)
@ -640,12 +633,12 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
val res = sender.expectMsgType[JValue](10 seconds) val res = sender.expectMsgType[JValue](10 seconds)
val previouslyReceivedByC = res.filter(_ \ "address" == JString(finalAddressC)).flatMap(_ \ "txids" \\ classOf[JString]) val previouslyReceivedByC = res.filter(_ \ "address" == JString(finalAddressC)).flatMap(_ \ "txids" \\ classOf[JString])
// we then generate enough blocks to make the htlc timeout // we then generate enough blocks to make the htlc timeout
sender.send(bitcoincli, BitcoinReq("generate", 11)) sender.send(bitcoincli, BitcoinReq("getnewaddress"))
sender.expectMsgType[JValue](10 seconds) val JString(address) = sender.expectMsgType[JValue]
generateBlocks(bitcoincli, 11, Some(address))
// we generate more blocks for the htlc-timeout to reach enough confirmations // we generate more blocks for the htlc-timeout to reach enough confirmations
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1, Some(address))
sender.expectMsgType[JValue](10 seconds)
paymentSender.msgAvailable paymentSender.msgAvailable
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// this will fail the htlc // this will fail the htlc
@ -655,8 +648,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
assert(failed.failures.size === 1) assert(failed.failures.size === 1)
assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("C").nodeParams.nodeId, PermanentChannelFailure)) assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("C").nodeParams.nodeId, PermanentChannelFailure))
// we then generate enough blocks to confirm all delayed transactions // we then generate enough blocks to confirm all delayed transactions
sender.send(bitcoincli, BitcoinReq("generate", 150)) generateBlocks(bitcoincli, 150, Some(address))
sender.expectMsgType[JValue](10 seconds)
// at this point C should have 2 recv transactions: its main output and the htlc timeout // at this point C should have 2 recv transactions: its main output and the htlc timeout
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0)) sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0))
@ -665,8 +657,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
(receivedByC diff previouslyReceivedByC).size == 2 (receivedByC diff previouslyReceivedByC).size == 2
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// we generate blocks to make tx confirm // we generate blocks to make tx confirm
sender.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2, Some(address))
sender.expectMsgType[JValue](10 seconds)
// and we wait for C'channel to close // and we wait for C'channel to close
awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds) awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds)
awaitAnnouncements(nodes.filterKeys(_ == "A"), 7, 9, 20) awaitAnnouncements(nodes.filterKeys(_ == "A"), 7, 9, 20)
@ -705,12 +696,12 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
sender.send(nodes("F4").register, Forward(htlc.channelId, CMD_FORCECLOSE)) sender.send(nodes("F4").register, Forward(htlc.channelId, CMD_FORCECLOSE))
sender.expectMsg("ok") sender.expectMsg("ok")
// we then generate enough blocks to make the htlc timeout // we then generate enough blocks to make the htlc timeout
sender.send(bitcoincli, BitcoinReq("generate", 11)) sender.send(bitcoincli, BitcoinReq("getnewaddress"))
sender.expectMsgType[JValue](10 seconds) val JString(address) = sender.expectMsgType[JValue]
generateBlocks(bitcoincli, 11, Some(address))
// we generate more blocks for the claim-htlc-timeout to reach enough confirmations // we generate more blocks for the claim-htlc-timeout to reach enough confirmations
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1, Some(address))
sender.expectMsgType[JValue](10 seconds)
paymentSender.msgAvailable paymentSender.msgAvailable
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// this will fail the htlc // this will fail the htlc
@ -720,8 +711,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
assert(failed.failures.size === 1) assert(failed.failures.size === 1)
assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("C").nodeParams.nodeId, PermanentChannelFailure)) assert(failed.failures.head.asInstanceOf[RemoteFailure].e === DecryptedFailurePacket(nodes("C").nodeParams.nodeId, PermanentChannelFailure))
// we then generate enough blocks to confirm all delayed transactions // we then generate enough blocks to confirm all delayed transactions
sender.send(bitcoincli, BitcoinReq("generate", 145)) generateBlocks(bitcoincli, 145, Some(address))
sender.expectMsgType[JValue](10 seconds)
// at this point C should have 2 recv transactions: its main output and the htlc timeout // at this point C should have 2 recv transactions: its main output and the htlc timeout
awaitCond({ awaitCond({
sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0)) sender.send(bitcoincli, BitcoinReq("listreceivedbyaddress", 0))
@ -730,8 +720,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
(receivedByC diff previouslyReceivedByC).size == 2 (receivedByC diff previouslyReceivedByC).size == 2
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// we generate blocks to make tx confirm // we generate blocks to make tx confirm
sender.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2, Some(address))
sender.expectMsgType[JValue](10 seconds)
// and we wait for C'channel to close // and we wait for C'channel to close
awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds) awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds)
awaitAnnouncements(nodes.filterKeys(_ == "A"), 6, 8, 18) awaitAnnouncements(nodes.filterKeys(_ == "A"), 6, 8, 18)
@ -837,8 +826,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
Transaction.correctlySpends(htlcSuccess, Seq(revokedCommitTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) Transaction.correctlySpends(htlcSuccess, Seq(revokedCommitTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS)
Transaction.correctlySpends(htlcTimeout, Seq(revokedCommitTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) Transaction.correctlySpends(htlcTimeout, Seq(revokedCommitTx), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS)
// we then generate blocks to make the htlc timeout (nothing will happen in the channel because all of them have already been fulfilled) // we then generate blocks to make the htlc timeout (nothing will happen in the channel because all of them have already been fulfilled)
sender.send(bitcoincli, BitcoinReq("generate", 20)) generateBlocks(bitcoincli, 20)
sender.expectMsgType[JValue](10 seconds)
// then we publish F's revoked transactions // then we publish F's revoked transactions
sender.send(bitcoincli, BitcoinReq("sendrawtransaction", revokedCommitTx.toString())) sender.send(bitcoincli, BitcoinReq("sendrawtransaction", revokedCommitTx.toString()))
sender.expectMsgType[JValue](10000 seconds) sender.expectMsgType[JValue](10000 seconds)
@ -854,8 +842,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
(receivedByC diff previouslyReceivedByC).size == 6 (receivedByC diff previouslyReceivedByC).size == 6
}, max = 30 seconds, interval = 1 second) }, max = 30 seconds, interval = 1 second)
// we generate blocks to make tx confirm // we generate blocks to make tx confirm
sender.send(bitcoincli, BitcoinReq("generate", 2)) generateBlocks(bitcoincli, 2)
sender.expectMsgType[JValue](10 seconds)
// and we wait for C'channel to close // and we wait for C'channel to close
awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds) awaitCond(stateListener.expectMsgType[ChannelStateChanged].currentState == CLOSED, max = 30 seconds)
// this will remove the channel // this will remove the channel
@ -867,16 +854,16 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
// we simulate fake channels by publishing a funding tx and sending announcement messages to a node at random // we simulate fake channels by publishing a funding tx and sending announcement messages to a node at random
logger.info(s"generating fake channels") logger.info(s"generating fake channels")
val sender = TestProbe() val sender = TestProbe()
sender.send(bitcoincli, BitcoinReq("getnewaddress"))
val JString(address) = sender.expectMsgType[JValue]
val channels = for (i <- 0 until 242) yield { val channels = for (i <- 0 until 242) yield {
// let's generate a block every 10 txs so that we can compute short ids // let's generate a block every 10 txs so that we can compute short ids
if (i % 10 == 0) { if (i % 10 == 0) {
sender.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1, Some(address))
sender.expectMsgType[JValue](10 seconds)
} }
AnnouncementsBatchValidationSpec.simulateChannel AnnouncementsBatchValidationSpec.simulateChannel
} }
sender.send(bitcoincli, BitcoinReq("generate", 1)) generateBlocks(bitcoincli, 1, Some(address))
sender.expectMsgType[JValue](10 seconds)
logger.info(s"simulated ${channels.size} channels") logger.info(s"simulated ${channels.size} channels")
val remoteNodeId = PrivateKey(ByteVector32(ByteVector.fill(32)(1))).publicKey val remoteNodeId = PrivateKey(ByteVector32(ByteVector.fill(32)(1))).publicKey

View file

@ -28,6 +28,8 @@ import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, Exten
import fr.acinq.eclair.transactions.Scripts import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.wire.{ChannelAnnouncement, ChannelUpdate} import fr.acinq.eclair.wire.{ChannelAnnouncement, ChannelUpdate}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, ShortChannelId, randomKey} import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, ShortChannelId, randomKey}
import org.json4s
import org.json4s.JsonAST.{JString, JValue}
import org.scalatest.FunSuite import org.scalatest.FunSuite
import scodec.bits.ByteVector import scodec.bits.ByteVector
@ -76,8 +78,13 @@ object AnnouncementsBatchValidationSpec {
case class SimulatedChannel(node1Key: PrivateKey, node2Key: PrivateKey, node1FundingKey: PrivateKey, node2FundingKey: PrivateKey, amount: Satoshi, fundingTx: Transaction, fundingOutputIndex: Int) case class SimulatedChannel(node1Key: PrivateKey, node2Key: PrivateKey, node1FundingKey: PrivateKey, node2FundingKey: PrivateKey, amount: Satoshi, fundingTx: Transaction, fundingOutputIndex: Int)
def generateBlocks(numBlocks: Int)(implicit extendedBitcoinClient: ExtendedBitcoinClient, ec: ExecutionContext) = def generateBlocks(numBlocks: Int)(implicit extendedBitcoinClient: ExtendedBitcoinClient, ec: ExecutionContext) = {
Await.result(extendedBitcoinClient.rpcClient.invoke("generate", numBlocks), 10 seconds) val generatedF = for {
JString(address) <- extendedBitcoinClient.rpcClient.invoke("getnewaddress")
_ <- extendedBitcoinClient.rpcClient.invoke("generatetoaddress", numBlocks, address)
} yield ()
Await.result(generatedF, 10 seconds)
}
def simulateChannel()(implicit extendedBitcoinClient: ExtendedBitcoinClient, ec: ExecutionContext): SimulatedChannel = { def simulateChannel()(implicit extendedBitcoinClient: ExtendedBitcoinClient, ec: ExecutionContext): SimulatedChannel = {
val node1Key = randomKey val node1Key = randomKey