mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-22 14:22:39 +01:00
Improve unit tests (#908)
* Bitcoin tests: generate 150 blocks instead of 500 We don't need to generate 432 blocks to activate segwit but we still need to have spendable coins and coinbase maturity is 100 blocks even on regtest. * Electrum client: test against mainnet Electrum servers Previous test against testnet servers was flaky because testnet Electrum servers are unrelable. Here we test against our own server on mainnet (and 2 servers from our list for the pool test).
This commit is contained in:
parent
1c9ac1d62d
commit
32d8a08ad1
5 changed files with 36 additions and 32 deletions
|
@ -86,7 +86,7 @@ trait BitcoindService extends Logging {
|
|||
sender.receiveOne(5 second).isInstanceOf[JValue]
|
||||
}, max = 30 seconds, interval = 500 millis)
|
||||
logger.info(s"generating initial blocks...")
|
||||
sender.send(bitcoincli, BitcoinReq("generate", 500))
|
||||
sender.send(bitcoincli, BitcoinReq("generate", 150))
|
||||
sender.expectMsgType[JValue](30 seconds)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package fr.acinq.eclair.blockchain.electrum
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
|
||||
import akka.actor.{ActorRef, ActorSystem, Props}
|
||||
import akka.testkit.{TestKit, TestProbe}
|
||||
import fr.acinq.bitcoin.{ByteVector32, Crypto, Transaction}
|
||||
|
@ -30,7 +32,8 @@ import scala.concurrent.duration._
|
|||
class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with FunSuiteLike with Logging with BeforeAndAfterAll {
|
||||
var pool: ActorRef = _
|
||||
val probe = TestProbe()
|
||||
val referenceTx = Transaction.read("0200000003947e307df3ab452d23f02b5a65f4ada1804ee733e168e6197b0bd6cc79932b6c010000006a473044022069346ec6526454a481690a3664609f9e8032c34553015cfa2e9b25ebb420a33002206998f21a2aa771ad92a0c1083f4181a3acdb0d42ca51d01be1309da2ffb9cecf012102b4568cc6ee751f6d39f4a908b1fcffdb878f5f784a26a48c0acb0acff9d88e3bfeffffff966d9d969cd5f95bfd53003a35fcc1a50f4fb51f211596e6472583fdc5d38470000000006b4830450221009c9757515009c5709b5b678d678185202b817ef9a69ffb954144615ab11762210220732216384da4bf79340e9c46d0effba6ba92982cca998adfc3f354cec7715f800121035f7c3e077108035026f4ebd5d6ca696ef088d4f34d45d94eab4c41202ec74f9bfefffffff8d5062f5b04455c6cfa7e3f250e5a4fb44308ba2b86baf77f9ad0d782f57071010000006a47304402207f9f7dd91fe537a26d5554105977e3949a5c8c4ef53a6a3bff6da2d36eff928f02202b9427bef487a1825fd0c3c6851d17d5f19e6d73dfee22bf06db591929a2044d012102b4568cc6ee751f6d39f4a908b1fcffdb878f5f784a26a48c0acb0acff9d88e3bfeffffff02809698000000000017a914c82753548fdf4be1c3c7b14872c90b5198e67eaa876e642500000000001976a914e2365ec29471b3e271388b22eadf0e7f54d307a788ac6f771200")
|
||||
// this is tx #2690 of block #500000
|
||||
val referenceTx = Transaction.read("0200000001983c5b32ced1de5ae97d3ce9b7436f8bb0487d15bf81e5cae97b1e238dc395c6000000006a47304402205957c75766e391350eba2c7b752f0056cb34b353648ecd0992a8a81fc9bcfe980220629c286592842d152cdde71177cd83086619744a533f262473298cacf60193500121021b8b51f74dbf0ac1e766d162c8707b5e8d89fc59da0796f3b4505e7c0fb4cf31feffffff0276bd0101000000001976a914219de672ba773aa0bc2e15cdd9d2e69b734138fa88ac3e692001000000001976a914301706dede031e9fb4b60836e073a4761855f6b188ac09a10700")
|
||||
val scriptHash = Crypto.sha256(referenceTx.txOut(0).publicKeyScript).reverse
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
|
@ -39,14 +42,14 @@ class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with FunSuiteL
|
|||
}
|
||||
|
||||
test("init an electrumx connection pool") {
|
||||
val stream = classOf[ElectrumClientSpec].getResourceAsStream("/electrum/servers_testnet.json")
|
||||
val addresses = ElectrumClientPool.readServerAddresses(stream, sslEnabled = false)
|
||||
val stream = classOf[ElectrumClientSpec].getResourceAsStream("/electrum/servers_mainnet.json")
|
||||
val addresses = ElectrumClientPool.readServerAddresses(stream, sslEnabled = false).take(2) + ElectrumClientPool.ElectrumServerAddress(new InetSocketAddress("electrum.acinq.co", 50002), SSL.STRICT)
|
||||
assert(addresses.nonEmpty)
|
||||
stream.close()
|
||||
pool = system.actorOf(Props(new ElectrumClientPool(addresses)), "electrum-client")
|
||||
}
|
||||
|
||||
test("connect to an electrumx testnet server") {
|
||||
test("connect to an electrumx mainnet server") {
|
||||
probe.send(pool, AddStatusListener(probe.ref))
|
||||
// make sure our master is stable, if the first master that we select is behind the other servers we will switch
|
||||
// during the first few seconds
|
||||
|
@ -56,18 +59,18 @@ class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with FunSuiteL
|
|||
}, max = 15 seconds, interval = 1000 millis) }
|
||||
|
||||
test("get transaction") {
|
||||
probe.send(pool, GetTransaction(ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202")))
|
||||
probe.send(pool, GetTransaction(referenceTx.txid))
|
||||
val GetTransactionResponse(tx) = probe.expectMsgType[GetTransactionResponse]
|
||||
assert(tx.txid == ByteVector32.fromValidHex("c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"))
|
||||
assert(tx == referenceTx)
|
||||
}
|
||||
|
||||
test("get merkle tree") {
|
||||
probe.send(pool, GetMerkle(ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"), 1210223))
|
||||
probe.send(pool, GetMerkle(referenceTx.txid, 500000))
|
||||
val response = probe.expectMsgType[GetMerkleResponse]
|
||||
assert(response.txid == ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"))
|
||||
assert(response.block_height == 1210223)
|
||||
assert(response.pos == 28)
|
||||
assert(response.root == ByteVector32(hex"203a52cf3cc071467e5b8780d62d5dfb672bf7bc0841bc823691961ea23402fb"))
|
||||
assert(response.txid == referenceTx.txid)
|
||||
assert(response.block_height == 500000)
|
||||
assert(response.pos == 2690)
|
||||
assert(response.root == ByteVector32(hex"1f6231ed3de07345b607ec2a39b2d01bec2fe10dfb7f516ba4958a42691c9531"))
|
||||
}
|
||||
|
||||
test("header subscription") {
|
||||
|
@ -87,12 +90,12 @@ class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with FunSuiteL
|
|||
test("get scripthash history") {
|
||||
probe.send(pool, GetScriptHashHistory(scriptHash))
|
||||
val GetScriptHashHistoryResponse(scriptHash1, history) = probe.expectMsgType[GetScriptHashHistoryResponse]
|
||||
assert(history.contains((TransactionHistoryItem(1210224, ByteVector32(hex"3903726806aa044fe59f40e42eed71bded068b43aaa9e2d716e38b7825412de0")))))
|
||||
assert(history.contains((TransactionHistoryItem(500000, referenceTx.txid))))
|
||||
}
|
||||
|
||||
test("list script unspents") {
|
||||
probe.send(pool, ScriptHashListUnspent(scriptHash))
|
||||
val ScriptHashListUnspentResponse(scriptHash1, unspents) = probe.expectMsgType[ScriptHashListUnspentResponse]
|
||||
assert(unspents.contains(UnspentItem(ByteVector32(hex"3903726806aa044fe59f40e42eed71bded068b43aaa9e2d716e38b7825412de0"), 0, 10000000L, 1210224L)))
|
||||
assert(unspents.isEmpty)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,32 +35,33 @@ class ElectrumClientSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
|||
|
||||
var client: ActorRef = _
|
||||
val probe = TestProbe()
|
||||
val referenceTx = Transaction.read("0200000003947e307df3ab452d23f02b5a65f4ada1804ee733e168e6197b0bd6cc79932b6c010000006a473044022069346ec6526454a481690a3664609f9e8032c34553015cfa2e9b25ebb420a33002206998f21a2aa771ad92a0c1083f4181a3acdb0d42ca51d01be1309da2ffb9cecf012102b4568cc6ee751f6d39f4a908b1fcffdb878f5f784a26a48c0acb0acff9d88e3bfeffffff966d9d969cd5f95bfd53003a35fcc1a50f4fb51f211596e6472583fdc5d38470000000006b4830450221009c9757515009c5709b5b678d678185202b817ef9a69ffb954144615ab11762210220732216384da4bf79340e9c46d0effba6ba92982cca998adfc3f354cec7715f800121035f7c3e077108035026f4ebd5d6ca696ef088d4f34d45d94eab4c41202ec74f9bfefffffff8d5062f5b04455c6cfa7e3f250e5a4fb44308ba2b86baf77f9ad0d782f57071010000006a47304402207f9f7dd91fe537a26d5554105977e3949a5c8c4ef53a6a3bff6da2d36eff928f02202b9427bef487a1825fd0c3c6851d17d5f19e6d73dfee22bf06db591929a2044d012102b4568cc6ee751f6d39f4a908b1fcffdb878f5f784a26a48c0acb0acff9d88e3bfeffffff02809698000000000017a914c82753548fdf4be1c3c7b14872c90b5198e67eaa876e642500000000001976a914e2365ec29471b3e271388b22eadf0e7f54d307a788ac6f771200")
|
||||
// this is tx #2690 of block #500000
|
||||
val referenceTx = Transaction.read("0200000001983c5b32ced1de5ae97d3ce9b7436f8bb0487d15bf81e5cae97b1e238dc395c6000000006a47304402205957c75766e391350eba2c7b752f0056cb34b353648ecd0992a8a81fc9bcfe980220629c286592842d152cdde71177cd83086619744a533f262473298cacf60193500121021b8b51f74dbf0ac1e766d162c8707b5e8d89fc59da0796f3b4505e7c0fb4cf31feffffff0276bd0101000000001976a914219de672ba773aa0bc2e15cdd9d2e69b734138fa88ac3e692001000000001976a914301706dede031e9fb4b60836e073a4761855f6b188ac09a10700")
|
||||
val scriptHash = Crypto.sha256(referenceTx.txOut(0).publicKeyScript).reverse
|
||||
|
||||
override protected def beforeAll(): Unit = {
|
||||
client = system.actorOf(Props(new ElectrumClient(new InetSocketAddress("testnet.qtornado.com", 51002), SSL.LOOSE)), "electrum-client")
|
||||
client = system.actorOf(Props(new ElectrumClient(new InetSocketAddress("electrum.acinq.co", 50002), SSL.STRICT)), "electrum-client")
|
||||
}
|
||||
|
||||
override protected def afterAll(): Unit = {
|
||||
TestKit.shutdownActorSystem(system)
|
||||
}
|
||||
|
||||
test("connect to an electrumx testnet server") {
|
||||
test("connect to an electrumx mainnet server") {
|
||||
probe.send(client, AddStatusListener(probe.ref))
|
||||
probe.expectMsgType[ElectrumReady](15 seconds)
|
||||
}
|
||||
|
||||
test("get transaction") {
|
||||
probe.send(client, GetTransaction(ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202")))
|
||||
probe.send(client, GetTransaction(referenceTx.txid))
|
||||
val GetTransactionResponse(tx) = probe.expectMsgType[GetTransactionResponse]
|
||||
assert(tx.txid == ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"))
|
||||
assert(tx == referenceTx)
|
||||
}
|
||||
|
||||
test("get header") {
|
||||
probe.send(client, GetHeader(10000))
|
||||
probe.send(client, GetHeader(100000))
|
||||
val GetHeaderResponse(height, header) = probe.expectMsgType[GetHeaderResponse]
|
||||
assert(header.blockId == ByteVector32(hex"000000000058b74204bb9d59128e7975b683ac73910660b6531e59523fb4a102"))
|
||||
assert(header.blockId == ByteVector32(hex"000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"))
|
||||
}
|
||||
|
||||
test("get headers") {
|
||||
|
@ -72,12 +73,12 @@ class ElectrumClientSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
|||
}
|
||||
|
||||
test("get merkle tree") {
|
||||
probe.send(client, GetMerkle(ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"), 1210223))
|
||||
probe.send(client, GetMerkle(referenceTx.txid, 500000))
|
||||
val response = probe.expectMsgType[GetMerkleResponse]
|
||||
assert(response.txid == ByteVector32(hex"c5efb5cbd35a44ba956b18100be0a91c9c33af4c7f31be20e33741d95f04e202"))
|
||||
assert(response.block_height == 1210223)
|
||||
assert(response.pos == 28)
|
||||
assert(response.root == ByteVector32(hex"203a52cf3cc071467e5b8780d62d5dfb672bf7bc0841bc823691961ea23402fb"))
|
||||
assert(response.txid == referenceTx.txid)
|
||||
assert(response.block_height == 500000)
|
||||
assert(response.pos == 2690)
|
||||
assert(response.root == ByteVector32(hex"1f6231ed3de07345b607ec2a39b2d01bec2fe10dfb7f516ba4958a42691c9531"))
|
||||
}
|
||||
|
||||
test("header subscription") {
|
||||
|
@ -97,12 +98,12 @@ class ElectrumClientSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
|||
test("get scripthash history") {
|
||||
probe.send(client, GetScriptHashHistory(scriptHash))
|
||||
val GetScriptHashHistoryResponse(scriptHash1, history) = probe.expectMsgType[GetScriptHashHistoryResponse]
|
||||
assert(history.contains((TransactionHistoryItem(1210224, ByteVector32(hex"3903726806aa044fe59f40e42eed71bded068b43aaa9e2d716e38b7825412de0")))))
|
||||
assert(history.contains((TransactionHistoryItem(500000, referenceTx.txid))))
|
||||
}
|
||||
|
||||
test("list script unspents") {
|
||||
probe.send(client, ScriptHashListUnspent(scriptHash))
|
||||
val ScriptHashListUnspentResponse(scriptHash1, unspents) = probe.expectMsgType[ScriptHashListUnspentResponse]
|
||||
assert(unspents.contains(UnspentItem(ByteVector32(hex"3903726806aa044fe59f40e42eed71bded068b43aaa9e2d716e38b7825412de0"), 0, 10000000L, 1210224L)))
|
||||
assert(unspents.isEmpty)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
|||
probe.expectMsgType[GetBalanceResponse]
|
||||
}
|
||||
|
||||
test("generate 500 blocks") {
|
||||
test("generate 150 blocks") {
|
||||
val sender = TestProbe()
|
||||
logger.info(s"waiting for bitcoind to initialize...")
|
||||
awaitCond({
|
||||
|
@ -82,9 +82,9 @@ class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with FunSuiteLike
|
|||
sender.receiveOne(5 second).isInstanceOf[JValue]
|
||||
}, max = 30 seconds, interval = 500 millis)
|
||||
logger.info(s"generating initial blocks...")
|
||||
sender.send(bitcoincli, BitcoinReq("generate", 500))
|
||||
sender.send(bitcoincli, BitcoinReq("generate", 150))
|
||||
sender.expectMsgType[JValue](30 seconds)
|
||||
DockerReadyChecker.LogLineContains("INFO:BlockProcessor:height: 501").looped(attempts = 15, delay = 1 second)
|
||||
DockerReadyChecker.LogLineContains("INFO:BlockProcessor:height: 151").looped(attempts = 15, delay = 1 second)
|
||||
}
|
||||
|
||||
test("wait until wallet is ready") {
|
||||
|
|
|
@ -114,7 +114,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
|
|||
sender.receiveOne(5 second).isInstanceOf[JValue]
|
||||
}, max = 30 seconds, interval = 500 millis)
|
||||
logger.info(s"generating initial blocks...")
|
||||
sender.send(bitcoincli, BitcoinReq("generate", 500))
|
||||
sender.send(bitcoincli, BitcoinReq("generate", 150))
|
||||
sender.expectMsgType[JValue](30 seconds)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue