Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions docs/release-notes/release-notes-0.21.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
# Bug Fixes

# New Features

- Basic Support for [onion messaging forwarding](https://github.com/lightningnetwork/lnd/pull/9868)
consisting of a new message type, `OnionMessage`. This includes the message's
definition, comprising a path key and an onion blob, along with the necessary
serialization and deserialization logic for peer-to-peer communication.

## Functional Enhancements

## RPC Additions
Expand Down
4 changes: 4 additions & 0 deletions itest/list_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,10 @@ var allTestCases = []*lntest.TestCase{
Name: "custom message",
TestFunc: testCustomMessage,
},
{
Name: "onion message",
TestFunc: testOnionMessage,
},
{
Name: "sign verify message with addr",
TestFunc: testSignVerifyMessageWithAddr,
Expand Down
80 changes: 80 additions & 0 deletions itest/lnd_onion_message_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package itest

import (
"time"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/stretchr/testify/require"
)

// testOnionMessage tests sending and receiving of the onion message type.
func testOnionMessage(ht *lntest.HarnessTest) {
alice := ht.NewNode("Alice", nil)
bob := ht.NewNode("Bob", nil)

// Subscribe Alice to onion messages before we send any, so that we
// don't miss any.
msgClient, cancel := alice.RPC.SubscribeOnionMessages()
defer cancel()

// Create a channel to receive onion messages on.
messages := make(chan *lnrpc.OnionMessage)
go func() {
for {
// If we fail to receive, just exit. The test should
// fail elsewhere if it doesn't get a message that it
// was expecting.
msg, err := msgClient.Recv()
if err != nil {
return
}

// Deliver the message into our channel or exit if the
// test is shutting down.
select {
case messages <- msg:
case <-ht.Context().Done():
return
}
}
}()

// Connect alice and bob so that they can exchange messages.
ht.EnsureConnected(alice, bob)

// Create a random onion message.
randomPriv, err := btcec.NewPrivateKey()
require.NoError(ht.T, err)
randomPub := randomPriv.PubKey()
msgPathKey := randomPub.SerializeCompressed()
// Create a random payload. The content doesn't matter for this and
// doesn't need to be encrypted. It's also of arbitrary length, so it
// doesn't follow the BOLT 4 spec for onion message payload length of
// either 1300 or 32768 bytes. Here we just use a few bytes to keep it
// simple.
msgOnion := []byte{1, 2, 3}
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't this fail because of the following (I know it is not a spec. MUST but why don't we follow it?):

SHOULD set onion_message_packet len to 1366 or 32834.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, we will follow it.
There's an ongoing debate on how to handle onion_message_packet sizes in the lightning-onion package, but whatever solution we end up with, in one of the PRs in this saga the size will be clamped to those two values.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Micro-nit: add a comment that this is only for testing purposes and the onionMsg is supposed to be either 1300 or 32... big


// Send it from Bob to Alice.
bobMsg := &lnrpc.SendOnionMessageRequest{
Peer: alice.PubKey[:],
PathKey: msgPathKey,
Onion: msgOnion,
}
bob.RPC.SendOnionMessage(bobMsg)

// Wait for Alice to receive the message.
select {
case msg := <-messages:
// Check our type and data and (sanity) check the peer we got
// it from.
require.Equal(ht, msgOnion, msg.Onion, "msg data wrong")
require.Equal(ht, msgPathKey, msg.PathKey, "msg "+
"path key wrong")
require.Equal(ht, bob.PubKey[:], msg.Peer, "msg peer wrong")

case <-time.After(lntest.DefaultTimeout):
ht.Fatalf("alice did not receive onion message: %v", bobMsg)
}
}
Loading
Loading