Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[anchors] anchors resolutions #3920

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 73 additions & 7 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ const (
// disk. This bit may be on if the funding transaction was crafted by a
// wallet external to the primary daemon.
NoFundingTxBit ChannelType = 1 << 2

// AnchorOutputsBit indicates that the channel makes use of anchor
// outputs to bump the commitment transaction's effective feerate. This
// channel type also uses a delayed to_remote output script. If bit is
// set, we'll find the size of the anchor outputs in the database.
AnchorOutputsBit ChannelType = 1 << 3
)

// IsSingleFunder returns true if the channel type if one of the known single
Expand All @@ -196,6 +202,12 @@ func (c ChannelType) HasFundingTx() bool {
return c&NoFundingTxBit == 0
}

// HasAnchors returns true if this channel type has anchor ouputs on its
// commitment.
func (c ChannelType) HasAnchors() bool {
return c&AnchorOutputsBit == AnchorOutputsBit
}

// ChannelConstraints represents a set of constraints meant to allow a node to
// limit their exposure, enact flow control and ensure that all HTLCs are
// economically relevant. This struct will be mirrored for both sides of the
Expand Down Expand Up @@ -1756,11 +1768,17 @@ func (c *OpenChannel) AppendRemoteCommitChain(diff *CommitDiff) error {
// this new pending commitment. Once they revoked their prior state, we'll swap
// these pointers, causing the tip and the tail to point to the same entry.
func (c *OpenChannel) RemoteCommitChainTip() (*CommitDiff, error) {
return c.RemoteCommitChainTipFrom(false)
}

// RemoteCommitChainTip returns the "tip" of the current remote commitment
// chain. The confirmed bool indicates which bucket to retrieve the data from.
func (c *OpenChannel) RemoteCommitChainTipFrom(confirmed bool) (*CommitDiff,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do #3952, the ...From() isn't needed.

error) {

var cd *CommitDiff
err := c.Db.View(func(tx *bbolt.Tx) error {
chanBucket, err := fetchChanBucket(
tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
)
chanBucket, err := c.fetchChanBucket(tx, confirmed)
switch err {
case nil:
case ErrNoChanDBExists, ErrNoActiveChannels, ErrChannelNotFound:
Expand Down Expand Up @@ -2427,15 +2445,63 @@ func (c *OpenChannel) Snapshot() *ChannelSnapshot {
return snapshot
}

// fetchPendingCloseChanBucket is a helper function that returns the bucket
// where a channel's pending close data resides in given the outpoint.
func fetchPendingCloseChanBucket(tx *bbolt.Tx, outPoint *wire.OutPoint) (
*bbolt.Bucket, error) {

// First fetch the top level bucket which stores all data related to
// current, active channels.
historicalBucket := tx.Bucket(historicalChannelBucket)
if historicalBucket == nil {
return nil, ErrNoChanDBExists
}

// With the bucket for the node and chain fetched, we can now go down
// another level, for this channel itself.
var chanPointBuf bytes.Buffer
if err := writeOutpoint(&chanPointBuf, outPoint); err != nil {
return nil, err
}
chanBucket := historicalBucket.Bucket(chanPointBuf.Bytes())
if chanBucket == nil {
return nil, ErrChannelNotFound
}

return chanBucket, nil
}

// fetchChanBucket returns either the open or the confirmed channel bucket.
func (c *OpenChannel) fetchChanBucket(tx *bbolt.Tx, confirmed bool) (
*bbolt.Bucket, error) {

if confirmed {
return fetchPendingCloseChanBucket(tx, &c.FundingOutpoint)
}

return fetchChanBucket(
tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
)
}

// LatestCommitments returns the two latest commitments for both the local and
// remote party. These commitments are read from disk to ensure that only the
// latest fully committed state is returned. The first commitment returned is
// the local commitment, and the second returned is the remote commitment.
func (c *OpenChannel) LatestCommitments() (*ChannelCommitment, *ChannelCommitment, error) {
func (c *OpenChannel) LatestCommitments() (*ChannelCommitment,
*ChannelCommitment, error) {

return c.LatestCommitmentsFrom(false)
}

// LatestCommitmentsFrom returns the two latest commitments for both the local
// and remote party. The confirmed boolean indicates the bucket to read the data
// from.
func (c *OpenChannel) LatestCommitmentsFrom(confirmed bool) (*ChannelCommitment,
*ChannelCommitment, error) {

err := c.Db.View(func(tx *bbolt.Tx) error {
chanBucket, err := fetchChanBucket(
tx, c.IdentityPub, &c.FundingOutpoint, c.ChainHash,
)
chanBucket, err := c.fetchChanBucket(tx, confirmed)
if err != nil {
return err
}
Expand Down
39 changes: 26 additions & 13 deletions channeldb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,23 +429,12 @@ func (d *DB) fetchNodeChannels(chainBucket *bbolt.Bucket) ([]*OpenChannel, error
return nil
}

// Once we've found a valid channel bucket, we'll extract it
// from the node's chain bucket.
chanBucket := chainBucket.Bucket(chanPoint)

var outPoint wire.OutPoint
err := readOutpoint(bytes.NewReader(chanPoint), &outPoint)
channel, err := d.fetchChannelFromBucket(chainBucket, chanPoint)
if err != nil {
return err
}
oChannel, err := fetchOpenChannel(chanBucket, &outPoint)
if err != nil {
return fmt.Errorf("unable to read channel data for "+
"chan_point=%v: %v", outPoint, err)
}
oChannel.Db = d

channels = append(channels, oChannel)
channels = append(channels, channel)

return nil
})
Expand All @@ -456,6 +445,30 @@ func (d *DB) fetchNodeChannels(chainBucket *bbolt.Bucket) ([]*OpenChannel, error
return channels, nil
}

// fetchChannelFromBucket fetches the channel identifier by chanPoint from the
// given bucket.
func (d *DB) fetchChannelFromBucket(bucket *bbolt.Bucket, chanPoint []byte) (
*OpenChannel, error) {

// Once we've found a valid channel bucket, we'll extract it
// from the node's chain bucket.
chanBucket := bucket.Bucket(chanPoint)

var outPoint wire.OutPoint
err := readOutpoint(bytes.NewReader(chanPoint), &outPoint)
if err != nil {
return nil, err
}
oChannel, err := fetchOpenChannel(chanBucket, &outPoint)
if err != nil {
return nil, fmt.Errorf("unable to read channel data for "+
"chan_point=%v: %v", outPoint, err)
}
oChannel.Db = d

return oChannel, nil
}

// FetchChannel attempts to locate a channel specified by the passed channel
// point. If the channel cannot be found, then an error will be returned.
func (d *DB) FetchChannel(chanPoint wire.OutPoint) (*OpenChannel, error) {
Expand Down
2 changes: 2 additions & 0 deletions fundingmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
Flags: msg.ChannelFlags,
MinConfs: 1,
Tweakless: tweaklessCommitment,
AnchorOutputs: false,
}

reservation, err := f.cfg.Wallet.InitChannelReservation(req)
Expand Down Expand Up @@ -2907,6 +2908,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
MinConfs: msg.minConfs,
Tweakless: tweaklessCommitment,
ChanFunder: msg.chanFunder,
AnchorOutputs: false,
}

reservation, err := f.cfg.Wallet.InitChannelReservation(req)
Expand Down
Loading