cnct: parse onion for resolvers
With the introduction of additional payload fields for mpp, it becomes a necessity to have their values available in the on-chain resolution flow. The incoming contest resolver notifies the invoice registry of the arrival of a payment and needs to supply all parameters for the registry to validate the htlc.
This commit is contained in:
8 files changed
+137
-17
No files matched your search
@@ -1,12 +1,14 @@
|
||||
package contractcourt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
"github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
@@ -65,6 +67,22 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// First try to parse the payload. If that fails, we can stop resolution
|
||||
// now.
|
||||
payload, err := h.decodePayload()
|
||||
if err != nil {
|
||||
log.Debugf("ChannelArbitrator(%v): cannot decode payload of "+
|
||||
"htlc %v", h.ChanPoint, h.HtlcPoint())
|
||||
|
||||
// If we've locked in an htlc with an invalid payload on our
|
||||
// commitment tx, we don't need to resolve it. The other party
|
||||
// will time it out and get their funds back. This situation can
|
||||
// present itself when we crash before processRemoteAdds in the
|
||||
// link has ran.
|
||||
h.resolved = true
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Register for block epochs. After registration, the current height
|
||||
// will be sent on the channel immediately.
|
||||
blockEpochs, err := h.Notifier.RegisterBlockEpochNtfn(nil)
|
||||
@@ -185,7 +203,7 @@ func (h *htlcIncomingContestResolver) Resolve() (ContractResolver, error) {
|
||||
|
||||
event, err := h.Registry.NotifyExitHopHtlc(
|
||||
h.htlc.RHash, h.htlc.Amt, h.htlcExpiry, currentHeight,
|
||||
circuitKey, hodlChan, nil,
|
||||
circuitKey, hodlChan, payload,
|
||||
)
|
||||
switch err {
|
||||
case channeldb.ErrInvoiceNotFound:
|
||||
@@ -344,6 +362,20 @@ func (h *htlcIncomingContestResolver) Supplement(htlc channeldb.HTLC) {
|
||||
h.htlc = htlc
|
||||
}
|
||||
|
||||
// decodePayload (re)decodes the hop payload of a received htlc.
|
||||
func (h *htlcIncomingContestResolver) decodePayload() (*hop.Payload, error) {
|
||||
|
||||
onionReader := bytes.NewReader(h.htlc.OnionBlob)
|
||||
iterator, err := h.OnionProcessor.ReconstructHopIterator(
|
||||
onionReader, h.htlc.RHash[:],
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iterator.HopPayload()
|
||||
}
|
||||
|
||||
// A compile time assertion to ensure htlcIncomingContestResolver meets the
|
||||
// ContractResolver interface.
|
||||
var _ htlcContractResolver = (*htlcIncomingContestResolver)(nil)
|
||||
Reference in new issue
Block a user