Skip to content

Add support for bech32m bitcoin wallets#2873

Closed
sstone wants to merge 1 commit into
masterfrom
use-bech32m-wallet
Closed

Add support for bech32m bitcoin wallets#2873
sstone wants to merge 1 commit into
masterfrom
use-bech32m-wallet

Conversation

@sstone

@sstone sstone commented Jul 3, 2024

Copy link
Copy Markdown
Member

These changes allow eclair to be used with a bitcoin core wallet configured to generate bech32m (p2tr) addresses and change addresses, which is not possible currently because there are a few place where p2wpkh is "hardcoded" (i.e. we implicitly assume that wallet addresses are p2wpkh addresses). We also handle the special case where eclair manages bitcoin core's private keys.
The wallet still needs to be able to generate bech32 (p2wpkh) addresses in some cases (support for static_remote_key for non anchor channels for example).

@sstone
sstone force-pushed the use-bech32m-wallet branch from 9f9774f to d603e95 Compare July 17, 2024 08:20
@sstone
sstone force-pushed the use-bech32m-wallet branch from d603e95 to 2353b24 Compare August 23, 2024 09:33
@sstone
sstone force-pushed the use-bech32m-wallet branch 2 times, most recently from cd2dac0 to 02c9ab2 Compare September 11, 2024 07:39
@sstone
sstone force-pushed the use-bech32m-wallet branch 2 times, most recently from 6f067ff to eb4b6c7 Compare October 8, 2024 16:43
These changes allow eclair to be used with a bitcoin core wallet configured to generate bech32m (p2tr) addresses and change addresses.
The wallet still needs to be able to generate bech32 (p2wpkh) addresses in some cases (support for static_remote_key for non anchor channels for example).
@sstone
sstone force-pushed the use-bech32m-wallet branch from eb4b6c7 to 39e2842 Compare December 9, 2024 17:18
* Created by PM on 06/07/2017.
*/

sealed trait AddressType

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is confusing, this isn't really what we're interested in (bech32 vs bech32m is just the encoding, not really the type of address). What we want to do here is distinguish between segwit v0 p2wpkh addresses and segwit v1 p2tr (with the standard BIP86 NoScriptTweak), right? Those are the only type of on-chain addresses we will generate. So I think we should more explicitly do:

// @formatter:off
sealed trait AddressType
object AddressType {
  /** A segwit v0 p2wpkh address. */
  case object P2WPKH extends AddressType { override def toString: String = "p2wpkh" }
  /** A segwit v1 p2tr address that doesn't have any script path, as defined in BIP86. */
  case object P2TR extends AddressType { override def toString: String = "p2tr" }
}
// @formatter:on

@@ -784,7 +785,7 @@ class EclairImpl(appKit: Kit) extends Eclair with Logging {
}

override def getOnChainMasterPubKey(account: Long): String = appKit.nodeParams.onChainKeyManager_opt match {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shoudn't this now return an object containing the master pubkey for p2wpkh addresses AND the master pubkey for p2tr addresses?

} yield address
private def verifyAddress(address: String)(implicit ec: ExecutionContext): Future[String] = {
for {
addressInfo <- rpcClient.invoke("getaddressinfo", address)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't make this call if onChainKeyManager_opt is empty, this makes unnecessary calls to bitcoind for which we ignore the result.

*/
def getP2wpkhPubkey(renew: Boolean = true): PublicKey

def getPubkeyScript(renew: Boolean = true): ByteVector

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is way too vague and confusing since in bitcoin terms a "scriptPubKey" can refer to a lot of things...and this trait is supposed to manage public keys directly. I think we should instead have:

def getP2wpkhPubkey(renew: Boolean = true): PublicKey
def getP2trPubkey(renew: Boolean = true): PublicKey

It's not the responsibility of this OnchainPubkeyCache to convert it to an actual script, this can be done from the public key afterwards. This should simplify the OnchainPubkeyRefresher because it should still simply refresh a pubkey (either segwit v0 or segwit v1), and can then also return the corresponding script if needed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not be much simpler as pubkeys for p2tr or p2wpkh are completely independent (i.e generated from different descriptors).

val finalScriptPubKey = Script.write(Script.pay2wpkh(finalPubKey))
private def generateFinalScriptPubKey(localFeatures: Features[InitFeature], remoteFeatures: Features[InitFeature]): ByteVector = {
val allowAnySegwit = Features.canUseFeature(localFeatures, remoteFeatures, Features.ShutdownAnySegwit)
val finalScriptPubKey = if (allowAnySegwit) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's confusing to only gate it on allowAnySegwit: it looks like this will use p2tr, but actually not, it's instead using the default address type configured on the bitcoin node. This is mixing configuration options from eclair and from bitcoind...shouldn't we instead always use p2tr when the channel is a taproot channel and always use p2wpkh otherwise? Or instead always use p2tr when allowAnySegwit is set (which allows deprecating support for p2wpkh at some point in the future)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bitcoind will add funding inputs that match the transaction being funded, so it's better to let it choose which kind of script pubkey to generate.

@sstone

sstone commented Mar 4, 2025

Copy link
Copy Markdown
Member Author

closed in favour of #3026

@sstone sstone closed this Mar 4, 2025
@sstone
sstone deleted the use-bech32m-wallet branch March 25, 2025 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants