@@ -317,7 +317,8 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
317317
318318 // Get the revocation base point first, so we can calculate our
319319 // commit point. We start with the old way where the revocation index
320- // was the same as the other indices.
320+ // was the same as the other indices. This applies to all channels
321+ // opened with versions prior to and including lnd v0.12.0-beta.
321322 revPath := []uint32 {
322323 lnd .HardenedKey (uint32 (
323324 keychain .KeyFamilyRevocationRoot ,
@@ -346,21 +347,56 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
346347 }, nil
347348 }
348349
349- // Now let's try with the new format where the index is one larger than
350- // the other indices.
351- revPath = []uint32 {
350+ // We could not derive the secrets to sweep the to_local output using
351+ // the old shachain root creation. Starting with lnd release
352+ // v0.13.0-beta the index for the revocation path creating the shachain
353+ // root changed. Now the shachain root is created using ECDH
354+ // with the local multisig public key
355+ // (for mainnet: m/1017'/0'/1'/0/idx). But we need to account for a
356+ // special case here. If the node was started with a version prior to
357+ // and including v0.12.0-beta the idx for the new shachain root
358+ // revocation is not one larger because idx 0 was already used for the
359+ // old creation scheme hence we need to replicate this behaviour here.
360+ // First trying the shachain root creation with the same index and if
361+ // this does not derive the secrets we increase the index of the
362+ // revocation key path by one (for mainnet: m/1017'/0'/5'/0/idx+1).
363+ // The exact path which was used for the shachain root can be seen
364+ // in the channel.backup file for every specific channel. The old
365+ // scheme has always a public key specified.The new one uses a key
366+ // locator and does not have a public key specified (nil).
367+ // Example
368+ // ShaChainRootDesc: (dump.KeyDescriptor) {
369+ // Path: (string) (len=17) "m/1017'/1'/5'/0/1",
370+ // PubKey: (string) (len=5) "<nil>"
371+ //
372+ // For more details:
373+ // https://github.com/lightningnetwork/lnd/commit/bb84f0ebc88620050dec7cf4be6283f5cba8b920
374+ //
375+ // Now the new shachain root revocation scheme is tried with
376+ // two different indicies as described above.
377+ revPath2 := []uint32 {
352378 lnd .HardenedKey (uint32 (
353379 keychain .KeyFamilyRevocationRoot ,
354- )), 0 , idx + 1 ,
380+ )), 0 , idx ,
381+ }
382+
383+ // Now we try the same with the new revocation producer format.
384+ multiSigPath := []uint32 {
385+ lnd .HardenedKey (uint32 (keychain .KeyFamilyMultiSig )),
386+ 0 , idx ,
355387 }
356- revRoot2 , err := lnd .ShaChainFromPath (baseKey , revPath , nil )
388+ multiSigPrivKey , err := lnd .PrivKeyFromPath (baseKey , multiSigPath )
389+ if err != nil {
390+ return 0 , nil , nil , nil , nil , err
391+ }
392+
393+ revRoot2 , err := lnd .ShaChainFromPath (
394+ baseKey , revPath2 , multiSigPrivKey .PubKey (),
395+ )
357396 if err != nil {
358397 return 0 , nil , nil , nil , nil , err
359398 }
360399
361- // We now have everything to brute force the lock script. This
362- // will take a long while as we both have to go through commit
363- // points and CSV values.
364400 csvTimeout , script , scriptHash , commitPoint , err = bruteForceDelayPoint (
365401 delayPrivKey .PubKey (), remoteRevPoint , revRoot2 , lockScript ,
366402 maxCsvTimeout , maxNumChanUpdates ,
@@ -376,18 +412,27 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
376412 }, nil
377413 }
378414
415+ // Now we try to increase the index by 1 to account for the situation
416+ // where the node was started with a version after (including)
417+ // v0.13.0-beta
418+ revPath3 := []uint32 {
419+ lnd .HardenedKey (uint32 (
420+ keychain .KeyFamilyRevocationRoot ,
421+ )), 0 , idx + 1 ,
422+ }
423+
379424 // Now we try the same with the new revocation producer format.
380- multiSigPath : = []uint32 {
425+ multiSigPath = []uint32 {
381426 lnd .HardenedKey (uint32 (keychain .KeyFamilyMultiSig )),
382427 0 , idx ,
383428 }
384- multiSigPrivKey , err : = lnd .PrivKeyFromPath (baseKey , multiSigPath )
429+ multiSigPrivKey , err = lnd .PrivKeyFromPath (baseKey , multiSigPath )
385430 if err != nil {
386431 return 0 , nil , nil , nil , nil , err
387432 }
388433
389434 revRoot3 , err := lnd .ShaChainFromPath (
390- baseKey , revPath , multiSigPrivKey .PubKey (),
435+ baseKey , revPath3 , multiSigPrivKey .PubKey (),
391436 )
392437 if err != nil {
393438 return 0 , nil , nil , nil , nil , err
0 commit comments