From c6ee42d3e2a1515a4095f1eb1f1d6f4a796b23f3 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 17 Sep 2019 19:12:11 -0700 Subject: [PATCH] chanbackup: create new Single version for tweakless commitment chans In this commit, we create a new Single version for channels that use the tweakless commitment scheme. When recovering from an SCB into an open channel shell, we'll now check this field and use it to determine the proper channel type. Otherwise, we may attempt to sweep the on chain funds using the commitment point, when it goes directly to our key, or the other way around. --- chanbackup/single.go | 22 ++++++++++++++++++---- chanbackup/single_test.go | 14 +++++++++++++- chanrestore.go | 14 ++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/chanbackup/single.go b/chanbackup/single.go index 83ddcb17..1bfb49ca 100644 --- a/chanbackup/single.go +++ b/chanbackup/single.go @@ -21,11 +21,16 @@ import ( type SingleBackupVersion byte const ( - // DefaultSingleVersion is the defautl version of the single channel - // backup. The seralized version of this static channel backup is + // DefaultSingleVersion is the default version of the single channel + // backup. The serialized version of this static channel backup is // simply: version || SCB. Where SCB is the known format of the // version. DefaultSingleVersion = 0 + + // TweaklessCommitVersion is the second SCB version. This version + // implicitly denotes that this channel uses the new tweakless commit + // format. + TweaklessCommitVersion = 1 ) // Single is a static description of an existing channel that can be used for @@ -121,8 +126,7 @@ func NewSingle(channel *channeldb.OpenChannel, // key. _, shaChainPoint := btcec.PrivKeyFromBytes(btcec.S256(), b.Bytes()) - return Single{ - Version: DefaultSingleVersion, + single := Single{ IsInitiator: channel.IsInitiator, ChainHash: channel.ChainHash, FundingOutpoint: channel.FundingOutpoint, @@ -139,6 +143,14 @@ func NewSingle(channel *channeldb.OpenChannel, }, }, } + + if channel.ChanType.IsTweakless() { + single.Version = TweaklessCommitVersion + } else { + single.Version = DefaultSingleVersion + } + + return single } // Serialize attempts to write out the serialized version of the target @@ -148,6 +160,7 @@ func (s *Single) Serialize(w io.Writer) error { // we're aware of. switch s.Version { case DefaultSingleVersion: + case TweaklessCommitVersion: default: return fmt.Errorf("unable to serialize w/ unknown "+ "version: %v", s.Version) @@ -305,6 +318,7 @@ func (s *Single) Deserialize(r io.Reader) error { switch s.Version { case DefaultSingleVersion: + case TweaklessCommitVersion: default: return fmt.Errorf("unable to de-serialize w/ unknown "+ "version: %v", s.Version) diff --git a/chanbackup/single_test.go b/chanbackup/single_test.go index 41f7bca8..ba56ece7 100644 --- a/chanbackup/single_test.go +++ b/chanbackup/single_test.go @@ -124,8 +124,14 @@ func genRandomOpenChannelShell() (*channeldb.OpenChannel, error) { isInitiator = true } + chanType := channeldb.SingleFunder + if rand.Int63()%2 == 0 { + chanType = channeldb.SingleFunderTweakless + } + return &channeldb.OpenChannel{ ChainHash: chainHash, + ChanType: chanType, IsInitiator: isInitiator, FundingOutpoint: chanPoint, ShortChannelID: lnwire.NewShortChanIDFromInt( @@ -223,6 +229,12 @@ func TestSinglePackUnpack(t *testing.T) { valid: true, }, + // The new tweakless version, should pack/unpack with no problem. + { + version: TweaklessCommitVersion, + valid: true, + }, + // A non-default version, atm this should result in a failure. { version: 99, @@ -274,7 +286,7 @@ func TestSinglePackUnpack(t *testing.T) { } rawBytes := rawSingle.Bytes() - rawBytes[0] ^= 1 + rawBytes[0] ^= 5 newReader := bytes.NewReader(rawBytes) err = unpackedSingle.Deserialize(newReader) diff --git a/chanrestore.go b/chanrestore.go index f771f91b..50ab9efd 100644 --- a/chanrestore.go +++ b/chanrestore.go @@ -83,9 +83,23 @@ func (c *chanDBRestorer) openChannelShell(backup chanbackup.Single) ( return nil, fmt.Errorf("unable to derive htlc key: %v", err) } + var chanType channeldb.ChannelType + switch backup.Version { + + case chanbackup.DefaultSingleVersion: + chanType = channeldb.SingleFunder + + case chanbackup.TweaklessCommitVersion: + chanType = channeldb.SingleFunderTweakless + + default: + return nil, fmt.Errorf("unknown Single version: %v", err) + } + chanShell := channeldb.ChannelShell{ NodeAddrs: backup.Addresses, Chan: &channeldb.OpenChannel{ + ChanType: chanType, ChainHash: backup.ChainHash, IsInitiator: backup.IsInitiator, Capacity: backup.Capacity,