Merge pull request #63 from ziggie1984/sweep-tolocal-bugfix

Minor Bugfixes and new sweeptimelockmanual logic
pull/66/head
Oliver Gugger 1 year ago committed by GitHub
commit f35a469949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -317,7 +317,8 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
// Get the revocation base point first, so we can calculate our
// commit point. We start with the old way where the revocation index
// was the same as the other indices.
// was the same as the other indices. This applies to all channels
// opened with versions prior to and including lnd v0.12.0-beta.
revPath := []uint32{
lnd.HardenedKey(uint32(
keychain.KeyFamilyRevocationRoot,
@ -346,21 +347,56 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
}, nil
}
// Now let's try with the new format where the index is one larger than
// the other indices.
revPath = []uint32{
// We could not derive the secrets to sweep the to_local output using
// the old shachain root creation. Starting with lnd release
// v0.13.0-beta the index for the revocation path creating the shachain
// root changed. Now the shachain root is created using ECDH
// with the local multisig public key
// (for mainnet: m/1017'/0'/1'/0/idx). But we need to account for a
// special case here. If the node was started with a version prior to
// and including v0.12.0-beta the idx for the new shachain root
// revocation is not one larger because idx 0 was already used for the
// old creation scheme hence we need to replicate this behaviour here.
// First trying the shachain root creation with the same index and if
// this does not derive the secrets we increase the index of the
// revocation key path by one (for mainnet: m/1017'/0'/5'/0/idx+1).
// The exact path which was used for the shachain root can be seen
// in the channel.backup file for every specific channel. The old
// scheme has always a public key specified.The new one uses a key
// locator and does not have a public key specified (nil).
// Example
// ShaChainRootDesc: (dump.KeyDescriptor) {
// Path: (string) (len=17) "m/1017'/1'/5'/0/1",
// PubKey: (string) (len=5) "<nil>"
//
// For more details:
// https://github.com/lightningnetwork/lnd/commit/bb84f0ebc88620050dec7cf4be6283f5cba8b920
//
// Now the new shachain root revocation scheme is tried with
// two different indicies as described above.
revPath2 := []uint32{
lnd.HardenedKey(uint32(
keychain.KeyFamilyRevocationRoot,
)), 0, idx + 1,
)), 0, idx,
}
// Now we try the same with the new revocation producer format.
multiSigPath := []uint32{
lnd.HardenedKey(uint32(keychain.KeyFamilyMultiSig)),
0, idx,
}
revRoot2, err := lnd.ShaChainFromPath(baseKey, revPath, nil)
multiSigPrivKey, err := lnd.PrivKeyFromPath(baseKey, multiSigPath)
if err != nil {
return 0, nil, nil, nil, nil, err
}
revRoot2, err := lnd.ShaChainFromPath(
baseKey, revPath2, multiSigPrivKey.PubKey(),
)
if err != nil {
return 0, nil, nil, nil, nil, err
}
// We now have everything to brute force the lock script. This
// will take a long while as we both have to go through commit
// points and CSV values.
csvTimeout, script, scriptHash, commitPoint, err = bruteForceDelayPoint(
delayPrivKey.PubKey(), remoteRevPoint, revRoot2, lockScript,
maxCsvTimeout, maxNumChanUpdates,
@ -376,18 +412,27 @@ func tryKey(baseKey *hdkeychain.ExtendedKey, remoteRevPoint *btcec.PublicKey,
}, nil
}
// Now we try to increase the index by 1 to account for the situation
// where the node was started with a version after (including)
// v0.13.0-beta
revPath3 := []uint32{
lnd.HardenedKey(uint32(
keychain.KeyFamilyRevocationRoot,
)), 0, idx + 1,
}
// Now we try the same with the new revocation producer format.
multiSigPath := []uint32{
multiSigPath = []uint32{
lnd.HardenedKey(uint32(keychain.KeyFamilyMultiSig)),
0, idx,
}
multiSigPrivKey, err := lnd.PrivKeyFromPath(baseKey, multiSigPath)
multiSigPrivKey, err = lnd.PrivKeyFromPath(baseKey, multiSigPath)
if err != nil {
return 0, nil, nil, nil, nil, err
}
revRoot3, err := lnd.ShaChainFromPath(
baseKey, revPath, multiSigPrivKey.PubKey(),
baseKey, revPath3, multiSigPrivKey.PubKey(),
)
if err != nil {
return 0, nil, nil, nil, nil, err

@ -23,8 +23,8 @@ var sweepTimeLockManualCases = []struct {
keyIndex: 7,
timeLockAddr: "bcrt1qf9zv4qtxh27c954rhlzg4tx58xh0vgssuu0csrlep0jdnv" +
"lx9xesmcl5qx",
remoteRevPubKey: "03235261ed5aaaf9fec0e91d5e1a4d17f1a2c7442f1c43806d32" +
"c9bd34abd002a3",
remoteRevPubKey: "03235261ed5aaaf9fec0e91d5e1a4d17f1a2c7442f1c43806d" +
"32c9bd34abd002a3",
}, {
// Old format with plain private key as revocation root.
baseKey: "tprv8dgoXnQWBN4CGGceRYMW495kWcrUZKZVFwMmbzpduFp1D4pi" +
@ -32,8 +32,41 @@ var sweepTimeLockManualCases = []struct {
keyIndex: 6,
timeLockAddr: "bcrt1qa5rrlswxefc870k7rsza5hhqd37uytczldjk5t0vzd95u9" +
"hs8xlsfdc3zf",
remoteRevPubKey: "03e82cdf164ce5aba253890e066129f134ca8d7e072ce5ad55c7" +
"21b9a13545ee04",
remoteRevPubKey: "03e82cdf164ce5aba253890e066129f134ca8d7e072ce5ad55" +
"c721b9a13545ee04",
}, {
// New format with ECDH revocation root.
baseKey: "tprv8fCiPGhoYhWESQg3kgubCizcHo21drnP9Fa5j9fFKCmbME" +
"ipgodofyXcf4NFhD4k55GM1Ym3JUUDonpEXcsjnyTDUMmkzMK9pCnGPH3NJ5i",
keyIndex: 0,
timeLockAddr: "bcrt1qmkyn0tqx6mpg5aujgjhzaw27rvvymdfc3xhgawp48zy8v" +
"3rlw45qzmjqrr",
remoteRevPubKey: "02dfecdc259a7e1cff36a67328ded3b4dae30369a3035e4f91" +
"1ce7ac4a80b28e5d",
}, {
// Old format with plain private key as revocation root. Test data
// created with lnd v0.12.0-beta (old shachain root creation)
baseKey: "tprv8e3Mee42NcUd2MbwxBCJyEEhvKa8KqjiDR76M7ym4DJSfZk" +
"fDyA46XZeA4kTj8YKktWrjGBDThxxcL4HBF89jDKseu24XtugVMNsm3GhHwK",
keyIndex: 0,
timeLockAddr: "bcrt1qux548e45wlg9sufhgd8ldfzqrapl303g5sj7xg5w637sge" +
"dst0wsk0xags",
remoteRevPubKey: "03647afa9c04025e997a5b7ecd2dd949f8f60f6880a94af73a" +
"0d4f48f166d127d1",
}, {
// New format with ECDH revocation root but this test data was created
// when already the old format was present, this leads to the situation
// where the idx for the shachain root (revocation root) is equal to
// the delay basepoint index. Normally when starting a node after
// lnd with the version v0.13.0-beta onwords, the index is always
// +1 compared to the delay basepoint index.
baseKey: "tprv8e3Mee42NcUd2MbwxBCJyEEhvKa8KqjiDR76M7ym4DJSfZ" +
"kfDyA46XZeA4kTj8YKktWrjGBDThxxcL4HBF89jDKseu24XtugVMNsm3GhHwK",
keyIndex: 1,
timeLockAddr: "bcrt1qsj7c97fj9xh8znlkjtg4x45xstypk5zp3kcnt5f5u6ps" +
"rhetju2srseqrh",
remoteRevPubKey: "0341692a025ad552c62689a630ff24d9439e3752d8e0ac5cb4" +
"1b5e71ab2bd46d0f",
}}
func TestSweepTimeLockManual(t *testing.T) {

@ -45,6 +45,9 @@ func (lc *LightningChannel) CreateSignDesc() error {
},
HashType: txscript.SigHashAll,
InputIndex: 0,
PrevOutputFetcher: txscript.NewCannedPrevOutputFetcher(
fundingPkScript, int64(lc.ChannelState.Capacity),
),
}
return nil

Loading…
Cancel
Save