Skip to content

Commit

Permalink
draft! store CloseTx inputs in SCB
Browse files Browse the repository at this point in the history
  • Loading branch information
starius committed Dec 30, 2023
1 parent 1d26157 commit ca7a4eb
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 99 deletions.
51 changes: 19 additions & 32 deletions chanbackup/backup.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package chanbackup

import (
"bytes"
"fmt"
"net"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnwallet"
)

// LiveChannelSource is an interface that allows us to query for the set of
Expand Down Expand Up @@ -56,31 +53,31 @@ func assembleChanBackup(addrSource AddressSource,
return &single, nil
}

func buildCloseTx(targetChan *channeldb.OpenChannel, signer input.Signer) ([]byte, error) {
chanMachine, err := lnwallet.NewLightningChannel(signer, targetChan, nil)
if err != nil {
return nil, fmt.Errorf("lnwallet.NewLightningChannel failed: %w", err)
}
closeSummary, err := chanMachine.GetLocalForceCloseSummary()
if err != nil {
return nil, fmt.Errorf("GetLocalForceCloseSummary failed: %w", err)
func buildCloseTxInputs(targetChan *channeldb.OpenChannel) *CloseTxInputs {
localCommit := targetChan.LocalCommitment
inputs := &CloseTxInputs{
CommitTx: localCommit.CommitTx,
CommitSig: localCommit.CommitSig,
}
var txBuf bytes.Buffer
if err := closeSummary.CloseTx.Serialize(&txBuf); err != nil {
return nil, fmt.Errorf("CloseTx.Serialize failed: %w", err)

if targetChan.ChanType.IsTaproot() {
inputs.CommitHeight = localCommit.CommitHeight
}
return txBuf.Bytes(), nil

return inputs
}

type BackupConfig struct {
signer input.Signer
// Whether to put CloseTxInputs into a backup. A backup with this data
// can be used by "chantools scbforceclose" command.
includeCloseTxInputs bool
}

type BackupOption func(*BackupConfig)

func WithCloseTx(signer input.Signer) BackupOption {
func WithCloseTxInputs(include bool) BackupOption {
return func(c *BackupConfig) {
c.signer = signer
c.includeCloseTxInputs = include
}
}

Expand Down Expand Up @@ -111,13 +108,8 @@ func FetchBackupForChan(chanPoint wire.OutPoint, chanSource LiveChannelSource,
return nil, fmt.Errorf("unable to create chan backup: %v", err)
}

if config.signer != nil {
// Add CloseTx.
closeTx, err := buildCloseTx(targetChan, config.signer)
if err != nil {
return nil, fmt.Errorf("unable to create close tx for ChannelPoint(%v): %w", targetChan, err)
}
staticChanBackup.CloseTx = closeTx
if config.includeCloseTxInputs {
staticChanBackup.CloseTxInputs = buildCloseTxInputs(targetChan)
}

return staticChanBackup, nil
Expand Down Expand Up @@ -150,13 +142,8 @@ func FetchStaticChanBackups(chanSource LiveChannelSource,
return nil, err
}

if config.signer != nil {
// Add CloseTx.
closeTx, err := buildCloseTx(openChan, config.signer)
if err != nil {
return nil, fmt.Errorf("unable to create close tx for ChannelPoint(%v): %w", openChan, err)
}
chanBackup.CloseTx = closeTx
if config.includeCloseTxInputs {
chanBackup.CloseTxInputs = buildCloseTxInputs(openChan)
}

staticChanBackups = append(staticChanBackups, *chanBackup)
Expand Down
23 changes: 10 additions & 13 deletions chanbackup/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
)

Expand Down Expand Up @@ -94,13 +93,14 @@ type SubSwapper struct {
// multi backup.
keyRing keychain.KeyRing

// signer is used to sign CloseTx.
signer input.Signer

Swapper

quit chan struct{}
wg sync.WaitGroup

// Whether to put CloseTxInputs into a backup. A backup with this data
// can be used by "chantools scbforceclose" command.
includeCloseTxInputs bool
}

// NewSubSwapper creates a new instance of the SubSwapper given the starting
Expand Down Expand Up @@ -138,9 +138,10 @@ func NewSubSwapper(startingChans []Single, chanNotifier ChannelNotifier,
backupState: backupState,
chanEvents: chanEvents,
keyRing: keyRing,
signer: config.signer,
Swapper: backupSwapper,
quit: make(chan struct{}),

includeCloseTxInputs: config.includeCloseTxInputs,
}, nil
}

Expand Down Expand Up @@ -277,14 +278,10 @@ func (s *SubSwapper) backupUpdater() {
newChan.FundingOutpoint)

single := NewSingle(newChan.OpenChannel, newChan.Addrs)
if s.signer != nil {
// Add CloseTx.
closeTx, err := buildCloseTx(newChan.OpenChannel, s.signer)
if err != nil {
log.Errorf("unable to create close tx for ChannelPoint(%v): %v", newChan.OpenChannel, err)
} else {
single.CloseTx = closeTx
}
if s.includeCloseTxInputs {
single.CloseTxInputs = buildCloseTxInputs(
newChan.OpenChannel,
)
}
s.backupState[newChan.FundingOutpoint] = single
}
Expand Down
87 changes: 78 additions & 9 deletions chanbackup/single.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ const (
// the musig2 based taproot commitment format.
SimpleTaprootVersion = 5

// XORed to some version on wire indicating that the backup has CloseTx.
// Byte mask used that is ORed to version byte on wire indicating that
// the backup has CloseTxInputs.
closeTxVersionMask = 1 << 7
)

Expand Down Expand Up @@ -142,7 +143,28 @@ type Single struct {
// - ScriptEnforcedLeaseVersion
LeaseExpiry uint32

CloseTx []byte
CloseTxInputs *CloseTxInputs
}

type CloseTxInputs struct {
// CommitTx is the latest version of the commitment state, broadcast
// able by us, but not signed.
// It can be signed by "chantools scbforceclose" command.
CommitTx *wire.MsgTx

// CommitSig is one half of the signature required to fully complete
// the script for the commitment transaction above. This is the
// signature signed by the remote party for our version of the
// commitment transactions.
CommitSig []byte

// CommitHeight is the update number that this ChannelDelta represents
// the total number of commitment updates to this point. This can be
// viewed as sort of a "commitment height" as this number is
// monotonically increasing.
//
// This field is filled only for taproot channels.
CommitHeight uint64
}

// NewSingle creates a new static channel backup based on an existing open
Expand Down Expand Up @@ -326,12 +348,32 @@ func (s *Single) Serialize(w io.Writer) error {
}

version := s.Version
if len(s.CloseTx) != 0 {
if s.CloseTxInputs != nil {
version |= closeTxVersionMask
err := lnwire.WriteElements(&singleBytes, uint16(len(s.CloseTx)), s.CloseTx)
if err != nil {

var txBuf bytes.Buffer
if err := s.CloseTxInputs.CommitTx.Serialize(&txBuf); err != nil {
return err
}
txBytes := txBuf.Bytes()
if err := lnwire.WriteElements(
&singleBytes,
uint16(len(txBytes)),
txBytes,
uint16(len(s.CloseTxInputs.CommitSig)),
s.CloseTxInputs.CommitSig,
); err != nil {
return err
}

if s.Version == SimpleTaprootVersion {
if err := lnwire.WriteElements(
&singleBytes,
s.CloseTxInputs.CommitHeight,
); err != nil {
return err
}
}
}

// TODO(yy): remove the type assertion when we finished refactoring db
Expand Down Expand Up @@ -550,14 +592,41 @@ func (s *Single) Deserialize(r io.Reader) error {
}

if hasCloseTx {
var closeTxLen uint16
if err := lnwire.ReadElement(r, &closeTxLen); err != nil {
var commitTxLen uint16
if err := lnwire.ReadElement(r, &commitTxLen); err != nil {
return err
}
commitTxBytes := make([]byte, commitTxLen)
if err := lnwire.ReadElement(r, commitTxBytes); err != nil {
return err
}
commitTx := &wire.MsgTx{}
err := commitTx.Deserialize(bytes.NewReader(commitTxBytes))
if err != nil {
return nil
}

var commitSigLen uint16
if err := lnwire.ReadElement(r, &commitSigLen); err != nil {
return err
}
s.CloseTx = make([]byte, closeTxLen)
if err := lnwire.ReadElement(r, s.CloseTx); err != nil {
commitSig := make([]byte, commitSigLen)
if err := lnwire.ReadElement(r, commitSig); err != nil {
return err
}

var commitHeight uint64
if s.Version == SimpleTaprootVersion {
if err := lnwire.ReadElement(r, &commitHeight); err != nil {
return err
}
}

s.CloseTxInputs = &CloseTxInputs{
CommitTx: commitTx,
CommitSig: commitSig,
CommitHeight: commitHeight,
}
}

return nil
Expand Down
Loading

0 comments on commit ca7a4eb

Please sign in to comment.