common: remove support for pre v0.10.2 onionmessages.

Temporarily disable sendpay_blinding test which uses obsolete onionmsg;
there's still some debate on the PR about how blinded HTLCs will work.

Changelog-EXPERIMENTAL: onionmessage: removed support for v0.10.1 onion messages.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-11-30 13:36:04 +10:30
parent 166ee4bac8
commit b74848f6f6
27 changed files with 53 additions and 1271 deletions

View File

@ -2321,7 +2321,6 @@ static void peer_in(struct peer *peer, const u8 *msg)
case WIRE_WARNING: case WIRE_WARNING:
case WIRE_ERROR: case WIRE_ERROR:
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
case WIRE_OBS_ONION_MESSAGE:
abort(); abort();
} }

View File

@ -11,95 +11,6 @@
#define SUPERVERBOSE(...) #define SUPERVERBOSE(...)
#endif #endif
/* Obsolete version: use enctlv() helper. */
struct onionmsg_path **make_blindedpath(const tal_t *ctx,
const struct pubkey *route,
struct pubkey *initial_blinding,
struct pubkey *final_blinding)
{
struct privkey e;
struct pubkey *pk_e, *b;
struct secret *rho;
struct onionmsg_path **path;
size_t num = tal_count(route);
if (!num)
abort();
/* E(i) */
pk_e = tal_arr(tmpctx, struct pubkey, num);
/* B(i) */
b = tal_arr(tmpctx, struct pubkey, num);
/* rho(i) */
rho = tal_arr(tmpctx, struct secret, num);
randombytes_buf(&e, sizeof(e));
if (!pubkey_from_privkey(&e, &pk_e[0]))
abort();
for (size_t i = 0; i < num; i++) {
struct secret ss;
struct secret hmac;
struct sha256 h;
if (secp256k1_ecdh(secp256k1_ctx, ss.data,
&route[i].pubkey, e.secret.data,
NULL, NULL) != 1)
abort();
subkey_from_hmac("blinded_node_id", &ss, &hmac);
b[i] = route[i];
if (i != 0) {
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx,
&b[i].pubkey, hmac.data) != 1)
abort();
}
subkey_from_hmac("rho", &ss, &rho[i]);
blinding_hash_e_and_ss(&pk_e[i], &ss, &h);
if (i != num-1)
blinding_next_pubkey(&pk_e[i], &h, &pk_e[i+1]);
blinding_next_privkey(&e, &h, &e);
}
*initial_blinding = pk_e[0];
*final_blinding = pk_e[num-1];
path = tal_arr(ctx, struct onionmsg_path *, num);
for (size_t i = 0; i < num; i++) {
path[i] = tal(path, struct onionmsg_path);
path[i]->node_id = b[i];
}
for (size_t i = 0; i < num - 1; i++) {
const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
struct tlv_encmsg_tlvs *inner;
int ret;
/* Inner is encrypted */
inner = tlv_encmsg_tlvs_new(tmpctx);
/* FIXME: We could support scids, too */
inner->next_node_id = cast_const(struct pubkey *, &route[i+1]);
path[i]->enctlv = tal_arr(path, u8, 0);
towire_encmsg_tlvs(&path[i]->enctlv, inner);
towire_pad(&path[i]->enctlv,
crypto_aead_chacha20poly1305_ietf_ABYTES);
ret = crypto_aead_chacha20poly1305_ietf_encrypt(path[i]->enctlv, NULL,
path[i]->enctlv,
tal_bytelen(path[i]->enctlv) - crypto_aead_chacha20poly1305_ietf_ABYTES,
NULL, 0,
NULL, npub,
rho[i].data);
assert(ret == 0);
}
/* Final one has no enctlv */
path[num-1]->enctlv = NULL;
return path;
}
/* Blinds node_id and calculates next blinding factor. */ /* Blinds node_id and calculates next blinding factor. */
static bool blind_node(const struct privkey *blinding, static bool blind_node(const struct privkey *blinding,
const struct secret *ss, const struct secret *ss,

View File

@ -10,13 +10,6 @@ struct pubkey;
struct privkey; struct privkey;
struct secret; struct secret;
/* Fills in *initial_blinding and *final_blinding and returns
* onionmsg_path array for this route */
struct onionmsg_path **make_blindedpath(const tal_t *ctx,
const struct pubkey *route,
struct pubkey *initial_blinding,
struct pubkey *final_blinding);
/** /**
* create_enctlv - Encrypt an encmsg to form an enctlv. * create_enctlv - Encrypt an encmsg to form an enctlv.
* @ctx: tal context * @ctx: tal context

View File

@ -144,15 +144,7 @@ int main(int argc, char **argv)
/* Inner is encrypted */ /* Inner is encrypted */
inner = tlv_encmsg_tlvs_new(tmpctx); inner = tlv_encmsg_tlvs_new(tmpctx);
/* Use scid if they provided one */ inner->next_node_id = tal_dup(inner, struct pubkey, &nodes[i+1]);
if (scids[i]) {
inner->obs_next_short_channel_id
= tal_dup(inner, struct short_channel_id,
scids[i]);
} else {
inner->next_node_id
= tal_dup(inner, struct pubkey, &nodes[i+1]);
}
p = tal_arr(tmpctx, u8, 0); p = tal_arr(tmpctx, u8, 0);
towire_encmsg_tlvs(&p, inner); towire_encmsg_tlvs(&p, inner);

View File

@ -1514,13 +1514,12 @@ type prefix, since c-lightning does not know how to parse the message.
Because this is a chained hook, the daemon expects the result to be Because this is a chained hook, the daemon expects the result to be
`{'result': 'continue'}`. It will fail if something else is returned. `{'result': 'continue'}`. It will fail if something else is returned.
### `onion_message`, `onion_message_blinded` and `onion_message_ourpath` ### `onion_message_blinded` and `onion_message_ourpath`
**(WARNING: experimental-offers only)** **(WARNING: experimental-offers only)**
These three hooks are almost identical, in that they are called when These two hooks are almost identical, in that they are called when
an onion message is received. The `onion_message` hook is only used an onion message is received.
for obsolete unblinded messages, and can be ignored for modern usage.
`onion_message_blinded` is used for unsolicited messages (where the `onion_message_blinded` is used for unsolicited messages (where the
source knows that it is sending to this node), and source knows that it is sending to this node), and
@ -1556,6 +1555,7 @@ The payload for a call follows this format:
All fields shown here are optional. All fields shown here are optional.
We suggest just returning `{'result': 'continue'}`; any other result We suggest just returning `{'result': 'continue'}`; any other result
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
will cause the message not to be handed to any other hooks. will cause the message not to be handed to any other hooks.
## Bitcoin backend ## Bitcoin backend

View File

@ -350,235 +350,6 @@ static bool handle_local_channel_announcement(struct daemon *daemon,
return true; return true;
} }
/* Peer sends obsolete onion msg. */
static u8 *handle_obs_onion_message(struct peer *peer, const u8 *msg)
{
enum onion_wire badreason;
struct onionpacket *op;
struct secret ss, *blinding_ss;
struct pubkey *blinding_in, ephemeral;
struct route_step *rs;
u8 *onion;
const u8 *cursor;
size_t max, maxlen;
struct tlv_onionmsg_payload *om;
struct tlv_obs_onion_message_tlvs *tlvs = tlv_obs_onion_message_tlvs_new(msg);
/* Ignore unless explicitly turned on. */
if (!feature_offered(peer->daemon->our_features->bits[NODE_ANNOUNCE_FEATURE],
OPT_ONION_MESSAGES))
return NULL;
/* FIXME: ratelimit! */
if (!fromwire_obs_onion_message(msg, msg, &onion, tlvs))
return towire_warningfmt(peer, NULL, "Bad onion_message");
/* We unwrap the onion now. */
op = parse_onionpacket(tmpctx, onion, tal_bytelen(onion), &badreason);
if (!op) {
status_debug("peer %s: onion msg: can't parse onionpacket: %s",
type_to_string(tmpctx, struct node_id, &peer->id),
onion_wire_name(badreason));
return NULL;
}
ephemeral = op->ephemeralkey;
if (tlvs->blinding) {
struct secret hmac;
/* E(i) */
blinding_in = tal_dup(msg, struct pubkey, tlvs->blinding);
status_debug("peer %s: blinding in = %s",
type_to_string(tmpctx, struct node_id, &peer->id),
type_to_string(tmpctx, struct pubkey, blinding_in));
blinding_ss = tal(msg, struct secret);
ecdh(blinding_in, blinding_ss);
/* b(i) = HMAC256("blinded_node_id", ss(i)) * k(i) */
subkey_from_hmac("blinded_node_id", blinding_ss, &hmac);
/* We instead tweak the *ephemeral* key from the onion and use
* our normal privkey: since hsmd knows only how to ECDH with
* our real key */
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx,
&ephemeral.pubkey,
hmac.data) != 1) {
status_debug("peer %s: onion msg: can't tweak pubkey",
type_to_string(tmpctx, struct node_id, &peer->id));
return NULL;
}
} else {
blinding_ss = NULL;
blinding_in = NULL;
}
ecdh(&ephemeral, &ss);
/* We make sure we can parse onion packet, so we know if shared secret
* is actually valid (this checks hmac). */
rs = process_onionpacket(tmpctx, op, &ss, NULL, 0, false);
if (!rs) {
status_debug("peer %s: onion msg: can't process onionpacket ss=%s",
type_to_string(tmpctx, struct node_id, &peer->id),
type_to_string(tmpctx, struct secret, &ss));
return NULL;
}
/* The raw payload is prepended with length in the TLV world. */
cursor = rs->raw_payload;
max = tal_bytelen(rs->raw_payload);
maxlen = fromwire_bigsize(&cursor, &max);
if (!cursor) {
status_debug("peer %s: onion msg: Invalid hop payload %s",
type_to_string(tmpctx, struct node_id, &peer->id),
tal_hex(tmpctx, rs->raw_payload));
return NULL;
}
if (maxlen > max) {
status_debug("peer %s: onion msg: overlong hop payload %s",
type_to_string(tmpctx, struct node_id, &peer->id),
tal_hex(tmpctx, rs->raw_payload));
return NULL;
}
om = tlv_onionmsg_payload_new(msg);
if (!fromwire_onionmsg_payload(&cursor, &maxlen, om)) {
status_debug("peer %s: onion msg: invalid onionmsg_payload %s",
type_to_string(tmpctx, struct node_id, &peer->id),
tal_hex(tmpctx, rs->raw_payload));
return NULL;
}
/* If we weren't given a blinding factor, tlv can provide one. */
if (om->obs_blinding && !blinding_ss) {
/* E(i) */
blinding_in = tal_dup(msg, struct pubkey, om->obs_blinding);
blinding_ss = tal(msg, struct secret);
ecdh(blinding_in, blinding_ss);
}
if (om->enctlv) {
const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
u8 *dec;
struct secret rho;
int ret;
if (!blinding_ss) {
status_debug("peer %s: enctlv but no blinding?",
type_to_string(tmpctx, struct node_id, &peer->id));
return NULL;
}
/* We need this to decrypt enctlv */
subkey_from_hmac("rho", blinding_ss, &rho);
/* Overrides next_scid / next_node */
if (tal_bytelen(om->enctlv)
< crypto_aead_chacha20poly1305_ietf_ABYTES) {
status_debug("peer %s: enctlv too short for mac",
type_to_string(tmpctx, struct node_id, &peer->id));
return NULL;
}
dec = tal_arr(msg, u8,
tal_bytelen(om->enctlv)
- crypto_aead_chacha20poly1305_ietf_ABYTES);
ret = crypto_aead_chacha20poly1305_ietf_decrypt(dec, NULL,
NULL,
om->enctlv,
tal_bytelen(om->enctlv),
NULL, 0,
npub,
rho.data);
if (ret != 0) {
status_debug("peer %s: Failed to decrypt enctlv field",
type_to_string(tmpctx, struct node_id, &peer->id));
return NULL;
}
status_debug("peer %s: enctlv -> %s",
type_to_string(tmpctx, struct node_id, &peer->id),
tal_hex(tmpctx, dec));
/* Replace onionmsg with one from enctlv */
cursor = dec;
maxlen = tal_bytelen(dec);
om = tlv_onionmsg_payload_new(msg);
if (!fromwire_onionmsg_payload(&cursor, &maxlen, om)) {
status_debug("peer %s: onion msg: invalid enctlv onionmsg_payload %s",
type_to_string(tmpctx, struct node_id, &peer->id),
tal_hex(tmpctx, dec));
return NULL;
}
} else if (blinding_ss && rs->nextcase != ONION_END) {
status_debug("peer %s: Onion had %s, but not enctlv?",
type_to_string(tmpctx, struct node_id, &peer->id),
tlvs->blinding ? "blinding" : "om blinding");
return NULL;
}
if (rs->nextcase == ONION_END) {
struct pubkey *blinding;
const struct onionmsg_path **path;
u8 *omsg;
if (om->obs_reply_path) {
blinding = &om->obs_reply_path->blinding;
path = cast_const2(const struct onionmsg_path **,
om->obs_reply_path->path);
} else {
blinding = NULL;
path = NULL;
}
/* We re-marshall here by policy, before handing to lightningd */
omsg = tal_arr(tmpctx, u8, 0);
towire_tlvstream_raw(&omsg, om->fields);
daemon_conn_send(peer->daemon->master,
take(towire_gossipd_got_obs_onionmsg_to_us(NULL,
blinding_in,
blinding,
path,
omsg)));
} else {
struct pubkey *next_blinding;
struct node_id *next_node;
/* This *MUST* have instructions on where to go next. */
if (!om->obs_next_short_channel_id && !om->obs_next_node_id) {
status_debug("peer %s: onion msg: no next field in %s",
type_to_string(tmpctx, struct node_id, &peer->id),
tal_hex(tmpctx, rs->raw_payload));
return NULL;
}
if (blinding_ss) {
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
struct sha256 h;
blinding_hash_e_and_ss(blinding_in, blinding_ss, &h);
next_blinding = tal(msg, struct pubkey);
blinding_next_pubkey(blinding_in, &h, next_blinding);
} else
next_blinding = NULL;
if (om->obs_next_node_id) {
next_node = tal(tmpctx, struct node_id);
node_id_from_pubkey(next_node, om->obs_next_node_id);
} else
next_node = NULL;
daemon_conn_send(peer->daemon->master,
take(towire_gossipd_got_obs_onionmsg_forward(NULL,
om->obs_next_short_channel_id,
next_node,
next_blinding,
serialize_onionpacket(tmpctx, rs->next))));
}
return NULL;
}
/* Peer sends onion msg. */ /* Peer sends onion msg. */
static u8 *handle_onion_message(struct peer *peer, const u8 *msg) static u8 *handle_onion_message(struct peer *peer, const u8 *msg)
{ {
@ -727,38 +498,6 @@ static u8 *handle_onion_message(struct peer *peer, const u8 *msg)
return NULL; return NULL;
} }
/* We send an obsolete onion msg. */
static struct io_plan *obs_onionmsg_req(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
struct node_id id;
u8 *onion_routing_packet;
struct pubkey *blinding;
struct peer *peer;
if (!fromwire_gossipd_send_obs_onionmsg(msg, msg, &id, &onion_routing_packet,
&blinding))
master_badmsg(WIRE_GOSSIPD_SEND_OBS_ONIONMSG, msg);
/* Even if lightningd were to check for valid ids, there's a race
* where it might vanish before we read this command; cleaner to
* handle it here with 'sent' = false. */
peer = find_peer(daemon, &id);
if (peer) {
struct tlv_obs_onion_message_tlvs *tlvs;
tlvs = tlv_obs_onion_message_tlvs_new(msg);
if (blinding)
tlvs->blinding = tal_dup(tlvs, struct pubkey, blinding);
queue_peer_msg(peer,
take(towire_obs_onion_message(NULL,
onion_routing_packet,
tlvs)));
}
return daemon_conn_read_next(conn, daemon->master);
}
static struct io_plan *onionmsg_req(struct io_conn *conn, struct daemon *daemon, static struct io_plan *onionmsg_req(struct io_conn *conn, struct daemon *daemon,
const u8 *msg) const u8 *msg)
{ {
@ -814,9 +553,6 @@ static struct io_plan *peer_msg_in(struct io_conn *conn,
case WIRE_REPLY_SHORT_CHANNEL_IDS_END: case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
err = handle_reply_short_channel_ids_end(peer, msg); err = handle_reply_short_channel_ids_end(peer, msg);
goto handled_relay; goto handled_relay;
case WIRE_OBS_ONION_MESSAGE:
err = handle_obs_onion_message(peer, msg);
goto handled_relay;
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
err = handle_onion_message(peer, msg); err = handle_onion_message(peer, msg);
goto handled_relay; goto handled_relay;
@ -1587,9 +1323,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
break; break;
#endif /* !DEVELOPER */ #endif /* !DEVELOPER */
case WIRE_GOSSIPD_SEND_OBS_ONIONMSG:
return obs_onionmsg_req(conn, daemon, msg);
case WIRE_GOSSIPD_SEND_ONIONMSG: case WIRE_GOSSIPD_SEND_ONIONMSG:
return onionmsg_req(conn, daemon, msg); return onionmsg_req(conn, daemon, msg);
@ -1599,8 +1332,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
case WIRE_GOSSIPD_GET_TXOUT: case WIRE_GOSSIPD_GET_TXOUT:
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY: case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:
case WIRE_GOSSIPD_GOT_OBS_ONIONMSG_TO_US:
case WIRE_GOSSIPD_GOT_OBS_ONIONMSG_FORWARD:
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US:
case WIRE_GOSSIPD_ADDGOSSIP_REPLY: case WIRE_GOSSIPD_ADDGOSSIP_REPLY:
break; break;

View File

@ -74,22 +74,6 @@ msgdata,gossipd_dev_compact_store_reply,success,bool,
msgtype,gossipd_new_blockheight,3026 msgtype,gossipd_new_blockheight,3026
msgdata,gossipd_new_blockheight,blockheight,u32, msgdata,gossipd_new_blockheight,blockheight,u32,
# Tell lightningd we got an obsolete onion message (for us, or to fwd)
msgtype,gossipd_got_obs_onionmsg_to_us,3142
msgdata,gossipd_got_obs_onionmsg_to_us,blinding_in,?pubkey,
msgdata,gossipd_got_obs_onionmsg_to_us,reply_blinding,?pubkey,
msgdata,gossipd_got_obs_onionmsg_to_us,reply_path_len,u16,
msgdata,gossipd_got_obs_onionmsg_to_us,reply_path,onionmsg_path,reply_path_len
msgdata,gossipd_got_obs_onionmsg_to_us,rawmsg_len,u16,
msgdata,gossipd_got_obs_onionmsg_to_us,rawmsg,u8,rawmsg_len
msgtype,gossipd_got_obs_onionmsg_forward,3143
msgdata,gossipd_got_obs_onionmsg_forward,next_scid,?short_channel_id,
msgdata,gossipd_got_obs_onionmsg_forward,next_node_id,?node_id,
msgdata,gossipd_got_obs_onionmsg_forward,next_blinding,?pubkey,
msgdata,gossipd_got_obs_onionmsg_forward,next_onion_len,u16,
msgdata,gossipd_got_obs_onionmsg_forward,next_onion,u8,next_onion_len
msgtype,gossipd_got_onionmsg_to_us,3145 msgtype,gossipd_got_onionmsg_to_us,3145
msgdata,gossipd_got_onionmsg_to_us,node_alias,pubkey, msgdata,gossipd_got_onionmsg_to_us,node_alias,pubkey,
msgdata,gossipd_got_onionmsg_to_us,self_id,?secret, msgdata,gossipd_got_onionmsg_to_us,self_id,?secret,
@ -101,12 +85,6 @@ msgdata,gossipd_got_onionmsg_to_us,rawmsg_len,u16,
msgdata,gossipd_got_onionmsg_to_us,rawmsg,u8,rawmsg_len msgdata,gossipd_got_onionmsg_to_us,rawmsg,u8,rawmsg_len
# Lightningd tells us to send a onion message. # Lightningd tells us to send a onion message.
msgtype,gossipd_send_obs_onionmsg,3040
msgdata,gossipd_send_obs_onionmsg,id,node_id,
msgdata,gossipd_send_obs_onionmsg,onion_len,u16,
msgdata,gossipd_send_obs_onionmsg,onion,u8,onion_len
msgdata,gossipd_send_obs_onionmsg,blinding,?pubkey,
msgtype,gossipd_send_onionmsg,3041 msgtype,gossipd_send_onionmsg,3041
msgdata,gossipd_send_onionmsg,id,node_id, msgdata,gossipd_send_onionmsg,id,node_id,
msgdata,gossipd_send_onionmsg,onion_len,u16, msgdata,gossipd_send_onionmsg,onion_len,u16,

1 #include <common/cryptomsg.h>
74 msgtype,gossipd_got_onionmsg_to_us,3145 msgdata,gossipd_send_onionmsg,blinding,pubkey,
75 msgdata,gossipd_got_onionmsg_to_us,node_alias,pubkey, # Lightningd tells us to inject a gossip message (for addgossip RPC)
76 msgdata,gossipd_got_onionmsg_to_us,self_id,?secret, msgtype,gossipd_addgossip,3044
msgdata,gossipd_got_onionmsg_to_us,reply_blinding,?pubkey,
msgdata,gossipd_got_onionmsg_to_us,reply_first_node,?pubkey,
msgdata,gossipd_got_onionmsg_to_us,reply_path_len,u16,
msgdata,gossipd_got_onionmsg_to_us,reply_path,onionmsg_path,reply_path_len
msgdata,gossipd_got_onionmsg_to_us,rawmsg_len,u16,
msgdata,gossipd_got_onionmsg_to_us,rawmsg,u8,rawmsg_len
# Lightningd tells us to send a onion message.
msgtype,gossipd_send_obs_onionmsg,3040
msgdata,gossipd_send_obs_onionmsg,id,node_id,
msgdata,gossipd_send_obs_onionmsg,onion_len,u16,
msgdata,gossipd_send_obs_onionmsg,onion,u8,onion_len
msgdata,gossipd_send_obs_onionmsg,blinding,?pubkey,
msgtype,gossipd_send_onionmsg,3041
msgdata,gossipd_send_onionmsg,id,node_id,
msgdata,gossipd_send_onionmsg,onion_len,u16,
msgdata,gossipd_send_onionmsg,onion,u8,onion_len
77 msgdata,gossipd_send_onionmsg,blinding,pubkey, msgdata,gossipd_addgossip,len,u16,
78 # Lightningd tells us to inject a gossip message (for addgossip RPC) msgdata,gossipd_addgossip,msg,u8,len
79 msgtype,gossipd_addgossip,3044 # Empty string means no problem.
85
86
87
88
89
90

View File

@ -123,7 +123,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIPD_DEV_COMPACT_STORE: case WIRE_GOSSIPD_DEV_COMPACT_STORE:
case WIRE_GOSSIPD_DEV_SET_TIME: case WIRE_GOSSIPD_DEV_SET_TIME:
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT: case WIRE_GOSSIPD_NEW_BLOCKHEIGHT:
case WIRE_GOSSIPD_SEND_OBS_ONIONMSG:
case WIRE_GOSSIPD_SEND_ONIONMSG: case WIRE_GOSSIPD_SEND_ONIONMSG:
case WIRE_GOSSIPD_ADDGOSSIP: case WIRE_GOSSIPD_ADDGOSSIP:
/* This is a reply, so never gets through to here. */ /* This is a reply, so never gets through to here. */
@ -134,12 +133,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIPD_ADDGOSSIP_REPLY: case WIRE_GOSSIPD_ADDGOSSIP_REPLY:
break; break;
case WIRE_GOSSIPD_GOT_OBS_ONIONMSG_TO_US:
handle_obs_onionmsg_to_us(gossip->ld, msg);
break;
case WIRE_GOSSIPD_GOT_OBS_ONIONMSG_FORWARD:
handle_obs_onionmsg_forward(gossip->ld, msg);
break;
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US:
handle_onionmsg_to_us(gossip->ld, msg); handle_onionmsg_to_us(gossip->ld, msg);
break; break;

View File

@ -15,15 +15,11 @@
#include <sodium/randombytes.h> #include <sodium/randombytes.h>
struct onion_message_hook_payload { struct onion_message_hook_payload {
/* Pre-spec or modern? */
bool obsolete;
/* Optional */ /* Optional */
struct pubkey *blinding_in; /* obsolete only */
struct pubkey *reply_blinding; struct pubkey *reply_blinding;
struct onionmsg_path **reply_path; struct onionmsg_path **reply_path;
struct pubkey *reply_first_node; /* non-obsolete only */ struct pubkey *reply_first_node;
struct pubkey *our_alias; /* non-obsolete only */ struct pubkey *our_alias;
struct tlv_onionmsg_payload *om; struct tlv_onionmsg_payload *om;
}; };
@ -53,34 +49,16 @@ static void onion_message_serialize(struct onion_message_hook_payload *payload,
struct plugin *plugin) struct plugin *plugin)
{ {
json_object_start(stream, "onion_message"); json_object_start(stream, "onion_message");
json_add_bool(stream, "obsolete", payload->obsolete);
if (payload->blinding_in)
json_add_pubkey(stream, "blinding_in", payload->blinding_in);
if (payload->our_alias) if (payload->our_alias)
json_add_pubkey(stream, "our_alias", payload->our_alias); json_add_pubkey(stream, "our_alias", payload->our_alias);
/* Modern style. */
if (payload->reply_first_node) { if (payload->reply_first_node) {
json_add_blindedpath(stream, "reply_blindedpath", json_add_blindedpath(stream, "reply_blindedpath",
payload->reply_blinding, payload->reply_blinding,
payload->reply_first_node, payload->reply_first_node,
payload->reply_path); payload->reply_path);
} else if (payload->reply_path) {
json_array_start(stream, "reply_path");
for (size_t i = 0; i < tal_count(payload->reply_path); i++) {
json_object_start(stream, NULL);
json_add_pubkey(stream, "id",
&payload->reply_path[i]->node_id);
if (tal_bytelen(payload->reply_path[i]->enctlv) != 0)
json_add_hex_talarr(stream, "enctlv",
payload->reply_path[i]->enctlv);
if (i == 0)
json_add_pubkey(stream, "blinding",
payload->reply_blinding);
json_object_end(stream);
}
json_array_end(stream);
} }
/* Common convenience fields */ /* Common convenience fields */
if (payload->om->invoice_request) if (payload->om->invoice_request)
json_add_hex_talarr(stream, "invoice_request", json_add_hex_talarr(stream, "invoice_request",
@ -117,12 +95,6 @@ onion_message_hook_cb(struct onion_message_hook_payload *payload STEALS)
/* Two hooks, because it's critical we only accept blinding if we expect that /* Two hooks, because it's critical we only accept blinding if we expect that
* exact blinding key. Otherwise, we can be probed using old blinded paths. */ * exact blinding key. Otherwise, we can be probed using old blinded paths. */
REGISTER_PLUGIN_HOOK(onion_message,
plugin_hook_continue,
onion_message_hook_cb,
onion_message_serialize,
struct onion_message_hook_payload *);
REGISTER_PLUGIN_HOOK(onion_message_blinded, REGISTER_PLUGIN_HOOK(onion_message_blinded,
plugin_hook_continue, plugin_hook_continue,
onion_message_hook_cb, onion_message_hook_cb,
@ -135,96 +107,6 @@ REGISTER_PLUGIN_HOOK(onion_message_ourpath,
onion_message_serialize, onion_message_serialize,
struct onion_message_hook_payload *); struct onion_message_hook_payload *);
void handle_obs_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
{
struct onion_message_hook_payload *payload;
u8 *submsg;
size_t submsglen;
const u8 *subptr;
#if DEVELOPER
if (ld->dev_ignore_obsolete_onion)
return;
#endif
payload = tal(ld, struct onion_message_hook_payload);
payload->obsolete = true;
payload->reply_first_node = NULL;
payload->om = tlv_onionmsg_payload_new(payload);
payload->our_alias = NULL;
if (!fromwire_gossipd_got_obs_onionmsg_to_us(payload, msg,
&payload->blinding_in,
&payload->reply_blinding,
&payload->reply_path,
&submsg)) {
log_broken(ld->log, "bad got_onionmsg_tous: %s",
tal_hex(tmpctx, msg));
return;
}
submsglen = tal_bytelen(submsg);
subptr = submsg;
if (!fromwire_onionmsg_payload(&subptr,
&submsglen, payload->om)) {
tal_free(payload);
log_broken(ld->log, "bad got_onionmsg_tous om: %s",
tal_hex(tmpctx, msg));
return;
}
tal_free(submsg);
if (payload->reply_path && !payload->reply_blinding) {
log_broken(ld->log,
"No reply blinding, ignoring reply path");
payload->reply_path = tal_free(payload->reply_path);
}
log_debug(ld->log, "Got obsolete onionmsg%s%s",
payload->reply_blinding ? " reply_blinding": "",
payload->reply_path ? " reply_path": "");
if (payload->blinding_in)
plugin_hook_call_onion_message_blinded(ld, payload);
else
plugin_hook_call_onion_message(ld, payload);
}
void handle_obs_onionmsg_forward(struct lightningd *ld, const u8 *msg)
{
struct short_channel_id *next_scid;
struct node_id *next_node;
struct pubkey *next_blinding;
u8 *onion;
if (!fromwire_gossipd_got_obs_onionmsg_forward(msg, msg, &next_scid,
&next_node,
&next_blinding, &onion)) {
log_broken(ld->log, "bad got_onionmsg_forward: %s",
tal_hex(tmpctx, msg));
return;
}
if (next_scid) {
struct channel *outchan = any_channel_by_scid(ld, next_scid);
if (outchan)
next_node = &outchan->peer->id;
}
if (!next_node) {
log_debug(ld->log, "Cannot forward onionmsg to %s",
next_scid ? type_to_string(tmpctx,
struct short_channel_id,
next_scid)
: "unspecified dest");
} else {
subd_send_msg(ld->gossip,
take(towire_gossipd_send_obs_onionmsg(NULL,
next_node,
onion,
next_blinding)));
}
}
void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg) void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
{ {
struct onion_message_hook_payload *payload; struct onion_message_hook_payload *payload;
@ -233,15 +115,8 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
size_t submsglen; size_t submsglen;
const u8 *subptr; const u8 *subptr;
#if DEVELOPER
if (ld->dev_ignore_modern_onion)
return;
#endif
payload = tal(ld, struct onion_message_hook_payload); payload = tal(ld, struct onion_message_hook_payload);
payload->obsolete = false;
payload->om = tlv_onionmsg_payload_new(payload); payload->om = tlv_onionmsg_payload_new(payload);
payload->blinding_in = NULL;
payload->our_alias = tal(payload, struct pubkey); payload->our_alias = tal(payload, struct pubkey);
if (!fromwire_gossipd_got_onionmsg_to_us(payload, msg, if (!fromwire_gossipd_got_onionmsg_to_us(payload, msg,
@ -290,290 +165,6 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
plugin_hook_call_onion_message_blinded(ld, payload); plugin_hook_call_onion_message_blinded(ld, payload);
} }
struct hop {
struct pubkey id;
struct short_channel_id *scid;
struct pubkey *blinding;
u8 *enctlv;
u8 *invoice;
u8 *invoice_req;
u8 *invoice_err;
u8 *rawtlv;
};
static struct command_result *param_hops(struct command *cmd,
const char *name,
const char *buffer,
const jsmntok_t *tok,
struct hop **hops)
{
size_t i;
const jsmntok_t *t;
if (tok->type != JSMN_ARRAY || tok->size == 0)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s must be an (non-empty) array", name);
*hops = tal_arr(cmd, struct hop, tok->size);
json_for_each_arr(i, t, tok) {
const jsmntok_t *tid, *tscid, *tblinding, *tenctlv, *trawtlv,
*tinvoice, *tinvoicereq, *tinvoiceerr;
tid = json_get_member(buffer, t, "id");
if (!tid)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] does not have 'id'",
name, i);
tscid = json_get_member(buffer, t, "short_channel_id");
tblinding = json_get_member(buffer, t, "blinding");
tenctlv = json_get_member(buffer, t, "enctlv");
tinvoice = json_get_member(buffer, t, "invoice");
tinvoicereq = json_get_member(buffer, t, "invoice_request");
tinvoiceerr = json_get_member(buffer, t, "invoice_error");
trawtlv = json_get_member(buffer, t, "rawtlv");
if (trawtlv && (tscid || tblinding || tenctlv || tinvoice || tinvoicereq))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] has 'rawtlv' with other fields",
name, i);
if (tblinding) {
(*hops)[i].blinding = tal(*hops, struct pubkey);
if (!json_to_pubkey(buffer, tblinding,
(*hops)[i].blinding))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'blinding' is invalid", name, i);
} else
(*hops)[i].blinding = NULL;
if (!json_to_pubkey(buffer, tid, &(*hops)[i].id))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'id' is invalid", name, i);
if (tscid) {
(*hops)[i].scid = tal(*hops, struct short_channel_id);
if (!json_to_short_channel_id(buffer, tscid,
(*hops)[i].scid))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'short_channel_id' is invalid", name, i);
} else
(*hops)[i].scid = NULL;
if (tenctlv) {
(*hops)[i].enctlv =
json_tok_bin_from_hex(*hops, buffer, tenctlv);
if (!(*hops)[i].enctlv)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'enctlv' is invalid", name, i);
} else
(*hops)[i].enctlv = NULL;
if (tinvoice) {
(*hops)[i].invoice =
json_tok_bin_from_hex(*hops, buffer, tinvoice);
if (!(*hops)[i].invoice)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'invoice' is invalid", name, i);
} else
(*hops)[i].invoice = NULL;
if (tinvoicereq) {
(*hops)[i].invoice_req =
json_tok_bin_from_hex(*hops, buffer, tinvoicereq);
if (!(*hops)[i].invoice_req)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'invoice_request' is invalid", name, i);
} else
(*hops)[i].invoice_req = NULL;
if (tinvoiceerr) {
(*hops)[i].invoice_err =
json_tok_bin_from_hex(*hops, buffer, tinvoiceerr);
if (!(*hops)[i].invoice_err)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'invoice_request' is invalid", name, i);
} else
(*hops)[i].invoice_err = NULL;
if (trawtlv) {
(*hops)[i].rawtlv =
json_tok_bin_from_hex(*hops, buffer, trawtlv);
if (!(*hops)[i].rawtlv)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s[%zu] 'rawtlv' is invalid", name, i);
} else
(*hops)[i].rawtlv = NULL;
}
return NULL;
}
static struct command_result *param_reply_path(struct command *cmd,
const char *name,
const char *buffer,
const jsmntok_t *tok,
struct tlv_onionmsg_payload_obs_reply_path **reply_path)
{
const jsmntok_t *tblinding, *tpath, *t;
size_t i;
*reply_path = tal(cmd, struct tlv_onionmsg_payload_obs_reply_path);
tblinding = json_get_member(buffer, tok, "blinding");
if (!tblinding)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s has no 'blinding'", name);
if (!json_to_pubkey(buffer, tblinding, &(*reply_path)->blinding))
return command_fail_badparam(cmd, name, buffer, tblinding,
"'blinding' should be valid pubkey");
tpath = json_get_member(buffer, tok, "path");
if (!tpath || tpath->type != JSMN_ARRAY)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s has no 'path' array", name);
(*reply_path)->path = tal_arr(*reply_path, struct onionmsg_path *,
tpath->size);
json_for_each_arr(i, t, tpath) {
const jsmntok_t *tid, *tenctlv;
struct onionmsg_path *path;
path = (*reply_path)->path[i] = tal((*reply_path)->path,
struct onionmsg_path);
tid = json_get_member(buffer, t, "id");
if (!tid)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s path[%zu] 'id' is missing",
name, i);
if (!json_to_pubkey(buffer, tid, &path->node_id))
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s path[%zu] 'id' is invalid",
name, i);
tenctlv = json_get_member(buffer, t, "enctlv");
if (!tenctlv) {
/* Optional for final destination */
if (i != tpath->size - 1)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s path[%zu] 'enctlv' is missing",
name, i);
path->enctlv = NULL;
} else {
path->enctlv = json_tok_bin_from_hex(path,
buffer, tenctlv);
if (!path->enctlv)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"%s path[%zu] 'enctlv' is invalid",
name, i);
}
}
return NULL;
}
/* Generate ->rawtlv if not already supplied. */
static void populate_tlvs(struct hop *hops,
struct tlv_onionmsg_payload_obs_reply_path *reply_path)
{
for (size_t i = 0; i < tal_count(hops); i++) {
struct tlv_onionmsg_payload *tlv;
if (hops[i].rawtlv)
continue;
tlv = tlv_onionmsg_payload_new(tmpctx);
/* If they don't give scid, use next node id */
if (hops[i].scid) {
tlv->obs_next_short_channel_id
= tal_dup(tlv, struct short_channel_id,
hops[i].scid);
} else if (i != tal_count(hops)-1) {
tlv->obs_next_node_id = tal_dup(tlv, struct pubkey,
&hops[i+1].id);
}
if (hops[i].blinding) {
tlv->obs_blinding = tal_dup(tlv, struct pubkey,
hops[i].blinding);
}
/* Note: tal_dup_talarr returns NULL for NULL */
tlv->enctlv = tal_dup_talarr(tlv, u8, hops[i].enctlv);
tlv->invoice = tal_dup_talarr(tlv, u8, hops[i].invoice);
tlv->invoice_request = tal_dup_talarr(tlv, u8,
hops[i].invoice_req);
tlv->invoice_error = tal_dup_talarr(tlv, u8,
hops[i].invoice_err);
if (i == tal_count(hops)-1 && reply_path)
tlv->obs_reply_path = reply_path;
hops[i].rawtlv = tal_arr(hops, u8, 0);
towire_onionmsg_payload(&hops[i].rawtlv, tlv);
}
}
static struct command_result *json_send_obs_onion_message(struct command *cmd,
const char *buffer,
const jsmntok_t *obj UNNEEDED,
const jsmntok_t *params)
{
struct hop *hops;
struct tlv_onionmsg_payload_obs_reply_path *reply_path;
struct sphinx_path *sphinx_path;
struct onionpacket *op;
struct secret *path_secrets;
struct node_id first_id;
size_t onion_size;
if (!param(cmd, buffer, params,
p_req("hops", param_hops, &hops),
p_opt("reply_path", param_reply_path, &reply_path),
NULL))
return command_param_failed();
if (!feature_offered(cmd->ld->our_features->bits[NODE_ANNOUNCE_FEATURE],
OPT_ONION_MESSAGES))
return command_fail(cmd, LIGHTNINGD,
"experimental-onion-messages not enabled");
node_id_from_pubkey(&first_id, &hops[0].id);
/* Sanity check first; gossipd doesn't bother telling us if peer
* can't be reached. */
if (!peer_by_id(cmd->ld, &first_id))
return command_fail(cmd, LIGHTNINGD, "Unknown first peer");
/* Create an onion which encodes this. */
populate_tlvs(hops, reply_path);
sphinx_path = sphinx_path_new(cmd, NULL);
for (size_t i = 0; i < tal_count(hops); i++)
sphinx_add_modern_hop(sphinx_path, &hops[i].id, hops[i].rawtlv);
/* BOLT-onion-message #4:
* - SHOULD set `len` to 1366 or 32834.
*/
if (sphinx_path_payloads_size(sphinx_path) <= ROUTING_INFO_SIZE)
onion_size = ROUTING_INFO_SIZE;
else
onion_size = 32768;
op = create_onionpacket(tmpctx, sphinx_path, onion_size, &path_secrets);
if (!op)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Creating onion failed (tlvs too long?)");
subd_send_msg(cmd->ld->gossip,
take(towire_gossipd_send_obs_onionmsg(NULL, &first_id,
serialize_onionpacket(tmpctx, op),
NULL)));
return command_success(cmd, json_stream_success(cmd));
}
static const struct json_command send_obs_onion_message_command = {
"sendobsonionmessage",
"utility",
json_send_obs_onion_message,
"Send message over {hops} (id, [short_channel_id], [blinding], [enctlv], [invoice], [invoice_request], [invoice_error], [rawtlv]) with optional {reply_path} (blinding, path[id, enctlv])"
};
AUTODATA(json_command, &send_obs_onion_message_command);
struct onion_hop { struct onion_hop {
struct pubkey node; struct pubkey node;
u8 *tlv; u8 *tlv;

View File

@ -5,9 +5,6 @@
struct lightningd; struct lightningd;
void handle_obs_onionmsg_to_us(struct lightningd *ld, const u8 *msg);
void handle_obs_onionmsg_forward(struct lightningd *ld, const u8 *msg);
void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg); void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg);
#endif /* LIGHTNING_LIGHTNINGD_ONION_MESSAGE_H */ #endif /* LIGHTNING_LIGHTNINGD_ONION_MESSAGE_H */

View File

@ -1286,7 +1286,6 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
case WIRE_ANNOUNCEMENT_SIGNATURES: case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_GOSSIP_TIMESTAMP_FILTER: case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
case WIRE_OBS_ONION_MESSAGE:
case WIRE_ACCEPT_CHANNEL2: case WIRE_ACCEPT_CHANNEL2:
case WIRE_TX_ADD_INPUT: case WIRE_TX_ADD_INPUT:
case WIRE_TX_REMOVE_INPUT: case WIRE_TX_REMOVE_INPUT:
@ -1633,7 +1632,6 @@ static bool run_tx_interactive(struct state *state,
case WIRE_ANNOUNCEMENT_SIGNATURES: case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_GOSSIP_TIMESTAMP_FILTER: case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
case WIRE_OBS_ONION_MESSAGE:
case WIRE_TX_SIGNATURES: case WIRE_TX_SIGNATURES:
case WIRE_OPEN_CHANNEL2: case WIRE_OPEN_CHANNEL2:
case WIRE_ACCEPT_CHANNEL2: case WIRE_ACCEPT_CHANNEL2:
@ -3687,7 +3685,6 @@ static u8 *handle_peer_in(struct state *state)
case WIRE_ANNOUNCEMENT_SIGNATURES: case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_GOSSIP_TIMESTAMP_FILTER: case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
case WIRE_OBS_ONION_MESSAGE:
case WIRE_ACCEPT_CHANNEL2: case WIRE_ACCEPT_CHANNEL2:
case WIRE_TX_ADD_INPUT: case WIRE_TX_ADD_INPUT:
case WIRE_TX_REMOVE_INPUT: case WIRE_TX_REMOVE_INPUT:

View File

@ -28,9 +28,7 @@ static LIST_HEAD(sent_list);
struct sent { struct sent {
/* We're in sent_invreqs, awaiting reply. */ /* We're in sent_invreqs, awaiting reply. */
struct list_node list; struct list_node list;
/* The blinding factor used by reply (obsolete only) */ /* The alias used by reply */
struct pubkey *reply_blinding;
/* The alias used by reply (modern only) */
struct pubkey *reply_alias; struct pubkey *reply_alias;
/* The command which sent us. */ /* The command which sent us. */
struct command *cmd; struct command *cmd;
@ -49,17 +47,6 @@ struct sent {
u32 wait_timeout; u32 wait_timeout;
}; };
static struct sent *find_sent_by_blinding(const struct pubkey *blinding)
{
struct sent *i;
list_for_each(&sent_list, i, list) {
if (i->reply_blinding && pubkey_eq(i->reply_blinding, blinding))
return i;
}
return NULL;
}
static struct sent *find_sent_by_alias(const struct pubkey *alias) static struct sent *find_sent_by_alias(const struct pubkey *alias)
{ {
struct sent *i; struct sent *i;
@ -443,48 +430,6 @@ static struct command_result *recv_modern_onion_message(struct command *cmd,
return command_hook_success(cmd); return command_hook_success(cmd);
} }
static struct command_result *recv_obs_onion_message(struct command *cmd,
const char *buf,
const jsmntok_t *params)
{
const jsmntok_t *om, *blindingtok;
bool obsolete;
struct sent *sent;
struct pubkey blinding;
struct command_result *err;
om = json_get_member(buf, params, "onion_message");
json_to_bool(buf, json_get_member(buf, om, "obsolete"), &obsolete);
if (!obsolete)
return command_hook_success(cmd);
blindingtok = json_get_member(buf, om, "blinding_in");
if (!blindingtok || !json_to_pubkey(buf, blindingtok, &blinding))
return command_hook_success(cmd);
sent = find_sent_by_blinding(&blinding);
if (!sent) {
plugin_log(cmd->plugin, LOG_DBG,
"No match for obsolete onion %.*s",
json_tok_full_len(om),
json_tok_full(buf, om));
return command_hook_success(cmd);
}
plugin_log(cmd->plugin, LOG_DBG, "Received onion message: %.*s",
json_tok_full_len(params),
json_tok_full(buf, params));
err = handle_error(cmd, sent, buf, om);
if (err)
return err;
if (sent->invreq)
return handle_invreq_response(cmd, sent, buf, om);
return command_hook_success(cmd);
}
static void destroy_sent(struct sent *sent) static void destroy_sent(struct sent *sent)
{ {
list_del(&sent->list); list_del(&sent->list);
@ -681,7 +626,7 @@ static struct pubkey *path_to_node(const tal_t *ctx,
return nodes; return nodes;
} }
/* Marshal arguments for sending obsolete and modern onion messages */ /* Marshal arguments for sending onion messages */
struct sending { struct sending {
struct sent *sent; struct sent *sent;
const char *msgfield; const char *msgfield;
@ -692,63 +637,6 @@ struct sending {
struct sent *sent); struct sent *sent);
}; };
/* Send this message down this path, with blinded reply path */
static struct command_result *send_obs_message(struct command *cmd,
const char *buf UNUSED,
const jsmntok_t *result UNUSED,
struct sending *sending)
{
struct pubkey *backwards;
struct onionmsg_path **path;
struct pubkey blinding;
struct out_req *req;
struct sent *sent = sending->sent;
/* FIXME: Maybe we should allow this? */
if (tal_count(sent->path) == 1)
return command_fail(cmd, PAY_ROUTE_NOT_FOUND,
"Refusing to talk to ourselves");
/* Reverse path is offset by one. */
backwards = tal_arr(tmpctx, struct pubkey, tal_count(sent->path) - 1);
for (size_t i = 0; i < tal_count(backwards); i++)
backwards[tal_count(backwards)-1-i] = sent->path[i];
/* Ok, now make reply for onion_message */
sent->reply_blinding = tal(sent, struct pubkey);
path = make_blindedpath(tmpctx, backwards, &blinding,
sent->reply_blinding);
req = jsonrpc_request_start(cmd->plugin, cmd, "sendobsonionmessage",
sending->done,
forward_error,
sent);
json_array_start(req->js, "hops");
for (size_t i = 1; i < tal_count(sent->path); i++) {
json_object_start(req->js, NULL);
json_add_pubkey(req->js, "id", &sent->path[i]);
if (i == tal_count(sent->path) - 1)
json_add_hex_talarr(req->js,
sending->msgfield, sending->msgval);
json_object_end(req->js);
}
json_array_end(req->js);
json_object_start(req->js, "reply_path");
json_add_pubkey(req->js, "blinding", &blinding);
json_array_start(req->js, "path");
for (size_t i = 0; i < tal_count(path); i++) {
json_object_start(req->js, NULL);
json_add_pubkey(req->js, "id", &path[i]->node_id);
if (path[i]->enctlv)
json_add_hex_talarr(req->js, "enctlv", path[i]->enctlv);
json_object_end(req->js);
}
json_array_end(req->js);
json_object_end(req->js);
return send_outreq(cmd->plugin, req);
}
static struct command_result * static struct command_result *
send_modern_message(struct command *cmd, send_modern_message(struct command *cmd,
struct tlv_onionmsg_payload_reply_path *reply_path, struct tlv_onionmsg_payload_reply_path *reply_path,
@ -810,10 +698,9 @@ send_modern_message(struct command *cmd,
payloads[nhops-1]->reply_path = reply_path; payloads[nhops-1]->reply_path = reply_path;
req = jsonrpc_request_start(cmd->plugin, cmd, "sendonionmessage", req = jsonrpc_request_start(cmd->plugin, cmd, "sendonionmessage",
/* We try obsolete msg next */ sending->done,
send_obs_message,
forward_error, forward_error,
sending); sending->sent);
json_add_pubkey(req->js, "first_id", &sent->path[1]); json_add_pubkey(req->js, "first_id", &sent->path[1]);
json_add_pubkey(req->js, "blinding", &fwd_blinding); json_add_pubkey(req->js, "blinding", &fwd_blinding);
json_array_start(req->js, "hops"); json_array_start(req->js, "hops");
@ -1942,10 +1829,6 @@ static const char *init(struct plugin *p, const char *buf UNUSED,
} }
static const struct plugin_hook hooks[] = { static const struct plugin_hook hooks[] = {
{
"onion_message_blinded",
recv_obs_onion_message
},
{ {
"onion_message_ourpath", "onion_message_ourpath",
recv_modern_onion_message recv_modern_onion_message

View File

@ -41,11 +41,11 @@ static struct command_result *sendonionmessage_error(struct command *cmd,
} }
/* FIXME: replyfield string interface is to accomodate obsolete API */ /* FIXME: replyfield string interface is to accomodate obsolete API */
static struct command_result * struct command_result *
send_modern_onion_reply(struct command *cmd, send_onion_reply(struct command *cmd,
struct tlv_onionmsg_payload_reply_path *reply_path, struct tlv_onionmsg_payload_reply_path *reply_path,
const char *replyfield, const char *replyfield,
const u8 *replydata) const u8 *replydata)
{ {
struct out_req *req; struct out_req *req;
size_t nhops = tal_count(reply_path->path); size_t nhops = tal_count(reply_path->path);
@ -84,104 +84,17 @@ send_modern_onion_reply(struct command *cmd,
return send_outreq(cmd->plugin, req); return send_outreq(cmd->plugin, req);
} }
struct command_result *WARN_UNUSED_RESULT
send_onion_reply(struct command *cmd,
struct tlv_onionmsg_payload_reply_path *reply_path,
const char *jsonbuf,
const jsmntok_t *replytok,
const char *replyfield,
const u8 *replydata)
{
struct out_req *req;
size_t i;
const jsmntok_t *t;
if (reply_path)
return send_modern_onion_reply(cmd, reply_path,
replyfield, replydata);
plugin_log(cmd->plugin, LOG_DBG, "sending obs reply %s = %s",
replyfield, tal_hex(tmpctx, replydata));
/* Send to requester, using return route. */
req = jsonrpc_request_start(cmd->plugin, cmd, "sendobsonionmessage",
finished, sendonionmessage_error, NULL);
/* Add reply into last hop. */
json_array_start(req->js, "hops");
json_for_each_arr(i, t, replytok) {
size_t j;
const jsmntok_t *t2;
plugin_log(cmd->plugin, LOG_DBG, "hops[%zu/%i]",
i, replytok->size);
json_object_start(req->js, NULL);
json_for_each_obj(j, t2, t)
json_add_tok(req->js,
json_strdup(tmpctx, jsonbuf, t2),
t2+1, jsonbuf);
if (i == replytok->size - 1) {
plugin_log(cmd->plugin, LOG_DBG, "... adding %s",
replyfield);
json_add_hex_talarr(req->js, replyfield, replydata);
}
json_object_end(req->js);
}
json_array_end(req->js);
return send_outreq(cmd->plugin, req);
}
static struct command_result *onion_message_call(struct command *cmd,
const char *buf,
const jsmntok_t *params)
{
const jsmntok_t *om, *invreqtok, *invtok;
if (!offers_enabled)
return command_hook_success(cmd);
om = json_get_member(buf, params, "onion_message");
invreqtok = json_get_member(buf, om, "invoice_request");
if (invreqtok) {
const jsmntok_t *replytok;
replytok = json_get_member(buf, om, "reply_path");
if (replytok && replytok->size > 0)
return handle_invoice_request(cmd, buf,
invreqtok, replytok, NULL);
else
plugin_log(cmd->plugin, LOG_DBG,
"invoice_request without reply_path");
}
invtok = json_get_member(buf, om, "invoice");
if (invtok) {
const jsmntok_t *replytok;
replytok = json_get_member(buf, om, "reply_path");
return handle_invoice(cmd, buf, invtok, replytok, NULL);
}
return command_hook_success(cmd);
}
static struct command_result *onion_message_modern_call(struct command *cmd, static struct command_result *onion_message_modern_call(struct command *cmd,
const char *buf, const char *buf,
const jsmntok_t *params) const jsmntok_t *params)
{ {
const jsmntok_t *om, *replytok, *invreqtok, *invtok; const jsmntok_t *om, *replytok, *invreqtok, *invtok;
bool obsolete;
struct tlv_onionmsg_payload_reply_path *reply_path; struct tlv_onionmsg_payload_reply_path *reply_path;
if (!offers_enabled) if (!offers_enabled)
return command_hook_success(cmd); return command_hook_success(cmd);
om = json_get_member(buf, params, "onion_message"); om = json_get_member(buf, params, "onion_message");
json_to_bool(buf, json_get_member(buf, om, "obsolete"), &obsolete);
if (obsolete)
return command_hook_success(cmd);
replytok = json_get_member(buf, om, "reply_blindedpath"); replytok = json_get_member(buf, om, "reply_blindedpath");
if (replytok) { if (replytok) {
reply_path = json_to_reply_path(cmd, buf, replytok); reply_path = json_to_reply_path(cmd, buf, replytok);
@ -194,10 +107,11 @@ static struct command_result *onion_message_modern_call(struct command *cmd,
invreqtok = json_get_member(buf, om, "invoice_request"); invreqtok = json_get_member(buf, om, "invoice_request");
if (invreqtok) { if (invreqtok) {
const u8 *invreqbin = json_tok_bin_from_hex(tmpctx, buf, invreqtok);
if (reply_path) if (reply_path)
return handle_invoice_request(cmd, buf, return handle_invoice_request(cmd,
invreqtok, invreqbin,
NULL, reply_path); reply_path);
else else
plugin_log(cmd->plugin, LOG_DBG, plugin_log(cmd->plugin, LOG_DBG,
"invoice_request without reply_path"); "invoice_request without reply_path");
@ -205,17 +119,15 @@ static struct command_result *onion_message_modern_call(struct command *cmd,
invtok = json_get_member(buf, om, "invoice"); invtok = json_get_member(buf, om, "invoice");
if (invtok) { if (invtok) {
return handle_invoice(cmd, buf, invtok, NULL, reply_path); const u8 *invbin = json_tok_bin_from_hex(tmpctx, buf, invtok);
if (invbin)
return handle_invoice(cmd, invbin, reply_path);
} }
return command_hook_success(cmd); return command_hook_success(cmd);
} }
static const struct plugin_hook hooks[] = { static const struct plugin_hook hooks[] = {
{
"onion_message",
onion_message_call
},
{ {
"onion_message_blinded", "onion_message_blinded",
onion_message_modern_call onion_message_modern_call

View File

@ -9,11 +9,7 @@ struct command;
/* Helper to send a reply */ /* Helper to send a reply */
struct command_result *WARN_UNUSED_RESULT struct command_result *WARN_UNUSED_RESULT
send_onion_reply(struct command *cmd, send_onion_reply(struct command *cmd,
/* Preferred */
struct tlv_onionmsg_payload_reply_path *reply_path, struct tlv_onionmsg_payload_reply_path *reply_path,
/* Used if reply_path is NULL */
const char *jsonbuf,
const jsmntok_t *replytok,
const char *replyfield, const char *replyfield,
const u8 *replydata); const u8 *replydata);
#endif /* LIGHTNING_PLUGINS_OFFERS_H */ #endif /* LIGHTNING_PLUGINS_OFFERS_H */

View File

@ -10,9 +10,7 @@
struct inv { struct inv {
struct tlv_invoice *inv; struct tlv_invoice *inv;
const char *buf;
/* May be NULL */ /* May be NULL */
const jsmntok_t *replytok;
struct tlv_onionmsg_payload_reply_path *reply_path; struct tlv_onionmsg_payload_reply_path *reply_path;
/* The offer, once we've looked it up. */ /* The offer, once we've looked it up. */
@ -41,7 +39,7 @@ fail_inv_level(struct command *cmd,
plugin_log(cmd->plugin, l, "%s", msg); plugin_log(cmd->plugin, l, "%s", msg);
/* Only reply if they gave us a path */ /* Only reply if they gave us a path */
if (!inv->replytok && !inv->reply_path) if (!inv->reply_path)
return command_hook_success(cmd); return command_hook_success(cmd);
/* Don't send back internal error details. */ /* Don't send back internal error details. */
@ -55,8 +53,7 @@ fail_inv_level(struct command *cmd,
errdata = tal_arr(cmd, u8, 0); errdata = tal_arr(cmd, u8, 0);
towire_invoice_error(&errdata, err); towire_invoice_error(&errdata, err);
return send_onion_reply(cmd, inv->reply_path, inv->buf, inv->replytok, return send_onion_reply(cmd, inv->reply_path, "invoice_error", errdata);
"invoice_error", errdata);
} }
static struct command_result *WARN_UNUSED_RESULT static struct command_result *WARN_UNUSED_RESULT
@ -315,12 +312,9 @@ static struct command_result *listoffers_error(struct command *cmd,
} }
struct command_result *handle_invoice(struct command *cmd, struct command_result *handle_invoice(struct command *cmd,
const char *buf, const u8 *invbin,
const jsmntok_t *invtok, struct tlv_onionmsg_payload_reply_path *reply_path STEALS)
const jsmntok_t *replytok,
struct tlv_onionmsg_payload_reply_path *reply_path)
{ {
const u8 *invbin = json_tok_bin_from_hex(cmd, buf, invtok);
size_t len = tal_count(invbin); size_t len = tal_count(invbin);
struct inv *inv = tal(cmd, struct inv); struct inv *inv = tal(cmd, struct inv);
struct out_req *req; struct out_req *req;
@ -328,17 +322,7 @@ struct command_result *handle_invoice(struct command *cmd,
int bad_feature; int bad_feature;
struct sha256 m, shash; struct sha256 m, shash;
if (reply_path) { inv->reply_path = tal_steal(inv, reply_path);
inv->buf = NULL;
inv->replytok = NULL;
inv->reply_path = reply_path;
} else {
/* Make a copy of entire buffer, for later. */
inv->buf = tal_dup_arr(inv, char, buf, replytok->end, 0);
inv->replytok = tal_dup_arr(inv, jsmntok_t, replytok,
json_next(replytok) - replytok, 0);
inv->reply_path = NULL;
}
inv->inv = tlv_invoice_new(cmd); inv->inv = tlv_invoice_new(cmd);
if (!fromwire_invoice(&invbin, &len, inv->inv)) { if (!fromwire_invoice(&invbin, &len, inv->inv)) {

View File

@ -3,10 +3,8 @@
#include "config.h" #include "config.h"
#include <plugins/libplugin.h> #include <plugins/libplugin.h>
/* We got an onionmessage with an invoice! replytok/reply_path could be NULL. */ /* We got an onionmessage with an invoice! reply_path could be NULL. */
struct command_result *handle_invoice(struct command *cmd, struct command_result *handle_invoice(struct command *cmd,
const char *buf, const u8 *invbin,
const jsmntok_t *invtok, struct tlv_onionmsg_payload_reply_path *reply_path STEALS);
const jsmntok_t *replytok,
struct tlv_onionmsg_payload_reply_path *reply_path);
#endif /* LIGHTNING_PLUGINS_OFFERS_INV_HOOK_H */ #endif /* LIGHTNING_PLUGINS_OFFERS_INV_HOOK_H */

View File

@ -15,10 +15,6 @@
/* We need to keep the reply path around so we can reply with invoice */ /* We need to keep the reply path around so we can reply with invoice */
struct invreq { struct invreq {
struct tlv_invoice_request *invreq; struct tlv_invoice_request *invreq;
const char *buf;
/* If obsolete style */
const jsmntok_t *replytok;
/* If modern style. */
struct tlv_onionmsg_payload_reply_path *reply_path; struct tlv_onionmsg_payload_reply_path *reply_path;
/* The offer, once we've looked it up. */ /* The offer, once we've looked it up. */
@ -63,9 +59,7 @@ fail_invreq_level(struct command *cmd,
errdata = tal_arr(cmd, u8, 0); errdata = tal_arr(cmd, u8, 0);
towire_invoice_error(&errdata, err); towire_invoice_error(&errdata, err);
return send_onion_reply(cmd, invreq->reply_path, return send_onion_reply(cmd, invreq->reply_path, "invoice_error", errdata);
invreq->buf, invreq->replytok,
"invoice_error", errdata);
} }
static struct command_result *WARN_UNUSED_RESULT PRINTF_FMT(3,4) static struct command_result *WARN_UNUSED_RESULT PRINTF_FMT(3,4)
@ -184,8 +178,7 @@ static struct command_result *createinvoice_done(struct command *cmd,
json_tok_full(buf, t)); json_tok_full(buf, t));
} }
return send_onion_reply(cmd, ir->reply_path, ir->buf, ir->replytok, return send_onion_reply(cmd, ir->reply_path, "invoice", rawinv);
"invoice", rawinv);
} }
static struct command_result *createinvoice_error(struct command *cmd, static struct command_result *createinvoice_error(struct command *cmd,
@ -836,28 +829,15 @@ static struct command_result *handle_offerless_request(struct command *cmd,
} }
struct command_result *handle_invoice_request(struct command *cmd, struct command_result *handle_invoice_request(struct command *cmd,
const char *buf, const u8 *invreqbin,
const jsmntok_t *invreqtok,
const jsmntok_t *replytok,
struct tlv_onionmsg_payload_reply_path *reply_path) struct tlv_onionmsg_payload_reply_path *reply_path)
{ {
const u8 *invreqbin = json_tok_bin_from_hex(cmd, buf, invreqtok);
size_t len = tal_count(invreqbin); size_t len = tal_count(invreqbin);
struct invreq *ir = tal(cmd, struct invreq); struct invreq *ir = tal(cmd, struct invreq);
struct out_req *req; struct out_req *req;
int bad_feature; int bad_feature;
/* Make a copy of entire buffer, for later. */ ir->reply_path = tal_steal(ir, reply_path);
if (reply_path) {
ir->buf = NULL;
ir->replytok = NULL;
ir->reply_path = reply_path;
} else {
ir->buf = tal_dup_arr(ir, char, buf, replytok->end, 0);
ir->replytok = tal_dup_arr(ir, jsmntok_t, replytok,
json_next(replytok) - replytok, 0);
ir->reply_path = NULL;
}
ir->invreq = tlv_invoice_request_new(cmd); ir->invreq = tlv_invoice_request_new(cmd);
if (!fromwire_invoice_request(&invreqbin, &len, ir->invreq)) { if (!fromwire_invoice_request(&invreqbin, &len, ir->invreq)) {

View File

@ -7,10 +7,6 @@ extern u32 cltv_final;
/* We got an onionmessage with an invreq! */ /* We got an onionmessage with an invreq! */
struct command_result *handle_invoice_request(struct command *cmd, struct command_result *handle_invoice_request(struct command *cmd,
const char *buf, const u8 *invreqbin,
const jsmntok_t *invreqtok, struct tlv_onionmsg_payload_reply_path *reply_path STEALS);
/* Obsolete onion */
const jsmntok_t *replytok,
/* Modern onion */
struct tlv_onionmsg_payload_reply_path *reply_path);
#endif /* LIGHTNING_PLUGINS_OFFERS_INVREQ_HOOK_H */ #endif /* LIGHTNING_PLUGINS_OFFERS_INVREQ_HOOK_H */

View File

@ -2252,77 +2252,6 @@ def test_sendcustommsg(node_factory):
]) ])
def test_sendobsonionmessage(node_factory):
l1, l2, l3 = node_factory.line_graph(3, opts={'experimental-onion-messages': None})
blindedpathtool = os.path.join(os.path.dirname(__file__), "..", "devtools", "blindedpath")
l1.rpc.call('sendobsonionmessage',
{'hops':
[{'id': l2.info['id']},
{'id': l3.info['id']}]})
assert l3.daemon.wait_for_log('Got obsolete onionmsg')
# Now by SCID.
l1.rpc.call('sendobsonionmessage',
{'hops':
[{'id': l2.info['id'],
'short_channel_id': l2.get_channel_scid(l3)},
{'id': l3.info['id']}]})
assert l3.daemon.wait_for_log('Got obsolete onionmsg')
# Now test blinded path.
output = subprocess.check_output(
[blindedpathtool, '--simple-output', 'create', l2.info['id'], l3.info['id']]
).decode('ASCII').strip()
# First line is blinding, then <peerid> then <encblob>.
blinding, p1, p1enc, p2 = output.split('\n')
# First hop can't be blinded!
assert p1 == l2.info['id']
l1.rpc.call('sendobsonionmessage',
{'hops':
[{'id': l2.info['id'],
'blinding': blinding,
'enctlv': p1enc},
{'id': p2}]})
assert l3.daemon.wait_for_log('Got obsolete onionmsg')
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs sendobsonionmessage")
def test_sendobsonionmessage_reply(node_factory):
blindedpathtool = os.path.join(os.path.dirname(__file__), "..", "devtools", "blindedpath")
plugin = os.path.join(os.path.dirname(__file__), "plugins", "onionmessage-reply.py")
l1, l2, l3 = node_factory.line_graph(3, opts={'plugin': plugin})
# Make reply path
output = subprocess.check_output(
[blindedpathtool, '--simple-output', 'create', l2.info['id'], l1.info['id']]
).decode('ASCII').strip()
# First line is blinding, then <peerid> then <encblob>.
blinding, p1, p1enc, p2 = output.split('\n')
# First hop can't be blinded!
assert p1 == l2.info['id']
# Also tests oversize payload which won't fit in 1366-byte onion.
l1.rpc.call('sendobsonionmessage',
{'hops':
[{'id': l2.info['id']},
{'id': l3.info['id'],
'invoice': '77' * 15000}],
'reply_path':
{'blinding': blinding,
'path': [{'id': p1, 'enctlv': p1enc}, {'id': p2}]}})
assert l3.daemon.wait_for_log('Got obsolete onionmsg reply_blinding reply_path')
assert l3.daemon.wait_for_log("Got onion_message invoice '{}'".format('77' * 15000))
assert l3.daemon.wait_for_log('Sent reply via')
assert l1.daemon.wait_for_log('Got obsolete onionmsg')
@pytest.mark.developer("needs --dev-force-privkey") @pytest.mark.developer("needs --dev-force-privkey")
def test_getsharedsecret(node_factory): def test_getsharedsecret(node_factory):
""" """

View File

@ -3259,6 +3259,7 @@ def test_reject_invalid_payload(node_factory):
l1.rpc.waitsendpay(inv['payment_hash']) l1.rpc.waitsendpay(inv['payment_hash'])
@pytest.mark.skip("Needs to be updated for modern onion")
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs blinding args to sendpay") @unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs blinding args to sendpay")
def test_sendpay_blinding(node_factory): def test_sendpay_blinding(node_factory):
l1, l2, l3, l4 = node_factory.line_graph(4) l1, l2, l3, l4 = node_factory.line_graph(4)
@ -4351,23 +4352,6 @@ def test_fetchinvoice_3hop(node_factory, bitcoind):
l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']}) l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']})
# Test with obsolete onion.
l4.stop()
l4.daemon.opts['dev-no-modern-onion'] = None
l4.start()
l4.rpc.connect(l3.info['id'], 'localhost', l3.port)
l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']})
# Test with modern onion.
l4.stop()
del l4.daemon.opts['dev-no-modern-onion']
l4.daemon.opts['dev-no-obsolete-onion'] = None
l4.start()
l4.rpc.connect(l3.info['id'], 'localhost', l3.port)
l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']})
def test_fetchinvoice(node_factory, bitcoind): def test_fetchinvoice(node_factory, bitcoind):
# We remove the conversion plugin on l3, causing it to get upset. # We remove the conversion plugin on l3, causing it to get upset.

View File

@ -1,30 +1,29 @@
--- wire/extracted_onion_wire_csv 2020-03-25 10:24:12.861645774 +1030 --- wire/extracted_onion_wire_csv 2020-03-25 10:24:12.861645774 +1030
+++ - 2020-03-26 13:47:13.498294435 +1030 +++ - 2020-03-26 13:47:13.498294435 +1030
@@ -8,6 +8,31 @@ @@ -8,6 +8,30 @@
tlvtype,tlv_payload,payment_data,8 tlvtype,tlv_payload,payment_data,8
tlvdata,tlv_payload,payment_data,payment_secret,byte,32 tlvdata,tlv_payload,payment_data,payment_secret,byte,32
tlvdata,tlv_payload,payment_data,total_msat,tu64, tlvdata,tlv_payload,payment_data,total_msat,tu64,
+tlvtype,onionmsg_payload,obs_next_node_id,4 +tlvtype,onionmsg_payload,reply_path,2
+tlvdata,onionmsg_payload,obs_next_node_id,node_id,point, +tlvdata,onionmsg_payload,reply_path,first_node_id,point,
+tlvtype,onionmsg_payload,obs_next_short_channel_id,6 +tlvdata,onionmsg_payload,reply_path,blinding,point,
+tlvdata,onionmsg_payload,obs_next_short_channel_id,short_channel_id,short_channel_id, +tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,...
+tlvtype,onionmsg_payload,obs_reply_path,8
+tlvdata,onionmsg_payload,obs_reply_path,blinding,point,
+tlvdata,onionmsg_payload,obs_reply_path,path,onionmsg_path,...
+tlvtype,onionmsg_payload,enctlv,10 +tlvtype,onionmsg_payload,enctlv,10
+tlvdata,onionmsg_payload,enctlv,enctlv,byte,... +tlvdata,onionmsg_payload,enctlv,enctlv,byte,...
+tlvtype,onionmsg_payload,obs_blinding,12
+tlvdata,onionmsg_payload,obs_blinding,blinding,point,
+tlvtype,onionmsg_payload,invoice_request,64 +tlvtype,onionmsg_payload,invoice_request,64
+tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,... +tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,...
+tlvtype,onionmsg_payload,invoice,66 +tlvtype,onionmsg_payload,invoice,66
+tlvdata,onionmsg_payload,invoice,invoice,byte,... +tlvdata,onionmsg_payload,invoice,invoice,byte,...
+tlvtype,onionmsg_payload,invoice_error,68 +tlvtype,onionmsg_payload,invoice_error,68
+tlvdata,onionmsg_payload,invoice_error,invoice_error,byte,... +tlvdata,onionmsg_payload,invoice_error,invoice_error,byte,...
+tlvtype,encmsg_tlvs,padding,1
+tlvdata,encmsg_tlvs,padding,pad,byte,...
+tlvtype,encmsg_tlvs,next_node_id,4 +tlvtype,encmsg_tlvs,next_node_id,4
+tlvdata,encmsg_tlvs,next_node_id,node_id,point, +tlvdata,encmsg_tlvs,next_node_id,node_id,point,
+tlvtype,encmsg_tlvs,obs_next_short_channel_id,6 +tlvtype,encmsg_tlvs,next_blinding,12
+tlvdata,encmsg_tlvs,obs_next_short_channel_id,short_channel_id,short_channel_id, +tlvdata,encmsg_tlvs,next_blinding,blinding,point,
+tlvtype,encmsg_tlvs,self_id,14
+tlvdata,encmsg_tlvs,self_id,data,byte,...
+subtype,onionmsg_path +subtype,onionmsg_path
+subtypedata,onionmsg_path,node_id,point, +subtypedata,onionmsg_path,node_id,point,
+subtypedata,onionmsg_path,enclen,u16, +subtypedata,onionmsg_path,enclen,u16,

View File

@ -1,30 +0,0 @@
--- onion_wire.csv 2021-08-25 12:41:02.872253965 +0930
+++ onion_wire.csv.raw 2021-08-25 13:52:00.748767887 +0930
@@ -8,6 +8,10 @@ tlvdata,tlv_payload,short_channel_id,short_channel_id,short_channel_id,
tlvtype,tlv_payload,payment_data,8
tlvdata,tlv_payload,payment_data,payment_secret,byte,32
tlvdata,tlv_payload,payment_data,total_msat,tu64,
+tlvtype,onionmsg_payload,reply_path,2
+tlvdata,onionmsg_payload,reply_path,first_node_id,point,
+tlvdata,onionmsg_payload,reply_path,blinding,point,
+tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,...
tlvtype,onionmsg_payload,obs_next_node_id,4
tlvdata,onionmsg_payload,obs_next_node_id,node_id,point,
tlvtype,onionmsg_payload,obs_next_short_channel_id,6
@@ -29,10 +29,16 @@ tlvtype,onionmsg_payload,invoice,66
tlvdata,onionmsg_payload,invoice,invoice,byte,...
tlvtype,onionmsg_payload,invoice_error,68
tlvdata,onionmsg_payload,invoice_error,invoice_error,byte,...
+tlvtype,encmsg_tlvs,padding,1
+tlvdata,encmsg_tlvs,padding,pad,byte,...
tlvtype,encmsg_tlvs,next_node_id,4
tlvdata,encmsg_tlvs,next_node_id,node_id,point,
tlvtype,encmsg_tlvs,obs_next_short_channel_id,6
tlvdata,encmsg_tlvs,obs_next_short_channel_id,short_channel_id,short_channel_id,
+tlvtype,encmsg_tlvs,next_blinding,12
+tlvdata,encmsg_tlvs,next_blinding,blinding,point,
+tlvtype,encmsg_tlvs,self_id,14
+tlvdata,encmsg_tlvs,self_id,data,byte,...
subtype,onionmsg_path
subtypedata,onionmsg_path,node_id,point,
subtypedata,onionmsg_path,enclen,u16,

View File

@ -1,12 +0,0 @@
--- wire/extracted_peer_wire_csv 2020-03-11 10:30:35.744376417 +1030
+++ - 2020-03-26 13:47:13.409755567 +1030
@@ -211,3 +211,9 @@
msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
msgdata,gossip_timestamp_filter,first_timestamp,u32,
msgdata,gossip_timestamp_filter,timestamp_range,u32,
+msgtype,obs_onion_message,385,option_onion_messages
+msgdata,obs_onion_message,len,u16,
+msgdata,obs_onion_message,onionmsg,byte,len
+msgdata,obs_onion_message,obs_onion_message_tlvs,obs_onion_message_tlvs,
+tlvtype,obs_onion_message_tlvs,blinding,2
+tlvdata,obs_onion_message_tlvs,blinding,blinding,point,

View File

@ -1,9 +1,9 @@
--- peer_wire.csv 2021-08-25 12:41:02.876254003 +0930 --- peer_wire.csv 2021-08-25 12:41:02.876254003 +0930
+++ peer_wire.csv.raw 2021-08-25 13:42:31.991693809 +0930 +++ peer_wire.csv.raw 2021-08-25 13:42:31.991693809 +0930
@@ -320,3 +210,7 @@ @@ -320,3 +210,7 @@
msgdata,obs_onion_message,obs_onion_message_tlvs,obs_onion_message_tlvs, msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
tlvtype,obs_onion_message_tlvs,blinding,2 msgdata,gossip_timestamp_filter,first_timestamp,u32,
tlvdata,obs_onion_message_tlvs,blinding,blinding,point, msgdata,gossip_timestamp_filter,timestamp_range,u32,
+msgtype,onion_message,387,option_onion_messages +msgtype,onion_message,387,option_onion_messages
+msgdata,onion_message,blinding,point, +msgdata,onion_message,blinding,point,
+msgdata,onion_message,len,u16, +msgdata,onion_message,len,u16,

View File

@ -12,17 +12,8 @@ tlvtype,onionmsg_payload,reply_path,2
tlvdata,onionmsg_payload,reply_path,first_node_id,point, tlvdata,onionmsg_payload,reply_path,first_node_id,point,
tlvdata,onionmsg_payload,reply_path,blinding,point, tlvdata,onionmsg_payload,reply_path,blinding,point,
tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,... tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,...
tlvtype,onionmsg_payload,obs_next_node_id,4
tlvdata,onionmsg_payload,obs_next_node_id,node_id,point,
tlvtype,onionmsg_payload,obs_next_short_channel_id,6
tlvdata,onionmsg_payload,obs_next_short_channel_id,short_channel_id,short_channel_id,
tlvtype,onionmsg_payload,obs_reply_path,8
tlvdata,onionmsg_payload,obs_reply_path,blinding,point,
tlvdata,onionmsg_payload,obs_reply_path,path,onionmsg_path,...
tlvtype,onionmsg_payload,enctlv,10 tlvtype,onionmsg_payload,enctlv,10
tlvdata,onionmsg_payload,enctlv,enctlv,byte,... tlvdata,onionmsg_payload,enctlv,enctlv,byte,...
tlvtype,onionmsg_payload,obs_blinding,12
tlvdata,onionmsg_payload,obs_blinding,blinding,point,
tlvtype,onionmsg_payload,invoice_request,64 tlvtype,onionmsg_payload,invoice_request,64
tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,... tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,...
tlvtype,onionmsg_payload,invoice,66 tlvtype,onionmsg_payload,invoice,66
@ -33,8 +24,6 @@ tlvtype,encmsg_tlvs,padding,1
tlvdata,encmsg_tlvs,padding,pad,byte,... tlvdata,encmsg_tlvs,padding,pad,byte,...
tlvtype,encmsg_tlvs,next_node_id,4 tlvtype,encmsg_tlvs,next_node_id,4
tlvdata,encmsg_tlvs,next_node_id,node_id,point, tlvdata,encmsg_tlvs,next_node_id,node_id,point,
tlvtype,encmsg_tlvs,obs_next_short_channel_id,6
tlvdata,encmsg_tlvs,obs_next_short_channel_id,short_channel_id,short_channel_id,
tlvtype,encmsg_tlvs,next_blinding,12 tlvtype,encmsg_tlvs,next_blinding,12
tlvdata,encmsg_tlvs,next_blinding,blinding,point, tlvdata,encmsg_tlvs,next_blinding,blinding,point,
tlvtype,encmsg_tlvs,self_id,14 tlvtype,encmsg_tlvs,self_id,14

1 #include <wire/onion_defs.h>
12 tlvdata,onionmsg_payload,reply_path,first_node_id,point,
13 tlvdata,onionmsg_payload,reply_path,blinding,point,
14 tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,...
tlvtype,onionmsg_payload,obs_next_node_id,4
tlvdata,onionmsg_payload,obs_next_node_id,node_id,point,
tlvtype,onionmsg_payload,obs_next_short_channel_id,6
tlvdata,onionmsg_payload,obs_next_short_channel_id,short_channel_id,short_channel_id,
tlvtype,onionmsg_payload,obs_reply_path,8
tlvdata,onionmsg_payload,obs_reply_path,blinding,point,
tlvdata,onionmsg_payload,obs_reply_path,path,onionmsg_path,...
15 tlvtype,onionmsg_payload,enctlv,10
16 tlvdata,onionmsg_payload,enctlv,enctlv,byte,...
tlvtype,onionmsg_payload,obs_blinding,12
tlvdata,onionmsg_payload,obs_blinding,blinding,point,
17 tlvtype,onionmsg_payload,invoice_request,64
18 tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,...
19 tlvtype,onionmsg_payload,invoice,66
24 tlvdata,encmsg_tlvs,padding,pad,byte,...
25 tlvtype,encmsg_tlvs,next_node_id,4
26 tlvdata,encmsg_tlvs,next_node_id,node_id,point,
tlvtype,encmsg_tlvs,obs_next_short_channel_id,6
tlvdata,encmsg_tlvs,obs_next_short_channel_id,short_channel_id,short_channel_id,
27 tlvtype,encmsg_tlvs,next_blinding,12
28 tlvdata,encmsg_tlvs,next_blinding,blinding,point,
29 tlvtype,encmsg_tlvs,self_id,14

View File

@ -34,7 +34,6 @@ static bool unknown_type(enum peer_wire t)
case WIRE_REPLY_CHANNEL_RANGE: case WIRE_REPLY_CHANNEL_RANGE:
case WIRE_GOSSIP_TIMESTAMP_FILTER: case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
case WIRE_OBS_ONION_MESSAGE:
case WIRE_TX_ADD_INPUT: case WIRE_TX_ADD_INPUT:
case WIRE_TX_REMOVE_INPUT: case WIRE_TX_REMOVE_INPUT:
case WIRE_TX_ADD_OUTPUT: case WIRE_TX_ADD_OUTPUT:
@ -64,7 +63,6 @@ bool is_msg_for_gossipd(const u8 *cursor)
case WIRE_QUERY_CHANNEL_RANGE: case WIRE_QUERY_CHANNEL_RANGE:
case WIRE_REPLY_CHANNEL_RANGE: case WIRE_REPLY_CHANNEL_RANGE:
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
case WIRE_OBS_ONION_MESSAGE:
return true; return true;
case WIRE_WARNING: case WIRE_WARNING:
case WIRE_INIT: case WIRE_INIT:

View File

@ -328,12 +328,6 @@ msgtype,gossip_timestamp_filter,265,gossip_queries
msgdata,gossip_timestamp_filter,chain_hash,chain_hash, msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
msgdata,gossip_timestamp_filter,first_timestamp,u32, msgdata,gossip_timestamp_filter,first_timestamp,u32,
msgdata,gossip_timestamp_filter,timestamp_range,u32, msgdata,gossip_timestamp_filter,timestamp_range,u32,
msgtype,obs_onion_message,385,option_onion_messages
msgdata,obs_onion_message,len,u16,
msgdata,obs_onion_message,onionmsg,byte,len
msgdata,obs_onion_message,obs_onion_message_tlvs,obs_onion_message_tlvs,
tlvtype,obs_onion_message_tlvs,blinding,2
tlvdata,obs_onion_message_tlvs,blinding,blinding,point,
msgtype,onion_message,387,option_onion_messages msgtype,onion_message,387,option_onion_messages
msgdata,onion_message,blinding,point, msgdata,onion_message,blinding,point,
msgdata,onion_message,len,u16, msgdata,onion_message,len,u16,

1 msgtype,init,16
328 msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
329 msgdata,gossip_timestamp_filter,first_timestamp,u32,
330 msgdata,gossip_timestamp_filter,timestamp_range,u32,
msgtype,obs_onion_message,385,option_onion_messages
msgdata,obs_onion_message,len,u16,
msgdata,obs_onion_message,onionmsg,byte,len
msgdata,obs_onion_message,obs_onion_message_tlvs,obs_onion_message_tlvs,
tlvtype,obs_onion_message_tlvs,blinding,2
tlvdata,obs_onion_message_tlvs,blinding,blinding,point,
331 msgtype,onion_message,387,option_onion_messages
332 msgdata,onion_message,blinding,point,
333 msgdata,onion_message,len,u16,