mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-19 01:43:22 +01:00
master
1 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Fabrice Drouin
|
6f8713788c
|
Delegate Bitcoin Core's private key management to Eclair (#2613)
* Make Eclair manage bitcoin core's wallet private keys We create an empty watch-only wallet and import public descriptors generated by Eclair. Bitcoin Core can fund transaction and manage utxos, but can no longer sign transactions. * Check that spent amounts and utxos are consistent before we sign a PSBT PSBT utxo fields include the amount that are being spent by the PSBT inputs, but there is a "fee attack" where using amounts that are lower than what is actually spent may make us sign a tx that spends much more in fees than we think. * Check that non-segwit uxto has been provided and inputs are signed with SIGHASH_ALL * Verify that Bitcoin Core's fee match what we specified When we call Bitcoin Core's `fundrawtransaction` RPC method, we check that the fee that we pay match the fee rate that we requested. The fee is computed using the utxo information that Bitcoin Core adds to our PSBT before we sign it. We can safely used this information because if Bitcoin Core lies about the value of the inputs that we're spending then the signature we produce will also not be valid (it commits to the value being spent). When we're adding wallet inputs to "bump" the fees of a parent transaction we need to take the whole package into account when we verify the actual fee rate, which is why some internal methods were modified to return the package weight that was used as reference when `fundrawtransaction` was called. * Check that fundrawtransaction does not add more than 1 change output * Validate addresses and keys generated by bitcoin core When eclair manages private keys, make sure that we can re-compute addresses and keys generated by bitcoin core. * Add a separate configuration file for Eclair's onchain signer Eclair's onchain signer now has its own `eclair-signer.conf` configuration file in HOCON format. It includes BIP39 mnemonic codes and passphrase, a wallet name and a timestamp. When an `eclair-signer.conf` file is found, Eclair's API will return descriptors that can be imported into an empty watch-only Bitcoin Wallet. When wallet name in `eclair-signer.conf` matches the name of the Bitcoin Core wallet defined in `eclair.conf` (`eclair.bitcoind.wallet`), Eclair will bypass Bitcoin Core and sign onchain transactions directly. * Skip validation of local non-change outputs: Local non-change outputs send to an external address, for splicing out funds for example. We assume that these inputs are trusted i.e have been created by a trusted API call and our local onchain key manager will not validate them during the signing process. * Document why we use a separate, specific file for the onchain key manager Using a new signer section is eclair.conf would be simpler but "leaks" because it becomes available everywhere in the code through the actor system's settings instead of being contained to where it is actually needed and could potentially be exposed through a bug that "exports" the configuration (through logs, ....) though this is highly unlikely. * Additional changes to delegate bitcoin core keys to eclair (#2726) Refactor the `BitcoinCoreClient` and `LocalOnChainKeyManager` to: - rely less on exceptions - use more idiomatic scala (reduce dependency on kotlin types) - provide more detailed logs We also simplify the `useEclairSigner` field in `BitcoinCoreClient`. The complexity of handling the case where there was an on-chain key manager but for a different wallet than the one configured isn't something that should be used, so it wasn't worth supporting. Some checks were inconsistent and are now unified: - checking the exact `scriptPubKey` in our outputs in TODO and TODO - we allow using `fundTransaction` with a tx that already includes a change output (which may happen when RBF-ing a transaction) - `getP2wpkhPubkeyHashForChange` didn't verify the returned key We completely separate the two cases in `signPsbt`, because otherwise in the non eclair-backed case, we were calling bitcoind's `processpsbt` twice for no good reason, which is bad for performance. We also decouple the `OnChainKeyManager` from the `BitcoinCoreClient`. This lets users keep running their eclair node with a bitcoin client that owns the private key while configuring the on-chain key manager for a future bitcoin client that will leverage this on-chain key manager. Users can use the eclair APIs to get the master xpub and descriptors to properly configure their next bitcoin core node, and switch to it once it has synchronized the descriptors. * Simplify replaceable tx funding We were previously signing twice (with makes a call to `bitcoind`), just to get the final weights and adjust the change outputs. This was unnecessary, as we can adjust the weights before adding inputs. We were also duplicating the checks where we verify that `bitcoind` is malicious. We only need to check that once, during the final signing step. --------- Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com> |