lnd
lnd copied to clipboard
fail recovery channel from SCB
Background
Recovery from SCB returned an error.
- channels
- 68cbece3cbd24e5c5203492ec0a7e8c1b4d6b15112c2614b44e57ed865fce2a4:0 (zero-conf)
- d59aae26e80b71851093c2c103b4a171f3d40e1b3d0a42f36e72518e194f4aa7:1 (zero-conf)
[ERR] RPCS: [/lnrpc.Lightning/RestoreChannelBackups]: unable to unpack chan backup: could not derive private key for legacy channel revocation root format: unable to derive private key
[INF] CHBU: Restoring ChannelPoint(68cbece3cbd24e5c5203492ec0a7e8c1b4d6b15112c2614b44e57ed865fce2a4:0) to disk:
[DBG] LTND: Using legacy revocation producer format for channel point 68cbece3cbd24e5c5203492ec0a7e8c1b4d6b15112c2614b44e57ed865fce2a4:0
Your environment
- LND v0.15.2-beta
- Android(Lndmobile.aar)
- Neutrino mainnet
- zero-conf channels
Steps to reproduce
- create two zero-conf channels
- (fundee) channel backup REST API
/v1/channels/backup
- recovery wallet by passphrase
- restore REST API
/v1/channels/backup/restore
Expected behaviour
Both channels are force closed from funder.
Actual behaviour
An error occurred and only one channel was closed. (It has only occurred once.)
@nayuta-ueno were both channels already confirmed?
I deleted the wallet so I don't have much data left, but I think it was these two channels. I think they were confirmed because it was a few hours ago.
https://mempool.space/ja/tx/68cbece3cbd24e5c5203492ec0a7e8c1b4d6b15112c2614b44e57ed865fce2a4:0 https://mempool.space/ja/tx/0:d59aae26e80b71851093c2c103b4a171f3d40e1b3d0a42f36e72518e194f4aa7
I do not know if it was confirmed when the channel backup was done.
When you say It has only occurred once
. Does that mean that you were able to successfully force close the channel in a later retry?
If you had more channels (ZC or not) did they all close successfully but this one?
I just tried to reproduce this and wasn't able to with 0.15.3. Could you please dump the raw bytes you sent as multi_chan_backup
in /v1/channels/backup/restore
into a file and use chantools dumpbackup --multi_file <the_file>
to dump the backup and then post the content here?
I'm mostly interested in the ShaChanRootDesc
which should look similar to this:
ShaChainRootDesc: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/1'/5'/0/7",
PubKey: (string) (len=5) "<nil>"
}
When you say
It has only occurred once
. Does that mean that you were able to successfully force close the channel in a later retry?
I have tried several times to recovery with the same channel backup data and the same error was returned. Errors always occur with this backup data. The same procedure (create an another zero-conf channel, backup and recover) succeeded.
use
chantools dumpbackup
chantools
returns error.
Error: could not extract multi file: chacha20poly1305: message authentication failed
Error: could not extract multi file: chacha20poly1305: message authentication failed
That's usually the message you get when the seed doesn't match the channel backup.
That's usually the message you get when the seed doesn't match the channel backup.
Sorry, I was using chantool incorrectly.
I deleted all the LND data and then recovered, so I don't have the channel.backup from before the recovery.
(I only have 24 words and multi_chan_backup
base64 string.)
you should be able to convert the multi_chan_backup
thing using echo <multi_chan_backup_string> | base64 -d > channel.backup
and then dump it with chantools
.
Was the backup string created with a vanilla/original lnd
or a fork? Did you do anything with the backup that you extracted (e.g. decrypt/de-serialize it and then serialize it again)? Or just store the content in a file for recovery later on?
chantools dumpbackup
output:
(dump.BackupMulti) {
Version: (chanbackup.MultiBackupVersion) 0,
StaticBackups: ([]dump.BackupSingle) (len=2 cap=2) {
(dump.BackupSingle) {
Version: (chanbackup.SingleBackupVersion) 3,
IsInitiator: (bool) false,
ChainHash: (string) (len=64) "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
FundingOutpoint: (string) (len=66) "68cbece3cbd24e5c5203492ec0a7e8c1b4d6b15112c2614b44e57ed865fce2a4:0",
ShortChannelID: (lnwire.ShortChannelID) 760345:752:0,
RemoteNodePub: (string) (len=66) "0381cb801ca3ed432b067b2f4db840ba6c1462782f043b86ecf60a3b1666ad13c5",
Addresses: ([]net.Addr) (len=1 cap=1) {
(*net.TCPAddr)(0xc000488630)(3.115.41.6:9735)
},
Capacity: (btcutil.Amount) 0.00024 BTC,
LocalChanCfg: (dump.ChannelConfig) {
ChannelConstraints: (channeldb.ChannelConstraints) {
DustLimit: (btcutil.Amount) 0 BTC,
ChanReserve: (btcutil.Amount) 0 BTC,
MaxPendingAmount: (lnwire.MilliSatoshi) 0 mSAT,
MinHTLC: (lnwire.MilliSatoshi) 0 mSAT,
MaxAcceptedHtlcs: (uint16) 0,
CsvDelay: (uint16) 144
},
MultiSigKey: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/1",
PubKey: (string) (len=5) "<nil>"
},
RevocationBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/1'/0/1",
PubKey: (string) (len=5) "<nil>"
},
PaymentBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/3'/0/1",
PubKey: (string) (len=5) "<nil>"
},
DelayBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/4'/0/1",
PubKey: (string) (len=5) "<nil>"
},
HtlcBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/2'/0/1",
PubKey: (string) (len=5) "<nil>"
}
},
RemoteChanCfg: (dump.ChannelConfig) {
ChannelConstraints: (channeldb.ChannelConstraints) {
DustLimit: (btcutil.Amount) 0 BTC,
ChanReserve: (btcutil.Amount) 0 BTC,
MaxPendingAmount: (lnwire.MilliSatoshi) 0 mSAT,
MinHTLC: (lnwire.MilliSatoshi) 0 mSAT,
MaxAcceptedHtlcs: (uint16) 0,
CsvDelay: (uint16) 4032
},
MultiSigKey: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "032b8ff881e22f8e18cb018176d048c665c71f3b365e99241fa071b98435ae0bf1"
},
RevocationBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "0239fd8f7d1cf08cf11c8064eae63654b86b2d3d6b8555359c2e8745452b89e58f"
},
PaymentBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "03f672a5d81bcbb3c989c07e48c99e625c42d4835c70b8a2cda6847e869b4f3dae"
},
DelayBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "0386075b368abd7c3e9205c32872b3f1c97117974c4080f4159a4dfd4cc370c87b"
},
HtlcBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "02822adbf2915d7af576d9f536ddf4208d6cd6912c610912548629775c069343de"
}
},
ShaChainRootDesc: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/5'/0/0",
PubKey: (string) (len=66) "03c655dd1d8b6554295022530f29052468d1bda94ecd5768e42dee83195ef4c176"
}
},
(dump.BackupSingle) {
Version: (chanbackup.SingleBackupVersion) 3,
IsInitiator: (bool) false,
ChainHash: (string) (len=64) "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
FundingOutpoint: (string) (len=66) "d59aae26e80b71851093c2c103b4a171f3d40e1b3d0a42f36e72518e194f4aa7:1",
ShortChannelID: (lnwire.ShortChannelID) 760512:0:0,
RemoteNodePub: (string) (len=66) "0381cb801ca3ed432b067b2f4db840ba6c1462782f043b86ecf60a3b1666ad13c5",
Addresses: ([]net.Addr) (len=1 cap=1) {
(*net.TCPAddr)(0xc000488690)(3.115.41.6:9735)
},
Capacity: (btcutil.Amount) 0.00025 BTC,
LocalChanCfg: (dump.ChannelConfig) {
ChannelConstraints: (channeldb.ChannelConstraints) {
DustLimit: (btcutil.Amount) 0 BTC,
ChanReserve: (btcutil.Amount) 0 BTC,
MaxPendingAmount: (lnwire.MilliSatoshi) 0 mSAT,
MinHTLC: (lnwire.MilliSatoshi) 0 mSAT,
MaxAcceptedHtlcs: (uint16) 0,
CsvDelay: (uint16) 144
},
MultiSigKey: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=5) "<nil>"
},
RevocationBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/1'/0/0",
PubKey: (string) (len=5) "<nil>"
},
PaymentBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/3'/0/0",
PubKey: (string) (len=5) "<nil>"
},
DelayBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/4'/0/0",
PubKey: (string) (len=5) "<nil>"
},
HtlcBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/2'/0/0",
PubKey: (string) (len=5) "<nil>"
}
},
RemoteChanCfg: (dump.ChannelConfig) {
ChannelConstraints: (channeldb.ChannelConstraints) {
DustLimit: (btcutil.Amount) 0 BTC,
ChanReserve: (btcutil.Amount) 0 BTC,
MaxPendingAmount: (lnwire.MilliSatoshi) 0 mSAT,
MinHTLC: (lnwire.MilliSatoshi) 0 mSAT,
MaxAcceptedHtlcs: (uint16) 0,
CsvDelay: (uint16) 4032
},
MultiSigKey: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "024cdae1b008449a8d5b7def640fe8070cd538087fa55734cbb371e3dce00b3c7a"
},
RevocationBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "03da4d28a0ee573eb81210462fec32eb4bb35afa26825dde993938deb025f490eb"
},
PaymentBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "03cb6cffcfd5e640e1654ce2aeb2fef53708ee4f9dab61845e4c05711cc2494d4d"
},
DelayBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "02c2e6becb4e28466bef9afd8dd0ad9f622f5a7de1a015a140569c2e19a2861e07"
},
HtlcBasePoint: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/0'/0/0",
PubKey: (string) (len=66) "03a591dc56b071e67da587e8e864c483062be32b09f8df77dd718d64798d7291e6"
}
},
ShaChainRootDesc: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/5'/0/1",
PubKey: (string) (len=5) "<nil>"
}
}
}
}
Was the backup string created with a vanilla/original lnd or a fork?
I have made some modifications to LND v0.15.2-beta, but not to the backup string.
The backup string is a multi_chan_backup
obtained with the REST API '/v1/channels/backup' and stored in JSON format.
Can you describe the modifications you made?
Because the issue is (as I expected) that the pubkey here is not nil
:
ShaChainRootDesc: (dump.KeyDescriptor) {
Path: (string) (len=17) "m/1017'/0'/5'/0/0",
PubKey: (string) (len=66) "03c655dd1d8b6554295022530f29052468d1bda94ecd5768e42dee83195ef4c176"
}
But that should only happen if the channel is created by an lnd
version before 0.14. Which I don't think can be the case given the channel was only created a few hundred blocks ago? Or did you upgrade that node from an old software? Or did your modifications change anything in the key derivation logic?
The channel-related modification is that ChanReserve
can now be set to zero.
The node was recently created in v0.15.2-beta, the key derivation logic has not been changed.
I will check to see if any other modifications have been made.
Converting this to a discussion, feel free to convert back to the issue if any specific action is required