mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
witness beacon: report node-ID next hop to the on-chain HTLC interceptor
Extend the on-chain interceptor path in the witness beacon to expose a node-ID next hop, mirroring the off-chain path. A node-ID next hop has no outgoing channel of its own, so the beacon reports hop.Exit as the outgoing channel (via ForwardingInfo.NextHopChannel().UnwrapOr) and the requested next node's public key. The RPC boundary maps that to the NodeIDForwardSCID sentinel so the forward is not misread as a final receive. This is the requested next hop, not the channel eventually selected by non-strict forwarding, so the beacon deliberately does not resolve it against the circuit map.
This commit is contained in:
parent
32373b76c7
commit
9c4b8bfec2
2 changed files with 59 additions and 5 deletions
|
|
@ -107,14 +107,26 @@ func (p *preimageBeacon) SubscribeUpdates(
|
|||
},
|
||||
}
|
||||
|
||||
// Report the forwarding next hop to the interceptor. A channel-ID next
|
||||
// hop is reported directly; a node-ID next hop has no outgoing channel
|
||||
// of its own, so outgoingChanID is hop.Exit and the requested node ID
|
||||
// is exposed separately, exactly as the off-chain interceptor does.
|
||||
// This is the requested next hop, not the channel that non-strict
|
||||
// forwarding eventually selects, so we deliberately do not resolve it
|
||||
// against the circuit map. The RPC boundary maps a node-ID hop to the
|
||||
// NodeIDForwardSCID sentinel for the client.
|
||||
//
|
||||
// Notify the htlc interceptor. There may be a client connected
|
||||
// and willing to supply a preimage.
|
||||
packet := &htlcswitch.InterceptedPacket{
|
||||
Hash: htlc.RHash,
|
||||
IncomingExpiry: htlc.RefundTimeout,
|
||||
IncomingAmount: htlc.Amt,
|
||||
IncomingCircuit: inKey,
|
||||
OutgoingChanID: payload.FwdInfo.NextHopChannel().UnwrapOr(hop.Exit),
|
||||
Hash: htlc.RHash,
|
||||
IncomingExpiry: htlc.RefundTimeout,
|
||||
IncomingAmount: htlc.Amt,
|
||||
IncomingCircuit: inKey,
|
||||
OutgoingChanID: payload.FwdInfo.NextHopChannel().UnwrapOr(
|
||||
hop.Exit,
|
||||
),
|
||||
OutgoingNodeID: payload.FwdInfo.NextHopNode(),
|
||||
OutgoingExpiry: payload.FwdInfo.OutgoingCLTV,
|
||||
OutgoingAmount: payload.FwdInfo.AmountToForward,
|
||||
InOnionCustomRecords: payload.CustomRecords(),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/chanstate"
|
||||
"github.com/lightningnetwork/lnd/fn/v2"
|
||||
"github.com/lightningnetwork/lnd/graph/db/models"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||
"github.com/lightningnetwork/lnd/htlcswitch/hop"
|
||||
|
|
@ -97,6 +98,47 @@ func TestWitnessBeaconInterceptErrorCancels(t *testing.T) {
|
|||
p.RUnlock()
|
||||
}
|
||||
|
||||
// TestWitnessBeaconInterceptNodeID asserts that for a node-ID next hop the
|
||||
// on-chain interceptor reports the exit-hop SCID (hop.Exit) together with the
|
||||
// requested next node's public key, matching the off-chain interceptor. The
|
||||
// next hop is not resolved against the circuit map; the RPC boundary maps
|
||||
// hop.Exit to the sentinel.
|
||||
func TestWitnessBeaconInterceptNodeID(t *testing.T) {
|
||||
var interceptedFwd htlcswitch.InterceptedForward
|
||||
interceptor := func(fwd htlcswitch.InterceptedForward) error {
|
||||
interceptedFwd = fwd
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
p := newPreimageBeacon(
|
||||
&mockWitnessCache{}, interceptor,
|
||||
func(models.CircuitKey) error {
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
var nodeID [33]byte
|
||||
nodeID[0] = 0x02
|
||||
|
||||
payload := &hop.Payload{
|
||||
FwdInfo: hop.ForwardingInfo{
|
||||
NextHop: hop.NewNodeNextHop(nodeID),
|
||||
},
|
||||
}
|
||||
|
||||
_, err := p.SubscribeUpdates(
|
||||
lnwire.NewShortChanIDFromInt(1),
|
||||
&chanstate.HTLC{RHash: lntypes.Hash{1}},
|
||||
payload, []byte{2},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
packet := interceptedFwd.Packet()
|
||||
require.Equal(t, hop.Exit, packet.OutgoingChanID)
|
||||
require.Equal(t, fn.Some(nodeID), packet.OutgoingNodeID)
|
||||
}
|
||||
|
||||
type mockWitnessCache struct {
|
||||
witnessCache
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue