Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,12 @@ You will find detailed guides and frequently asked questions there.

### Configuring Bitcoin Core

:warning: Eclair requires Bitcoin Core 0.18.1, 0.19.1 or 0.20.1. If you are upgrading an existing wallet, you need to create a new address and send all your funds to that address.
:warning: Eclair requires Bitcoin Core 0.18.1, 0.19.1 or 0.20.1. If you are upgrading an existing wallet, you may need to create a new address and send all your funds to that address.

Eclair needs a _synchronized_, _segwit-ready_, **_zeromq-enabled_**, _wallet-enabled_, _non-pruning_, _tx-indexing_ [Bitcoin Core](https://github.com/bitcoin/bitcoin) node.
Eclair will use any BTC it finds in the default Bitcoin Core wallet to fund any channels you choose to open. Eclair will return BTC from closed channels to this wallet. You can have multiple Bitcoin Core wallets but make sure that the default one is always available.
Any BTC found in the wallet can be used to fund the channels you choose to open and the BTC from closed channels will return to this wallet.
You can configure your Bitcoin Node to use either `p2sh-segwit` addresses or `bech32` addresses, Eclair is compatible with both modes.
If your Bitcoin Core wallet has "non-segwit UTXOs" (outputs that are neither `p2sh-segwit` or `bech32`), you must send them to a `p2sh-segwit` or `bech32` address.

You can configure your Bitcoin node to use either `p2sh-segwit` addresses or `bech32` addresses, Eclair is compatible with both modes.
If your wallet has "non-segwit UTXOs" (outputs that are neither `p2sh-segwit` or `bech32`), you must send them to a `p2sh-segwit` or `bech32` address before running eclair.

Run bitcoind with the following minimal `bitcoin.conf`:

Expand Down Expand Up @@ -100,11 +99,22 @@ name | description
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).

→ see [`reference.conf`](eclair-core/src/main/resources/reference.conf) for full reference. There are many more options!

#### Configure Bitcoin Core wallet

Eclair will use the default loaded Bitcoin Core wallet to fund any channels you choose to open.
If you want to use a different wallet from the default one, you must set `eclair.bitcoind.wallet` accordingly in your `eclair.conf`.

:warning: Once a wallet is configured, you must be very careful if you want to change it: changing the wallet when you have channels open may result in a loss of funds (or a complex recovery procedure).

Eclair will return BTC from closed channels to the wallet configured.
Any BTC found in the wallet can be used to fund the channels you choose to open.

#### Java Environment Variables

Some advanced parameters can be changed with java environment variables. Most users won't need this and can skip this section.
Expand Down
4 changes: 4 additions & 0 deletions eclair-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ eclair {
rpcport = 8332
rpcuser = "foo"
rpcpassword = "bar"
// Name of the bitcoind wallet that should be used to fund channels.
// Once set you should NOT change it if your node has channels open, otherwise you may lose funds.
// NB: leave empty to automatically select the default loaded wallet.
wallet = ""
zmqblock = "tcp://127.0.0.1:29000"
zmqtx = "tcp://127.0.0.1:29000"
}
Expand Down
15 changes: 10 additions & 5 deletions eclair-core/src/main/scala/fr/acinq/eclair/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,20 @@ class Setup(datadir: File,

val bitcoin = nodeParams.watcherType match {
case BITCOIND =>
val wallet = {
val name = config.getString("bitcoind.wallet")
if (!name.isBlank) Some(name) else None
}
val bitcoinClient = new BasicBitcoinJsonRPCClient(
user = config.getString("bitcoind.rpcuser"),
password = config.getString("bitcoind.rpcpassword"),
host = config.getString("bitcoind.host"),
port = config.getInt("bitcoind.rpcport"))
port = config.getInt("bitcoind.rpcport"),
wallet = wallet)
val future = for {
json <- bitcoinClient.invoke("getblockchaininfo").recover { case _ => throw BitcoinRPCConnectionException }
json <- bitcoinClient.invoke("getblockchaininfo").recover { case e => throw BitcoinRPCConnectionException(e) }
// Make sure wallet support is enabled in bitcoind.
_ <- bitcoinClient.invoke("getbalance").recover { case _ => throw BitcoinWalletDisabledException }
_ <- bitcoinClient.invoke("getbalance").recover { case e => throw BitcoinWalletDisabledException(e) }
progress = (json \ "verificationprogress").extract[Double]
ibd = (json \ "initialblockdownload").extract[Boolean]
blocks = (json \ "blocks").extract[Long]
Expand Down Expand Up @@ -396,9 +401,9 @@ object Kit {

case object BitcoinZMQConnectionTimeoutException extends RuntimeException("could not connect to bitcoind using zeromq")

case object BitcoinRPCConnectionException extends RuntimeException("could not connect to bitcoind using json-rpc")
case class BitcoinRPCConnectionException(e: Throwable) extends RuntimeException("could not connect to bitcoind using json-rpc", e)

case object BitcoinWalletDisabledException extends RuntimeException("bitcoind must have wallet support enabled")
case class BitcoinWalletDisabledException(e: Throwable) extends RuntimeException("bitcoind wallet not available", e)

case object EmptyAPIPasswordException extends RuntimeException("must set a password for the json-rpc api")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,27 @@ import com.softwaremill.sttp.json4s._
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.eclair.KamonExt
import fr.acinq.eclair.blockchain.Monitoring.{Metrics, Tags}
import org.json4s.{CustomSerializer, DefaultFormats}
import org.json4s.JsonAST.{JString, JValue}
import org.json4s.jackson.Serialization
import org.json4s.{CustomSerializer, DefaultFormats}

import scala.concurrent.{ExecutionContext, Future}

class BasicBitcoinJsonRPCClient(user: String, password: String, host: String = "127.0.0.1", port: Int = 8332, ssl: Boolean = false)(implicit http: SttpBackend[Future, Nothing]) extends BitcoinJsonRPCClient {
class BasicBitcoinJsonRPCClient(user: String, password: String, host: String = "127.0.0.1", port: Int = 8332, ssl: Boolean = false, wallet: Option[String] = None)(implicit http: SttpBackend[Future, Nothing]) extends BitcoinJsonRPCClient {

// necessary to properly serialize ByteVector32 into String readable by bitcoind
object ByteVector32Serializer extends CustomSerializer[ByteVector32](_ => ( {
null
}, {
case x: ByteVector32 => JString(x.toHex)
}))

implicit val formats = DefaultFormats.withBigDecimal + ByteVector32Serializer
private val scheme = if (ssl) "https" else "http"
private val serviceUri = uri"$scheme://$host:$port/wallet/" // wallet/ specifies to use the default bitcoind wallet, named ""
private val serviceUri = wallet match {
case Some(name) => uri"$scheme://$host:$port/wallet/$name"
case None => uri"$scheme://$host:$port"
}
implicit val serialization = Serialization

override def invoke(method: String, params: Any*)(implicit ec: ExecutionContext): Future[JValue] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class FxApp extends Application with Logging {
def onError(t: Throwable): Unit = t match {
case e@TCPBindException(port) =>
notifyPreloader(new ErrorNotification("Setup", s"Could not bind to port $port", e))
case e@BitcoinRPCConnectionException =>
case e: BitcoinRPCConnectionException =>
notifyPreloader(new ErrorNotification("Setup", "Could not connect to Bitcoin Core using JSON-RPC.", e))
notifyPreloader(new AppNotification(InfoAppNotification, "Make sure that Bitcoin Core is up and running and RPC parameters are correct."))
case e@BitcoinZMQConnectionTimeoutException =>
Expand Down