mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-19 01:43:22 +01:00
Test change address type generation (#2513)
Starting with bitcoind 23.0, a new `changetype` parameter was introduced. If not specified, bitcoind will generate a change output with a type that matches the main output to make it harder for chain analysis to detect which output is the change. The issue is that lightning requires segwit utxos: if an on-chain payment is sent to a non-segwit address, we still want our change output to use segwit, otherwise we won't be able to use it. We thus must set `addresstype` and `changetype` in `bitcoin.conf` to ensure we never generate legacy change addresses.
This commit is contained in:
parent
5b0aa35c8d
commit
a230395f5f
@ -60,7 +60,7 @@ This means that instead of re-implementing them, Eclair benefits from the verifi
|
||||
:warning: This also means that Eclair has strong requirements on how your Bitcoin Core node is configured (see below), and that you must back up your Bitcoin Core wallet as well as your Eclair node (see [here](#configure-bitcoin-core-wallet)):
|
||||
|
||||
* Eclair needs a _synchronized_, _segwit-ready_, **_zeromq-enabled_**, _wallet-enabled_, _non-pruning_, _tx-indexing_ [Bitcoin Core](https://github.com/bitcoin/bitcoin) node.
|
||||
* You must configure your Bitcoin node to use `bech32` (segwit) addresses. If your wallet has "non-segwit UTXOs" (outputs that are neither `p2sh-segwit` or `bech32`), you must send them to a `bech32` address before running Eclair.
|
||||
* You must configure your Bitcoin node to use `bech32` or `bech32m` (segwit) addresses. If your wallet has "non-segwit UTXOs" (outputs that are neither `p2sh-segwit`, `bech32` or `bech32m`), you must send them to a `bech32` or `bech32m` address before running Eclair.
|
||||
* Eclair requires Bitcoin Core 23.0 or higher. If you are upgrading an existing wallet, you may need to create a new address and send all your funds to that address.
|
||||
|
||||
Run bitcoind with the following minimal `bitcoin.conf`:
|
||||
@ -70,6 +70,8 @@ server=1
|
||||
rpcuser=foo
|
||||
rpcpassword=bar
|
||||
txindex=1
|
||||
addresstype=bech32
|
||||
changetype=bech32
|
||||
zmqpubhashblock=tcp://127.0.0.1:29000
|
||||
zmqpubrawtx=tcp://127.0.0.1:29000
|
||||
```
|
||||
@ -280,6 +282,8 @@ so you can easily run your Bitcoin node on both mainnet and testnet. For example
|
||||
```conf
|
||||
server=1
|
||||
txindex=1
|
||||
addresstype=bech32
|
||||
changetype=bech32
|
||||
|
||||
[main]
|
||||
rpcuser=<your-mainnet-rpc-user-here>
|
||||
|
@ -33,6 +33,7 @@ Values do not need to be surrounded by quotes, except if they contain special ch
|
||||
### Changing the data directory
|
||||
|
||||
You can change the data directory with the `eclair.datadir` parameter:
|
||||
|
||||
```sh
|
||||
eclair-node.sh -Declair.datadir="/path/to/custom/eclair/data/folder"
|
||||
```
|
||||
@ -41,7 +42,7 @@ eclair-node.sh -Declair.datadir="/path/to/custom/eclair/data/folder"
|
||||
|
||||
Note that HOCON allows you to have files include other files. This allows you to split your configuration file into
|
||||
several logical files, for easier management. For example, you could define a file `routing.conf` file with parameters
|
||||
related to routing configuration, and include it from `eclair.conf`.
|
||||
related to routing configuration, and include it from `eclair.conf`.
|
||||
|
||||
## Options reference
|
||||
|
||||
@ -234,13 +235,14 @@ You'll also have to make sure the node is accessible from the outside world (por
|
||||
|
||||
### Bitcoin Core cookie authentication
|
||||
|
||||
If you run Eclair and Bitcoin on the same computer an alternative way to handle the Bitcoin Core RPC authentication
|
||||
If you run Eclair and Bitcoin on the same computer an alternative way to handle the Bitcoin Core RPC authentication.
|
||||
is to use the safecookie. To use safecookie authentication, you need to remove `rpcpassword=***` and `rpcuser=***` from your `bitcoin.conf` and add the following to `eclair.conf`:
|
||||
|
||||
```conf
|
||||
eclair.bitcoind.auth = "safecookie"
|
||||
eclair.bitcoind.cookie = "PATH TO THE COOKIE FILE"
|
||||
```
|
||||
|
||||
Setting `eclair.bitcoind.cookie` might not be necessary if Bitcoin is running on mainnet and using the default datadir.
|
||||
|
||||
Eclair will need read access to Bitcoin Core's cookie file.
|
||||
|
@ -21,7 +21,7 @@ import akka.pattern.pipe
|
||||
import akka.testkit.TestProbe
|
||||
import fr.acinq.bitcoin
|
||||
import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey
|
||||
import fr.acinq.bitcoin.scalacompat.{Block, Btc, BtcDouble, ByteVector32, MilliBtcDouble, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxIn, TxOut, computeP2WpkhAddress}
|
||||
import fr.acinq.bitcoin.scalacompat.{Block, Btc, BtcDouble, ByteVector32, MilliBtcDouble, OutPoint, Satoshi, SatoshiLong, Script, ScriptWitness, Transaction, TxIn, TxOut, computeP2PkhAddress, computeP2WpkhAddress}
|
||||
import fr.acinq.bitcoin.{Bech32, SigHash, SigVersion}
|
||||
import fr.acinq.eclair.blockchain.OnChainWallet.{FundTransactionResponse, MakeFundingTxResponse, OnChainBalance, SignTransactionResponse}
|
||||
import fr.acinq.eclair.blockchain.WatcherSpec.{createSpendManyP2WPKH, createSpendP2WPKH}
|
||||
@ -961,4 +961,21 @@ class BitcoinCoreClientSpec extends TestKitBaseClass with BitcoindService with A
|
||||
assert(Btc(receivedAmount.values).toMilliBtc == amount)
|
||||
}
|
||||
|
||||
test("generate segwit change outputs") {
|
||||
val sender = TestProbe()
|
||||
val bitcoinClient = new BitcoinCoreClient(bitcoinrpcclient)
|
||||
|
||||
// Even when we pay a legacy address, our change output must use segwit, otherwise it won't be usable for lightning channels.
|
||||
val pubKey = randomKey().publicKey
|
||||
val legacyAddress = computeP2PkhAddress(pubKey, Block.RegtestGenesisBlock.hash)
|
||||
bitcoinClient.sendToAddress(legacyAddress, 150_000 sat, 1).pipeTo(sender.ref)
|
||||
val txId = sender.expectMsgType[ByteVector32]
|
||||
bitcoinClient.getTransaction(txId).pipeTo(sender.ref)
|
||||
val tx = sender.expectMsgType[Transaction]
|
||||
// We have a change output.
|
||||
assert(tx.txOut.length == 2)
|
||||
assert(tx.txOut.count(txOut => txOut.publicKeyScript == Script.write(Script.pay2pkh(pubKey))) == 1)
|
||||
assert(tx.txOut.count(txOut => Script.isNativeWitnessScript(txOut.publicKeyScript)) == 1)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user