1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-03-13 11:35:47 +01:00

Add support for the signet test network (#2387)

This commit is contained in:
Richard Myers 2022-08-19 11:15:05 +02:00 committed by GitHub
parent 8f2028f600
commit 323aeec09c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 113 additions and 48 deletions

View file

@ -115,18 +115,18 @@ eclair.node-color=49daaa
Here are some of the most common options:
name | description | default value
-----------------------------|---------------------------------------------------------------------------------------|--------------
eclair.chain | Which blockchain to use: *regtest*, *testnet* or *mainnet* | mainnet
eclair.server.port | Lightning TCP port | 9735
eclair.api.enabled | Enable/disable the API | false. By default the API is disabled. If you want to enable it, you must set a password.
eclair.api.port | API HTTP port | 8080
eclair.api.password | API password (BASIC) | "" (must be set if the API is enabled)
eclair.bitcoind.rpcuser | Bitcoin Core RPC user | foo
eclair.bitcoind.rpcpassword | Bitcoin Core RPC password | bar
eclair.bitcoind.zmqblock | Bitcoin Core ZMQ block address | "tcp://127.0.0.1:29000"
eclair.bitcoind.zmqtx | Bitcoin Core ZMQ tx address | "tcp://127.0.0.1:29000"
eclair.bitcoind.wallet | Bitcoin Core wallet name | ""
name | description | default value
-----------------------------|----------------------------------------------------------------------|--------------
eclair.chain | Which blockchain to use: *regtest*, *testnet*, *signet* or *mainnet* | mainnet
eclair.server.port | Lightning TCP port | 9735
eclair.api.enabled | Enable/disable the API | false. By default the API is disabled. If you want to enable it, you must set a password.
eclair.api.port | API HTTP port | 8080
eclair.api.password | API password (BASIC) | "" (must be set if the API is enabled)
eclair.bitcoind.rpcuser | Bitcoin Core RPC user | foo
eclair.bitcoind.rpcpassword | Bitcoin Core RPC password | bar
eclair.bitcoind.zmqblock | Bitcoin Core ZMQ block address | "tcp://127.0.0.1:29000"
eclair.bitcoind.zmqtx | Bitcoin Core ZMQ tx address | "tcp://127.0.0.1:29000"
eclair.bitcoind.wallet | Bitcoin Core wallet name | ""
Quotes are not required unless the value contains special characters. Full syntax guide [here](https://github.com/lightbend/config/blob/master/HOCON.md).
@ -187,7 +187,7 @@ created. See [Managing Wallets](https://github.com/bitcoin/bitcoin/blob/master/d
For Eclair, the files that you need to backup are located in your data directory. You must backup:
* your seeds (`node_seed.dat` and `channel_seed.dat`)
* your channel database (`eclair.sqlite.bak` under directory `mainnet`, `testnet` or `regtest` depending on which chain you're running on)
* your channel database (`eclair.sqlite.bak` under directory `mainnet`, `testnet`, `signet` or `regtest` depending on which chain you're running on)
Your seeds never change once they have been created, but your channels will change whenever you receive or send payments. Eclair will
create and maintain a snapshot of its database, named `eclair.sqlite.bak`, in your data directory, and update it when needed. This file is
@ -248,7 +248,7 @@ If you need support for these plugins, head over to their respective github repo
## Testnet usage
Eclair is configured to run on mainnet by default, but you can still run it on testnet (or regtest): start your Bitcoin node in
Eclair is configured to run on mainnet by default, but you can still run it on testnet (or regtest/signet): start your Bitcoin node in
testnet mode (add `testnet=1` in `bitcoin.conf` or start with `-testnet`), and change Eclair's chain parameter and Bitcoin RPC port:
```conf
@ -256,17 +256,33 @@ eclair.chain=testnet
eclair.bitcoind.rpcport=18332
```
For regtest, add `regtest=1` in `bitcoin.conf` or start with `-regtest`, and modify `eclair.conf`:
```conf
eclair.chain = "regtest"
eclair.bitcoind.rpcport=18443
```
For signet, add `signet=1` in `bitcoin.conf` or start with `-signet`, and modify `eclair.conf`:
```conf
eclair.chain = "signet"
eclair.bitcoind.rpcport=38332
```
You may also want to take advantage of the new configuration sections in `bitcoin.conf` to manage parameters that are network specific,
so you can easily run your Bitcoin node on both mainnet and testnet. For example you could use:
```conf
server=1
txindex=1
[main]
rpcuser=<your-mainnet-rpc-user-here>
rpcpassword=<your-mainnet-rpc-password-here>
zmqpubhashblock=tcp://127.0.0.1:29000
zmqpubrawtx=tcp://127.0.0.1:29000
[test]
rpcuser=<your-testnet-rpc-user-here>
rpcpassword=<your-testnet-rpc-password-here>

View file

@ -47,21 +47,21 @@ related to routing configuration, and include it from `eclair.conf`.
Here are some of the most common options:
name | description | default value
-----------------------------|--------------------------------------------------------------------|--------------
eclair.chain | Which blockchain to use: *regtest*, *testnet* or *mainnet* | mainnet
eclair.server.port | Lightning TCP port | 9735
eclair.api.port | API HTTP port | 8080
eclair.api.enabled | Enables the JSON API | false
eclair.api.password | Password protecting the API (BASIC auth) | _no default_
eclair.bitcoind.auth | Bitcoin Core RPC authentication method: *password* or *safecookie* | password
eclair.bitcoind.rpcuser | Bitcoin Core RPC user | foo
eclair.bitcoind.rpcpassword | Bitcoin Core RPC password | bar
eclair.bitcoind.cookie | Bitcoin Core RPC cookie path | ${user.home}"/.bitcoin/.cookie"
eclair.bitcoind.zmqblock | Bitcoin Core ZMQ block address | "tcp://127.0.0.1:29000"
eclair.bitcoind.zmqtx | Bitcoin Core ZMQ tx address | "tcp://127.0.0.1:29000"
eclair.bitcoind.wallet | Bitcoin Core wallet name | ""
eclair.server.public-ips | List of node public ip | _no default_
name | description | default value
-----------------------------|----------------------------------------------------------------------|--------------
eclair.chain | Which blockchain to use: *regtest*, *testnet*, *signet* or *mainnet* | mainnet
eclair.server.port | Lightning TCP port | 9735
eclair.api.port | API HTTP port | 8080
eclair.api.enabled | Enables the JSON API | false
eclair.api.password | Password protecting the API (BASIC auth) | _no default_
eclair.bitcoind.auth | Bitcoin Core RPC authentication method: *password* or *safecookie* | password
eclair.bitcoind.rpcuser | Bitcoin Core RPC user | foo
eclair.bitcoind.rpcpassword | Bitcoin Core RPC password | bar
eclair.bitcoind.cookie | Bitcoin Core RPC cookie path | ${user.home}"/.bitcoin/.cookie"
eclair.bitcoind.zmqblock | Bitcoin Core ZMQ block address | "tcp://127.0.0.1:29000"
eclair.bitcoind.zmqtx | Bitcoin Core ZMQ tx address | "tcp://127.0.0.1:29000"
eclair.bitcoind.wallet | Bitcoin Core wallet name | ""
eclair.server.public-ips | List of node public ip | _no default_
&rarr; see [`reference.conf`](https://github.com/ACINQ/eclair/blob/master/eclair-core/src/main/resources/reference.conf) for full reference. There are many more options!

View file

@ -147,6 +147,15 @@ If the mempool becomes congested and the feerate is too low, the commitment tran
You can now specify a DNS host name as one of your `server.public-ips` addresses (see PR [#911](https://github.com/lightning/bolts/pull/911)). Note: you can not specify more than one DNS host name.
#### Support for testing on the signet network
To test Eclair with bitcoind configured for signet, set the following values in `eclair.conf`:
```conf
eclair.chain = "signet"
eclair.bitcoind.rpcport=38332
```
## Verifying signatures
You will need `gpg` and our release signing key 7A73FE77DE2C4027. Note that you can get it:

View file

@ -1,7 +1,7 @@
eclair {
datadir = ${user.home}"/.eclair"
chain = "mainnet" // "regtest" for regtest, "testnet" for testnet, "mainnet" for mainnet
chain = "mainnet" // "regtest" for regtest, "testnet" for testnet, "mainnet" for mainnet, "signet" for signet
server {
public-ips = [] // external ips, will be announced on the network

View file

@ -163,6 +163,7 @@ object NodeParams extends Logging {
private val chain2Hash: Map[String, ByteVector32] = Map(
"regtest" -> Block.RegtestGenesisBlock.hash,
"testnet" -> Block.TestnetGenesisBlock.hash,
"signet" -> Block.SignetGenesisBlock.hash,
"mainnet" -> Block.LivenetGenesisBlock.hash
)

View file

@ -185,6 +185,7 @@ class Setup(val datadir: File,
_ <- chain match {
case "mainnet" => bitcoinClient.invoke("getrawtransaction", "2157b554dcfda405233906e461ee593875ae4b1b97615872db6a25130ecc1dd6") // coinbase of #500000
case "testnet" => bitcoinClient.invoke("getrawtransaction", "8f38a0dd41dc0ae7509081e262d791f8d53ed6f884323796d5ec7b0966dd3825") // coinbase of #1500000
case "signet" => bitcoinClient.invoke("getrawtransaction", "ff1027486b628b2d160859205a3401fb2ee379b43527153b0b50a92c17ee7955") // coinbase of #5000
case "regtest" => Future.successful(())
}
} yield (progress, ibd, chainHash, bitcoinVersion, unspentAddresses, blocks, headers)

View file

@ -20,8 +20,8 @@ import akka.actor.ActorSystem
import akka.actor.typed.scaladsl.{ActorContext, Behaviors}
import akka.actor.typed.{ActorRef, Behavior}
import akka.pattern.after
import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
import fr.acinq.bitcoin.BlockHeader
import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
import fr.acinq.eclair.blockchain.watchdogs.BlockchainWatchdog.{BlockHeaderAt, LatestHeaders}
import fr.acinq.eclair.blockchain.watchdogs.Monitoring.{Metrics, Tags}
import fr.acinq.eclair.tor.Socks5ProxyParams
@ -225,12 +225,14 @@ object ExplorerApi {
override val baseUris = if (useTorEndpoints) {
Map(
Block.TestnetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api",
Block.LivenetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api"
Block.LivenetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api",
Block.SignetGenesisBlock.hash -> uri"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/signet/api"
)
} else {
Map(
Block.TestnetGenesisBlock.hash -> uri"https://mempool.space/testnet/api",
Block.LivenetGenesisBlock.hash -> uri"https://mempool.space/api"
Block.LivenetGenesisBlock.hash -> uri"https://mempool.space/api",
Block.SignetGenesisBlock.hash -> uri"https://mempool.space/signet/api"
)
}
}

View file

@ -18,7 +18,7 @@ package fr.acinq.eclair.crypto.keymanager
import com.google.common.cache.{CacheBuilder, CacheLoader, LoadingCache}
import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey}
import fr.acinq.bitcoin.scalacompat.DeterministicWallet.{derivePrivateKey, _}
import fr.acinq.bitcoin.scalacompat.DeterministicWallet._
import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, ByteVector64, Crypto, DeterministicWallet}
import fr.acinq.eclair.crypto.Generators
import fr.acinq.eclair.crypto.Monitoring.{Metrics, Tags}
@ -32,7 +32,7 @@ import scodec.bits.ByteVector
object LocalChannelKeyManager {
def keyBasePath(chainHash: ByteVector32): List[Long] = (chainHash: @unchecked) match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(1) :: Nil
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(1) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(1) :: Nil
}
}

View file

@ -28,7 +28,7 @@ object LocalNodeKeyManager {
// Note that the node path and the above channel path are on different branches so even if the
// node key is compromised there is no way to retrieve the wallet keys
def keyBasePath(chainHash: ByteVector32): List[Long] = (chainHash: @unchecked) match {
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil
case Block.RegtestGenesisBlock.hash | Block.TestnetGenesisBlock.hash | Block.SignetGenesisBlock.hash => DeterministicWallet.hardened(46) :: DeterministicWallet.hardened(0) :: Nil
case Block.LivenetGenesisBlock.hash => DeterministicWallet.hardened(47) :: DeterministicWallet.hardened(0) :: Nil
}
}

View file

@ -92,9 +92,9 @@ package object eclair {
}
Try(decodeBase58(address)) match {
case Success((Base58.Prefix.PubkeyAddressTestnet, pubKeyHash)) if chainHash == Block.TestnetGenesisBlock.hash || chainHash == Block.RegtestGenesisBlock.hash => Script.pay2pkh(pubKeyHash)
case Success((Base58.Prefix.PubkeyAddressTestnet, pubKeyHash)) if chainHash == Block.TestnetGenesisBlock.hash || chainHash == Block.RegtestGenesisBlock.hash || chainHash == Block.SignetGenesisBlock.hash => Script.pay2pkh(pubKeyHash)
case Success((Base58.Prefix.PubkeyAddress, pubKeyHash)) if chainHash == Block.LivenetGenesisBlock.hash => Script.pay2pkh(pubKeyHash)
case Success((Base58.Prefix.ScriptAddressTestnet, scriptHash)) if chainHash == Block.TestnetGenesisBlock.hash || chainHash == Block.RegtestGenesisBlock.hash => OP_HASH160 :: OP_PUSHDATA(scriptHash) :: OP_EQUAL :: Nil
case Success((Base58.Prefix.ScriptAddressTestnet, scriptHash)) if chainHash == Block.TestnetGenesisBlock.hash || chainHash == Block.RegtestGenesisBlock.hash || chainHash == Block.SignetGenesisBlock.hash => OP_HASH160 :: OP_PUSHDATA(scriptHash) :: OP_EQUAL :: Nil
case Success((Base58.Prefix.ScriptAddress, scriptHash)) if chainHash == Block.LivenetGenesisBlock.hash => OP_HASH160 :: OP_PUSHDATA(scriptHash) :: OP_EQUAL :: Nil
case Success(_) => throw new IllegalArgumentException("base58 address does not match our blockchain")
case Failure(base58error) =>
@ -102,7 +102,7 @@ package object eclair {
case Success((_, version, _)) if version != 0.toByte => throw new IllegalArgumentException(s"invalid version $version in bech32 address")
case Success((_, _, bin)) if bin.length != 20 && bin.length != 32 => throw new IllegalArgumentException("hash length in bech32 address must be either 20 or 32 bytes")
case Success(("bc", _, bin)) if chainHash == Block.LivenetGenesisBlock.hash => OP_0 :: OP_PUSHDATA(bin) :: Nil
case Success(("tb", _, bin)) if chainHash == Block.TestnetGenesisBlock.hash => OP_0 :: OP_PUSHDATA(bin) :: Nil
case Success(("tb", _, bin)) if chainHash == Block.TestnetGenesisBlock.hash || chainHash == Block.SignetGenesisBlock.hash => OP_0 :: OP_PUSHDATA(bin) :: Nil
case Success(("bcrt", _, bin)) if chainHash == Block.RegtestGenesisBlock.hash => OP_0 :: OP_PUSHDATA(bin) :: Nil
case Success(_) => throw new IllegalArgumentException("bech32 address does not match our blockchain")
case Failure(bech32error) => throw new IllegalArgumentException(s"$address is neither a valid Base58 address ($base58error) nor a valid Bech32 address ($bech32error)")

View file

@ -32,7 +32,7 @@ import scala.util.{Failure, Success, Try}
* Lightning Bolt 11 invoice
* see https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
*
* @param prefix currency prefix; lnbc for bitcoin, lntb for bitcoin testnet
* @param prefix currency prefix; lnbc for bitcoin, lntb for bitcoin testnet, lntbs for bitcoin signet
* @param amount_opt amount to pay (empty string means no amount is specified)
* @param createdAt invoice timestamp (UNIX format)
* @param nodeId id of the node emitting the invoice
@ -136,6 +136,7 @@ object Bolt11Invoice {
val prefixes = Map(
Block.RegtestGenesisBlock.hash -> "lnbcrt",
Block.SignetGenesisBlock.hash -> "lntbs",
Block.TestnetGenesisBlock.hash -> "lntb",
Block.LivenetGenesisBlock.hash -> "lnbc"
)
@ -292,11 +293,12 @@ object Bolt11Invoice {
f.version match {
case 17 if prefix == "lnbc" => Base58Check.encode(Base58.Prefix.PubkeyAddress, data.toArray)
case 18 if prefix == "lnbc" => Base58Check.encode(Base58.Prefix.ScriptAddress, data.toArray)
case 17 if prefix == "lntb" || prefix == "lnbcrt" => Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, data.toArray)
case 18 if prefix == "lntb" || prefix == "lnbcrt" => Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, data.toArray)
case 17 if prefix == "lntb" || prefix == "lnbcrt" || prefix == "lntbs" => Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, data.toArray)
case 18 if prefix == "lntb" || prefix == "lnbcrt" || prefix == "lntbs" => Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, data.toArray)
case version if prefix == "lnbc" => Bech32.encodeWitnessAddress("bc", version, data.toArray)
case version if prefix == "lntb" => Bech32.encodeWitnessAddress("tb", version, data.toArray)
case version if prefix == "lnbcrt" => Bech32.encodeWitnessAddress("bcrt", version, data.toArray)
case version if prefix == "lntbs" => Bech32.encodeWitnessAddress("tb", version, data.toArray)
}
}
}

View file

@ -16,10 +16,9 @@
package fr.acinq.eclair
import com.google.common.net.InetAddresses
import fr.acinq.bitcoin.{Base58, Base58Check, Bech32}
import fr.acinq.bitcoin.scalacompat.Crypto.PrivateKey
import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32, Crypto, Script}
import fr.acinq.bitcoin.{Base58, Base58Check, Bech32}
import org.scalatest.funsuite.AnyFunSuite
import scodec.bits._
@ -52,6 +51,7 @@ class PackageSpec extends AnyFunSuite {
// valid chain
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160), Block.TestnetGenesisBlock.hash) == Script.pay2pkh(pub))
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160), Block.RegtestGenesisBlock.hash) == Script.pay2pkh(pub))
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddressTestnet, pub.hash160), Block.SignetGenesisBlock.hash) == Script.pay2pkh(pub))
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160), Block.LivenetGenesisBlock.hash) == Script.pay2pkh(pub))
// wrong chain
@ -60,6 +60,7 @@ class PackageSpec extends AnyFunSuite {
}
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160), Block.TestnetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160), Block.RegtestGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.PubkeyAddress, pub.hash160), Block.SignetGenesisBlock.hash)).isFailure)
// p2sh
val script = Script.write(Script.pay2wpkh(pub))
@ -67,12 +68,14 @@ class PackageSpec extends AnyFunSuite {
// valid chain
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script)), Block.TestnetGenesisBlock.hash) == Script.pay2sh(script))
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script)), Block.RegtestGenesisBlock.hash) == Script.pay2sh(script))
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script)), Block.SignetGenesisBlock.hash) == Script.pay2sh(script))
assert(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script)), Block.LivenetGenesisBlock.hash) == Script.pay2sh(script))
// wrong chain
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddressTestnet, Crypto.hash160(script)), Block.LivenetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script)), Block.TestnetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script)), Block.RegtestGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Base58Check.encode(Base58.Prefix.ScriptAddress, Crypto.hash160(script)), Block.SignetGenesisBlock.hash)).isFailure)
}
test("decode bech32 addresses") {
@ -83,21 +86,25 @@ class PackageSpec extends AnyFunSuite {
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bc", 0, pub.hash160), Block.LivenetGenesisBlock.hash) == Script.pay2wpkh(pub))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 0, pub.hash160), Block.TestnetGenesisBlock.hash) == Script.pay2wpkh(pub))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bcrt", 0, pub.hash160), Block.RegtestGenesisBlock.hash) == Script.pay2wpkh(pub))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 0, pub.hash160), Block.SignetGenesisBlock.hash) == Script.pay2wpkh(pub))
// wrong version
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bc", 1, pub.hash160), Block.LivenetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 1, pub.hash160), Block.TestnetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bcrt", 1, pub.hash160), Block.RegtestGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 1, pub.hash160), Block.SignetGenesisBlock.hash)).isFailure)
// wrong chain
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bc", 0, pub.hash160), Block.TestnetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 0, pub.hash160), Block.LivenetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bcrt", 0, pub.hash160), Block.LivenetGenesisBlock.hash)).isFailure)
assert(Try(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 0, pub.hash160), Block.LivenetGenesisBlock.hash)).isFailure)
val script = Script.write(Script.pay2wpkh(pub))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bc", 0, Crypto.sha256(script)), Block.LivenetGenesisBlock.hash) == Script.pay2wsh(script))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 0, Crypto.sha256(script)), Block.TestnetGenesisBlock.hash) == Script.pay2wsh(script))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("bcrt", 0, Crypto.sha256(script)), Block.RegtestGenesisBlock.hash) == Script.pay2wsh(script))
assert(addressToPublicKeyScript(Bech32.encodeWitnessAddress("tb", 0, Crypto.sha256(script)), Block.SignetGenesisBlock.hash) == Script.pay2wsh(script))
}
test("fail to decode invalid addresses") {

View file

@ -38,6 +38,7 @@ class BlockchainWatchdogSpec extends ScalaTestWithActorTestKit(ConfigFactory.loa
// and comment these:
val nodeParamsLivenet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.LivenetGenesisBlock.hash))
val nodeParamsTestnet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.TestnetGenesisBlock.hash))
val nodeParamsSignet = removeBlockcypher(TestConstants.Alice.nodeParams.copy(chainHash = Block.SignetGenesisBlock.hash))
test("fetch block headers from four sources on mainnet", TestTags.ExternalApi) {
@ -75,6 +76,19 @@ class BlockchainWatchdogSpec extends ScalaTestWithActorTestKit(ConfigFactory.loa
testKit.stop(watchdog)
}
test("fetch block headers from one source on signet", TestTags.ExternalApi) {
val eventListener = TestProbe[DangerousBlocksSkew]()
system.eventStream ! EventStream.Subscribe(eventListener.ref)
val watchdog = testKit.spawn(BlockchainWatchdog(nodeParamsSignet, 1 second))
watchdog ! WrappedCurrentBlockHeight(BlockHeight(5000))
val event = eventListener.expectMessageType[DangerousBlocksSkew]
eventListener.expectNoMessage(100 millis)
assert(event.recentHeaders.source == "mempool.space")
testKit.stop(watchdog)
}
test("fetch block headers when we don't receive blocks", TestTags.ExternalApi) {
val eventListener = TestProbe[DangerousBlocksSkew]()
system.eventStream ! EventStream.Subscribe(eventListener.ref)

View file

@ -23,14 +23,13 @@ import fr.acinq.bitcoin.scalacompat.{Block, ByteVector32}
import fr.acinq.eclair.FeatureSupport.{Mandatory, Optional}
import fr.acinq.eclair.Features.{BasicMultiPartPayment, ChannelRangeQueries, PaymentSecret, VariableLengthOnion}
import fr.acinq.eclair.TestConstants._
import fr.acinq.eclair.RealShortChannelId
import fr.acinq.eclair._
import fr.acinq.eclair.crypto.TransportHandler
import fr.acinq.eclair.message.OnionMessages.{Recipient, buildMessage}
import fr.acinq.eclair.router.Router._
import fr.acinq.eclair.router.RoutingSyncSpec
import fr.acinq.eclair.wire.protocol
import fr.acinq.eclair.wire.protocol._
import fr.acinq.eclair.{RealShortChannelId, _}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, ParallelTestExecution}
import scodec.bits._
@ -198,7 +197,7 @@ class PeerConnectionSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike wi
probe.send(peerConnection, PeerConnection.InitializeConnection(peer.ref, nodeParams.chainHash, nodeParams.features.initFeatures(), doSync = true))
transport.expectMsgType[TransportHandler.Listener]
transport.expectMsgType[protocol.Init]
transport.send(peerConnection, protocol.Init(Bob.nodeParams.features.initFeatures(), TlvStream(InitTlv.Networks(Block.LivenetGenesisBlock.hash :: Block.SegnetGenesisBlock.hash :: Nil))))
transport.send(peerConnection, protocol.Init(Bob.nodeParams.features.initFeatures(), TlvStream(InitTlv.Networks(Block.LivenetGenesisBlock.hash :: Block.SignetGenesisBlock.hash :: Nil))))
transport.expectMsgType[TransportHandler.ReadAck]
probe.expectTerminated(transport.ref)
origin.expectMsg(PeerConnection.ConnectionResult.InitializationFailed("incompatible networks"))

View file

@ -207,6 +207,20 @@ class Bolt11InvoiceSpec extends AnyFunSuite {
assert(invoice.sign(priv).toString == ref)
}
test("Parse a signet invoice") {
val ref = "lntbs2500u1p30ukj3pp5flaka84tayag36uj06k58tn5zukel0paskxwmc0gppc6t6utmp3sdq809hkcmcsp5uv40j7x3dx6sqfrefmj6lu933zakwedejyl4rsakv2lzg53fqxlsmqz9gxqrrsscqp79q2sqqqqqysgqmq30dcj5l8lc02e6pxq0wmagy5qafc05hv6e0yd6ftudes2awa8psu63tuf39dch0dk3hdckfd64g2v3y58tnpma68fxfyqr4vw22wsqm4jkrn"
val Success(invoice) = Bolt11Invoice.fromString(ref)
assert(invoice.prefix == "lntbs")
assert(invoice.amount_opt.contains(250000000 msat))
assert(invoice.paymentHash.bytes == hex"4ffb6e9eabe93a88eb927ead43ae74172d9fbc3d858cede1e80871a5eb8bd863")
assert(invoice.features == Features(VariableLengthOnion -> Mandatory, PaymentSecret -> Mandatory, BasicMultiPartPayment -> Optional, PaymentMetadata -> Optional ))
assert(invoice.createdAt == TimestampSecond(1660836433))
assert(invoice.nodeId == PublicKey(hex"02e899d99662f2e64ea0eeaecb53c4628fa40a22d7185076e42e8a3d67fcb7b8e6"))
assert(invoice.description == Left("yolo"))
assert(invoice.fallbackAddress().isEmpty)
assert(invoice.tags.size == 7)
}
test("On mainnet, with fallback address 1RustyRX2oai4EYYDpQGWvEL62BBGqN9T with extra routing info to go via nodes 029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255 then 039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255") {
val ref = "lnbc20m1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzq9qrsgqdfjcdk6w3ak5pca9hwfwfh63zrrz06wwfya0ydlzpgzxkn5xagsqz7x9j4jwe7yj7vaf2k9lqsdk45kts2fd0fkr28am0u4w95tt2nsq76cqw0"
val Success(invoice) = Bolt11Invoice.fromString(ref)

View file

@ -72,7 +72,7 @@
<akka.version>2.6.18</akka.version>
<akka.http.version>10.2.7</akka.http.version>
<sttp.version>3.4.1</sttp.version>
<bitcoinlib.version>0.23</bitcoinlib.version>
<bitcoinlib.version>0.24</bitcoinlib.version>
<guava.version>31.1-jre</guava.version>
<kamon.version>2.4.6</kamon.version>
</properties>