mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-19 20:15:18 +02:00
contractcourt: add onchain interception
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
@@ -75,7 +76,9 @@ type WitnessSubscription struct {
|
||||
type WitnessBeacon interface {
|
||||
// SubscribeUpdates returns a channel that will be sent upon *each* time
|
||||
// a new preimage is discovered.
|
||||
SubscribeUpdates() *WitnessSubscription
|
||||
SubscribeUpdates(chanID lnwire.ShortChannelID, htlc *channeldb.HTLC,
|
||||
payload *hop.Payload,
|
||||
nextHopOnionBlob []byte) (*WitnessSubscription, error)
|
||||
|
||||
// LookupPreImage attempts to lookup a preimage in the global cache.
|
||||
// True is returned for the second argument if the preimage is found.
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// htlcIncomingContestResolver is a ContractResolver that's able to resolve an
|
||||
@@ -70,7 +71,7 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
||||
|
||||
// First try to parse the payload. If that fails, we can stop resolution
|
||||
// now.
|
||||
payload, err := h.decodePayload()
|
||||
payload, nextHopOnionBlob, err := h.decodePayload()
|
||||
if err != nil {
|
||||
log.Debugf("ChannelArbitrator(%v): cannot decode payload of "+
|
||||
"htlc %v", h.ChanPoint, h.HtlcPoint())
|
||||
@@ -152,7 +153,7 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
||||
// Update htlcResolution with the matching preimage.
|
||||
h.htlcResolution.Preimage = preimage
|
||||
|
||||
log.Infof("%T(%v): extracted preimage=%v from beacon!", h,
|
||||
log.Infof("%T(%v): applied preimage=%v", h,
|
||||
h.htlcResolution.ClaimOutpoint, preimage)
|
||||
|
||||
// If this is our commitment transaction, then we'll need to
|
||||
@@ -277,7 +278,13 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
||||
// NOTE: This is done BEFORE opportunistically querying the db,
|
||||
// to ensure the preimage can't be delivered between querying
|
||||
// and registering for the preimage subscription.
|
||||
preimageSubscription := h.PreimageDB.SubscribeUpdates()
|
||||
preimageSubscription, err := h.PreimageDB.SubscribeUpdates(
|
||||
h.htlcSuccessResolver.ShortChanID, &h.htlc,
|
||||
payload, nextHopOnionBlob,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer preimageSubscription.CancelSubscription()
|
||||
|
||||
// With the epochs and preimage subscriptions initialized, we'll
|
||||
@@ -440,16 +447,31 @@ func (h *htlcIncomingContestResolver) SupplementState(_ *channeldb.OpenChannel)
|
||||
}
|
||||
|
||||
// decodePayload (re)decodes the hop payload of a received htlc.
|
||||
func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload, error) {
|
||||
func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload,
|
||||
[]byte, error) {
|
||||
|
||||
onionReader := bytes.NewReader(h.htlc.OnionBlob)
|
||||
iterator, err := h.OnionProcessor.ReconstructHopIterator(
|
||||
onionReader, h.htlc.RHash[:],
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return iterator.HopPayload()
|
||||
payload, err := iterator.HopPayload()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Transform onion blob for the next hop.
|
||||
var onionBlob [lnwire.OnionPacketSize]byte
|
||||
buf := bytes.NewBuffer(onionBlob[0:0])
|
||||
err = iterator.EncodeNextHop(buf)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return payload, onionBlob[:], nil
|
||||
}
|
||||
|
||||
// A compile time assertion to ensure htlcIncomingContestResolver meets the
|
||||
|
@@ -276,6 +276,10 @@ func (h *mockHopIterator) HopPayload() (*hop.Payload, error) {
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (h *mockHopIterator) EncodeNextHop(w io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type mockOnionProcessor struct {
|
||||
isExit bool
|
||||
offeredOnionBlob []byte
|
||||
|
@@ -14,11 +14,13 @@ import (
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
"github.com/lightningnetwork/lnd/lntest/mock"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -36,11 +38,15 @@ func newMockWitnessBeacon() *mockWitnessBeacon {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *mockWitnessBeacon) SubscribeUpdates() *WitnessSubscription {
|
||||
func (m *mockWitnessBeacon) SubscribeUpdates(
|
||||
chanID lnwire.ShortChannelID, htlc *channeldb.HTLC,
|
||||
payload *hop.Payload,
|
||||
nextHopOnionBlob []byte) (*WitnessSubscription, error) {
|
||||
|
||||
return &WitnessSubscription{
|
||||
WitnessUpdates: m.preImageUpdates,
|
||||
CancelSubscription: func() {},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mockWitnessBeacon) LookupPreimage(payhash lntypes.Hash) (lntypes.Preimage, bool) {
|
||||
|
Reference in New Issue
Block a user