Rename subdaemons, move them into top level.

We leave the *build* results in lightningd/ for ease of in-place testing though.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2017-08-29 13:42:04 +09:30
committed by Christian Decker
parent 739b163f8b
commit bbed5e3411
62 changed files with 330 additions and 304 deletions

14
lightningd/.gitignore vendored
View File

@@ -1,7 +1,9 @@
lightningd
lightningd_channel
lightningd_connect
lightningd_gossip
lightningd_handshake
lightningd_hsm
lightningd_opening
lightning_channeld
lightning_connectd
lightning_gossipd
lightning_handshaked
lightning_hsmd
lightning_openingd
lightning_closingd
lightning_onchaind

View File

@@ -4,11 +4,11 @@
lightningd-wrongdir:
$(MAKE) -C .. lightningd-all
LIGHTNINGD_BINS := lightningd/lightningd lightningd/lightningd_hsm lightningd/lightningd_handshake lightningd/lightningd_gossip lightningd/lightningd_opening lightningd/lightningd_channel lightningd/lightningd_closing lightningd/lightningd_onchain
LIGHTNINGD_PROGRAM := lightningd/lightningd
ALL_PROGRAMS += $(LIGHTNINGD_BINS)
ALL_PROGRAMS += $(LIGHTNINGD_PROGRAM)
lightningd-all: $(LIGHTNINGD_BINS)
lightningd-all: $(LIGHTNINGD_PROGRAM)
default: lightningd-all
@@ -76,19 +76,11 @@ LIGHTNINGD_HEADERS_NOGEN = \
LIGHTNINGD_HEADERS_GEN = \
lightningd/gen_peer_state_names.h
ALL_GEN_HEADERS += $(LIGHTNINGD_HEADERS_GEN)
# All together in one convenient var
LIGHTNINGD_HEADERS = $(LIGHTNINGD_HEADERS_NOGEN) $(LIGHTNINGD_HEADERS_GEN) $(EXTERNAL_HEADERS) $(WIRE_HEADERS) $(BITCOIN_HEADERS) $(COMMON_HEADERS) $(WALLET_LIB_HEADERS)
# These included makefiles add their headers to the LIGHTNINGD_HEADERS
# variable so the include must preceed any actual use of the variable.
include lightningd/hsm/Makefile
include lightningd/handshake/Makefile
include lightningd/gossip/Makefile
include lightningd/opening/Makefile
include lightningd/channel/Makefile
include lightningd/closing/Makefile
include lightningd/onchain/Makefile
$(LIGHTNINGD_OBJS): $(LIGHTNINGD_HEADERS)
lightningd/gen_peer_state_names.h: lightningd/peer_state.h ccan/ccan/cdump/tools/cdump-enumstr
@@ -104,11 +96,11 @@ check-makefile: check-lightningd-makefile
check-lightningd-makefile:
@for f in lightningd/*.h lightningd/*/*.h; do if ! echo $(LIGHTNINGD_HEADERS_NOGEN) $(LIGHTNINGD_HEADERS_GEN) "" | grep -q "$$f "; then echo $$f not mentioned in LIGHTNINGD_HEADERS_NOGEN or LIGHTNINGD_HEADERS_GEN >&2; exit 1; fi; done
lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(WIRE_ONION_OBJS) $(CCAN_OBJS) $(LIGHTNINGD_HSM_CONTROL_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIGHTNINGD_OPENING_CONTROL_OBJS) $(LIGHTNINGD_CHANNEL_CONTROL_OBJS) $(LIGHTNINGD_CLOSING_CONTROL_OBJS) $(LIGHTNINGD_ONCHAIN_CONTROL_OBJS) $(WALLET_LIB_OBJS)
lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(WIRE_ONION_OBJS) $(LIGHTNINGD_HSM_CONTROL_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIGHTNINGD_OPENING_CONTROL_OBJS) $(LIGHTNINGD_CHANNEL_CONTROL_OBJS) $(LIGHTNINGD_CLOSING_CONTROL_OBJS) $(LIGHTNINGD_ONCHAIN_CONTROL_OBJS) $(WALLET_LIB_OBJS)
clean: lightningd-clean
lightningd-clean:
$(RM) $(LIGHTNINGD_OBJS) $(LIGHTNINGD_JSMN_OBJS) $(LIGHTNINGD_BINS)
$(RM) $(LIGHTNINGD_OBJS) $(LIGHTNINGD_JSMN_OBJS) $(LIGHTNINGD_PROGRAM)
include lightningd/test/Makefile

View File

@@ -1,94 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/channel-wrongdir:
$(MAKE) -C ../.. lightningd/channel-all
default: lightningd/channel-all
lightningd/channel-all: lightningd/lightningd_channel
# lightningd/channel needs these:
LIGHTNINGD_CHANNEL_HEADERS_GEN := \
lightningd/channel/gen_channel_wire.h
LIGHTNINGD_CHANNEL_HEADERS_NOGEN := \
lightningd/channel/channeld_htlc.h \
lightningd/channel/commit_tx.h \
lightningd/channel/full_channel.h
LIGHTNINGD_CHANNEL_HEADERS := $(LIGHTNINGD_CHANNEL_HEADERS_GEN) $(LIGHTNINGD_CHANNEL_HEADERS_NOGEN)
LIGHTNINGD_CHANNEL_SRC := lightningd/channel/channel.c \
lightningd/channel/commit_tx.c \
lightningd/channel/full_channel.c \
$(LIGHTNINGD_CHANNEL_HEADERS_GEN:.h=.c)
LIGHTNINGD_CHANNEL_OBJS := $(LIGHTNINGD_CHANNEL_SRC:.c=.o)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_CHANNEL_OBJS)
# Common source we use.
CHANNELD_COMMON_OBJS := \
common/channel_config.o \
common/crypto_sync.o \
common/cryptomsg.o \
common/daemon_conn.o \
common/debug.o \
common/derive_basepoints.o \
common/dev_disconnect.o \
common/htlc_state.o \
common/htlc_tx.o \
common/htlc_wire.o \
common/initial_channel.o \
common/initial_commit_tx.o \
common/keyset.o \
common/key_derive.o \
common/msg_queue.o \
common/ping.o \
common/peer_failed.o \
common/permute_tx.o \
common/pseudorand.o \
common/sphinx.o \
common/status.o \
common/timeout.o \
common/type_to_string.o \
common/utils.o \
common/version.o
# Control daemon uses this:
LIGHTNINGD_CHANNEL_CONTROL_HEADERS := $(LIGHTNINGD_CHANNEL_HEADERS_GEN)
LIGHTNINGD_CHANNEL_CONTROL_SRC := $(LIGHTNINGD_CHANNEL_HEADERS_GEN:.h=.c)
LIGHTNINGD_CHANNEL_CONTROL_OBJS := $(LIGHTNINGD_CHANNEL_CONTROL_SRC:.c=.o)
LIGHTNINGD_CHANNEL_GEN_SRC := $(filter lightningd/channel/gen_%, $(LIGHTNINGD_CHANNEL_SRC) $(LIGHTNINGD_CHANNEL_CONTROL_SRC))
LIGHTNINGD_CHANNEL_SRC_NOGEN := $(filter-out lightningd/channel/gen_%, $(LIGHTNINGD_CHANNEL_SRC))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_CHANNEL_HEADERS_GEN)
LIGHTNINGD_HEADERS_NOGEN += $(LIGHTNINGD_CHANNEL_HEADERS_NOGEN)
$(LIGHTNINGD_CHANNEL_OBJS): $(LIGHTNINGD_HEADERS)
lightningd/channel/gen_channel_wire.h: $(WIRE_GEN) lightningd/channel/channel_wire.csv
$(WIRE_GEN) --header $@ channel_wire_type < lightningd/channel/channel_wire.csv > $@
lightningd/channel/gen_channel_wire.c: $(WIRE_GEN) lightningd/channel/channel_wire.csv
$(WIRE_GEN) ${@:.c=.h} channel_wire_type < lightningd/channel/channel_wire.csv > $@
LIGHTNINGD_CHANNEL_OBJS := $(LIGHTNINGD_CHANNEL_SRC:.c=.o) $(LIGHTNINGD_CHANNEL_GEN_SRC:.c=.o)
lightningd/lightningd_channel: $(LIGHTNINGD_CHANNEL_OBJS) $(WIRE_ONION_OBJS) $(CHANNELD_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS)
check-source: $(LIGHTNINGD_CHANNEL_SRC_NOGEN:%=check-src-include-order/%)
check-source-bolt: $(LIGHTNINGD_CHANNEL_SRC:%=bolt-check/%) $(LIGHTNINGD_CHANNEL_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_CHANNEL_SRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_CHANNEL_HEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/channel-clean
lightningd/channel-clean:
$(RM) $(LIGHTNINGD_CHANNEL_OBJS) gen_*
-include lightningd/channel/test/Makefile

File diff suppressed because it is too large Load Diff

View File

@@ -1,189 +0,0 @@
# Shouldn't happen
channel_bad_command,0x8000
# Also shouldn't happen
channel_hsm_failed,0x8001
channel_crypto_failed,0x8002
channel_internal_error,0x8003
channel_gossip_bad_message,0x8004
# These are due to peer.
channel_peer_write_failed,0x8010
channel_peer_read_failed,0x8011
channel_peer_bad_message,0x8012
channel_peer_bad_message,,len,u16
channel_peer_bad_message,,msg,len*u8
# Received and sent funding_locked
channel_normal_operation,1001
#include <common/cryptomsg.h>
#include <common/channel_config.h>
# Begin! (passes gossipd-client fd)
channel_init,1
channel_init,,chain_hash,struct sha256_double
channel_init,,funding_txid,struct sha256_double
channel_init,,funding_txout,2
channel_init,,funding_satoshi,8
channel_init,,our_config,struct channel_config
channel_init,,their_config,struct channel_config
channel_init,,feerate_per_kw,4
channel_init,,first_commit_sig,secp256k1_ecdsa_signature
channel_init,,crypto_state,struct crypto_state
channel_init,,remote_fundingkey,33
channel_init,,revocation_basepoint,33
channel_init,,payment_basepoint,33
channel_init,,delayed_payment_basepoint,33
channel_init,,remote_per_commit,33
channel_init,,old_remote_per_commit,33
channel_init,,funder,enum side
channel_init,,fee_base,4
channel_init,,fee_proportional,4
channel_init,,local_msatoshi,8
channel_init,,seed,struct privkey
channel_init,,local_node_id,struct pubkey
channel_init,,remote_node_id,struct pubkey
channel_init,,commit_msec,4
channel_init,,cltv_delta,u16
channel_init,,last_was_revoke,bool
channel_init,,num_last_sent_commit,u16
channel_init,,last_sent_commit,num_last_sent_commit*struct changed_htlc
channel_init,,next_index_local,u64
channel_init,,next_index_remote,u64
channel_init,,revocations_received,u64
channel_init,,next_htlc_id,u64
channel_init,,num_htlcs,u16
channel_init,,htlcs,num_htlcs*struct added_htlc
channel_init,,htlc_states,num_htlcs*enum htlc_state
channel_init,,num_fulfilled,u16
channel_init,,fulfilled,num_fulfilled*struct fulfilled_htlc
channel_init,,fulfilled_sides,num_fulfilled*enum side
channel_init,,num_failed,u16
channel_init,,failed,num_failed*struct failed_htlc
channel_init,,failed_sides,num_failed*enum side
channel_init,,local_funding_locked,bool
channel_init,,remote_funding_locked,bool
channel_init,,funding_short_id,struct short_channel_id
channel_init,,reestablish,bool
channel_init,,shutdown_scriptpubkey_len,u16
channel_init,,shutdown_scriptpubkey,shutdown_scriptpubkey_len*u8
channel_init,,remote_shutdown_received,bool
channel_init,,flags,u8
channel_init,,init_peer_pkt_len,u16
channel_init,,init_peer_pkt,init_peer_pkt_len*u8
# Tx is deep enough, go!
channel_funding_locked,2
channel_funding_locked,,short_channel_id,struct short_channel_id
# Tell the channel that we may announce the channel's existence
channel_funding_announce_depth,3
# Tell channel to offer this htlc
channel_offer_htlc,4
channel_offer_htlc,,amount_msat,8
channel_offer_htlc,,cltv_expiry,4
channel_offer_htlc,,payment_hash,32
channel_offer_htlc,,onion_routing_packet,1366*u8
# Reply; synchronous since IDs have to increment.
channel_offer_htlc_reply,104
channel_offer_htlc_reply,,id,8
# Zero failure code means success.
channel_offer_htlc_reply,,failure_code,2
channel_offer_htlc_reply,,failurestrlen,2
channel_offer_htlc_reply,,failurestr,failurestrlen*u8
# Main daemon found out the preimage for an htlc
#include <bitcoin/preimage.h>
channel_fulfill_htlc,5
channel_fulfill_htlc,,id,8
channel_fulfill_htlc,,payment_preimage,struct preimage
# Main daemon says HTLC failed
channel_fail_htlc,6
channel_fail_htlc,,id,8
# If malformed is non-zero, it's a BADONION code
channel_fail_htlc,,malformed,u16
# Otherwise, error_pkt contains failreason.
channel_fail_htlc,,len,2
channel_fail_htlc,,error_pkt,len*u8
# Ping/pong test.
channel_ping,11
channel_ping,,num_pong_bytes,u16
channel_ping,,len,u16
channel_ping_reply,111
channel_ping_reply,,totlen,u16
# Channeld tells the master that the channel has been announced
channel_announced,12
# When we receive funding_locked.
channel_got_funding_locked,19
channel_got_funding_locked,,next_per_commit_point,struct pubkey
# When we send a commitment_signed message, tell master.
channel_sending_commitsig,20
channel_sending_commitsig,,commitnum,u64
# SENT_ADD_COMMIT, SENT_REMOVE_ACK_COMMIT, SENT_ADD_ACK_COMMIT, SENT_REMOVE_COMMIT
channel_sending_commitsig,,num_changed,u16
channel_sending_commitsig,,changed,num_changed*struct changed_htlc
channel_sending_commitsig,,commit_sig,secp256k1_ecdsa_signature
channel_sending_commitsig,,num_htlc_sigs,u16
channel_sending_commitsig,,htlc_sigs,num_htlc_sigs*secp256k1_ecdsa_signature
# Wait for reply, to make sure it's on disk before we send commit.
channel_sending_commitsig_reply,120
# When we have a commitment_signed message, tell master to remember.
channel_got_commitsig,21
channel_got_commitsig,,commitnum,u64
channel_got_commitsig,,signature,secp256k1_ecdsa_signature
channel_got_commitsig,,num_htlcs,u16
channel_got_commitsig,,htlc_signature,num_htlcs*secp256k1_ecdsa_signature
# RCVD_ADD_COMMIT: we're now committed to their new offered HTLCs.
channel_got_commitsig,,num_added,u16
channel_got_commitsig,,added,num_added*struct added_htlc
channel_got_commitsig,,shared_secret,num_added*struct secret
# RCVD_REMOVE_COMMIT: we're now no longer committed to these HTLCs.
channel_got_commitsig,,num_fulfilled,u16
channel_got_commitsig,,fulfilled,num_fulfilled*struct fulfilled_htlc
channel_got_commitsig,,num_failed,u16
channel_got_commitsig,,failed,num_failed*struct failed_htlc
# RCVD_ADD_ACK_COMMIT, RCVD_REMOVE_ACK_COMMIT
channel_got_commitsig,,num_changed,u16
channel_got_commitsig,,changed,num_changed*struct changed_htlc
channel_got_commitsig,,tx,struct bitcoin_tx
# Wait for reply, to make sure it's on disk before we send revocation.
channel_got_commitsig_reply,121
#include <common/htlc_wire.h>
channel_got_revoke,22
channel_got_revoke,,revokenum,u64
channel_got_revoke,,per_commitment_secret,struct sha256
channel_got_revoke,,next_per_commit_point,struct pubkey
# RCVD_ADD_ACK_REVOCATION, RCVD_REMOVE_ACK_REVOCATION, RCVD_ADD_REVOCATION, RCVD_REMOVE_REVOCATION
channel_got_revoke,,num_changed,u16
channel_got_revoke,,changed,num_changed*struct changed_htlc
# Wait for reply, to make sure it's on disk before we continue
# (eg. if we sent another commitment_signed, that would implicitly ack).
channel_got_revoke_reply,122
# Tell peer that channel is shutting down
channel_send_shutdown,23
channel_send_shutdown,,scriptpubkey_len,u16
channel_send_shutdown,,scriptpubkey,scriptpubkey_len*u8
# Peer told us that channel is shutting down
channel_got_shutdown,24
channel_got_shutdown,,scriptpubkey_len,u16
channel_got_shutdown,,scriptpubkey,scriptpubkey_len*u8
# Shutdown is complete, ready for closing negotiation. + peer_fd & gossip_fd.
channel_shutdown_complete,25
channel_shutdown_complete,,crypto_state,struct crypto_state
1 # Shouldn't happen
2 channel_bad_command,0x8000
3 # Also shouldn't happen
4 channel_hsm_failed,0x8001
5 channel_crypto_failed,0x8002
6 channel_internal_error,0x8003
7 channel_gossip_bad_message,0x8004
8 # These are due to peer.
9 channel_peer_write_failed,0x8010
10 channel_peer_read_failed,0x8011
11 channel_peer_bad_message,0x8012
12 channel_peer_bad_message,,len,u16
13 channel_peer_bad_message,,msg,len*u8
14 # Received and sent funding_locked
15 channel_normal_operation,1001
16 #include <common/cryptomsg.h>
17 #include <common/channel_config.h>
18 # Begin! (passes gossipd-client fd)
19 channel_init,1
20 channel_init,,chain_hash,struct sha256_double
21 channel_init,,funding_txid,struct sha256_double
22 channel_init,,funding_txout,2
23 channel_init,,funding_satoshi,8
24 channel_init,,our_config,struct channel_config
25 channel_init,,their_config,struct channel_config
26 channel_init,,feerate_per_kw,4
27 channel_init,,first_commit_sig,secp256k1_ecdsa_signature
28 channel_init,,crypto_state,struct crypto_state
29 channel_init,,remote_fundingkey,33
30 channel_init,,revocation_basepoint,33
31 channel_init,,payment_basepoint,33
32 channel_init,,delayed_payment_basepoint,33
33 channel_init,,remote_per_commit,33
34 channel_init,,old_remote_per_commit,33
35 channel_init,,funder,enum side
36 channel_init,,fee_base,4
37 channel_init,,fee_proportional,4
38 channel_init,,local_msatoshi,8
39 channel_init,,seed,struct privkey
40 channel_init,,local_node_id,struct pubkey
41 channel_init,,remote_node_id,struct pubkey
42 channel_init,,commit_msec,4
43 channel_init,,cltv_delta,u16
44 channel_init,,last_was_revoke,bool
45 channel_init,,num_last_sent_commit,u16
46 channel_init,,last_sent_commit,num_last_sent_commit*struct changed_htlc
47 channel_init,,next_index_local,u64
48 channel_init,,next_index_remote,u64
49 channel_init,,revocations_received,u64
50 channel_init,,next_htlc_id,u64
51 channel_init,,num_htlcs,u16
52 channel_init,,htlcs,num_htlcs*struct added_htlc
53 channel_init,,htlc_states,num_htlcs*enum htlc_state
54 channel_init,,num_fulfilled,u16
55 channel_init,,fulfilled,num_fulfilled*struct fulfilled_htlc
56 channel_init,,fulfilled_sides,num_fulfilled*enum side
57 channel_init,,num_failed,u16
58 channel_init,,failed,num_failed*struct failed_htlc
59 channel_init,,failed_sides,num_failed*enum side
60 channel_init,,local_funding_locked,bool
61 channel_init,,remote_funding_locked,bool
62 channel_init,,funding_short_id,struct short_channel_id
63 channel_init,,reestablish,bool
64 channel_init,,shutdown_scriptpubkey_len,u16
65 channel_init,,shutdown_scriptpubkey,shutdown_scriptpubkey_len*u8
66 channel_init,,remote_shutdown_received,bool
67 channel_init,,flags,u8
68 channel_init,,init_peer_pkt_len,u16
69 channel_init,,init_peer_pkt,init_peer_pkt_len*u8
70 # Tx is deep enough, go!
71 channel_funding_locked,2
72 channel_funding_locked,,short_channel_id,struct short_channel_id
73 # Tell the channel that we may announce the channel's existence
74 channel_funding_announce_depth,3
75 # Tell channel to offer this htlc
76 channel_offer_htlc,4
77 channel_offer_htlc,,amount_msat,8
78 channel_offer_htlc,,cltv_expiry,4
79 channel_offer_htlc,,payment_hash,32
80 channel_offer_htlc,,onion_routing_packet,1366*u8
81 # Reply; synchronous since IDs have to increment.
82 channel_offer_htlc_reply,104
83 channel_offer_htlc_reply,,id,8
84 # Zero failure code means success.
85 channel_offer_htlc_reply,,failure_code,2
86 channel_offer_htlc_reply,,failurestrlen,2
87 channel_offer_htlc_reply,,failurestr,failurestrlen*u8
88 # Main daemon found out the preimage for an htlc
89 #include <bitcoin/preimage.h>
90 channel_fulfill_htlc,5
91 channel_fulfill_htlc,,id,8
92 channel_fulfill_htlc,,payment_preimage,struct preimage
93 # Main daemon says HTLC failed
94 channel_fail_htlc,6
95 channel_fail_htlc,,id,8
96 # If malformed is non-zero, it's a BADONION code
97 channel_fail_htlc,,malformed,u16
98 # Otherwise, error_pkt contains failreason.
99 channel_fail_htlc,,len,2
100 channel_fail_htlc,,error_pkt,len*u8
101 # Ping/pong test.
102 channel_ping,11
103 channel_ping,,num_pong_bytes,u16
104 channel_ping,,len,u16
105 channel_ping_reply,111
106 channel_ping_reply,,totlen,u16
107 # Channeld tells the master that the channel has been announced
108 channel_announced,12
109 # When we receive funding_locked.
110 channel_got_funding_locked,19
111 channel_got_funding_locked,,next_per_commit_point,struct pubkey
112 # When we send a commitment_signed message, tell master.
113 channel_sending_commitsig,20
114 channel_sending_commitsig,,commitnum,u64
115 # SENT_ADD_COMMIT, SENT_REMOVE_ACK_COMMIT, SENT_ADD_ACK_COMMIT, SENT_REMOVE_COMMIT
116 channel_sending_commitsig,,num_changed,u16
117 channel_sending_commitsig,,changed,num_changed*struct changed_htlc
118 channel_sending_commitsig,,commit_sig,secp256k1_ecdsa_signature
119 channel_sending_commitsig,,num_htlc_sigs,u16
120 channel_sending_commitsig,,htlc_sigs,num_htlc_sigs*secp256k1_ecdsa_signature
121 # Wait for reply, to make sure it's on disk before we send commit.
122 channel_sending_commitsig_reply,120
123 # When we have a commitment_signed message, tell master to remember.
124 channel_got_commitsig,21
125 channel_got_commitsig,,commitnum,u64
126 channel_got_commitsig,,signature,secp256k1_ecdsa_signature
127 channel_got_commitsig,,num_htlcs,u16
128 channel_got_commitsig,,htlc_signature,num_htlcs*secp256k1_ecdsa_signature
129 # RCVD_ADD_COMMIT: we're now committed to their new offered HTLCs.
130 channel_got_commitsig,,num_added,u16
131 channel_got_commitsig,,added,num_added*struct added_htlc
132 channel_got_commitsig,,shared_secret,num_added*struct secret
133 # RCVD_REMOVE_COMMIT: we're now no longer committed to these HTLCs.
134 channel_got_commitsig,,num_fulfilled,u16
135 channel_got_commitsig,,fulfilled,num_fulfilled*struct fulfilled_htlc
136 channel_got_commitsig,,num_failed,u16
137 channel_got_commitsig,,failed,num_failed*struct failed_htlc
138 # RCVD_ADD_ACK_COMMIT, RCVD_REMOVE_ACK_COMMIT
139 channel_got_commitsig,,num_changed,u16
140 channel_got_commitsig,,changed,num_changed*struct changed_htlc
141 channel_got_commitsig,,tx,struct bitcoin_tx
142 # Wait for reply, to make sure it's on disk before we send revocation.
143 channel_got_commitsig_reply,121
144 #include <common/htlc_wire.h>
145 channel_got_revoke,22
146 channel_got_revoke,,revokenum,u64
147 channel_got_revoke,,per_commitment_secret,struct sha256
148 channel_got_revoke,,next_per_commit_point,struct pubkey
149 # RCVD_ADD_ACK_REVOCATION, RCVD_REMOVE_ACK_REVOCATION, RCVD_ADD_REVOCATION, RCVD_REMOVE_REVOCATION
150 channel_got_revoke,,num_changed,u16
151 channel_got_revoke,,changed,num_changed*struct changed_htlc
152 # Wait for reply, to make sure it's on disk before we continue
153 # (eg. if we sent another commitment_signed, that would implicitly ack).
154 channel_got_revoke_reply,122
155 # Tell peer that channel is shutting down
156 channel_send_shutdown,23
157 channel_send_shutdown,,scriptpubkey_len,u16
158 channel_send_shutdown,,scriptpubkey,scriptpubkey_len*u8
159 # Peer told us that channel is shutting down
160 channel_got_shutdown,24
161 channel_got_shutdown,,scriptpubkey_len,u16
162 channel_got_shutdown,,scriptpubkey,scriptpubkey_len*u8
163 # Shutdown is complete, ready for closing negotiation. + peer_fd & gossip_fd.
164 channel_shutdown_complete,25
165 channel_shutdown_complete,,crypto_state,struct crypto_state

View File

@@ -1,79 +0,0 @@
#ifndef LIGHTNING_LIGHTNINGD_CHANNEL_CHANNELD_HTLC_H
#define LIGHTNING_LIGHTNINGD_CHANNEL_CHANNELD_HTLC_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <common/pseudorand.h>
#include <wire/gen_onion_wire.h>
struct htlc {
/* What's the status. */
enum htlc_state state;
/* The unique ID for this peer and this direction (LOCAL or REMOTE) */
u64 id;
/* The amount in millisatoshi. */
u64 msatoshi;
/* When the HTLC can no longer be redeemed. */
struct abs_locktime expiry;
/* The hash of the preimage which can redeem this HTLC */
struct sha256 rhash;
/* The preimage which hashes to rhash (if known) */
struct preimage *r;
/* FIXME: We could union these together: */
/* Routing information sent with this HTLC. */
const u8 *routing;
const u8 *fail;
enum onion_type malformed;
};
static inline bool htlc_has(const struct htlc *h, int flag)
{
return htlc_state_flags(h->state) & flag;
}
static inline enum side htlc_owner(const struct htlc *h)
{
return htlc_state_owner(h->state);
}
/* htlc_map: ID -> htlc mapping. */
static inline u64 htlc_key(const struct htlc *h)
{
return h->id;
}
static inline bool htlc_cmp(const struct htlc *h, u64 id)
{
return h->id == id;
}
static inline size_t htlc_hash(u64 id)
{
return siphash24(siphash_seed(), &id, sizeof(id));
}
HTABLE_DEFINE_TYPE(struct htlc, htlc_key, htlc_hash, htlc_cmp, htlc_map);
static inline struct htlc *htlc_get(struct htlc_map *htlcs, u64 id, enum side owner)
{
struct htlc *h;
struct htlc_map_iter it;
for (h = htlc_map_getfirst(htlcs, id, &it);
h;
h = htlc_map_getnext(htlcs, id, &it)) {
if (h->id == id && htlc_has(h, HTLC_FLAG(owner,HTLC_F_OWNER)))
return h;
}
return NULL;
}
static inline size_t htlc_map_count(const struct htlc_map *htlcs)
{
return htlcs->raw.elems;
}
/* FIXME: Move these out of the hash! */
static inline bool htlc_is_dead(const struct htlc *htlc)
{
return htlc->state == RCVD_REMOVE_ACK_REVOCATION
|| htlc->state == SENT_REMOVE_ACK_REVOCATION;
}
#endif /* LIGHTNING_LIGHTNINGD_CHANNEL_CHANNELD_HTLC_H */

View File

@@ -1,292 +0,0 @@
#include <bitcoin/script.h>
#include <bitcoin/tx.h>
#include <ccan/endian/endian.h>
#include <common/htlc_tx.h>
#include <common/keyset.h>
#include <common/permute_tx.h>
#include <common/utils.h>
#include <lightningd/channel/commit_tx.h>
#ifndef SUPERVERBOSE
#define SUPERVERBOSE(...)
#endif
static bool trim(const struct htlc *htlc,
u64 feerate_per_kw, u64 dust_limit_satoshis,
enum side side)
{
u64 htlc_fee;
/* BOLT #3:
*
* For every offered HTLC, if the HTLC amount minus the HTLC-timeout
* fee would be less than `dust_limit_satoshis` set by the transaction
* owner, the commitment transaction MUST NOT contain that output,
* otherwise it MUST be generated as specified in [Offered HTLC
* Outputs](#offered-htlc-outputs).
*/
if (htlc_owner(htlc) == side)
htlc_fee = htlc_timeout_fee(feerate_per_kw);
/* BOLT #3:
*
* For every received HTLC, if the HTLC amount minus the HTLC-success
* fee would be less than `dust_limit_satoshis` set by the transaction
* owner, the commitment transaction MUST NOT contain that output,
* otherwise it MUST be generated as specified in [Received HTLC
* Outputs](#received-htlc-outputs).
*/
else
htlc_fee = htlc_success_fee(feerate_per_kw);
return htlc->msatoshi / 1000 < dust_limit_satoshis + htlc_fee;
}
size_t commit_tx_num_untrimmed(const struct htlc **htlcs,
u64 feerate_per_kw, u64 dust_limit_satoshis,
enum side side)
{
size_t i, n;
for (i = n = 0; i < tal_count(htlcs); i++)
n += !trim(htlcs[i], feerate_per_kw, dust_limit_satoshis, side);
return n;
}
static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
const struct htlc *htlc,
const struct keyset *keyset)
{
struct ripemd160 ripemd;
u8 *wscript;
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_offered_wscript(tx->output, &ripemd, keyset);
tx->output[n].amount = htlc->msatoshi / 1000;
tx->output[n].script = scriptpubkey_p2wsh(tx, wscript);
SUPERVERBOSE("# HTLC %"PRIu64" offered amount %"PRIu64" wscript %s\n",
htlc->id, tx->output[n].amount, tal_hex(wscript, wscript));
tal_free(wscript);
}
static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
const struct htlc *htlc,
const struct keyset *keyset)
{
struct ripemd160 ripemd;
u8 *wscript;
ripemd160(&ripemd, htlc->rhash.u.u8, sizeof(htlc->rhash.u.u8));
wscript = htlc_received_wscript(tx, &ripemd, &htlc->expiry, keyset);
tx->output[n].amount = htlc->msatoshi / 1000;
tx->output[n].script = scriptpubkey_p2wsh(tx->output, wscript);
SUPERVERBOSE("# HTLC %"PRIu64" received amount %"PRIu64" wscript %s\n",
htlc->id, tx->output[n].amount, tal_hex(wscript, wscript));
tal_free(wscript);
}
struct bitcoin_tx *commit_tx(const tal_t *ctx,
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshis,
enum side funder,
u16 to_self_delay,
const struct keyset *keyset,
u64 feerate_per_kw,
u64 dust_limit_satoshis,
u64 self_pay_msat,
u64 other_pay_msat,
const struct htlc **htlcs,
const struct htlc ***htlcmap,
u64 obscured_commitment_number,
enum side side)
{
const tal_t *tmpctx = tal_tmpctx(ctx);
u64 base_fee_msat;
struct bitcoin_tx *tx;
size_t i, n, untrimmed;
assert(self_pay_msat + other_pay_msat <= funding_satoshis * 1000);
/* BOLT #3:
*
* 1. Calculate which committed HTLCs need to be trimmed (see
* [Trimmed Outputs](#trimmed-outputs)).
*/
untrimmed = commit_tx_num_untrimmed(htlcs,
feerate_per_kw,
dust_limit_satoshis, side);
/* BOLT #3:
*
* 2. Calculate the base [commitment transaction
* fee](#fee-calculation).
*/
base_fee_msat = commit_tx_base_fee(feerate_per_kw, untrimmed) * 1000;
SUPERVERBOSE("# base commitment transaction fee = %"PRIu64"\n",
base_fee_msat / 1000);
/* BOLT #3:
*
* 3. Subtract this base fee from the funder (either `to_local` or
* `to_remote`), with a floor of zero (see [Fee Payment](#fee-payment)).
*/
try_subtract_fee(funder, side, base_fee_msat,
&self_pay_msat, &other_pay_msat);
#ifdef PRINT_ACTUAL_FEE
{
u64 satoshis_out = 0;
for (i = n = 0; i < tal_count(htlcs); i++) {
if (!trim(htlcs[i], feerate_per_kw, dust_limit_satoshis,
side))
satoshis_out += htlcs[i]->msatoshi / 1000;
}
if (self_pay_msat / 1000 >= dust_limit_satoshis)
satoshis_out += self_pay_msat / 1000;
if (other_pay_msat / 1000 >= dust_limit_satoshis)
satoshis_out += other_pay_msat / 1000;
SUPERVERBOSE("# actual commitment transaction fee = %"PRIu64"\n",
funding_satoshis - satoshis_out);
}
#endif
/* Worst-case sizing: both to-local and to-remote outputs. */
tx = bitcoin_tx(ctx, 1, untrimmed + 2);
/* We keep track of which outputs have which HTLCs */
if (htlcmap)
*htlcmap = tal_arr(tx, const struct htlc *,
tal_count(tx->output));
/* This could be done in a single loop, but we follow the BOLT
* literally to make comments in test vectors clearer. */
n = 0;
/* BOLT #3:
*
* 3. For every offered HTLC, if it is not trimmed, add an
* [offered HTLC output](#offered-htlc-outputs).
*/
for (i = 0; i < tal_count(htlcs); i++) {
if (htlc_owner(htlcs[i]) != side)
continue;
if (trim(htlcs[i], feerate_per_kw, dust_limit_satoshis, side))
continue;
add_offered_htlc_out(tx, n, htlcs[i], keyset);
if (htlcmap)
(*htlcmap)[n++] = htlcs[i];
}
/* BOLT #3:
*
* 4. For every received HTLC, if it is not trimmed, add an
* [received HTLC output](#received-htlc-outputs).
*/
for (i = 0; i < tal_count(htlcs); i++) {
if (htlc_owner(htlcs[i]) == side)
continue;
if (trim(htlcs[i], feerate_per_kw, dust_limit_satoshis, side))
continue;
add_received_htlc_out(tx, n, htlcs[i], keyset);
if (htlcmap)
(*htlcmap)[n++] = htlcs[i];
}
/* BOLT #3:
*
* 5. If the `to_local` amount is greater or equal to
* `dust_limit_satoshis`, add a [`to_local`
* Output](#to-local-output).
*/
if (self_pay_msat / 1000 >= dust_limit_satoshis) {
u8 *wscript = to_self_wscript(tmpctx, to_self_delay,keyset);
tx->output[n].amount = self_pay_msat / 1000;
tx->output[n].script = scriptpubkey_p2wsh(tx, wscript);
if (htlcmap)
(*htlcmap)[n] = NULL;
SUPERVERBOSE("# to-local amount %"PRIu64" wscript %s\n",
tx->output[n].amount,
tal_hex(tmpctx, wscript));
n++;
}
/* BOLT #3:
*
* 6. If the `to_remote` amount is greater or equal to
* `dust_limit_satoshis`, add a [`to_remote`
* Output](#to-remote-output).
*/
if (other_pay_msat / 1000 >= dust_limit_satoshis) {
/* BOLT #3:
*
* #### `to_remote` Output
*
* This output sends funds to the other peer, thus is a simple
* P2WPKH to `remotekey`.
*/
tx->output[n].amount = other_pay_msat / 1000;
tx->output[n].script = scriptpubkey_p2wpkh(tx,
&keyset->other_payment_key);
if (htlcmap)
(*htlcmap)[n] = NULL;
SUPERVERBOSE("# to-remote amount %"PRIu64" P2WPKH(%s)\n",
tx->output[n].amount,
type_to_string(tmpctx, struct pubkey,
&keyset->other_payment_key));
n++;
}
assert(n <= tal_count(tx->output));
tal_resize(&tx->output, n);
if (htlcmap)
tal_resize(htlcmap, n);
/* BOLT #3:
*
* 7. Sort the outputs into [BIP 69
* order](#transaction-input-and-output-ordering)
*/
permute_outputs(tx->output, tal_count(tx->output),
htlcmap ? (const void **)*htlcmap : NULL);
/* BOLT #3:
*
* ## Commitment Transaction
*
* * version: 2
*/
assert(tx->version == 2);
/* BOLT #3:
*
* * locktime: upper 8 bits are 0x20, lower 24 bits are the lower
* 24 bits of the obscured commitment transaction number.
*/
tx->lock_time
= (0x20000000 | (obscured_commitment_number & 0xFFFFFF));
/* BOLT #3:
*
* * txin count: 1
* * `txin[0]` outpoint: `txid` and `output_index` from
* `funding_created` message
*/
tx->input[0].txid = *funding_txid;
tx->input[0].index = funding_txout;
/* BOLT #3:
*
* * `txin[0]` sequence: upper 8 bits are 0x80, lower 24 bits are
* upper 24 bits of the obscured commitment transaction number.
*/
tx->input[0].sequence_number
= (0x80000000 | ((obscured_commitment_number>>24) & 0xFFFFFF));
/* Input amount needed for signature code. */
tx->input[0].amount = tal_dup(tx->input, u64, &funding_satoshis);
tal_free(tmpctx);
return tx;
}

View File

@@ -1,61 +0,0 @@
#ifndef LIGHTNING_LIGHTNINGD_CHANNEL_COMMIT_TX_H
#define LIGHTNING_LIGHTNINGD_CHANNEL_COMMIT_TX_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <common/htlc.h>
#include <common/initial_commit_tx.h>
#include <lightningd/channel/channeld_htlc.h>
struct keyset;
struct sha256_double;
/**
* commit_tx_num_untrimmed: how many of these htlc outputs will commit tx have?
* @htlcs: tal_arr of HTLCs
* @feerate_per_kw: feerate to use
* @dust_limit_satoshis: dust limit below which to trim outputs.
* @side: from which side's point of view
*
* We need @side because HTLC fees are different for offered and
* received HTLCs.
*/
size_t commit_tx_num_untrimmed(const struct htlc **htlcs,
u64 feerate_per_kw, u64 dust_limit_satoshis,
enum side side);
/**
* commit_tx: create (unsigned) commitment tx to spend the funding tx output
* @ctx: context to allocate transaction and @htlc_map from.
* @funding_txid, @funding_out, @funding_satoshis: funding outpoint.
* @funder: is the LOCAL or REMOTE paying the fee?
* @keyset: keys derived for this commit tx.
* @feerate_per_kw: feerate to use
* @dust_limit_satoshis: dust limit below which to trim outputs.
* @self_pay_msat: amount to pay directly to self
* @other_pay_msat: amount to pay directly to the other side
* @htlcs: tal_arr of htlcs committed by transaction (some may be trimmed)
* @htlc_map: outputed map of outnum->HTLC (NULL for direct outputs), or NULL.
* @obscured_commitment_number: number to encode in commitment transaction
* @side: side to generate commitment transaction for.
*
* We need to be able to generate the remote side's tx to create signatures,
* but the BOLT is expressed in terms of generating our local commitment
* transaction, so we carefully use the terms "self" and "other" here.
*/
struct bitcoin_tx *commit_tx(const tal_t *ctx,
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshis,
enum side funder,
u16 to_self_delay,
const struct keyset *keyset,
u64 feerate_per_kw,
u64 dust_limit_satoshis,
u64 self_pay_msat,
u64 other_pay_msat,
const struct htlc **htlcs,
const struct htlc ***htlcmap,
u64 obscured_commitment_number,
enum side side);
#endif /* LIGHTNING_LIGHTNINGD_CHANNEL_COMMIT_TX_H */

View File

@@ -1,932 +0,0 @@
#include <assert.h>
#include <bitcoin/preimage.h>
#include <bitcoin/script.h>
#include <bitcoin/tx.h>
#include <ccan/array_size/array_size.h>
#include <ccan/mem/mem.h>
#include <ccan/structeq/structeq.h>
#include <ccan/tal/str/str.h>
#include <common/channel_config.h>
#include <common/htlc.h>
#include <common/htlc_tx.h>
#include <common/htlc_wire.h>
#include <common/key_derive.h>
#include <common/keyset.h>
#include <common/status.h>
#include <common/type_to_string.h>
#include <inttypes.h>
#include <lightningd/channel/commit_tx.h>
#include <lightningd/channel/full_channel.h>
#include <string.h>
struct channel *new_channel(const tal_t *ctx,
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshis,
u64 local_msatoshi,
u32 feerate_per_kw,
const struct channel_config *local,
const struct channel_config *remote,
const struct basepoints *local_basepoints,
const struct basepoints *remote_basepoints,
const struct pubkey *local_funding_pubkey,
const struct pubkey *remote_funding_pubkey,
enum side funder)
{
struct channel *channel = new_initial_channel(ctx, funding_txid,
funding_txout,
funding_satoshis,
local_msatoshi,
feerate_per_kw,
local, remote,
local_basepoints,
remote_basepoints,
local_funding_pubkey,
remote_funding_pubkey,
funder);
if (channel) {
channel->htlcs = tal(channel, struct htlc_map);
htlc_map_init(channel->htlcs);
tal_add_destructor(channel->htlcs, htlc_map_clear);
}
return channel;
}
static void htlc_arr_append(const struct htlc ***arr, const struct htlc *htlc)
{
size_t n;
if (!arr)
return;
n = tal_count(*arr);
tal_resize(arr, n+1);
(*arr)[n] = htlc;
}
/* What does adding the HTLC do to the balance for this side */
static s64 balance_adding_htlc(const struct htlc *htlc, enum side side)
{
if (htlc_owner(htlc) == side)
return -htlc->msatoshi;
return 0;
}
/* What does removing the HTLC do to the balance for this side */
static s64 balance_removing_htlc(const struct htlc *htlc, enum side side)
{
enum side paid_to;
/* Fulfilled HTLCs are paid to recipient, otherwise returns to owner */
if (htlc->r)
paid_to = !htlc_owner(htlc);
else
paid_to = htlc_owner(htlc);
if (side == paid_to)
return htlc->msatoshi;
return 0;
}
static void dump_htlc(const struct htlc *htlc, const char *prefix)
{
enum htlc_state remote_state;
if (htlc->state <= RCVD_REMOVE_ACK_REVOCATION)
remote_state = htlc->state + 10;
else
remote_state = htlc->state - 10;
status_trace("%s: HTLC %s %"PRIu64" = %s/%s %s",
prefix,
htlc_owner(htlc) == LOCAL ? "LOCAL" : "REMOTE",
htlc->id,
htlc_state_name(htlc->state),
htlc_state_name(remote_state),
htlc->r ? "FULFILLED" : htlc->fail ? "FAILED" :
htlc->malformed ? "MALFORMED" : "");
}
void dump_htlcs(const struct channel *channel, const char *prefix)
{
struct htlc_map_iter it;
const struct htlc *htlc;
for (htlc = htlc_map_first(channel->htlcs, &it);
htlc;
htlc = htlc_map_next(channel->htlcs, &it)) {
dump_htlc(htlc, prefix);
}
}
/* Returns up to three arrays:
* committed: HTLCs currently committed.
* pending_removal: HTLCs pending removal (subset of committed)
* pending_addition: HTLCs pending addition (no overlap with committed)
*/
static void gather_htlcs(const tal_t *ctx,
const struct channel *channel,
enum side side,
const struct htlc ***committed,
const struct htlc ***pending_removal,
const struct htlc ***pending_addition)
{
struct htlc_map_iter it;
const struct htlc *htlc;
const int committed_flag = HTLC_FLAG(side, HTLC_F_COMMITTED);
const int pending_flag = HTLC_FLAG(side, HTLC_F_PENDING);
*committed = tal_arr(ctx, const struct htlc *, 0);
if (pending_removal)
*pending_removal = tal_arr(ctx, const struct htlc *, 0);
if (pending_addition)
*pending_addition = tal_arr(ctx, const struct htlc *, 0);
if (!channel->htlcs)
return;
for (htlc = htlc_map_first(channel->htlcs, &it);
htlc;
htlc = htlc_map_next(channel->htlcs, &it)) {
if (htlc_has(htlc, committed_flag)) {
htlc_arr_append(committed, htlc);
if (htlc_has(htlc, pending_flag))
htlc_arr_append(pending_removal, htlc);
} else if (htlc_has(htlc, pending_flag))
htlc_arr_append(pending_addition, htlc);
}
}
static u64 total_offered_msatoshis(const struct htlc **htlcs, enum side side)
{
size_t i;
u64 total = 0;
for (i = 0; i < tal_count(htlcs); i++) {
if (htlc_owner(htlcs[i]) == side)
total += htlcs[i]->msatoshi;
}
return total;
}
static void add_htlcs(struct bitcoin_tx ***txs,
const u8 ***wscripts,
const struct htlc **htlcmap,
const struct channel *channel,
const struct keyset *keyset,
enum side side)
{
size_t i, n;
struct sha256_double txid;
u32 feerate_per_kw = channel->view[side].feerate_per_kw;
/* Get txid of commitment transaction */
bitcoin_txid((*txs)[0], &txid);
for (i = 0; i < tal_count(htlcmap); i++) {
const struct htlc *htlc = htlcmap[i];
struct bitcoin_tx *tx;
u8 *wscript;
if (!htlc)
continue;
if (htlc_owner(htlc) == side) {
tx = htlc_timeout_tx(*txs, &txid, i,
htlc->msatoshi,
htlc->expiry.locktime,
to_self_delay(channel, side),
feerate_per_kw,
keyset);
wscript = bitcoin_wscript_htlc_offer(*wscripts,
&keyset->self_payment_key,
&keyset->other_payment_key,
&htlc->rhash,
&keyset->self_revocation_key);
} else {
tx = htlc_success_tx(*txs, &txid, i,
htlc->msatoshi,
to_self_delay(channel, side),
feerate_per_kw,
keyset);
wscript = bitcoin_wscript_htlc_receive(*wscripts,
&htlc->expiry,
&keyset->self_payment_key,
&keyset->other_payment_key,
&htlc->rhash,
&keyset->self_revocation_key);
}
/* Append to array. */
n = tal_count(*txs);
assert(n == tal_count(*wscripts));
tal_resize(wscripts, n+1);
tal_resize(txs, n+1);
(*wscripts)[n] = wscript;
(*txs)[n] = tx;
}
}
/* FIXME: We could cache these. */
struct bitcoin_tx **channel_txs(const tal_t *ctx,
const struct htlc ***htlcmap,
const u8 ***wscripts,
const struct channel *channel,
const struct pubkey *per_commitment_point,
u64 commitment_number,
enum side side)
{
struct bitcoin_tx **txs;
const struct htlc **committed;
struct keyset keyset;
if (!derive_keyset(per_commitment_point,
&channel->basepoints[side].payment,
&channel->basepoints[!side].payment,
&channel->basepoints[side].delayed_payment,
&channel->basepoints[!side].revocation,
&keyset))
return NULL;
/* Figure out what @side will already be committed to. */
gather_htlcs(ctx, channel, side, &committed, NULL, NULL);
/* NULL map only allowed at beginning, when we know no HTLCs */
if (!htlcmap)
assert(tal_count(committed) == 0);
txs = tal_arr(ctx, struct bitcoin_tx *, 1);
txs[0] = commit_tx(ctx, &channel->funding_txid,
channel->funding_txout,
channel->funding_msat / 1000,
channel->funder,
to_self_delay(channel, side),
&keyset,
channel->view[side].feerate_per_kw,
dust_limit_satoshis(channel, side),
channel->view[side].owed_msat[side],
channel->view[side].owed_msat[!side],
committed,
htlcmap,
commitment_number ^ channel->commitment_number_obscurer,
side);
*wscripts = tal_arr(ctx, const u8 *, 1);
(*wscripts)[0] = bitcoin_redeem_2of2(*wscripts,
&channel->funding_pubkey[side],
&channel->funding_pubkey[!side]);
if (htlcmap)
add_htlcs(&txs, wscripts, *htlcmap, channel, &keyset, side);
tal_free(committed);
return txs;
}
static enum channel_add_err add_htlc(struct channel *channel,
enum side sender,
u64 id, u64 msatoshi, u32 cltv_expiry,
const struct sha256 *payment_hash,
const u8 routing[TOTAL_PACKET_SIZE],
struct htlc **htlcp,
bool enforce_aggregate_limits)
{
const tal_t *tmpctx = tal_tmpctx(channel);
struct htlc *htlc, *old;
s64 msat_in_htlcs, fee_msat, balance_msat;
enum side recipient = !sender;
const struct htlc **committed, **adding, **removing;
enum channel_add_err e;
const struct channel_view *view;
size_t i;
htlc = tal(tmpctx, struct htlc);
if (sender == LOCAL)
htlc->state = SENT_ADD_HTLC;
else
htlc->state = RCVD_ADD_HTLC;
htlc->id = id;
htlc->msatoshi = msatoshi;
/* FIXME: Change expiry to simple u32 */
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if a sending node... sets
* `cltv_expiry` to greater or equal to 500000000.
*/
if (!blocks_to_abs_locktime(cltv_expiry, &htlc->expiry)) {
e = CHANNEL_ERR_INVALID_EXPIRY;
goto out;
}
htlc->rhash = *payment_hash;
htlc->fail = NULL;
htlc->malformed = 0;
htlc->r = NULL;
htlc->routing = tal_dup_arr(htlc, u8, routing, TOTAL_PACKET_SIZE, 0);
old = htlc_get(channel->htlcs, htlc->id, htlc_owner(htlc));
if (old) {
if (old->state != htlc->state
|| old->msatoshi != htlc->msatoshi
|| old->expiry.locktime != htlc->expiry.locktime
|| !structeq(&old->rhash, &htlc->rhash))
e = CHANNEL_ERR_DUPLICATE_ID_DIFFERENT;
else
e = CHANNEL_ERR_DUPLICATE;
goto out;
}
/* We're always considering the recipient's view of the channel here */
view = &channel->view[recipient];
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if it receives an
* `amount_msat` equal to zero, below its own `htlc_minimum_msat`,
* or...
*/
if (htlc->msatoshi == 0) {
e = CHANNEL_ERR_HTLC_BELOW_MINIMUM;
goto out;
}
if (htlc->msatoshi < htlc_minimum_msat(channel, recipient)) {
e = CHANNEL_ERR_HTLC_BELOW_MINIMUM;
goto out;
}
/* BOLT #2:
*
* For channels with `chain_hash` identifying the Bitcoin blockchain,
* the sending node MUST set the 4 most significant bytes of
* `amount_msat` to zero.
*/
if (htlc->msatoshi & 0xFFFFFFFF00000000ULL) {
e = CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
goto out;
}
/* Figure out what receiver will already be committed to. */
gather_htlcs(tmpctx, channel, recipient, &committed, &removing, &adding);
htlc_arr_append(&adding, htlc);
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if a sending node
* adds more than its `max_accepted_htlcs` HTLCs to its local
* commitment transaction */
if (enforce_aggregate_limits
&& tal_count(committed) - tal_count(removing) + tal_count(adding)
> max_accepted_htlcs(channel, recipient)) {
e = CHANNEL_ERR_TOO_MANY_HTLCS;
goto out;
}
msat_in_htlcs = total_offered_msatoshis(committed, htlc_owner(htlc))
- total_offered_msatoshis(removing, htlc_owner(htlc))
+ total_offered_msatoshis(adding, htlc_owner(htlc));
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if a sending node ... or
* adds more than its `max_htlc_value_in_flight_msat` worth of offered
* HTLCs to its local commitment transaction */
if (enforce_aggregate_limits
&& msat_in_htlcs > max_htlc_value_in_flight_msat(channel, recipient)) {
e = CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED;
goto out;
}
/* BOLT #2:
*
* or which the sending node cannot afford at the current
* `feerate_per_kw` while maintaining its channel reserve.
*/
if (channel->funder == htlc_owner(htlc)) {
u64 feerate = view->feerate_per_kw;
u64 dust = dust_limit_satoshis(channel, recipient);
size_t untrimmed;
assert(feerate >= 1);
assert(dust >= 1);
untrimmed = commit_tx_num_untrimmed(committed, feerate, dust,
recipient)
+ commit_tx_num_untrimmed(adding, feerate, dust,
recipient)
- commit_tx_num_untrimmed(removing, feerate, dust,
recipient);
fee_msat = commit_tx_base_fee(feerate, untrimmed);
} else
fee_msat = 0;
assert(fee_msat >= 0);
/* Figure out what balance sender would have after applying all
* pending changes. */
balance_msat = view->owed_msat[sender];
assert(balance_msat >= 0);
for (i = 0; i < tal_count(removing); i++)
balance_msat += balance_removing_htlc(removing[i], sender);
assert(balance_msat >= 0);
for (i = 0; i < tal_count(adding); i++)
balance_msat += balance_adding_htlc(adding[i], sender);
/* This is a little subtle:
*
* The change is being applied to the receiver but it will
* come back to the sender after revoke_and_ack. So the check
* here is that the balance to the sender doesn't go below the
* sender's reserve. */
if (enforce_aggregate_limits
&& balance_msat - fee_msat < (s64)channel_reserve_msat(channel, sender)) {
e = CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED;
goto out;
}
dump_htlc(htlc, "NEW:");
htlc_map_add(channel->htlcs, tal_steal(channel, htlc));
e = CHANNEL_ERR_ADD_OK;
if (htlcp)
*htlcp = htlc;
out:
tal_free(tmpctx);
return e;
}
enum channel_add_err channel_add_htlc(struct channel *channel,
enum side sender,
u64 id,
u64 msatoshi,
u32 cltv_expiry,
const struct sha256 *payment_hash,
const u8 routing[TOTAL_PACKET_SIZE])
{
/* FIXME: check expiry etc. against config. */
return add_htlc(channel, sender, id, msatoshi, cltv_expiry, payment_hash,
routing, NULL, true);
}
struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id)
{
return htlc_get(channel->htlcs, id, sender);
}
enum channel_remove_err channel_fulfill_htlc(struct channel *channel,
enum side owner,
u64 id,
const struct preimage *preimage)
{
struct sha256 hash;
struct htlc *htlc;
htlc = channel_get_htlc(channel, owner, id);
if (!htlc)
return CHANNEL_ERR_NO_SUCH_ID;
if (htlc->r)
return CHANNEL_ERR_ALREADY_FULFILLED;
sha256(&hash, preimage, sizeof(*preimage));
/* BOLT #2:
*
* A receiving node MUST check that the `payment_preimage` value in
* `update_fulfill_htlc` SHA256 hashes to the corresponding HTLC
* `payment_hash`, and MUST fail the channel if it does not.
*/
if (!structeq(&hash, &htlc->rhash))
return CHANNEL_ERR_BAD_PREIMAGE;
htlc->r = tal_dup(htlc, struct preimage, preimage);
/* BOLT #2:
*
* A receiving node MUST check that `id` corresponds to an HTLC in its
* current commitment transaction, and MUST fail the channel if it
* does not.
*/
if (!htlc_has(htlc, HTLC_FLAG(!htlc_owner(htlc), HTLC_F_COMMITTED))) {
status_trace("channel_fulfill_htlc: %"PRIu64" in state %s",
htlc->id, htlc_state_name(htlc->state));
return CHANNEL_ERR_HTLC_UNCOMMITTED;
}
/* We enforce a stricter check, forcing state machine to be linear,
* based on: */
/* BOLT #2:
*
* A node MUST NOT send `update_fulfill_htlc` until an HTLC is
* irrevocably committed in both sides' commitment transactions.
*/
if (htlc->state == SENT_ADD_ACK_REVOCATION)
htlc->state = RCVD_REMOVE_HTLC;
else if (htlc->state == RCVD_ADD_ACK_REVOCATION)
htlc->state = SENT_REMOVE_HTLC;
else {
status_trace("channel_fulfill_htlc: %"PRIu64" in state %s",
htlc->id, htlc_state_name(htlc->state));
return CHANNEL_ERR_HTLC_NOT_IRREVOCABLE;
}
dump_htlc(htlc, "FULFILL:");
return CHANNEL_ERR_REMOVE_OK;
}
enum channel_remove_err channel_fail_htlc(struct channel *channel,
enum side owner, u64 id)
{
struct htlc *htlc;
htlc = channel_get_htlc(channel, owner, id);
if (!htlc)
return CHANNEL_ERR_NO_SUCH_ID;
/* BOLT #2:
*
* A receiving node MUST check that `id` corresponds to an HTLC in its
* current commitment transaction, and MUST fail the channel if it
* does not.
*/
if (!htlc_has(htlc, HTLC_FLAG(!htlc_owner(htlc), HTLC_F_COMMITTED))) {
status_trace("channel_fail_htlc: %"PRIu64" in state %s",
htlc->id, htlc_state_name(htlc->state));
return CHANNEL_ERR_HTLC_UNCOMMITTED;
}
/* FIXME: Technically, they can fail this before we're committed to
* it. This implies a non-linear state machine. */
if (htlc->state == SENT_ADD_ACK_REVOCATION)
htlc->state = RCVD_REMOVE_HTLC;
else if (htlc->state == RCVD_ADD_ACK_REVOCATION)
htlc->state = SENT_REMOVE_HTLC;
else {
status_trace("channel_fail_htlc: %"PRIu64" in state %s",
htlc->id, htlc_state_name(htlc->state));
return CHANNEL_ERR_HTLC_NOT_IRREVOCABLE;
}
dump_htlc(htlc, "FAIL:");
return CHANNEL_ERR_REMOVE_OK;
}
static void htlc_incstate(struct channel *channel,
struct htlc *htlc,
enum side sidechanged)
{
int preflags, postflags;
const int committed_f = HTLC_FLAG(sidechanged, HTLC_F_COMMITTED);
status_trace("htlc %"PRIu64": %s->%s", htlc->id,
htlc_state_name(htlc->state),
htlc_state_name(htlc->state+1));
preflags = htlc_state_flags(htlc->state);
postflags = htlc_state_flags(htlc->state + 1);
/* You can't change sides. */
assert((preflags & (HTLC_LOCAL_F_OWNER|HTLC_REMOTE_F_OWNER))
== (postflags & (HTLC_LOCAL_F_OWNER|HTLC_REMOTE_F_OWNER)));
htlc->state++;
/* If we've added or removed, adjust balances. */
if (!(preflags & committed_f) && (postflags & committed_f)) {
status_trace("htlc added %s: local %+"PRIi64" remote %+"PRIi64,
side_to_str(sidechanged),
balance_adding_htlc(htlc, LOCAL),
balance_adding_htlc(htlc, REMOTE));
channel->view[sidechanged].owed_msat[LOCAL]
+= balance_adding_htlc(htlc, LOCAL);
channel->view[sidechanged].owed_msat[REMOTE]
+= balance_adding_htlc(htlc, REMOTE);
} else if ((preflags & committed_f) && !(postflags & committed_f)) {
status_trace("htlc removed %s: local %+"PRIi64" remote %+"PRIi64,
side_to_str(sidechanged),
balance_removing_htlc(htlc, LOCAL),
balance_removing_htlc(htlc, REMOTE));
channel->view[sidechanged].owed_msat[LOCAL]
+= balance_removing_htlc(htlc, LOCAL);
channel->view[sidechanged].owed_msat[REMOTE]
+= balance_removing_htlc(htlc, REMOTE);
}
}
static void append_htlc(const struct htlc ***htlcs, const struct htlc *h)
{
size_t n;
if (!htlcs)
return;
n = tal_count(*htlcs);
tal_resize(htlcs, n+1);
(*htlcs)[n] = h;
}
/* Returns flags which were changed. */
static int change_htlcs(struct channel *channel,
enum side sidechanged,
const enum htlc_state *htlc_states,
size_t n_hstates,
const struct htlc ***htlcs,
const char *prefix)
{
struct htlc_map_iter it;
struct htlc *h;
int cflags = 0;
size_t i;
for (h = htlc_map_first(channel->htlcs, &it);
h;
h = htlc_map_next(channel->htlcs, &it)) {
for (i = 0; i < n_hstates; i++) {
if (h->state == htlc_states[i]) {
htlc_incstate(channel, h, sidechanged);
dump_htlc(h, prefix);
append_htlc(htlcs, h);
cflags |= (htlc_state_flags(htlc_states[i])
^ htlc_state_flags(h->state));
}
}
}
return cflags;
}
/* FIXME: Handle fee changes too. */
bool channel_sending_commit(struct channel *channel,
const struct htlc ***htlcs)
{
int change;
const enum htlc_state states[] = { SENT_ADD_HTLC,
SENT_REMOVE_REVOCATION,
SENT_ADD_REVOCATION,
SENT_REMOVE_HTLC };
status_trace("Trying commit");
change = change_htlcs(channel, REMOTE, states, ARRAY_SIZE(states),
htlcs, "sending_commit");
return change & HTLC_REMOTE_F_COMMITTED;
}
bool channel_rcvd_revoke_and_ack(struct channel *channel,
const struct htlc ***htlcs)
{
int change;
const enum htlc_state states[] = { SENT_ADD_COMMIT,
SENT_REMOVE_ACK_COMMIT,
SENT_ADD_ACK_COMMIT,
SENT_REMOVE_COMMIT };
status_trace("Received revoke_and_ack");
change = change_htlcs(channel, LOCAL, states, ARRAY_SIZE(states),
htlcs, "rcvd_revoke_and_ack");
return change & HTLC_LOCAL_F_COMMITTED;
}
/* FIXME: We can actually merge these two... */
bool channel_rcvd_commit(struct channel *channel, const struct htlc ***htlcs)
{
int change;
const enum htlc_state states[] = { RCVD_ADD_REVOCATION,
RCVD_REMOVE_HTLC,
RCVD_ADD_HTLC,
RCVD_REMOVE_REVOCATION };
status_trace("Received commit");
change = change_htlcs(channel, LOCAL, states, ARRAY_SIZE(states), htlcs,
"rcvd_commit");
return change & HTLC_LOCAL_F_COMMITTED;
}
bool channel_sending_revoke_and_ack(struct channel *channel)
{
int change;
const enum htlc_state states[] = { RCVD_ADD_ACK_COMMIT,
RCVD_REMOVE_COMMIT,
RCVD_ADD_COMMIT,
RCVD_REMOVE_ACK_COMMIT };
status_trace("Sending revoke_and_ack");
change = change_htlcs(channel, REMOTE, states, ARRAY_SIZE(states), NULL,
"sending_revoke_and_ack");
return change & HTLC_REMOTE_F_PENDING;
}
/* FIXME: Trivial to optimize: set flag on channel_sending_commit,
* clear in channel_rcvd_revoke_and_ack. */
bool channel_awaiting_revoke_and_ack(const struct channel *channel)
{
const enum htlc_state states[] = { SENT_ADD_COMMIT,
SENT_REMOVE_ACK_COMMIT,
SENT_ADD_ACK_COMMIT,
SENT_REMOVE_COMMIT };
struct htlc_map_iter it;
struct htlc *h;
size_t i;
for (h = htlc_map_first(channel->htlcs, &it);
h;
h = htlc_map_next(channel->htlcs, &it)) {
for (i = 0; i < ARRAY_SIZE(states); i++)
if (h->state == states[i])
return true;
}
return false;
}
bool channel_has_htlcs(const struct channel *channel)
{
struct htlc_map_iter it;
const struct htlc *htlc;
for (htlc = htlc_map_first(channel->htlcs, &it);
htlc;
htlc = htlc_map_next(channel->htlcs, &it)) {
/* FIXME: Clean these out! */
if (!htlc_is_dead(htlc))
return true;
}
return false;
}
static bool adjust_balance(struct channel *channel, struct htlc *htlc)
{
enum side side;
for (side = 0; side < NUM_SIDES; side++) {
/* Did it ever add it? */
if (!htlc_has(htlc, HTLC_FLAG(side, HTLC_F_WAS_COMMITTED)))
continue;
/* Add it. */
channel->view[side].owed_msat[LOCAL]
+= balance_adding_htlc(htlc, LOCAL);
channel->view[side].owed_msat[REMOTE]
+= balance_adding_htlc(htlc, REMOTE);
/* If it is no longer committed, remove it (depending
* on fail || fulfill). */
if (htlc_has(htlc, HTLC_FLAG(side, HTLC_F_COMMITTED)))
continue;
if (!htlc->fail && !htlc->malformed && !htlc->r) {
status_trace("%s HTLC %"PRIu64
" %s neither fail nor fulfull?",
htlc_state_owner(htlc->state) == LOCAL
? "out" : "in",
htlc->id,
htlc_state_name(htlc->state));
return false;
}
channel->view[side].owed_msat[LOCAL]
+= balance_removing_htlc(htlc, LOCAL);
channel->view[side].owed_msat[REMOTE]
+= balance_removing_htlc(htlc, REMOTE);
}
return true;
}
bool channel_force_htlcs(struct channel *channel,
const struct added_htlc *htlcs,
const enum htlc_state *hstates,
const struct fulfilled_htlc *fulfilled,
const enum side *fulfilled_sides,
const struct failed_htlc *failed,
const enum side *failed_sides)
{
size_t i;
if (tal_count(hstates) != tal_count(htlcs)) {
status_trace("#hstates %zu != #htlcs %zu",
tal_count(hstates), tal_count(htlcs));
return false;
}
if (tal_count(fulfilled) != tal_count(fulfilled_sides)) {
status_trace("#fulfilled sides %zu != #fulfilled %zu",
tal_count(fulfilled_sides), tal_count(fulfilled));
return false;
}
if (tal_count(failed) != tal_count(failed_sides)) {
status_trace("#failed sides %zu != #failed %zu",
tal_count(failed_sides), tal_count(failed));
return false;
}
for (i = 0; i < tal_count(htlcs); i++) {
enum channel_add_err e;
struct htlc *htlc;
status_trace("Restoring HTLC %zu/%zu:"
" id=%"PRIu64" msat=%"PRIu64" ctlv=%u"
" payment_hash=%s",
i, tal_count(htlcs),
htlcs[i].id, htlcs[i].amount_msat,
htlcs[i].cltv_expiry,
type_to_string(trc, struct sha256,
&htlcs[i].payment_hash));
e = add_htlc(channel, htlc_state_owner(hstates[i]),
htlcs[i].id, htlcs[i].amount_msat,
htlcs[i].cltv_expiry,
&htlcs[i].payment_hash,
htlcs[i].onion_routing_packet, &htlc, false);
if (e != CHANNEL_ERR_ADD_OK) {
status_trace("%s HTLC %"PRIu64" failed error %u",
htlc_state_owner(hstates[i]) == LOCAL
? "out" : "in", htlcs[i].id, e);
return false;
}
/* Override state. */
htlc->state = hstates[i];
}
for (i = 0; i < tal_count(fulfilled); i++) {
struct htlc *htlc = channel_get_htlc(channel,
fulfilled_sides[i],
fulfilled[i].id);
if (!htlc) {
status_trace("Fulfill %s HTLC %"PRIu64" not found",
fulfilled_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id);
return false;
}
if (htlc->r) {
status_trace("Fulfill %s HTLC %"PRIu64" already fulfilled",
fulfilled_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id);
return false;
}
if (htlc->fail) {
status_trace("Fulfill %s HTLC %"PRIu64" already failed",
fulfilled_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id);
return false;
}
if (!htlc_has(htlc, HTLC_REMOVING)) {
status_trace("Fulfill %s HTLC %"PRIu64" state %s",
fulfilled_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id,
htlc_state_name(htlc->state));
return false;
}
htlc->r = tal_dup(htlc, struct preimage,
&fulfilled[i].payment_preimage);
}
for (i = 0; i < tal_count(failed); i++) {
struct htlc *htlc;
htlc = channel_get_htlc(channel, failed_sides[i],
failed[i].id);
if (!htlc) {
status_trace("Fail %s HTLC %"PRIu64" not found",
failed_sides[i] == LOCAL ? "out" : "in",
failed[i].id);
return false;
}
if (htlc->r) {
status_trace("Fail %s HTLC %"PRIu64" already fulfilled",
failed_sides[i] == LOCAL ? "out" : "in",
failed[i].id);
return false;
}
if (htlc->fail) {
status_trace("Fail %s HTLC %"PRIu64" already failed",
failed_sides[i] == LOCAL ? "out" : "in",
failed[i].id);
return false;
}
if (htlc->malformed) {
status_trace("Fail %s HTLC %"PRIu64" already malformed",
failed_sides[i] == LOCAL ? "out" : "in",
failed[i].id);
return false;
}
if (!htlc_has(htlc, HTLC_REMOVING)) {
status_trace("Fail %s HTLC %"PRIu64" state %s",
failed_sides[i] == LOCAL ? "out" : "in",
fulfilled[i].id,
htlc_state_name(htlc->state));
return false;
}
if (failed[i].malformed)
htlc->malformed = failed[i].malformed;
else
htlc->fail = tal_dup_arr(htlc, u8, failed[i].failreason,
tal_len(failed[i].failreason),
0);
}
for (i = 0; i < tal_count(htlcs); i++) {
struct htlc *htlc;
htlc = channel_get_htlc(channel,
htlc_state_owner(hstates[i]),
htlcs[i].id);
if (!adjust_balance(channel, htlc))
return false;
}
return true;
}

View File

@@ -1,278 +0,0 @@
/* This is the full channel routines, with HTLC support. */
#ifndef LIGHTNING_LIGHTNINGD_CHANNEL_FULL_CHANNEL_H
#define LIGHTNING_LIGHTNINGD_CHANNEL_FULL_CHANNEL_H
#include "config.h"
#include <common/initial_channel.h>
#include <common/sphinx.h>
#include <lightningd/channel/channeld_htlc.h>
/**
* new_channel: Given initial fees and funding, what is initial state?
* @ctx: tal context to allocate return value from.
* @funding_txid: The commitment transaction id.
* @funding_txout: The commitment transaction output number.
* @funding_satoshis: The commitment transaction amount.
* @local_msatoshi: The amount for the local side (remainder goes to remote)
* @feerate_per_kw: feerate per kiloweight (satoshis) for the commitment
* transaction and HTLCS
* @local: local channel configuration
* @remote: remote channel configuration
* @local_basepoints: local basepoints.
* @remote_basepoints: remote basepoints.
* @local_fundingkey: local funding key
* @remote_fundingkey: remote funding key
* @funder: which side initiated it.
*
* Returns state, or NULL if malformed.
*/
struct channel *new_channel(const tal_t *ctx,
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshis,
u64 local_msatoshi,
u32 feerate_per_kw,
const struct channel_config *local,
const struct channel_config *remote,
const struct basepoints *local_basepoints,
const struct basepoints *remote_basepoints,
const struct pubkey *local_funding_pubkey,
const struct pubkey *remote_funding_pubkey,
enum side funder);
/**
* channel_txs: Get the current commitment and htlc txs for the channel.
* @ctx: tal context to allocate return value from.
* @channel: The channel to evaluate
* @htlc_map: Pointer to htlcs for each tx output (allocated off @ctx) or NULL.
* @wscripts: Pointer to array of wscript for each tx returned (alloced off @ctx)
* @per_commitment_point: Per-commitment point to determine keys
* @commitment_number: The index of this commitment.
* @side: which side to get the commitment transaction for
*
* Returns the unsigned commitment transaction for the committed state
* for @side, followed by the htlc transactions in output order, and
* fills in @htlc_map (if not NULL), or NULL on key derivation
* failure.
*/
struct bitcoin_tx **channel_txs(const tal_t *ctx,
const struct htlc ***htlcmap,
const u8 ***wscripts,
const struct channel *channel,
const struct pubkey *per_commitment_point,
u64 commitment_number,
enum side side);
/**
* actual_feerate: what is the actual feerate for the local side.
* @channel: The channel state
* @theirsig: The other side's signature
*
* The fee calculated on a commitment transaction is a worst-case
* approximation. It's also possible that the desired feerate is not
* met, because the initiator sets it while the other side is adding many
* htlcs.
*
* This is the fee rate we actually care about, if we're going to check
* whether it's actually too low.
*/
uint32_t actual_feerate(const struct channel *channel,
const struct signature *theirsig);
enum channel_add_err {
/* All OK! */
CHANNEL_ERR_ADD_OK,
/* Bad expiry value */
CHANNEL_ERR_INVALID_EXPIRY,
/* Not really a failure, if expected: it's an exact duplicate. */
CHANNEL_ERR_DUPLICATE,
/* Same ID, but otherwise different. */
CHANNEL_ERR_DUPLICATE_ID_DIFFERENT,
/* Would exceed the specified max_htlc_value_in_flight_msat */
CHANNEL_ERR_MAX_HTLC_VALUE_EXCEEDED,
/* Can't afford it */
CHANNEL_ERR_CHANNEL_CAPACITY_EXCEEDED,
/* HTLC is below htlc_minimum_msat */
CHANNEL_ERR_HTLC_BELOW_MINIMUM,
/* HTLC would push past max_accepted_htlcs */
CHANNEL_ERR_TOO_MANY_HTLCS,
};
/**
* channel_add_htlc: append an HTLC to channel if it can afford it
* @channel: The channel
* @offerer: the side offering the HTLC (to the other side).
* @id: unique HTLC id.
* @msatoshi: amount in millisatoshi.
* @cltv_expiry: block number when HTLC can no longer be redeemed.
* @payment_hash: hash whose preimage can redeem HTLC.
* @routing: routing information (copied)
*
* If this returns CHANNEL_ERR_NONE, the fee htlc was added and
* the output amounts adjusted accordingly. Otherwise nothing
* is changed.
*/
enum channel_add_err channel_add_htlc(struct channel *channel,
enum side sender,
u64 id,
u64 msatoshi,
u32 cltv_expiry,
const struct sha256 *payment_hash,
const u8 routing[TOTAL_PACKET_SIZE]);
/**
* channel_get_htlc: find an HTLC
* @channel: The channel
* @offerer: the side offering the HTLC.
* @id: unique HTLC id.
*/
struct htlc *channel_get_htlc(struct channel *channel, enum side sender, u64 id);
enum channel_remove_err {
/* All OK! */
CHANNEL_ERR_REMOVE_OK,
/* No such HTLC. */
CHANNEL_ERR_NO_SUCH_ID,
/* Already have fulfilled it */
CHANNEL_ERR_ALREADY_FULFILLED,
/* Preimage doesn't hash to value. */
CHANNEL_ERR_BAD_PREIMAGE,
/* HTLC is not committed */
CHANNEL_ERR_HTLC_UNCOMMITTED,
/* HTLC is not committed and prior revoked on both sides */
CHANNEL_ERR_HTLC_NOT_IRREVOCABLE
};
/**
* channel_fail_htlc: remove an HTLC, funds to the side which offered it.
* @channel: The channel state
* @owner: the side who offered the HTLC (opposite to that failing it)
* @id: unique HTLC id.
*
* This will remove the htlc and credit the value of the HTLC (back)
* to its offerer.
*/
enum channel_remove_err channel_fail_htlc(struct channel *channel,
enum side owner, u64 id);
/**
* channel_fulfill_htlc: remove an HTLC, funds to side which accepted it.
* @channel: The channel state
* @owner: the side who offered the HTLC (opposite to that fulfilling it)
* @id: unique HTLC id.
*
* If the htlc exists, is not already fulfilled, the preimage is correct and
* HTLC committed at the recipient, this will add a pending change to
* remove the htlc and give the value of the HTLC to its recipient,
* and return CHANNEL_ERR_FULFILL_OK. Otherwise, it will return another error.
*/
enum channel_remove_err channel_fulfill_htlc(struct channel *channel,
enum side owner,
u64 id,
const struct preimage *preimage);
/**
* approx_max_feerate: what's the we (initiator) could raise fee rate to?
* @channel: The channel state
*
* This is not exact! To check if their offer is valid, use can_afford_feerate.
*/
u64 approx_max_feerate(const struct channel *channel);
/**
* can_afford_feerate: could the initiator pay for the fee at fee_rate?
* @channel: The channel state
* @feerate_per_kw: the new fee rate proposed
*/
bool can_afford_feerate(const struct channel *channel, u64 feerate_per_kw);
/**
* adjust_fee: Change fee rate.
* @channel: The channel state
* @feerate_per_kw: fee in satoshi per 1000 bytes.
* @side: which side to adjust.
*/
void adjust_fee(struct channel *channel, u64 feerate_per_kw, enum side side);
/**
* channel_sending_commit: commit all remote outstanding changes.
* @channel: the channel
* @htlcs: initially-empty tal_arr() for htlcs which changed state.
*
* This is where we commit to pending changes we've added; returns true if
* anything changed for the remote side (if not, don't send!) */
bool channel_sending_commit(struct channel *channel,
const struct htlc ***htlcs);
/**
* channel_rcvd_revoke_and_ack: accept ack on remote committed changes.
* @channel: the channel
* @htlcs: initially-empty tal_arr() for htlcs which changed state.
*
* This is where we commit to pending changes we've added; returns true if
* anything changed for our local commitment (ie. we have pending changes).
*/
bool channel_rcvd_revoke_and_ack(struct channel *channel,
const struct htlc ***htlcs);
/**
* channel_rcvd_commit: commit all local outstanding changes.
* @channel: the channel
* @htlcs: initially-empty tal_arr() for htlcs which changed state.
*
* This is where we commit to pending changes we've added; returns true if
* anything changed for our local commitment (ie. we had pending changes).
*/
bool channel_rcvd_commit(struct channel *channel,
const struct htlc ***htlcs);
/**
* channel_sending_revoke_and_ack: sending ack on local committed changes.
* @channel: the channel
*
* This is where we commit to pending changes we've added. Returns true if
* anything changed for the remote commitment (ie. send a new commit).*/
bool channel_sending_revoke_and_ack(struct channel *channel);
/**
* channel_awaiting_revoke_and_ack: are we waiting for revoke_and_ack?
* @channel: the channel
*
* If true, we can't send a new commit message.
*/
bool channel_awaiting_revoke_and_ack(const struct channel *channel);
/**
* channel_has_htlcs: are there any (live) HTLCs at all in channel?
* @channel: the channel
*/
bool channel_has_htlcs(const struct channel *channel);
/**
* channel_force_htlcs: force these htlcs into the (new) channel
* @channel: the channel
* @htlcs: the htlcs to add (tal_arr)
* @hstates: the states for the htlcs (tal_arr of same size)
* @fulfilled: htlcs of those which are fulfilled
* @fulfilled_sides: sides for ids in @fulfilled
* @failed: htlcs of those which are failed
* @failed_sides: sides for ids in @failed
*
* This is used for restoring a channel state.
*/
bool channel_force_htlcs(struct channel *channel,
const struct added_htlc *htlcs,
const enum htlc_state *hstates,
const struct fulfilled_htlc *fulfilled,
const enum side *fulfilled_sides,
const struct failed_htlc *failed,
const enum side *failed_sides);
/**
* dump_htlcs: debugging dump of all HTLCs
* @channel: the channel
* @prefix: the prefix to prepend to each line.
*
* Uses status_trace() on every HTLC.
*/
void dump_htlcs(const struct channel *channel, const char *prefix);
#endif /* LIGHTNING_LIGHTNINGD_CHANNEL_FULL_CHANNEL_H */

View File

@@ -1,78 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/closing-wrongdir:
$(MAKE) -C ../.. lightningd/closing-all
default: lightningd/closing-all
lightningd/closing-all: lightningd/lightningd_closing
# lightningd/closing needs these:
LIGHTNINGD_CLOSING_HEADERS_GEN := \
lightningd/closing/gen_closing_wire.h
LIGHTNINGD_CLOSING_HEADERS_NOGEN :=
LIGHTNINGD_CLOSING_HEADERS := $(LIGHTNINGD_CLOSING_HEADERS_GEN) $(LIGHTNINGD_CLOSING_HEADERS_NOGEN)
LIGHTNINGD_CLOSING_SRC := lightningd/closing/closing.c \
$(LIGHTNINGD_CLOSING_HEADERS:.h=.c)
LIGHTNINGD_CLOSING_OBJS := $(LIGHTNINGD_CLOSING_SRC:.c=.o)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_CLOSING_OBJS)
# Control daemon uses this:
LIGHTNINGD_CLOSING_CONTROL_HEADERS := $(LIGHTNINGD_CLOSING_HEADERS)
LIGHTNINGD_CLOSING_CONTROL_SRC := $(LIGHTNINGD_CLOSING_HEADERS:.h=.c)
LIGHTNINGD_CLOSING_CONTROL_OBJS := $(LIGHTNINGD_CLOSING_CONTROL_SRC:.c=.o)
LIGHTNINGD_CLOSING_GEN_SRC := $(filter lightningd/closing/gen_%, $(LIGHTNINGD_CLOSING_SRC) $(LIGHTNINGD_CLOSING_CONTROL_SRC))
LIGHTNINGD_CLOSING_SRC_NOGEN := $(filter-out lightningd/closing/gen_%, $(LIGHTNINGD_CLOSING_SRC))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_CLOSING_HEADERS_GEN)
LIGHTNINGD_HEADERS_NOGEN += $(LIGHTNINGD_CLOSING_HEADERS_NOGEN)
$(LIGHTNINGD_CLOSING_OBJS): $(LIGHTNINGD_HEADERS)
# Common source we use.
CLOSINGD_COMMON_OBJS := \
common/close_tx.o \
common/crypto_sync.o \
common/cryptomsg.o \
common/daemon_conn.o \
common/debug.o \
common/dev_disconnect.o \
common/derive_basepoints.o \
common/htlc_wire.o \
common/msg_queue.o \
common/permute_tx.o \
common/status.o \
common/type_to_string.o \
common/utils.o \
common/version.o
lightningd/closing/gen_closing_wire.h: $(WIRE_GEN) lightningd/closing/closing_wire.csv
$(WIRE_GEN) --header $@ closing_wire_type < lightningd/closing/closing_wire.csv > $@
lightningd/closing/gen_closing_wire.c: $(WIRE_GEN) lightningd/closing/closing_wire.csv
$(WIRE_GEN) ${@:.c=.h} closing_wire_type < lightningd/closing/closing_wire.csv > $@
LIGHTNINGD_CLOSING_OBJS := $(LIGHTNINGD_CLOSING_SRC:.c=.o) $(LIGHTNINGD_CLOSING_GEN_SRC:.c=.o)
lightningd/lightningd_closing: $(LIGHTNINGD_CLOSING_OBJS) $(WIRE_ONION_OBJS) $(CLOSINGD_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS)
check-source: $(LIGHTNINGD_CLOSING_SRC_NOGEN:%=check-src-include-order/%)
check-source-bolt: $(LIGHTNINGD_CLOSING_SRC:%=bolt-check/%) $(LIGHTNINGD_CLOSING_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_CLOSING_SRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_CLOSING_HEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/closing-clean
lightningd/closing-clean:
$(RM) $(LIGHTNINGD_CLOSING_OBJS) gen_*
-include lightningd/closing/test/Makefile

View File

@@ -1,476 +0,0 @@
#include <bitcoin/script.h>
#include <common/close_tx.h>
#include <common/crypto_sync.h>
#include <common/debug.h>
#include <common/derive_basepoints.h>
#include <common/htlc.h>
#include <common/status.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <common/version.h>
#include <errno.h>
#include <inttypes.h>
#include <lightningd/closing/gen_closing_wire.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>
/* stdin == requests, 3 == peer, 4 = gossip */
#define REQ_FD STDIN_FILENO
#define PEER_FD 3
#define GOSSIP_FD 4
static struct bitcoin_tx *close_tx(const tal_t *ctx,
u8 *scriptpubkey[NUM_SIDES],
const struct sha256_double *funding_txid,
unsigned int funding_txout,
u64 funding_satoshi,
const u64 satoshi_out[NUM_SIDES],
enum side funder,
uint64_t fee,
uint64_t dust_limit)
{
struct bitcoin_tx *tx;
if (satoshi_out[funder] < fee)
status_failed(WIRE_CLOSING_NEGOTIATION_ERROR,
"Funder cannot afford fee %"PRIu64
" (%"PRIu64" and %"PRIu64")",
fee, satoshi_out[LOCAL],
satoshi_out[REMOTE]);
status_trace("Making close tx at = %"PRIu64"/%"PRIu64" fee %"PRIu64,
satoshi_out[LOCAL], satoshi_out[REMOTE], fee);
tx = create_close_tx(ctx, scriptpubkey[LOCAL], scriptpubkey[REMOTE],
funding_txid,
funding_txout,
funding_satoshi,
satoshi_out[LOCAL] - (funder == LOCAL ? fee : 0),
satoshi_out[REMOTE] - (funder == REMOTE ? fee : 0),
dust_limit);
if (!tx)
status_failed(WIRE_CLOSING_NEGOTIATION_ERROR,
"Both outputs below dust limit:"
" funding = %"PRIu64
" fee = %"PRIu64
" dust_limit = %"PRIu64
" LOCAL = %"PRIu64
" REMOTE = %"PRIu64,
funding_satoshi,
fee,
dust_limit,
satoshi_out[LOCAL],
satoshi_out[REMOTE]);
return tx;
}
static u64 one_towards(u64 target, u64 value)
{
if (value > target)
return value-1;
else if (value < target)
return value+1;
return value;
}
static void do_reconnect(struct crypto_state *cs,
const struct channel_id *channel_id,
const u64 next_index[NUM_SIDES],
u64 revocations_received)
{
u8 *msg;
struct channel_id their_channel_id;
const tal_t *tmpctx = tal_tmpctx(NULL);
u64 next_local_commitment_number, next_remote_revocation_number;
/* BOLT #2:
*
* On reconnection, a node MUST transmit `channel_reestablish` for
* each channel, and MUST wait for to receive the other node's
* `channel_reestablish` message before sending any other messages for
* that channel. The sending node MUST set
* `next_local_commitment_number` to the commitment number of the next
* `commitment_signed` it expects to receive, and MUST set
* `next_remote_revocation_number` to the commitment number of the
* next `revoke_and_ack` message it expects to receive.
*/
msg = towire_channel_reestablish(tmpctx, channel_id,
next_index[LOCAL],
revocations_received);
if (!sync_crypto_write(cs, PEER_FD, take(msg)))
status_failed(WIRE_CLOSING_PEER_WRITE_FAILED,
"Failed writing reestablish: %s", strerror(errno));
again:
msg = sync_crypto_read(tmpctx, cs, PEER_FD);
if (!msg)
status_failed(WIRE_CLOSING_PEER_READ_FAILED,
"Failed reading reestablish: %s", strerror(errno));
if (is_gossip_msg(msg)) {
if (!wire_sync_write(GOSSIP_FD, take(msg)))
status_failed(WIRE_CLOSING_GOSSIP_FAILED,
"Writing gossip");
goto again;
}
if (!fromwire_channel_reestablish(msg, NULL, &their_channel_id,
&next_local_commitment_number,
&next_remote_revocation_number)) {
status_failed(WIRE_CLOSING_PEER_READ_FAILED,
"bad reestablish msg: %s %s",
wire_type_name(fromwire_peektype(msg)),
tal_hex(tmpctx, msg));
}
status_trace("Got reestablish commit=%"PRIu64" revoke=%"PRIu64,
next_local_commitment_number,
next_remote_revocation_number);
/* FIXME: Spec says to re-xmit funding_locked here if we haven't
* done any updates. */
/* BOLT #2:
*
* On reconnection if the node has sent a previous `closing_signed` it
* MUST send another `closing_signed`
*/
/* Since we always transmit closing_signed immediately, if
* we're reconnecting we consider ourselves to have transmitted once,
* and we'll immediately do the retransmit now anyway. */
tal_free(tmpctx);
}
int main(int argc, char *argv[])
{
struct crypto_state cs;
const tal_t *ctx = tal_tmpctx(NULL);
u8 *msg;
struct privkey seed;
struct pubkey funding_pubkey[NUM_SIDES];
struct sha256_double funding_txid;
u16 funding_txout;
u64 funding_satoshi, satoshi_out[NUM_SIDES];
u64 our_dust_limit;
u64 minfee, maxfee, sent_fee;
s64 last_received_fee = -1;
enum side funder;
u8 *scriptpubkey[NUM_SIDES], *funding_wscript;
struct channel_id channel_id;
struct secrets secrets;
secp256k1_ecdsa_signature sig;
bool reconnected;
u64 next_index[NUM_SIDES], revocations_received;
if (argc == 2 && streq(argv[1], "--version")) {
printf("%s\n", version());
exit(0);
}
subdaemon_debug(argc, argv);
/* We handle write returning errors! */
signal(SIGCHLD, SIG_IGN);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
status_setup_sync(REQ_FD);
msg = wire_sync_read(ctx, REQ_FD);
if (!fromwire_closing_init(ctx, msg, NULL,
&cs, &seed,
&funding_txid, &funding_txout,
&funding_satoshi,
&funding_pubkey[REMOTE],
&funder,
&satoshi_out[LOCAL],
&satoshi_out[REMOTE],
&our_dust_limit,
&minfee, &maxfee, &sent_fee,
&scriptpubkey[LOCAL],
&scriptpubkey[REMOTE],
&reconnected,
&next_index[LOCAL],
&next_index[REMOTE],
&revocations_received)) {
status_failed(WIRE_CLOSING_PEER_BAD_MESSAGE,
"Bad init message %s", tal_hex(ctx, msg));
}
status_trace("satoshi_out = %"PRIu64"/%"PRIu64,
satoshi_out[LOCAL], satoshi_out[REMOTE]);
status_trace("dustlimit = %"PRIu64, our_dust_limit);
status_trace("fee = %"PRIu64, sent_fee);
derive_channel_id(&channel_id, &funding_txid, funding_txout);
derive_basepoints(&seed, &funding_pubkey[LOCAL], NULL,
&secrets, NULL);
funding_wscript = bitcoin_redeem_2of2(ctx,
&funding_pubkey[LOCAL],
&funding_pubkey[REMOTE]);
if (reconnected)
do_reconnect(&cs, &channel_id, next_index, revocations_received);
/* BOLT #2:
*
* Nodes SHOULD send a `closing_signed` message after `shutdown` has
* been received and no HTLCs remain in either commitment transaction.
*/
/* BOLT #2:
*
* On reconnection, ... if the node has sent a previous
* `closing_signed` it MUST send another `closing_signed`, otherwise
* if the node has sent a previous `shutdown` it MUST retransmit it.
*/
for (;;) {
const tal_t *tmpctx = tal_tmpctx(ctx);
struct bitcoin_tx *tx;
u64 received_fee, limit_fee, new_fee;
/* BOLT #2:
*
* The sender MUST set `signature` to the Bitcoin signature of
* the close transaction as specified in [BOLT
* #3](03-transactions.md#closing-transaction).
*/
tx = close_tx(tmpctx, scriptpubkey,
&funding_txid,
funding_txout,
funding_satoshi,
satoshi_out, funder, sent_fee, our_dust_limit);
/* BOLT #3:
*
* ## Closing Transaction
*...
* Each node offering a signature... MAY also eliminate its
* own output.
*/
/* (We don't do this). */
sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey,
&funding_pubkey[LOCAL],
&sig);
status_trace("sending fee offer %"PRIu64, sent_fee);
/* Now send closing offer */
msg = towire_closing_signed(tmpctx, &channel_id, sent_fee, &sig);
if (!sync_crypto_write(&cs, PEER_FD, take(msg)))
status_failed(WIRE_CLOSING_PEER_WRITE_FAILED,
"Writing closing_signed");
/* Did we just agree with them? If so, we're done. */
if (sent_fee == last_received_fee)
break;
again:
msg = sync_crypto_read(tmpctx, &cs, PEER_FD);
if (!msg)
status_failed(WIRE_CLOSING_PEER_READ_FAILED,
"Reading input");
/* We don't send gossip at this stage, but we can recv it */
if (is_gossip_msg(msg)) {
if (!wire_sync_write(GOSSIP_FD, take(msg)))
status_failed(WIRE_CLOSING_GOSSIP_FAILED,
"Writing gossip");
goto again;
}
/* BOLT #2:
*
* On reconnection, a node MUST ignore a redundant
* `funding_locked` if it receives one.
*/
/* This should only happen if we've made no commitments, but
* we don't have to check that: it's their problem. */
if (fromwire_peektype(msg) == WIRE_FUNDING_LOCKED) {
tal_free(msg);
goto again;
}
/* BOLT #2:
*
* ...if the node has sent a previous `shutdown` it MUST
* retransmit it.
*/
if (fromwire_peektype(msg) == WIRE_SHUTDOWN) {
tal_free(msg);
goto again;
}
if (!fromwire_closing_signed(msg, NULL, &channel_id,
&received_fee, &sig))
status_failed(WIRE_CLOSING_PEER_BAD_MESSAGE,
"Expected closing_signed: %s",
tal_hex(trc, msg));
/* BOLT #2:
*
* The receiver MUST check `signature` is valid for either
* variant of close transaction specified in [BOLT
* #3](03-transactions.md#closing-transaction), and MUST fail
* the connection if it is not.
*/
tx = close_tx(tmpctx, scriptpubkey,
&funding_txid,
funding_txout,
funding_satoshi,
satoshi_out, funder, received_fee, our_dust_limit);
if (!check_tx_sig(tx, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &sig)) {
/* Trim it by reducing their output to minimum */
struct bitcoin_tx *trimmed;
u64 trimming_satoshi_out[NUM_SIDES];
if (funder == REMOTE)
trimming_satoshi_out[REMOTE] = received_fee;
else
trimming_satoshi_out[REMOTE] = 0;
trimming_satoshi_out[LOCAL] = satoshi_out[LOCAL];
/* BOLT #3:
*
* Each node offering a signature MUST subtract the
* fee given by `fee_satoshis` from the output to the
* funder; it MUST then remove any output below its
* own `dust_limit_satoshis`, and MAY also eliminate
* its own output.
*/
trimmed = close_tx(tmpctx, scriptpubkey,
&funding_txid,
funding_txout,
funding_satoshi,
trimming_satoshi_out,
funder, received_fee, our_dust_limit);
if (!trimmed
|| !check_tx_sig(trimmed, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &sig)) {
status_failed(WIRE_CLOSING_PEER_BAD_MESSAGE,
"Bad closing_signed signature for"
" %s (and trimmed version %s)",
type_to_string(tmpctx,
struct bitcoin_tx,
tx),
trimmed ?
type_to_string(tmpctx,
struct bitcoin_tx,
trimmed)
: "NONE");
}
tx = trimmed;
}
status_trace("Received fee offer %"PRIu64, received_fee);
/* BOLT #2:
*
* Otherwise, the recipient MUST fail the connection if
* `fee_satoshis` is greater than the base fee of the final
* commitment transaction as calculated in [BOLT #3] */
if (received_fee > maxfee)
status_failed(WIRE_CLOSING_PEER_BAD_MESSAGE,
"Bad closing_signed fee %"PRIu64
" > %"PRIu64,
received_fee, maxfee);
/* Is fee reasonable? Tell master. */
if (received_fee < minfee) {
status_trace("Fee too low, below %"PRIu64, minfee);
limit_fee = minfee;
} else {
status_trace("Fee accepted.");
msg = towire_closing_received_signature(tmpctx,
&sig, tx);
if (!wire_sync_write(REQ_FD, take(msg)))
status_failed(WIRE_CLOSING_INTERNAL_ERROR,
"Writing received to master: %s",
strerror(errno));
msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_closing_received_signature_reply(msg,NULL))
status_failed(WIRE_CLOSING_INTERNAL_ERROR,
"Bad received reply from master");
limit_fee = received_fee;
}
/* BOLT #2:
*
* If `fee_satoshis` is equal to its previously sent
* `fee_satoshis`, the receiver SHOULD sign and broadcast the
* final closing transaction and MAY close the connection.
*/
if (received_fee == sent_fee)
break;
/* BOLT #2:
*
* the recipient SHOULD fail the connection if `fee_satoshis`
* is not strictly between its last-sent `fee_satoshis` and
* its previously-received `fee_satoshis`, unless it has
* reconnected since then. */
if (last_received_fee != -1) {
bool previous_dir = sent_fee < last_received_fee;
bool dir = received_fee < last_received_fee;
bool next_dir = sent_fee < received_fee;
/* They went away from our offer? */
if (dir != previous_dir)
status_failed(WIRE_CLOSING_NEGOTIATION_ERROR,
"Their fee went %"
PRIu64" to %"PRIu64
" when ours was %"PRIu64,
last_received_fee,
received_fee,
sent_fee);
/* They jumped over our offer? */
if (next_dir != previous_dir)
status_failed(WIRE_CLOSING_NEGOTIATION_ERROR,
"Their fee jumped %"
PRIu64" to %"PRIu64
" when ours was %"PRIu64,
last_received_fee,
received_fee,
sent_fee);
}
/* BOLT #2:
*
* ...otherwise it MUST propose a value strictly between the
* received `fee_satoshis` and its previously-sent
* `fee_satoshis`.
*/
/* We do it by bisection, with twists:
* 1. Don't go outside limits, or reach them immediately:
* treat out-of-limit offers as on-limit offers.
* 2. Round towards the target, otherwise we can't close
* a final 1-satoshi gap.
*
* Note: Overflow impossible here, since fee <= funder amount */
new_fee = one_towards(limit_fee, limit_fee + sent_fee) / 2;
/* If we didn't move, give up (we're ~ at min/max). */
if (new_fee == sent_fee)
status_failed(WIRE_CLOSING_NEGOTIATION_ERROR,
"Final fee %"PRIu64" vs %"PRIu64
" at limits %"PRIu64"-%"PRIu64,
sent_fee, received_fee,
minfee, maxfee);
last_received_fee = received_fee;
sent_fee = new_fee;
tal_free(tmpctx);
}
/* We're done! */
wire_sync_write(REQ_FD, take(towire_closing_complete(ctx)));
tal_free(ctx);
return 0;
}

View File

@@ -1,51 +0,0 @@
# Shouldn't happen
closing_bad_command,0x8000
# Also shouldn't happen
closing_gossip_failed,0x8001
closing_internal_error,0x8003
# These are due to peer.
closing_peer_write_failed,0x8010
closing_peer_read_failed,0x8011
closing_peer_bad_message,0x8012
closing_peer_bad_message,,len,u16
closing_peer_bad_message,,msg,len*u8
closing_negotiation_error,0x8013
closing_negotiation_error,,len,u16
closing_negotiation_error,,msg,len*u8
#include <common/cryptomsg.h>
#include <common/htlc_wire.h>
# Begin! (passes peer fd, gossipd-client fd)
closing_init,1
closing_init,,crypto_state,struct crypto_state
closing_init,,seed,struct privkey
closing_init,,funding_txid,struct sha256_double
closing_init,,funding_txout,u16
closing_init,,funding_satoshi,u64
closing_init,,remote_fundingkey,struct pubkey
closing_init,,funder,enum side
closing_init,,local_msatoshi,u64
closing_init,,remote_msatoshi,u64
closing_init,,our_dust_limit,u64
closing_init,,min_fee_satoshi,u64
closing_init,,max_fee_satoshi,u64
closing_init,,initial_fee_satoshi,u64
closing_init,,local_scriptpubkey_len,u16
closing_init,,local_scriptpubkey,local_scriptpubkey_len*u8
closing_init,,remote_scriptpubkey_len,u16
closing_init,,remote_scriptpubkey,remote_scriptpubkey_len*u8
closing_init,,reconnected,bool
closing_init,,next_index_local,u64
closing_init,,next_index_remote,u64
closing_init,,revocations_received,u64
# We received an offer, save signature.
closing_received_signature,2
closing_received_signature,,signature,secp256k1_ecdsa_signature
closing_received_signature,,tx,struct bitcoin_tx
closing_received_signature_reply,102
# Negotiations complete, we're exiting.
closing_complete,4
1 # Shouldn't happen
2 closing_bad_command,0x8000
3 # Also shouldn't happen
4 closing_gossip_failed,0x8001
5 closing_internal_error,0x8003
6 # These are due to peer.
7 closing_peer_write_failed,0x8010
8 closing_peer_read_failed,0x8011
9 closing_peer_bad_message,0x8012
10 closing_peer_bad_message,,len,u16
11 closing_peer_bad_message,,msg,len*u8
12 closing_negotiation_error,0x8013
13 closing_negotiation_error,,len,u16
14 closing_negotiation_error,,msg,len*u8
15 #include <common/cryptomsg.h>
16 #include <common/htlc_wire.h>
17 # Begin! (passes peer fd, gossipd-client fd)
18 closing_init,1
19 closing_init,,crypto_state,struct crypto_state
20 closing_init,,seed,struct privkey
21 closing_init,,funding_txid,struct sha256_double
22 closing_init,,funding_txout,u16
23 closing_init,,funding_satoshi,u64
24 closing_init,,remote_fundingkey,struct pubkey
25 closing_init,,funder,enum side
26 closing_init,,local_msatoshi,u64
27 closing_init,,remote_msatoshi,u64
28 closing_init,,our_dust_limit,u64
29 closing_init,,min_fee_satoshi,u64
30 closing_init,,max_fee_satoshi,u64
31 closing_init,,initial_fee_satoshi,u64
32 closing_init,,local_scriptpubkey_len,u16
33 closing_init,,local_scriptpubkey,local_scriptpubkey_len*u8
34 closing_init,,remote_scriptpubkey_len,u16
35 closing_init,,remote_scriptpubkey,remote_scriptpubkey_len*u8
36 closing_init,,reconnected,bool
37 closing_init,,next_index_local,u64
38 closing_init,,next_index_remote,u64
39 closing_init,,revocations_received,u64
40 # We received an offer, save signature.
41 closing_received_signature,2
42 closing_received_signature,,signature,secp256k1_ecdsa_signature
43 closing_received_signature,,tx,struct bitcoin_tx
44 closing_received_signature_reply,102
45 # Negotiations complete, we're exiting.
46 closing_complete,4

View File

@@ -1,7 +1,7 @@
#include <channeld/gen_channel_wire.h>
#include <common/sphinx.h>
#include <common/utils.h>
#include <lightningd/channel/gen_channel_wire.h>
#include <lightningd/gossip/gen_gossip_wire.h>
#include <gossipd/gen_gossip_wire.h>
#include <lightningd/htlc_end.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
@@ -16,7 +16,7 @@ static bool ping_reply(struct subd *subd, const u8 *msg, const int *fds,
bool ok;
log_debug(subd->ld->log, "Got ping reply!");
if (streq(subd->name, "lightningd_channel"))
if (streq(subd->name, "lightning_channeld"))
ok = fromwire_channel_ping_reply(msg, NULL, &totlen);
else
ok = fromwire_gossip_ping_reply(msg, NULL, &totlen);
@@ -59,8 +59,8 @@ static void json_dev_ping(struct command *cmd,
/* FIXME: These checks are horrible, use a peer flag to say it's
* ready to forward! */
if (peer->owner && !streq(peer->owner->name, "lightningd_channel")
&& !streq(peer->owner->name, "lightningd_gossip")) {
if (peer->owner && !streq(peer->owner->name, "lightning_channeld")
&& !streq(peer->owner->name, "lightning_gossipd")) {
command_fail(cmd, "Peer in %s",
peer->owner ? peer->owner->name : "unattached");
return;
@@ -80,7 +80,7 @@ static void json_dev_ping(struct command *cmd,
return;
}
if (streq(peer->owner->name, "lightningd_channel"))
if (streq(peer->owner->name, "lightning_channeld"))
msg = towire_channel_ping(cmd, pongbytes, len);
else
msg = towire_gossip_ping(cmd, peer->unique_id, pongbytes, len);

View File

@@ -1,72 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/gossip-wrongdir:
$(MAKE) -C .. lightningd/gossip-all
default: lightningd/gossip-all
# Control daemon uses this:
LIGHTNINGD_GOSSIP_CONTROL_HEADERS := lightningd/gossip/gen_gossip_wire.h
LIGHTNINGD_GOSSIP_CONTROL_SRC := lightningd/gossip/gen_gossip_wire.c
LIGHTNINGD_GOSSIP_CONTROL_OBJS := $(LIGHTNINGD_GOSSIP_CONTROL_SRC:.c=.o)
# lightningd/gossip needs these:
LIGHTNINGD_GOSSIP_HEADERS := lightningd/gossip/gen_gossip_wire.h \
lightningd/gossip/routing.h \
lightningd/gossip/broadcast.h
LIGHTNINGD_GOSSIP_SRC := lightningd/gossip/gossip.c \
$(LIGHTNINGD_GOSSIP_HEADERS:.h=.c)
LIGHTNINGD_GOSSIP_OBJS := $(LIGHTNINGD_GOSSIP_SRC:.c=.o)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_GOSSIP_OBJS)
# For checking
LIGHTNINGD_GOSSIP_ALLSRC_NOGEN := $(filter-out lightningd/gossip/gen_%, $(LIGHTNINGD_GOSSIP_CLIENT_SRC) $(LIGHTNINGD_GOSSIP_SRC))
LIGHTNINGD_GOSSIP_ALLHEADERS_NOGEN := $(filter-out lightningd/gossip/gen_%, $(LIGHTNINGD_GOSSIP_CLIENT_HEADERS) $(LIGHTNINGD_GOSSIP_HEADERS))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_GOSSIP_HEADERS)
# Common source we use.
GOSSIPD_COMMON_OBJS := \
common/crypto_sync.o \
common/cryptomsg.o \
common/daemon_conn.o \
common/debug.o \
common/dev_disconnect.o \
common/msg_queue.o \
common/ping.o \
common/pseudorand.o \
common/status.o \
common/timeout.o \
common/type_to_string.o \
common/utils.o \
common/version.o \
lightningd/gossip_msg.o
$(LIGHTNINGD_GOSSIP_OBJS) $(LIGHTNINGD_GOSSIP_CLIENT_OBJS): $(LIGHTNINGD_HEADERS)
$(LIGHTNINGD_GOSSIP_CONTROL_OBJS) : $(LIGHTNINGD_GOSSIP_CONTROL_HEADERS)
lightningd/gossip-all: lightningd/lightningd_gossip $(LIGHTNINGD_GOSSIP_CLIENT_OBJS)
lightningd/lightningd_gossip: $(LIGHTNINGD_GOSSIP_OBJS) $(GOSSIPD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS)
lightningd/gossip/gen_gossip_wire.h: $(WIRE_GEN) lightningd/gossip/gossip_wire.csv
$(WIRE_GEN) --header $@ gossip_wire_type < lightningd/gossip/gossip_wire.csv > $@
lightningd/gossip/gen_gossip_wire.c: $(WIRE_GEN) lightningd/gossip/gossip_wire.csv
$(WIRE_GEN) ${@:.c=.h} gossip_wire_type < lightningd/gossip/gossip_wire.csv > $@
check-source: $(LIGHTNINGD_GOSSIP_ALLSRC_NOGEN:%=check-src-include-order/%) $(LIGHTNINGD_GOSSIP_ALLHEADERS_NOGEN:%=check-hdr-include-order/%)
check-source-bolt: $(LIGHTNINGD_GOSSIP_SRC:%=bolt-check/%) $(LIGHTNINGD_GOSSIP_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_GOSSIP_ALLSRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_GOSSIP_ALLHEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/gossip-clean
lightningd/gossip-clean:
$(RM) $(LIGHTNINGD_GOSSIP_OBJS) gen_*
-include lightningd/gossip/test/Makefile

View File

@@ -1,51 +0,0 @@
#include <lightningd/gossip/broadcast.h>
struct broadcast_state *new_broadcast_state(tal_t *ctx)
{
struct broadcast_state *bstate = tal(ctx, struct broadcast_state);
uintmap_init(&bstate->broadcasts);
/* Skip 0 because we initialize peers with 0 */
bstate->next_index = 1;
return bstate;
}
static struct queued_message *new_queued_message(tal_t *ctx,
const int type,
const u8 *tag,
const u8 *payload)
{
struct queued_message *msg = tal(ctx, struct queued_message);
msg->type = type;
msg->tag = tal_dup_arr(msg, u8, tag, tal_count(tag), 0);
msg->payload = tal_dup_arr(msg, u8, payload, tal_count(payload), 0);
return msg;
}
void queue_broadcast(struct broadcast_state *bstate,
const int type,
const u8 *tag,
const u8 *payload)
{
struct queued_message *msg;
u64 index = 0;
/* Remove any tag&type collisions */
while (true) {
msg = next_broadcast_message(bstate, &index);
if (msg == NULL)
break;
else if (msg->type == type && memcmp(msg->tag, tag, tal_count(tag)) == 0) {
uintmap_del(&bstate->broadcasts, index);
tal_free(msg);
}
}
/* Now add the message to the queue */
msg = new_queued_message(bstate, type, tag, payload);
uintmap_add(&bstate->broadcasts, bstate->next_index, msg);
bstate->next_index += 1;
}
struct queued_message *next_broadcast_message(struct broadcast_state *bstate, u64 *last_index)
{
return uintmap_after(&bstate->broadcasts, last_index);
}

View File

@@ -1,40 +0,0 @@
#ifndef LIGHTNING_LIGHTNINGD_GOSSIP_BROADCAST_H
#define LIGHTNING_LIGHTNINGD_GOSSIP_BROADCAST_H
#include "config.h"
#include <ccan/intmap/intmap.h>
#include <ccan/list/list.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
/* Common functionality to implement staggered broadcasts with replacement. */
struct queued_message {
int type;
/* Unique tag specifying the msg origin */
void *tag;
/* Serialized payload */
u8 *payload;
};
struct broadcast_state {
u32 next_index;
UINTMAP(struct queued_message *) broadcasts;
};
struct broadcast_state *new_broadcast_state(tal_t *ctx);
/* Queue a new message to be broadcast and replace any outdated
* broadcast. Replacement is done by comparing the `type` and the
* `tag`, if both match the old message is dropped from the queue. The
* new message is added to the top of the broadcast queue. */
void queue_broadcast(struct broadcast_state *bstate,
const int type,
const u8 *tag,
const u8 *payload);
struct queued_message *next_broadcast_message(struct broadcast_state *bstate, u64 *last_index);
#endif /* LIGHTNING_LIGHTNINGD_GOSSIP_BROADCAST_H */

View File

@@ -1,817 +0,0 @@
#include <ccan/container_of/container_of.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/endian/endian.h>
#include <ccan/fdpass/fdpass.h>
#include <ccan/io/fdpass/fdpass.h>
#include <ccan/io/io.h>
#include <ccan/list/list.h>
#include <ccan/noerr/noerr.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/take/take.h>
#include <ccan/tal/str/str.h>
#include <ccan/timer/timer.h>
#include <common/cryptomsg.h>
#include <common/daemon_conn.h>
#include <common/debug.h>
#include <common/ping.h>
#include <common/status.h>
#include <common/timeout.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <common/version.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <lightningd/gossip/broadcast.h>
#include <lightningd/gossip/gen_gossip_wire.h>
#include <lightningd/gossip/routing.h>
#include <lightningd/gossip_msg.h>
#include <secp256k1_ecdh.h>
#include <sodium/randombytes.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wire/gen_peer_wire.h>
#include <wire/wire_io.h>
struct daemon {
struct list_head peers;
/* Connection to main daemon. */
struct daemon_conn master;
/* Routing information */
struct routing_state *rstate;
struct timers timers;
u32 broadcast_interval;
};
struct peer {
struct daemon *daemon;
/* daemon->peers */
struct list_node list;
u64 unique_id;
struct peer_crypto_state pcs;
/* File descriptor corresponding to conn. */
int fd;
/* Our connection (and owner) */
struct io_conn *conn;
/* If this is non-NULL, it means we failed. */
const char *error;
/* High water mark for the staggered broadcast */
u64 broadcast_index;
/* Message queue for outgoing. */
struct msg_queue peer_out;
/* Is it time to continue the staggered broadcast? */
bool gossip_sync;
/* The peer owner will use this to talk to gossipd */
struct daemon_conn owner_conn;
/* How many pongs are we expecting? */
size_t num_pings_outstanding;
/* Are we the owner of the peer? */
bool local;
};
static void wake_pkt_out(struct peer *peer);
static void destroy_peer(struct peer *peer)
{
list_del_from(&peer->daemon->peers, &peer->list);
if (peer->error) {
u8 *msg = towire_gossipstatus_peer_bad_msg(peer,
peer->unique_id,
(u8 *)peer->error);
daemon_conn_send(&peer->daemon->master, take(msg));
}
}
static struct peer *setup_new_peer(struct daemon *daemon, const u8 *msg)
{
struct peer *peer = tal(daemon, struct peer);
init_peer_crypto_state(peer, &peer->pcs);
if (!fromwire_gossipctl_new_peer(msg, NULL, &peer->unique_id,
&peer->pcs.cs))
return tal_free(peer);
peer->daemon = daemon;
peer->error = NULL;
peer->local = true;
peer->num_pings_outstanding = 0;
peer->broadcast_index = 0;
msg_queue_init(&peer->peer_out, peer);
list_add_tail(&daemon->peers, &peer->list);
tal_add_destructor(peer, destroy_peer);
wake_pkt_out(peer);
return peer;
}
static struct peer *setup_new_remote_peer(struct daemon *daemon,
u64 unique_id, bool sync)
{
struct peer *peer = tal(daemon, struct peer);
peer->daemon = daemon;
peer->error = NULL;
peer->local = false;
peer->num_pings_outstanding = 0;
peer->fd = -1;
peer->unique_id = unique_id;
if (sync)
peer->broadcast_index = 0;
else
peer->broadcast_index = daemon->rstate->broadcasts->next_index;
msg_queue_init(&peer->peer_out, peer);
list_add_tail(&daemon->peers, &peer->list);
tal_add_destructor(peer, destroy_peer);
wake_pkt_out(peer);
return peer;
}
static struct io_plan *owner_msg_in(struct io_conn *conn,
struct daemon_conn *dc);
static struct io_plan *nonlocal_dump_gossip(struct io_conn *conn,
struct daemon_conn *dc);
/* When a peer is to be owned by another daemon, we create a socket
* pair to send/receive gossip from it */
static void send_peer_with_fds(struct peer *peer, const u8 *msg)
{
int fds[2];
u8 *out;
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
out = towire_gossipstatus_peer_failed(msg,
peer->unique_id,
(u8 *)tal_fmt(msg,
"Failed to create socketpair: %s",
strerror(errno)));
daemon_conn_send(&peer->daemon->master, take(out));
/* FIXME: Send error to peer? */
/* Peer will be freed when caller closes conn. */
return;
}
/* Now we talk to socket to get to peer's owner daemon. */
peer->local = false;
/* FIXME: Forget peer if other end is closed. */
daemon_conn_init(peer, &peer->owner_conn, fds[0], owner_msg_in, NULL);
peer->owner_conn.msg_queue_cleared_cb = nonlocal_dump_gossip;
/* Peer stays around, even though we're going to free conn. */
tal_steal(peer->daemon, peer);
daemon_conn_send(&peer->daemon->master, msg);
daemon_conn_send_fd(&peer->daemon->master, peer->fd);
daemon_conn_send_fd(&peer->daemon->master, fds[1]);
/* Don't get confused: we can't use this any more. */
peer->fd = -1;
}
static void handle_gossip_msg(struct routing_state *rstate, u8 *msg)
{
int t = fromwire_peektype(msg);
switch(t) {
case WIRE_CHANNEL_ANNOUNCEMENT:
handle_channel_announcement(rstate, msg, tal_count(msg));
break;
case WIRE_NODE_ANNOUNCEMENT:
handle_node_announcement(rstate, msg, tal_count(msg));
break;
case WIRE_CHANNEL_UPDATE:
handle_channel_update(rstate, msg, tal_count(msg));
break;
}
}
static bool handle_ping(struct peer *peer, u8 *ping)
{
u8 *pong;
if (!check_ping_make_pong(peer, ping, &pong)) {
peer->error = "Bad ping";
return false;
}
if (pong)
msg_enqueue(&peer->peer_out, take(pong));
return true;
}
static bool handle_pong(struct peer *peer, const u8 *pong)
{
u8 *ignored;
status_trace("Got pong!");
if (!fromwire_pong(pong, pong, NULL, &ignored)) {
peer->error = "pad pong";
return false;
}
if (!peer->num_pings_outstanding) {
peer->error = "unexpected pong";
return false;
}
peer->num_pings_outstanding--;
daemon_conn_send(&peer->daemon->master,
take(towire_gossip_ping_reply(pong, tal_len(pong))));
return true;
}
static struct io_plan *peer_msgin(struct io_conn *conn,
struct peer *peer, u8 *msg)
{
u8 *s;
enum wire_type t = fromwire_peektype(msg);
switch (t) {
case WIRE_ERROR:
/* FIXME: Report error from msg. */
peer->error = "ERROR message received";
return io_close(conn);
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
handle_gossip_msg(peer->daemon->rstate, msg);
return peer_read_message(conn, &peer->pcs, peer_msgin);
case WIRE_PING:
if (!handle_ping(peer, msg))
return io_close(conn);
return peer_read_message(conn, &peer->pcs, peer_msgin);
case WIRE_PONG:
if (!handle_pong(peer, msg))
return io_close(conn);
return peer_read_message(conn, &peer->pcs, peer_msgin);
case WIRE_OPEN_CHANNEL:
case WIRE_CHANNEL_REESTABLISH:
case WIRE_ACCEPT_CHANNEL:
case WIRE_FUNDING_CREATED:
case WIRE_FUNDING_SIGNED:
case WIRE_FUNDING_LOCKED:
case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_UPDATE_FEE:
case WIRE_SHUTDOWN:
case WIRE_CLOSING_SIGNED:
case WIRE_UPDATE_ADD_HTLC:
case WIRE_UPDATE_FULFILL_HTLC:
case WIRE_UPDATE_FAIL_HTLC:
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
case WIRE_COMMITMENT_SIGNED:
case WIRE_REVOKE_AND_ACK:
case WIRE_INIT:
/* Not our place to handle this, so we punt */
s = towire_gossipstatus_peer_nongossip(msg, peer->unique_id,
&peer->pcs.cs, msg);
send_peer_with_fds(peer, take(s));
return io_close_taken_fd(conn);
}
/* BOLT #1:
*
* The type follows the _it's ok to be odd_ rule, so nodes MAY send
* odd-numbered types without ascertaining that the recipient
* understands it. */
if (t & 1) {
status_trace("Peer %"PRIu64" sent unknown packet %u, ignoring",
peer->unique_id, t);
return peer_read_message(conn, &peer->pcs, peer_msgin);
}
peer->error = tal_fmt(peer, "Unknown packet %u", t);
return io_close(conn);
}
/* Wake up the outgoing direction of the connection and write any
* queued messages. Needed since the `io_wake` method signature does
* not allow us to specify it as the callback for `new_reltimer`, but
* it allows us to set an additional flag for the routing dump..
*/
static void wake_pkt_out(struct peer *peer)
{
peer->gossip_sync = true;
new_reltimer(&peer->daemon->timers, peer,
time_from_msec(peer->daemon->broadcast_interval),
wake_pkt_out, peer);
/* Notify the peer-write loop */
msg_wake(&peer->peer_out);
/* Notify the daemon_conn-write loop */
msg_wake(&peer->owner_conn.out);
}
static struct io_plan *peer_pkt_out(struct io_conn *conn, struct peer *peer)
{
/* First priority is queued packets, if any */
const u8 *out = msg_dequeue(&peer->peer_out);
if (out)
return peer_write_message(conn, &peer->pcs, take(out),
peer_pkt_out);
/* If we're supposed to be sending gossip, do so now. */
if (peer->gossip_sync) {
struct queued_message *next;
next = next_broadcast_message(peer->daemon->rstate->broadcasts,
&peer->broadcast_index);
if (next)
return peer_write_message(conn, &peer->pcs,
next->payload, peer_pkt_out);
/* Gossip is drained. Wait for next timer. */
peer->gossip_sync = false;
}
return msg_queue_wait(conn, &peer->peer_out, peer_pkt_out, peer);
}
/**
* owner_msg_in - Called by the `peer->owner_conn` upon receiving a
* message
*/
static struct io_plan *owner_msg_in(struct io_conn *conn,
struct daemon_conn *dc)
{
struct peer *peer = container_of(dc, struct peer, owner_conn);
u8 *msg = dc->msg_in;
int type = fromwire_peektype(msg);
if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE ||
type == WIRE_NODE_ANNOUNCEMENT) {
handle_gossip_msg(peer->daemon->rstate, dc->msg_in);
}
return daemon_conn_read_next(conn, dc);
}
/**
* nonlocal_dump_gossip - catch the nonlocal peer up with the latest gossip.
*
* Registered as `msg_queue_cleared_cb` by the `peer->owner_conn`.
*/
static struct io_plan *nonlocal_dump_gossip(struct io_conn *conn, struct daemon_conn *dc)
{
struct queued_message *next;
struct peer *peer = container_of(dc, struct peer, owner_conn);
/* Make sure we are not connected directly */
if (peer->local)
return msg_queue_wait(conn, &peer->owner_conn.out,
daemon_conn_write_next, dc);
next = next_broadcast_message(peer->daemon->rstate->broadcasts,
&peer->broadcast_index);
if (!next) {
return msg_queue_wait(conn, &peer->owner_conn.out,
daemon_conn_write_next, dc);
} else {
return io_write_wire(conn, next->payload, nonlocal_dump_gossip, dc);
}
}
static struct io_plan *peer_start_gossip(struct io_conn *conn, struct peer *peer)
{
/* Need to go duplex here, otherwise backpressure would mean
* we both wait indefinitely */
return io_duplex(conn,
peer_read_message(conn, &peer->pcs, peer_msgin),
peer_pkt_out(conn, peer));
}
static struct io_plan *new_peer_got_fd(struct io_conn *conn, struct peer *peer)
{
peer->conn = io_new_conn(conn, peer->fd, peer_start_gossip, peer);
if (!peer->conn) {
peer->error = "Could not create connection";
tal_free(peer);
} else {
/* If conn dies, we forget peer. */
tal_steal(peer->conn, peer);
}
return daemon_conn_read_next(conn,&peer->daemon->master);
}
static struct io_plan *new_peer(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
struct peer *peer = setup_new_peer(daemon, msg);
if (!peer)
status_failed(WIRE_GOSSIPSTATUS_BAD_NEW_PEER_REQUEST,
"%s", tal_hex(trc, msg));
return io_recv_fd(conn, &peer->fd, new_peer_got_fd, peer);
}
static struct peer *find_peer(struct daemon *daemon, u64 unique_id)
{
struct peer *peer;
list_for_each(&daemon->peers, peer, list)
if (peer->unique_id == unique_id)
return peer;
return NULL;
}
static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
u64 unique_id;
struct peer *peer;
if (!fromwire_gossipctl_release_peer(msg, NULL, &unique_id))
status_failed(WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST,
"%s", tal_hex(trc, msg));
peer = find_peer(daemon, unique_id);
if (!peer || !peer->local) {
/* This can happen with a reconnect vs connect race.
* See gossip_peer_released in master daemon. It may
* also happen if we asked to release just before
* failing the peer*/
daemon_conn_send(&daemon->master,
take(towire_gossipctl_release_peer_replyfail(msg)));
} else {
send_peer_with_fds(peer,
take(towire_gossipctl_release_peer_reply(msg,
&peer->pcs.cs)));
io_close_taken_fd(peer->conn);
}
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *fail_peer(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
u64 unique_id;
struct peer *peer;
if (!fromwire_gossipctl_fail_peer(msg, NULL, &unique_id))
status_failed(WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST,
"%s", tal_hex(trc, msg));
/* This may not find the peer, if we fail beforehand. */
peer = find_peer(daemon, unique_id);
if (!peer)
status_trace("Unknown fail_peer %"PRIu64, unique_id);
else if (peer->local) {
status_trace("fail_peer %"PRIu64, unique_id);
/* This owns the peer, so we can free it */
io_close(peer->conn);
} else {
status_trace("Could not fail_peer %"PRIu64", it's not local",
unique_id);
}
return daemon_conn_read_next(conn, &daemon->master);
}
static void forget_peer(struct io_conn *conn, struct daemon_conn *dc)
{
/* Free peer. */
tal_free(dc->ctx);
}
static struct io_plan *new_peer_fd(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
int fds[2];
u8 *out;
u64 unique_id;
bool sync;
struct peer *peer;
if (!fromwire_gossipctl_get_peer_gossipfd(msg, NULL,
&unique_id, &sync))
status_failed(WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST,
"%s", tal_hex(trc, msg));
peer = setup_new_remote_peer(daemon, unique_id, sync);
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
status_trace("Failed to create socketpair: %s",
strerror(errno));
out = towire_gossipctl_get_peer_gossipfd_replyfail(msg);
daemon_conn_send(&peer->daemon->master, take(out));
return daemon_conn_read_next(conn, &daemon->master);
}
daemon_conn_init(peer, &peer->owner_conn, fds[0], owner_msg_in,
forget_peer);
peer->owner_conn.msg_queue_cleared_cb = nonlocal_dump_gossip;
out = towire_gossipctl_get_peer_gossipfd_reply(msg);
daemon_conn_send(&peer->daemon->master, out);
daemon_conn_send_fd(&peer->daemon->master, fds[1]);
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
u8 *msg)
{
tal_t *tmpctx = tal_tmpctx(msg);
struct pubkey source, destination;
u32 msatoshi;
u16 riskfactor;
u8 *out;
struct route_hop *hops;
fromwire_gossip_getroute_request(msg, NULL, &source, &destination,
&msatoshi, &riskfactor);
status_trace("Trying to find a route from %s to %s for %d msatoshi",
pubkey_to_hexstr(tmpctx, &source),
pubkey_to_hexstr(tmpctx, &destination), msatoshi);
hops = get_route(tmpctx, daemon->rstate, &source, &destination,
msatoshi, 1);
out = towire_gossip_getroute_reply(msg, hops);
tal_free(tmpctx);
daemon_conn_send(&daemon->master, out);
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *getchannels_req(struct io_conn *conn, struct daemon *daemon,
u8 *msg)
{
tal_t *tmpctx = tal_tmpctx(daemon);
u8 *out;
size_t j, num_chans = 0;
struct gossip_getchannels_entry *entries;
struct node *n;
struct node_map_iter i;
entries = tal_arr(tmpctx, struct gossip_getchannels_entry, num_chans);
n = node_map_first(daemon->rstate->nodes, &i);
while (n != NULL) {
for (j=0; j<tal_count(n->out); j++){
tal_resize(&entries, num_chans + 1);
entries[num_chans].source = n->out[j]->src->id;
entries[num_chans].destination = n->out[j]->dst->id;
entries[num_chans].active = n->out[j]->active;
entries[num_chans].delay = n->out[j]->delay;
entries[num_chans].fee_per_kw = n->out[j]->proportional_fee;
entries[num_chans].last_update_timestamp = n->out[j]->last_timestamp;
entries[num_chans].flags = n->out[j]->flags;
entries[num_chans].short_channel_id = n->out[j]->short_channel_id;
num_chans++;
}
n = node_map_next(daemon->rstate->nodes, &i);
}
out = towire_gossip_getchannels_reply(daemon, entries);
daemon_conn_send(&daemon->master, take(out));
tal_free(tmpctx);
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon)
{
tal_t *tmpctx = tal_tmpctx(daemon);
u8 *out;
struct node *n;
struct node_map_iter i;
struct gossip_getnodes_entry *nodes;
size_t node_count = 0;
nodes = tal_arr(tmpctx, struct gossip_getnodes_entry, node_count);
n = node_map_first(daemon->rstate->nodes, &i);
while (n != NULL) {
tal_resize(&nodes, node_count + 1);
nodes[node_count].nodeid = n->id;
nodes[node_count].addresses = n->addresses;
node_count++;
n = node_map_next(daemon->rstate->nodes, &i);
}
out = towire_gossip_getnodes_reply(daemon, nodes);
daemon_conn_send(&daemon->master, take(out));
tal_free(tmpctx);
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
u64 unique_id;
u16 num_pong_bytes, len;
struct peer *peer;
u8 *ping;
if (!fromwire_gossip_ping(msg, NULL, &unique_id, &num_pong_bytes, &len))
status_failed(WIRE_GOSSIPSTATUS_BAD_REQUEST,
"%s", tal_hex(trc, msg));
peer = find_peer(daemon, unique_id);
if (!peer)
status_failed(WIRE_GOSSIPSTATUS_BAD_REQUEST,
"Unknown peer %"PRIu64, unique_id);
ping = make_ping(peer, num_pong_bytes, len);
if (tal_len(ping) > 65535)
status_failed(WIRE_GOSSIPSTATUS_BAD_REQUEST, "Oversize ping");
msg_enqueue(&peer->peer_out, take(ping));
status_trace("sending ping expecting %sresponse",
num_pong_bytes >= 65532 ? "no " : "");
/* BOLT #1:
*
* if `num_pong_bytes` is less than 65532 it MUST respond by sending a
* `pong` message with `byteslen` equal to `num_pong_bytes`, otherwise
* it MUST ignore the `ping`.
*/
if (num_pong_bytes >= 65532)
daemon_conn_send(&daemon->master,
take(towire_gossip_ping_reply(peer, 0)));
else
peer->num_pings_outstanding++;
return daemon_conn_read_next(conn, &daemon->master);
}
/* Parse an incoming gossip init message and assign config variables
* to the daemon.
*/
static struct io_plan *gossip_init(struct daemon_conn *master,
struct daemon *daemon, u8 *msg)
{
struct sha256_double chain_hash;
if (!fromwire_gossipctl_init(msg, NULL, &daemon->broadcast_interval,
&chain_hash)) {
status_failed(WIRE_GOSSIPSTATUS_INIT_FAILED,
"Unable to parse init message");
}
daemon->rstate = new_routing_state(daemon, &chain_hash);
return daemon_conn_read_next(master->conn, master);
}
static struct io_plan *resolve_channel_req(struct io_conn *conn,
struct daemon *daemon, const u8 *msg)
{
struct short_channel_id scid;
struct node_connection *nc;
struct pubkey *keys;
if (!fromwire_gossip_resolve_channel_request(msg, NULL, &scid))
status_failed(WIRE_GOSSIPSTATUS_BAD_REQUEST,
"Unable to parse resolver request");
nc = get_connection_by_scid(daemon->rstate, &scid, 0);
if (!nc) {
status_trace("Failed to resolve channel %s",
type_to_string(trc, struct short_channel_id, &scid));
keys = NULL;
} else {
keys = tal_arr(msg, struct pubkey, 2);
keys[0] = nc->src->id;
keys[1] = nc->dst->id;
status_trace("Resolved channel %s %s<->%s",
type_to_string(trc, struct short_channel_id, &scid),
type_to_string(trc, struct pubkey, &keys[0]),
type_to_string(trc, struct pubkey, &keys[1]));
}
daemon_conn_send(&daemon->master,
take(towire_gossip_resolve_channel_reply(msg, keys)));
return daemon_conn_read_next(conn, &daemon->master);
}
static void handle_forwarded_msg(struct io_conn *conn, struct daemon *daemon, const u8 *msg)
{
u8 *payload;
if (!fromwire_gossip_forwarded_msg(msg, msg, NULL, &payload)) {
status_trace("Malformed forwarded message: %s", tal_hex(trc, msg));
return;
}
handle_gossip_msg(daemon->rstate, payload);
}
static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master)
{
struct daemon *daemon = container_of(master, struct daemon, master);
enum gossip_wire_type t = fromwire_peektype(master->msg_in);
status_trace("req: type %s len %zu",
gossip_wire_type_name(t), tal_count(master->msg_in));
switch (t) {
case WIRE_GOSSIPCTL_INIT:
return gossip_init(master, daemon, master->msg_in);
case WIRE_GOSSIPCTL_NEW_PEER:
return new_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIPCTL_RELEASE_PEER:
return release_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIPCTL_FAIL_PEER:
return fail_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD:
return new_peer_fd(conn, daemon, master->msg_in);
case WIRE_GOSSIP_GETNODES_REQUEST:
return getnodes(conn, daemon);
case WIRE_GOSSIP_GETROUTE_REQUEST:
return getroute_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
return getchannels_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_PING:
return ping_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_RESOLVE_CHANNEL_REQUEST:
return resolve_channel_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_FORWARDED_MSG:
handle_forwarded_msg(conn, daemon, daemon->master.msg_in);
return daemon_conn_read_next(conn, &daemon->master);
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLY:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLYFAIL:
case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY:
case WIRE_GOSSIP_PING_REPLY:
case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY:
case WIRE_GOSSIPSTATUS_INIT_FAILED:
case WIRE_GOSSIPSTATUS_BAD_NEW_PEER_REQUEST:
case WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST:
case WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST:
case WIRE_GOSSIPSTATUS_BAD_REQUEST:
case WIRE_GOSSIPSTATUS_FDPASS_FAILED:
case WIRE_GOSSIPSTATUS_PEER_BAD_MSG:
case WIRE_GOSSIPSTATUS_PEER_FAILED:
case WIRE_GOSSIPSTATUS_PEER_NONGOSSIP:
break;
}
/* Control shouldn't give bad requests. */
status_failed(WIRE_GOSSIPSTATUS_BAD_REQUEST, "%i", t);
}
#ifndef TESTING
static void master_gone(struct io_conn *unused, struct daemon_conn *dc)
{
/* Can't tell master, it's gone. */
exit(2);
}
int main(int argc, char *argv[])
{
struct daemon *daemon;
subdaemon_debug(argc, argv);
if (argc == 2 && streq(argv[1], "--version")) {
printf("%s\n", version());
exit(0);
}
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY |
SECP256K1_CONTEXT_SIGN);
daemon = tal(NULL, struct daemon);
list_head_init(&daemon->peers);
timers_init(&daemon->timers, time_mono());
daemon->broadcast_interval = 30000;
/* stdin == control */
daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req,
master_gone);
status_setup_async(&daemon->master);
/* When conn closes, everything is freed. */
tal_steal(daemon->master.conn, daemon);
for (;;) {
struct timer *expired = NULL;
io_loop(&daemon->timers, &expired);
if (!expired) {
break;
} else {
timer_expired(daemon, expired);
}
}
return 0;
}
#endif

View File

@@ -1,122 +0,0 @@
# These are fatal.
gossipstatus_init_failed,0x8000
gossipstatus_bad_new_peer_request,0x8001
gossipstatus_bad_release_request,0x8002
gossipstatus_bad_fail_request,0x8003
gossipstatus_bad_request,0x8004
gossipstatus_fdpass_failed,0x8005
# Peers can give a bad message, we close their fd, but no harm done.
gossipstatus_peer_bad_msg,1000
gossipstatus_peer_bad_msg,,unique_id,8
gossipstatus_peer_bad_msg,,len,2
gossipstatus_peer_bad_msg,,err,len*u8
# Misc problems like opening control fd.
gossipstatus_peer_failed,1001
gossipstatus_peer_failed,,unique_id,8
gossipstatus_peer_failed,,len,2
gossipstatus_peer_failed,,err,len*u8
#include <common/cryptomsg.h>
# Initialize the gossip daemon
gossipctl_init,0
gossipctl_init,,broadcast_interval,4
gossipctl_init,,chain_hash,struct sha256_double
# These take an fd, but have no response
# (if it is to move onto a channel, we get a status msg).
gossipctl_new_peer,1
gossipctl_new_peer,,unique_id,8
gossipctl_new_peer,,crypto_state,struct crypto_state
# Tell it to release a peer which has initialized.
gossipctl_release_peer,2
gossipctl_release_peer,,unique_id,8
# This releases the peer and returns the cryptostate (followed two fds: peer and gossip)
gossipctl_release_peer_reply,102
gossipctl_release_peer_reply,,crypto_state,struct crypto_state
# This is if we couldn't find the peer.
gossipctl_release_peer_replyfail,202
# This is where we save a peer's features.
#gossipstatus_peer_features,1
#gossipstatus_peer_features,,unique_id,8
#gossipstatus_peer_features,,gflen,2
#gossipstatus_peer_features,,globalfeatures,gflen
#gossipstatus_peer_features,,lflen,2
#gossipstatus_peer_features,,localfeatures,lflen
# Peer can send non-gossip packet (usually an open_channel) (followed two fds: peer and gossip)
gossipstatus_peer_nongossip,4
gossipstatus_peer_nongossip,,unique_id,8
gossipstatus_peer_nongossip,,crypto_state,struct crypto_state
gossipstatus_peer_nongossip,,len,2
gossipstatus_peer_nongossip,,msg,len*u8
# Pass JSON-RPC getnodes call through
gossip_getnodes_request,5
#include <lightningd/gossip_msg.h>
gossip_getnodes_reply,105
gossip_getnodes_reply,,num_nodes,u16
gossip_getnodes_reply,,nodes,num_nodes*struct gossip_getnodes_entry
# Pass JSON-RPC getroute call through
gossip_getroute_request,6
gossip_getroute_request,,source,struct pubkey
gossip_getroute_request,,destination,struct pubkey
gossip_getroute_request,,msatoshi,u32
gossip_getroute_request,,riskfactor,u16
gossip_getroute_reply,106
gossip_getroute_reply,,num_hops,u16
gossip_getroute_reply,,hops,num_hops*struct route_hop
gossip_getchannels_request,7
gossip_getchannels_reply,107
gossip_getchannels_reply,,num_channels,u16
gossip_getchannels_reply,,nodes,num_channels*struct gossip_getchannels_entry
# Ping/pong test.
gossip_ping,8
gossip_ping,,unique_id,u64
gossip_ping,,num_pong_bytes,u16
gossip_ping,,len,u16
gossip_ping_reply,108
gossip_ping_reply,,totlen,u16
# Given a short_channel_id, return the endpoints
gossip_resolve_channel_request,9
gossip_resolve_channel_request,,channel_id,struct short_channel_id
gossip_resolve_channel_reply,109
gossip_resolve_channel_reply,,num_keys,u16
gossip_resolve_channel_reply,,keys,num_keys*struct pubkey
# The main daemon forward some gossip message to gossipd, allows injecting
# arbitrary gossip messages.
gossip_forwarded_msg,10
gossip_forwarded_msg,,msglen,2
gossip_forwarded_msg,,msg,msglen
# If peer is still connected, fail it (master does this for reconnect)
gossipctl_fail_peer,11
gossipctl_fail_peer,,unique_id,8
# Get a gossip fd for this peer (it has reconnected)
gossipctl_get_peer_gossipfd,12
gossipctl_get_peer_gossipfd,,unique_id,u64
# Does it want a full dump of gossip?
gossipctl_get_peer_gossipfd,,sync,bool
# + fd.
gossipctl_get_peer_gossipfd_reply,112
# Failure (can't make new socket)
gossipctl_get_peer_gossipfd_replyfail,212
1 # These are fatal.
2 gossipstatus_init_failed,0x8000
3 gossipstatus_bad_new_peer_request,0x8001
4 gossipstatus_bad_release_request,0x8002
5 gossipstatus_bad_fail_request,0x8003
6 gossipstatus_bad_request,0x8004
7 gossipstatus_fdpass_failed,0x8005
8 # Peers can give a bad message, we close their fd, but no harm done.
9 gossipstatus_peer_bad_msg,1000
10 gossipstatus_peer_bad_msg,,unique_id,8
11 gossipstatus_peer_bad_msg,,len,2
12 gossipstatus_peer_bad_msg,,err,len*u8
13 # Misc problems like opening control fd.
14 gossipstatus_peer_failed,1001
15 gossipstatus_peer_failed,,unique_id,8
16 gossipstatus_peer_failed,,len,2
17 gossipstatus_peer_failed,,err,len*u8
18 #include <common/cryptomsg.h>
19 # Initialize the gossip daemon
20 gossipctl_init,0
21 gossipctl_init,,broadcast_interval,4
22 gossipctl_init,,chain_hash,struct sha256_double
23 # These take an fd, but have no response
24 # (if it is to move onto a channel, we get a status msg).
25 gossipctl_new_peer,1
26 gossipctl_new_peer,,unique_id,8
27 gossipctl_new_peer,,crypto_state,struct crypto_state
28 # Tell it to release a peer which has initialized.
29 gossipctl_release_peer,2
30 gossipctl_release_peer,,unique_id,8
31 # This releases the peer and returns the cryptostate (followed two fds: peer and gossip)
32 gossipctl_release_peer_reply,102
33 gossipctl_release_peer_reply,,crypto_state,struct crypto_state
34 # This is if we couldn't find the peer.
35 gossipctl_release_peer_replyfail,202
36 # This is where we save a peer's features.
37 #gossipstatus_peer_features,1
38 #gossipstatus_peer_features,,unique_id,8
39 #gossipstatus_peer_features,,gflen,2
40 #gossipstatus_peer_features,,globalfeatures,gflen
41 #gossipstatus_peer_features,,lflen,2
42 #gossipstatus_peer_features,,localfeatures,lflen
43 # Peer can send non-gossip packet (usually an open_channel) (followed two fds: peer and gossip)
44 gossipstatus_peer_nongossip,4
45 gossipstatus_peer_nongossip,,unique_id,8
46 gossipstatus_peer_nongossip,,crypto_state,struct crypto_state
47 gossipstatus_peer_nongossip,,len,2
48 gossipstatus_peer_nongossip,,msg,len*u8
49 # Pass JSON-RPC getnodes call through
50 gossip_getnodes_request,5
51 #include <lightningd/gossip_msg.h>
52 gossip_getnodes_reply,105
53 gossip_getnodes_reply,,num_nodes,u16
54 gossip_getnodes_reply,,nodes,num_nodes*struct gossip_getnodes_entry
55 # Pass JSON-RPC getroute call through
56 gossip_getroute_request,6
57 gossip_getroute_request,,source,struct pubkey
58 gossip_getroute_request,,destination,struct pubkey
59 gossip_getroute_request,,msatoshi,u32
60 gossip_getroute_request,,riskfactor,u16
61 gossip_getroute_reply,106
62 gossip_getroute_reply,,num_hops,u16
63 gossip_getroute_reply,,hops,num_hops*struct route_hop
64 gossip_getchannels_request,7
65 gossip_getchannels_reply,107
66 gossip_getchannels_reply,,num_channels,u16
67 gossip_getchannels_reply,,nodes,num_channels*struct gossip_getchannels_entry
68 # Ping/pong test.
69 gossip_ping,8
70 gossip_ping,,unique_id,u64
71 gossip_ping,,num_pong_bytes,u16
72 gossip_ping,,len,u16
73 gossip_ping_reply,108
74 gossip_ping_reply,,totlen,u16
75 # Given a short_channel_id, return the endpoints
76 gossip_resolve_channel_request,9
77 gossip_resolve_channel_request,,channel_id,struct short_channel_id
78 gossip_resolve_channel_reply,109
79 gossip_resolve_channel_reply,,num_keys,u16
80 gossip_resolve_channel_reply,,keys,num_keys*struct pubkey
81 # The main daemon forward some gossip message to gossipd, allows injecting
82 # arbitrary gossip messages.
83 gossip_forwarded_msg,10
84 gossip_forwarded_msg,,msglen,2
85 gossip_forwarded_msg,,msg,msglen
86 # If peer is still connected, fail it (master does this for reconnect)
87 gossipctl_fail_peer,11
88 gossipctl_fail_peer,,unique_id,8
89 # Get a gossip fd for this peer (it has reconnected)
90 gossipctl_get_peer_gossipfd,12
91 gossipctl_get_peer_gossipfd,,unique_id,u64
92 # Does it want a full dump of gossip?
93 gossipctl_get_peer_gossipfd,,sync,bool
94 # + fd.
95 gossipctl_get_peer_gossipfd_reply,112
96 # Failure (can't make new socket)
97 gossipctl_get_peer_gossipfd_replyfail,212

View File

@@ -1,929 +0,0 @@
#include "routing.h"
#include <arpa/inet.h>
#include <bitcoin/block.h>
#include <ccan/array_size/array_size.h>
#include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/endian/endian.h>
#include <ccan/structeq/structeq.h>
#include <ccan/tal/str/str.h>
#include <common/overflows.h>
#include <common/pseudorand.h>
#include <common/status.h>
#include <common/type_to_string.h>
#include <inttypes.h>
#include <wire/gen_peer_wire.h>
/* 365.25 * 24 * 60 / 10 */
#define BLOCKS_PER_YEAR 52596
struct routing_state *new_routing_state(const tal_t *ctx,
const struct sha256_double *chain_hash)
{
struct routing_state *rstate = tal(ctx, struct routing_state);
rstate->nodes = empty_node_map(rstate);
rstate->broadcasts = new_broadcast_state(rstate);
rstate->chain_hash = *chain_hash;
return rstate;
}
const secp256k1_pubkey *node_map_keyof_node(const struct node *n)
{
return &n->id.pubkey;
}
size_t node_map_hash_key(const secp256k1_pubkey *key)
{
return siphash24(siphash_seed(), key, sizeof(*key));
}
bool node_map_node_eq(const struct node *n, const secp256k1_pubkey *key)
{
return structeq(&n->id.pubkey, key);
}
struct node_map *empty_node_map(const tal_t *ctx)
{
struct node_map *map = tal(ctx, struct node_map);
node_map_init(map);
return map;
}
struct node *get_node(struct routing_state *rstate,
const struct pubkey *id)
{
return node_map_get(rstate->nodes, &id->pubkey);
}
static void destroy_node(struct node *node)
{
/* These remove themselves from the array. */
while (tal_count(node->in))
tal_free(node->in[0]);
while (tal_count(node->out))
tal_free(node->out[0]);
}
struct node *new_node(struct routing_state *rstate,
const struct pubkey *id)
{
struct node *n;
assert(!get_node(rstate, id));
n = tal(rstate, struct node);
n->id = *id;
n->in = tal_arr(n, struct node_connection *, 0);
n->out = tal_arr(n, struct node_connection *, 0);
n->alias = NULL;
n->node_announcement = NULL;
n->last_timestamp = 0;
n->addresses = tal_arr(n, struct ipaddr, 0);
node_map_add(rstate->nodes, n);
tal_add_destructor(n, destroy_node);
return n;
}
struct node *add_node(
struct routing_state *rstate,
const struct pubkey *pk)
{
struct node *n = get_node(rstate, pk);
if (!n) {
n = new_node(rstate, pk);
status_trace("Creating new node %s",
type_to_string(trc, struct pubkey, pk));
} else {
status_trace("Update existing node %s",
type_to_string(trc, struct pubkey, pk));
}
return n;
}
static bool remove_conn_from_array(struct node_connection ***conns,
struct node_connection *nc)
{
size_t i, n;
n = tal_count(*conns);
for (i = 0; i < n; i++) {
if ((*conns)[i] != nc)
continue;
n--;
memmove(*conns + i, *conns + i + 1, sizeof(**conns) * (n - i));
tal_resize(conns, n);
return true;
}
return false;
}
static void destroy_connection(struct node_connection *nc)
{
if (!remove_conn_from_array(&nc->dst->in, nc)
|| !remove_conn_from_array(&nc->src->out, nc))
/* FIXME! */
abort();
}
struct node_connection * get_connection(struct routing_state *rstate,
const struct pubkey *from_id,
const struct pubkey *to_id)
{
int i, n;
struct node *from, *to;
from = get_node(rstate, from_id);
to = get_node(rstate, to_id);
if (!from || ! to)
return NULL;
n = tal_count(to->in);
for (i = 0; i < n; i++) {
if (to->in[i]->src == from)
return to->in[i];
}
return NULL;
}
struct node_connection *get_connection_by_scid(const struct routing_state *rstate,
const struct short_channel_id *schanid,
const u8 direction)
{
struct node *n;
int i, num_conn;
struct node_map *nodes = rstate->nodes;
struct node_connection *c;
struct node_map_iter it;
//FIXME(cdecker) We probably want to speed this up by indexing by chanid.
for (n = node_map_first(nodes, &it); n; n = node_map_next(nodes, &it)) {
num_conn = tal_count(n->out);
for (i = 0; i < num_conn; i++){
c = n->out[i];
if (short_channel_id_eq(&c->short_channel_id, schanid) &&
(c->flags&0x1) == direction)
return c;
}
}
return NULL;
}
static struct node_connection *
get_or_make_connection(struct routing_state *rstate,
const struct pubkey *from_id,
const struct pubkey *to_id)
{
size_t i, n;
struct node *from, *to;
struct node_connection *nc;
from = get_node(rstate, from_id);
if (!from)
from = new_node(rstate, from_id);
to = get_node(rstate, to_id);
if (!to)
to = new_node(rstate, to_id);
n = tal_count(to->in);
for (i = 0; i < n; i++) {
if (to->in[i]->src == from) {
status_trace("Updating existing route from %s to %s",
type_to_string(trc, struct pubkey,
&from->id),
type_to_string(trc, struct pubkey,
&to->id));
return to->in[i];
}
}
status_trace("Creating new route from %s to %s",
type_to_string(trc, struct pubkey, &from->id),
type_to_string(trc, struct pubkey, &to->id));
nc = tal(rstate, struct node_connection);
nc->src = from;
nc->dst = to;
nc->channel_announcement = NULL;
nc->channel_update = NULL;
/* Hook it into in/out arrays. */
i = tal_count(to->in);
tal_resize(&to->in, i+1);
to->in[i] = nc;
i = tal_count(from->out);
tal_resize(&from->out, i+1);
from->out[i] = nc;
tal_add_destructor(nc, destroy_connection);
return nc;
}
struct node_connection *half_add_connection(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to,
const struct short_channel_id *schanid,
const u16 flags
)
{
struct node_connection *nc;
nc = get_or_make_connection(rstate, from, to);
nc->short_channel_id = *schanid;
nc->active = false;
nc->last_timestamp = 0;
nc->flags = flags;
nc->min_blocks = 0;
nc->proportional_fee = 0;
nc->base_fee = 0;
nc->delay = 0;
return nc;
}
/* Updates existing route if required. */
struct node_connection *add_connection(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to,
u32 base_fee, s32 proportional_fee,
u32 delay, u32 min_blocks)
{
struct node_connection *c = get_or_make_connection(rstate, from, to);
c->base_fee = base_fee;
c->proportional_fee = proportional_fee;
c->delay = delay;
c->min_blocks = min_blocks;
c->active = true;
c->last_timestamp = 0;
memset(&c->short_channel_id, 0, sizeof(c->short_channel_id));
c->flags = get_channel_direction(from, to);
return c;
}
void remove_connection(struct routing_state *rstate,
const struct pubkey *src, const struct pubkey *dst)
{
struct node *from, *to;
size_t i, num_edges;
status_trace("Removing route from %s to %s",
type_to_string(trc, struct pubkey, src),
type_to_string(trc, struct pubkey, dst));
from = get_node(rstate, src);
to = get_node(rstate, dst);
if (!from || !to) {
status_trace("Not found: src=%p dst=%p", from, to);
return;
}
num_edges = tal_count(from->out);
for (i = 0; i < num_edges; i++) {
if (from->out[i]->dst != to)
continue;
status_trace("Matched route %zu of %zu", i, num_edges);
/* Destructor makes it delete itself */
tal_free(from->out[i]);
return;
}
status_trace(" None of %zu routes matched", num_edges);
}
/* Too big to reach, but don't overflow if added. */
#define INFINITE 0x3FFFFFFFFFFFFFFFULL
static void clear_bfg(struct node_map *nodes)
{
struct node *n;
struct node_map_iter it;
for (n = node_map_first(nodes, &it); n; n = node_map_next(nodes, &it)) {
size_t i;
for (i = 0; i < ARRAY_SIZE(n->bfg); i++) {
n->bfg[i].total = INFINITE;
n->bfg[i].risk = 0;
}
}
}
s64 connection_fee(const struct node_connection *c, u64 msatoshi)
{
s64 fee;
if (mul_overflows_s64(c->proportional_fee, msatoshi))
return INFINITE;
fee = (c->proportional_fee * msatoshi) / 1000000;
/* This can't overflow: c->base_fee is a u32 */
return c->base_fee + fee;
}
/* Risk of passing through this channel. We insert a tiny constant here
* in order to prefer shorter routes, all things equal. */
static u64 risk_fee(s64 amount, u32 delay, double riskfactor)
{
/* If fees are so negative we're making money, ignore risk. */
if (amount < 0)
return 1;
return 1 + amount * delay * riskfactor / BLOCKS_PER_YEAR / 10000;
}
/* We track totals, rather than costs. That's because the fee depends
* on the current amount passing through. */
static void bfg_one_edge(struct node *node, size_t edgenum, double riskfactor)
{
struct node_connection *c = node->in[edgenum];
size_t h;
assert(c->dst == node);
for (h = 0; h < ROUTING_MAX_HOPS; h++) {
/* FIXME: Bias against smaller channels. */
s64 fee = connection_fee(c, node->bfg[h].total);
u64 risk = node->bfg[h].risk + risk_fee(node->bfg[h].total + fee,
c->delay, riskfactor);
if (node->bfg[h].total + (s64)fee + (s64)risk
< c->src->bfg[h+1].total + (s64)c->src->bfg[h+1].risk) {
c->src->bfg[h+1].total = node->bfg[h].total + fee;
c->src->bfg[h+1].risk = risk;
c->src->bfg[h+1].prev = c;
}
}
}
struct node_connection *
find_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *from, const struct pubkey *to, u64 msatoshi,
double riskfactor, s64 *fee, struct node_connection ***route)
{
struct node *n, *src, *dst;
struct node_map_iter it;
struct node_connection *first_conn;
int runs, i, best;
/* Note: we map backwards, since we know the amount of satoshi we want
* at the end, and need to derive how much we need to send. */
dst = get_node(rstate, from);
src = get_node(rstate, to);
if (!src) {
status_trace("find_route: cannot find %s",
type_to_string(trc, struct pubkey, to));
return NULL;
} else if (!dst) {
status_trace("find_route: cannot find myself (%s)",
type_to_string(trc, struct pubkey, to));
return NULL;
} else if (dst == src) {
status_trace("find_route: this is %s, refusing to create empty route",
type_to_string(trc, struct pubkey, to));
return NULL;
}
/* Reset all the information. */
clear_bfg(rstate->nodes);
/* Bellman-Ford-Gibson: like Bellman-Ford, but keep values for
* every path length. */
src->bfg[0].total = msatoshi;
src->bfg[0].risk = 0;
for (runs = 0; runs < ROUTING_MAX_HOPS; runs++) {
status_trace("Run %i", runs);
/* Run through every edge. */
for (n = node_map_first(rstate->nodes, &it);
n;
n = node_map_next(rstate->nodes, &it)) {
size_t num_edges = tal_count(n->in);
for (i = 0; i < num_edges; i++) {
if (!n->in[i]->active)
continue;
bfg_one_edge(n, i, riskfactor);
status_trace("We seek %p->%p, this is %p -> %p",
dst, src,
n->in[i]->src, n->in[i]->dst);
status_trace("Checking from %s to %s",
type_to_string(trc,
struct pubkey,
&n->in[i]->src->id),
type_to_string(trc,
struct pubkey,
&n->in[i]->dst->id));
}
}
}
best = 0;
for (i = 1; i <= ROUTING_MAX_HOPS; i++) {
if (dst->bfg[i].total < dst->bfg[best].total)
best = i;
}
/* No route? */
if (dst->bfg[best].total >= INFINITE) {
status_trace("find_route: No route to %s",
type_to_string(trc, struct pubkey, to));
return NULL;
}
/* Save route from *next* hop (we return first hop as peer).
* Note that we take our own fees into account for routing, even
* though we don't pay them: it presumably effects preference. */
first_conn = dst->bfg[best].prev;
dst = dst->bfg[best].prev->dst;
best--;
*fee = dst->bfg[best].total - msatoshi;
*route = tal_arr(ctx, struct node_connection *, best);
for (i = 0, n = dst;
i < best;
n = n->bfg[best-i].prev->dst, i++) {
(*route)[i] = n->bfg[best-i].prev;
}
assert(n == src);
msatoshi += *fee;
status_trace("find_route: via %s",
type_to_string(trc, struct pubkey, &first_conn->dst->id));
/* If there are intermidiaries, dump them, and total fees. */
if (best != 0) {
for (i = 0; i < best; i++) {
status_trace(" %s (%i+%i=%"PRIu64")",
type_to_string(trc, struct pubkey,
&(*route)[i]->dst->id),
(*route)[i]->base_fee,
(*route)[i]->proportional_fee,
connection_fee((*route)[i], msatoshi));
msatoshi -= connection_fee((*route)[i], msatoshi);
}
status_trace(" =%"PRIi64"(%+"PRIi64")",
(*route)[best-1]->dst->bfg[best-1].total, *fee);
}
return first_conn;
}
bool add_channel_direction(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to,
const struct short_channel_id *short_channel_id,
const u8 *announcement)
{
struct node_connection *c = get_connection(rstate, from, to);
u16 direction = get_channel_direction(from, to);
if (c){
/* Do not clobber connections added otherwise */
memcpy(&c->short_channel_id, short_channel_id,
sizeof(c->short_channel_id));
c->flags = direction;
return false;
}else if(get_connection_by_scid(rstate, short_channel_id, direction)) {
return false;
}
c = half_add_connection(rstate, from, to, short_channel_id, direction);
/* Remember the announcement so we can forward it to new peers */
tal_free(c->channel_announcement);
c->channel_announcement = tal_dup_arr(c, u8, announcement,
tal_count(announcement), 0);
return true;
}
/* BOLT #7:
*
* The following `address descriptor` types are defined:
*
* * `0`: padding. data = none (length 0).
* * `1`: ipv4. data = `[4:ipv4_addr][2:port]` (length 6)
* * `2`: ipv6. data = `[16:ipv6_addr][2:port]` (length 18)
*/
/* FIXME: Don't just take first one, depends whether we have IPv6 ourselves */
/* Returns false iff it was malformed */
bool read_ip(const tal_t *ctx, const u8 *addresses, char **hostname,
int *port)
{
size_t len = tal_count(addresses);
const u8 *p = addresses;
char tempaddr[INET6_ADDRSTRLEN];
be16 portnum;
*hostname = NULL;
while (len) {
u8 type = *p;
p++;
len--;
switch (type) {
case 0:
break;
case 1:
/* BOLT #7:
*
* The receiving node SHOULD fail the connection if
* `addrlen` is insufficient to hold the address
* descriptors of the known types.
*/
if (len < 6)
return false;
inet_ntop(AF_INET, p, tempaddr, sizeof(tempaddr));
memcpy(&portnum, p + 4, sizeof(portnum));
*hostname = tal_strdup(ctx, tempaddr);
*port = be16_to_cpu(portnum);
return true;
case 2:
if (len < 18)
return false;
inet_ntop(AF_INET6, p, tempaddr, sizeof(tempaddr));
memcpy(&portnum, p + 16, sizeof(portnum));
*hostname = tal_strdup(ctx, tempaddr);
*port = be16_to_cpu(portnum);
return true;
default:
/* BOLT #7:
*
* The receiving node SHOULD ignore the first `address
* descriptor` which does not match the types defined
* above.
*/
return true;
}
}
/* Not a fatal error. */
return true;
}
/* BOLT #7:
*
* The creating node SHOULD fill `addresses` with an address descriptor for
* each public network address which expects incoming connections, and MUST
* set `addrlen` to the number of bytes in `addresses`. Non-zero typed
* address descriptors MUST be placed in ascending order; any number of
* zero-typed address descriptors MAY be placed anywhere, but SHOULD only be
* used for aligning fields following `addresses`.
*
* The creating node MUST NOT create a type 1 or type 2 address descriptor
* with `port` equal to zero, and SHOULD ensure `ipv4_addr` and `ipv6_addr`
* are routable addresses. The creating node MUST NOT include more than one
* `address descriptor` of the same type.
*/
/* FIXME: handle case where we have both ipv6 and ipv4 addresses! */
u8 *write_ip(const tal_t *ctx, const char *srcip, int port)
{
u8 *address;
be16 portnum = cpu_to_be16(port);
if (!port)
return tal_arr(ctx, u8, 0);
if (!strchr(srcip, ':')) {
address = tal_arr(ctx, u8, 7);
address[0] = 1;
inet_pton(AF_INET, srcip, address+1);
memcpy(address + 5, &portnum, sizeof(portnum));
return address;
} else {
address = tal_arr(ctx, u8, 18);
address[0] = 2;
inet_pton(AF_INET6, srcip, address+1);
memcpy(address + 17, &portnum, sizeof(portnum));
return address;
}
}
/* Verify the signature of a channel_update message */
static bool check_channel_update(const struct pubkey *node_key,
const secp256k1_ecdsa_signature *node_sig,
const u8 *update)
{
/* 2 byte msg type + 64 byte signatures */
int offset = 66;
struct sha256_double hash;
sha256_double(&hash, update + offset, tal_len(update) - offset);
return check_signed_hash(&hash, node_sig, node_key);
}
static bool check_channel_announcement(
const struct pubkey *node1_key, const struct pubkey *node2_key,
const struct pubkey *bitcoin1_key, const struct pubkey *bitcoin2_key,
const secp256k1_ecdsa_signature *node1_sig,
const secp256k1_ecdsa_signature *node2_sig,
const secp256k1_ecdsa_signature *bitcoin1_sig,
const secp256k1_ecdsa_signature *bitcoin2_sig, const u8 *announcement)
{
/* 2 byte msg type + 256 byte signatures */
int offset = 258;
struct sha256_double hash;
sha256_double(&hash, announcement + offset,
tal_len(announcement) - offset);
return check_signed_hash(&hash, node1_sig, node1_key) &&
check_signed_hash(&hash, node2_sig, node2_key) &&
check_signed_hash(&hash, bitcoin1_sig, bitcoin1_key) &&
check_signed_hash(&hash, bitcoin2_sig, bitcoin2_key);
}
void handle_channel_announcement(
struct routing_state *rstate,
const u8 *announce, size_t len)
{
u8 *serialized;
bool forward = false;
secp256k1_ecdsa_signature node_signature_1;
secp256k1_ecdsa_signature node_signature_2;
struct short_channel_id short_channel_id;
secp256k1_ecdsa_signature bitcoin_signature_1;
secp256k1_ecdsa_signature bitcoin_signature_2;
struct pubkey node_id_1;
struct pubkey node_id_2;
struct pubkey bitcoin_key_1;
struct pubkey bitcoin_key_2;
struct sha256_double chain_hash;
const tal_t *tmpctx = tal_tmpctx(rstate);
u8 *features;
serialized = tal_dup_arr(tmpctx, u8, announce, len, 0);
if (!fromwire_channel_announcement(tmpctx, serialized, NULL,
&node_signature_1, &node_signature_2,
&bitcoin_signature_1,
&bitcoin_signature_2,
&features,
&chain_hash,
&short_channel_id,
&node_id_1, &node_id_2,
&bitcoin_key_1, &bitcoin_key_2)) {
tal_free(tmpctx);
return;
}
/* BOLT #7:
*
* The receiving node MUST ignore the message if the specified
* `chain_hash` is unknown to the receiver.
*/
if (!structeq(&chain_hash, &rstate->chain_hash)) {
status_trace("Received channel_announcement for unknown chain"
" %s",
type_to_string(tmpctx, struct sha256_double,
&chain_hash));
tal_free(tmpctx);
return;
}
// FIXME: Check features!
//FIXME(cdecker) Check chain topology for the anchor TX
status_trace("Received channel_announcement for channel %s",
type_to_string(trc, struct short_channel_id,
&short_channel_id));
if (!check_channel_announcement(&node_id_1, &node_id_2, &bitcoin_key_1,
&bitcoin_key_2, &node_signature_1,
&node_signature_2, &bitcoin_signature_1,
&bitcoin_signature_2, serialized)) {
status_trace(
"Signature verification of channel announcement failed");
tal_free(tmpctx);
return;
}
forward |= add_channel_direction(rstate, &node_id_1, &node_id_2,
&short_channel_id, serialized);
forward |= add_channel_direction(rstate, &node_id_2, &node_id_1,
&short_channel_id, serialized);
if (!forward) {
status_trace("Not forwarding channel_announcement");
tal_free(tmpctx);
return;
}
u8 *tag = tal_arr(tmpctx, u8, 0);
towire_short_channel_id(&tag, &short_channel_id);
queue_broadcast(rstate->broadcasts, WIRE_CHANNEL_ANNOUNCEMENT,
tag, serialized);
tal_free(tmpctx);
}
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len)
{
u8 *serialized;
struct node_connection *c;
secp256k1_ecdsa_signature signature;
struct short_channel_id short_channel_id;
u32 timestamp;
u16 flags;
u16 expiry;
u64 htlc_minimum_msat;
u32 fee_base_msat;
u32 fee_proportional_millionths;
const tal_t *tmpctx = tal_tmpctx(rstate);
struct sha256_double chain_hash;
serialized = tal_dup_arr(tmpctx, u8, update, len, 0);
if (!fromwire_channel_update(serialized, NULL, &signature,
&chain_hash, &short_channel_id,
&timestamp, &flags, &expiry,
&htlc_minimum_msat, &fee_base_msat,
&fee_proportional_millionths)) {
tal_free(tmpctx);
return;
}
/* BOLT #7:
*
* The receiving node MUST ignore the channel update if the specified
* `chain_hash` value is unknown, meaning it isn't active on the
* specified chain. */
if (!structeq(&chain_hash, &rstate->chain_hash)) {
status_trace("Received channel_update for unknown chain %s",
type_to_string(tmpctx, struct sha256_double,
&chain_hash));
tal_free(tmpctx);
return;
}
status_trace("Received channel_update for channel %s(%d)",
type_to_string(trc, struct short_channel_id,
&short_channel_id),
flags & 0x01);
c = get_connection_by_scid(rstate, &short_channel_id, flags & 0x1);
if (!c) {
status_trace("Ignoring update for unknown channel %s",
type_to_string(trc, struct short_channel_id,
&short_channel_id));
tal_free(tmpctx);
return;
} else if (c->last_timestamp >= timestamp) {
status_trace("Ignoring outdated update.");
tal_free(tmpctx);
return;
} else if (!check_channel_update(&c->src->id, &signature, serialized)) {
status_trace("Signature verification failed.");
tal_free(tmpctx);
return;
}
//FIXME(cdecker) Check signatures
c->last_timestamp = timestamp;
c->delay = expiry;
c->htlc_minimum_msat = htlc_minimum_msat;
c->base_fee = fee_base_msat;
c->proportional_fee = fee_proportional_millionths;
c->active = (flags & ROUTING_FLAGS_DISABLED) == 0;
status_trace("Channel %s(%d) was updated.",
type_to_string(trc, struct short_channel_id,
&short_channel_id),
flags);
u8 *tag = tal_arr(tmpctx, u8, 0);
towire_short_channel_id(&tag, &short_channel_id);
towire_u16(&tag, flags & 0x1);
queue_broadcast(rstate->broadcasts,
WIRE_CHANNEL_UPDATE,
tag,
serialized);
tal_free(c->channel_update);
c->channel_update = tal_steal(c, serialized);
tal_free(tmpctx);
}
static struct ipaddr *read_addresses(const tal_t *ctx, u8 *ser)
{
const u8 *cursor = ser;
size_t max = tal_len(ser);
struct ipaddr *ipaddrs = tal_arr(ctx, struct ipaddr, 0);
int numaddrs = 0;
while (cursor < ser + max) {
numaddrs++;
tal_resize(&ipaddrs, numaddrs);
fromwire_ipaddr(&cursor, &max, &ipaddrs[numaddrs-1]);
if (cursor == NULL) {
/* Parsing address failed */
return tal_free(ipaddrs);
}
}
return ipaddrs;
}
void handle_node_announcement(
struct routing_state *rstate, const u8 *node_ann, size_t len)
{
u8 *serialized;
struct sha256_double hash;
struct node *node;
secp256k1_ecdsa_signature signature;
u32 timestamp;
struct pubkey node_id;
u8 rgb_color[3];
u8 alias[32];
u8 *features, *addresses;
const tal_t *tmpctx = tal_tmpctx(rstate);
struct ipaddr *ipaddrs;
serialized = tal_dup_arr(tmpctx, u8, node_ann, len, 0);
if (!fromwire_node_announcement(tmpctx, serialized, NULL,
&signature, &features, &timestamp,
&node_id, rgb_color, alias,
&addresses)) {
tal_free(tmpctx);
return;
}
// FIXME: Check features!
status_trace("Received node_announcement for node %s",
type_to_string(trc, struct pubkey, &node_id));
sha256_double(&hash, serialized + 66, tal_count(serialized) - 66);
if (!check_signed_hash(&hash, &signature, &node_id)) {
status_trace("Ignoring node announcement, signature verification failed.");
tal_free(tmpctx);
return;
}
node = get_node(rstate, &node_id);
if (!node) {
status_trace("Node not found, was the node_announcement preceeded by at least channel_announcement?");
tal_free(tmpctx);
return;
} else if (node->last_timestamp >= timestamp) {
status_trace("Ignoring node announcement, it's outdated.");
tal_free(tmpctx);
return;
}
ipaddrs = read_addresses(tmpctx, addresses);
if (!ipaddrs) {
status_trace("Unable to parse addresses.");
tal_free(serialized);
return;
}
tal_free(node->addresses);
node->addresses = tal_steal(node, ipaddrs);
node->last_timestamp = timestamp;
memcpy(node->rgb_color, rgb_color, 3);
u8 *tag = tal_arr(tmpctx, u8, 0);
towire_pubkey(&tag, &node_id);
queue_broadcast(rstate->broadcasts,
WIRE_NODE_ANNOUNCEMENT,
tag,
serialized);
tal_free(node->node_announcement);
node->node_announcement = tal_steal(node, serialized);
tal_free(tmpctx);
}
struct route_hop *get_route(tal_t *ctx, struct routing_state *rstate,
const struct pubkey *source,
const struct pubkey *destination,
const u32 msatoshi, double riskfactor)
{
struct node_connection **route;
u64 total_amount;
unsigned int total_delay;
s64 fee;
struct route_hop *hops;
int i;
struct node_connection *first_conn;
first_conn = find_route(ctx, rstate, source, destination, msatoshi,
riskfactor, &fee, &route);
if (!first_conn) {
return NULL;
}
/* Fees, delays need to be calculated backwards along route. */
hops = tal_arr(ctx, struct route_hop, tal_count(route) + 1);
total_amount = msatoshi;
total_delay = 0;
for (i = tal_count(route) - 1; i >= 0; i--) {
hops[i + 1].channel_id = route[i]->short_channel_id;
hops[i + 1].nodeid = route[i]->dst->id;
hops[i + 1].amount = total_amount;
total_amount += connection_fee(route[i], total_amount);
total_delay += route[i]->delay;
if (total_delay < route[i]->min_blocks)
total_delay = route[i]->min_blocks;
hops[i + 1].delay = total_delay;
}
/* Backfill the first hop manually */
hops[0].channel_id = first_conn->short_channel_id;
hops[0].nodeid = first_conn->dst->id;
/* We don't charge ourselves any fees. */
hops[0].amount = total_amount;
/* We do require delay though. */
total_delay += first_conn->delay;
hops[0].delay = total_delay;
return hops;
}

View File

@@ -1,176 +0,0 @@
#ifndef LIGHTNING_LIGHTNINGD_GOSSIP_ROUTING_H
#define LIGHTNING_LIGHTNINGD_GOSSIP_ROUTING_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <ccan/htable/htable_type.h>
#include <lightningd/gossip/broadcast.h>
#include <wire/wire.h>
#define ROUTING_MAX_HOPS 20
#define ROUTING_FLAGS_DISABLED 2
struct node_connection {
struct node *src, *dst;
/* millisatoshi. */
u32 base_fee;
/* millionths */
s32 proportional_fee;
/* Delay for HTLC in blocks.*/
u32 delay;
/* Minimum allowable HTLC expiry in blocks. */
u32 min_blocks;
/* Is this connection active? */
bool active;
u32 last_timestamp;
/* Minimum number of msatoshi in an HTLC */
u32 htlc_minimum_msat;
/* The channel ID, as determined by the anchor transaction */
struct short_channel_id short_channel_id;
/* Flags as specified by the `channel_update`s, among other
* things indicated direction wrt the `channel_id` */
u16 flags;
/* Cached `channel_announcement` and `channel_update` we might forward to new peers*/
u8 *channel_announcement;
u8 *channel_update;
};
struct node {
struct pubkey id;
/* IP/Hostname and port of this node (may be NULL) */
struct ipaddr *addresses;
u32 last_timestamp;
/* Routes connecting to us, from us. */
struct node_connection **in, **out;
/* Temporary data for routefinding. */
struct {
/* Total to get to here from target. */
s64 total;
/* Total risk premium of this route. */
u64 risk;
/* Where that came from. */
struct node_connection *prev;
} bfg[ROUTING_MAX_HOPS+1];
/* UTF-8 encoded alias as tal_arr, not zero terminated */
u8 *alias;
/* Color to be used when displaying the name */
u8 rgb_color[3];
/* Cached `node_announcement` we might forward to new peers. */
u8 *node_announcement;
};
const secp256k1_pubkey *node_map_keyof_node(const struct node *n);
size_t node_map_hash_key(const secp256k1_pubkey *key);
bool node_map_node_eq(const struct node *n, const secp256k1_pubkey *key);
HTABLE_DEFINE_TYPE(struct node, node_map_keyof_node, node_map_hash_key, node_map_node_eq, node_map);
struct routing_state {
/* All known nodes. */
struct node_map *nodes;
struct broadcast_state *broadcasts;
struct sha256_double chain_hash;
};
struct route_hop {
struct short_channel_id channel_id;
struct pubkey nodeid;
u32 amount;
u32 delay;
};
struct routing_state *new_routing_state(const tal_t *ctx,
const struct sha256_double *chain_hash);
struct node *new_node(struct routing_state *rstate,
const struct pubkey *id);
struct node *get_node(struct routing_state *rstate,
const struct pubkey *id);
/* msatoshi must be possible (< 21 million BTC), ie < 2^60.
* If it returns more than msatoshi, it overflowed. */
s64 connection_fee(const struct node_connection *c, u64 msatoshi);
/* Updates existing node, or creates a new one as required. */
struct node *add_node(struct routing_state *rstate,
const struct pubkey *pk);
/* Updates existing connection, or creates new one as required. */
struct node_connection *add_connection(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to,
u32 base_fee, s32 proportional_fee,
u32 delay, u32 min_blocks);
/* Add a connection to the routing table, but do not mark it as usable
* yet. Used by channel_announcements before the channel_update comes
* in. */
struct node_connection *half_add_connection(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to,
const struct short_channel_id *schanid,
const u16 flags);
/* Get an existing connection between `from` and `to`, NULL if no such
* connection exists. */
struct node_connection *get_connection(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to);
/* Given a short_channel_id, retrieve the matching connection, or NULL if it is
* unknown. */
struct node_connection *get_connection_by_scid(const struct routing_state *rstate,
const struct short_channel_id *schanid,
const u8 direction);
void remove_connection(struct routing_state *rstate,
const struct pubkey *src, const struct pubkey *dst);
struct node_connection *
find_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *from, const struct pubkey *to, u64 msatoshi,
double riskfactor, s64 *fee, struct node_connection ***route);
struct node_map *empty_node_map(const tal_t *ctx);
bool add_channel_direction(struct routing_state *rstate,
const struct pubkey *from,
const struct pubkey *to,
const struct short_channel_id *short_channel_id,
const u8 *announcement);
bool read_ip(const tal_t *ctx, const u8 *addresses, char **hostname, int *port);
u8 *write_ip(const tal_t *ctx, const char *srcip, int port);
/* Handlers for incoming messages */
void handle_channel_announcement(struct routing_state *rstate, const u8 *announce, size_t len);
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len);
void handle_node_announcement(struct routing_state *rstate, const u8 *node, size_t len);
/* Compute a route to a destination, for a given amount and riskfactor. */
struct route_hop *get_route(tal_t *ctx, struct routing_state *rstate,
const struct pubkey *source,
const struct pubkey *destination,
const u32 msatoshi, double riskfactor);
/* Utility function that, given a source and a destination, gives us
* the direction bit the matching channel should get */
#define get_channel_direction(from, to) (pubkey_cmp(from, to) > 0)
#endif /* LIGHTNING_LIGHTNINGD_GOSSIP_ROUTING_H */

View File

@@ -7,8 +7,8 @@
#include <ccan/tal/str/str.h>
#include <common/type_to_string.h>
#include <common/utils.h>
#include <gossipd/gen_gossip_wire.h>
#include <inttypes.h>
#include <lightningd/gossip/gen_gossip_wire.h>
#include <lightningd/gossip_msg.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/log.h>
@@ -144,7 +144,7 @@ void gossip_init(struct lightningd *ld)
{
tal_t *tmpctx = tal_tmpctx(ld);
u8 *init;
ld->gossip = new_subd(ld, ld, "lightningd_gossip", NULL,
ld->gossip = new_subd(ld, ld, "lightning_gossipd", NULL,
gossip_wire_type_name,
gossip_msg, gossip_finished, NULL);
if (!ld->gossip)

View File

@@ -2,7 +2,7 @@
#define LIGHTNING_LIGHTNINGD_GOSSIP_MSG_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <lightningd/gossip/routing.h>
#include <gossipd/routing.h>
struct gossip_getnodes_entry {
struct pubkey nodeid;

View File

@@ -1,68 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/handshake-wrongdir:
$(MAKE) -C .. lightningd/handshake-all
default: lightningd/handshake-all
lightningd/handshake-all: lightningd/lightningd_handshake
# lightningd/handshake needs these:
LIGHTNINGD_HANDSHAKE_HEADERS := \
lightningd/handshake/gen_handshake_wire.h
LIGHTNINGD_HANDSHAKE_SRC := lightningd/handshake/handshake.c \
$(LIGHTNINGD_HANDSHAKE_HEADERS:.h=.c)
LIGHTNINGD_HANDSHAKE_OBJS := $(LIGHTNINGD_HANDSHAKE_SRC:.c=.o)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_HANDSHAKE_OBJS)
# Control daemon uses this:
LIGHTNINGD_HANDSHAKE_CONTROL_HEADERS := $(LIGHTNINGD_HANDSHAKE_HEADERS)
LIGHTNINGD_HANDSHAKE_CONTROL_SRC := $(LIGHTNINGD_HANDSHAKE_HEADERS:.h=.c)
LIGHTNINGD_HANDSHAKE_CONTROL_OBJS := $(LIGHTNINGD_HANDSHAKE_CONTROL_SRC:.c=.o)
LIGHTNINGD_HANDSHAKE_GEN_SRC := $(filter lightningd/handshake/gen_%, $(LIGHTNINGD_HANDSHAKE_SRC) $(LIGHTNINGD_HANDSHAKE_CONTROL_SRC))
LIGHTNINGD_HANDSHAKE_SRC_NOGEN := $(filter-out lightningd/handshake/gen_%, $(LIGHTNINGD_HANDSHAKE_SRC))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_HANDSHAKE_HEADERS)
$(LIGHTNINGD_HANDSHAKE_OBJS): $(LIGHTNINGD_HEADERS)
# Common source we use.
HANDSHAKED_COMMON_OBJS := \
common/crypto_sync.o \
common/cryptomsg.o \
common/daemon_conn.o \
common/debug.o \
common/dev_disconnect.o \
common/msg_queue.o \
common/status.o \
common/type_to_string.o \
common/utils.o \
common/version.o
lightningd/handshake/gen_handshake_wire.h: $(WIRE_GEN) lightningd/handshake/handshake_wire.csv
$(WIRE_GEN) --header $@ handshake_wire_type < lightningd/handshake/handshake_wire.csv > $@
lightningd/handshake/gen_handshake_wire.c: $(WIRE_GEN) lightningd/handshake/handshake_wire.csv
$(WIRE_GEN) ${@:.c=.h} handshake_wire_type < lightningd/handshake/handshake_wire.csv > $@
LIGHTNINGD_HANDSHAKE_OBJS := $(LIGHTNINGD_HANDSHAKE_SRC:.c=.o) $(LIGHTNINGD_HANDSHAKE_GEN_SRC:.c=.o)
lightningd/lightningd_handshake: $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(LIGHTNINGD_HANDSHAKE_OBJS) $(HANDSHAKED_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS)
check-source: $(LIGHTNINGD_HANDSHAKE_SRC_NOGEN:%=check-src-include-order/%)
check-source-bolt: $(LIGHTNINGD_HANDSHAKE_SRC:%=bolt-check/%) $(LIGHTNINGD_HANDSHAKE_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_HANDSHAKE_SRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_HANDSHAKE_HEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/handshake-clean
lightningd/handshake-clean:
$(RM) $(LIGHTNINGD_HANDSHAKE_OBJS) gen_*
-include lightningd/handshake/test/Makefile

File diff suppressed because it is too large Load Diff

View File

@@ -1,56 +0,0 @@
#include <common/cryptomsg.h>
handshake_bad_command,0x8000
initr_act1_bad_ecdh_for_ss,0x8011
initr_act1_write_failed,0x8012
initr_act2_read_failed,0x8013
initr_act2_bad_version,0x8014
initr_act2_bad_pubkey,0x8015
initr_act2_bad_ecdh_for_ss,0x8016
initr_act2_bad_tag,0x8017
initr_act3_bad_hsm_ecdh,0x8018
initr_act3_write_failed,0x8019
respr_act1_read_failed,0x801A
respr_act1_bad_version,0x801B
respr_act1_bad_pubkey,0x801C
respr_act1_bad_hsm_ecdh,0x801D
respr_act1_bad_tag,0x801E
respr_act2_bad_ecdh_for_ss,0x801F
respr_act2_write_failed,0x8020
respr_act3_read_failed,0x8021
respr_act3_bad_version,0x8022
respr_act3_bad_ciphertext,0x8023
respr_act3_bad_pubkey,0x8024
respr_act3_bad_ecdh_for_ss,0x8025
respr_act3_bad_tag,0x8026
initmsg_write_failed,0x8030
initmsg_read_failed,0x8031
# FIXME: This is probably too finegrained.
initr_act_one,1001
initr_act_two,1002
initr_act_three,1003
respr_act_one,1011
respr_act_two,1012
respr_act_three,1013
success,0
handshake_responder,1
handshake_responder,,my_id,33
handshake_responder_reply,101
handshake_responder_reply,,initiator_id,33
handshake_responder_reply,,cs,struct crypto_state
handshake_responder_reply,,gflen,2
handshake_responder_reply,,globalfeatures,gflen
handshake_responder_reply,,lflen,2
handshake_responder_reply,,localfeatures,lflen
handshake_initiator,2
handshake_initiator,,my_id,33
handshake_initiator,,responder_id,33
handshake_initiator_reply,102
handshake_initiator_reply,,cs,struct crypto_state
handshake_initiator_reply,,gflen,2
handshake_initiator_reply,,globalfeatures,gflen
handshake_initiator_reply,,lflen,2
handshake_initiator_reply,,localfeatures,lflen
1 #include <common/cryptomsg.h>
2 handshake_bad_command,0x8000
3 initr_act1_bad_ecdh_for_ss,0x8011
4 initr_act1_write_failed,0x8012
5 initr_act2_read_failed,0x8013
6 initr_act2_bad_version,0x8014
7 initr_act2_bad_pubkey,0x8015
8 initr_act2_bad_ecdh_for_ss,0x8016
9 initr_act2_bad_tag,0x8017
10 initr_act3_bad_hsm_ecdh,0x8018
11 initr_act3_write_failed,0x8019
12 respr_act1_read_failed,0x801A
13 respr_act1_bad_version,0x801B
14 respr_act1_bad_pubkey,0x801C
15 respr_act1_bad_hsm_ecdh,0x801D
16 respr_act1_bad_tag,0x801E
17 respr_act2_bad_ecdh_for_ss,0x801F
18 respr_act2_write_failed,0x8020
19 respr_act3_read_failed,0x8021
20 respr_act3_bad_version,0x8022
21 respr_act3_bad_ciphertext,0x8023
22 respr_act3_bad_pubkey,0x8024
23 respr_act3_bad_ecdh_for_ss,0x8025
24 respr_act3_bad_tag,0x8026
25 initmsg_write_failed,0x8030
26 initmsg_read_failed,0x8031
27 # FIXME: This is probably too finegrained.
28 initr_act_one,1001
29 initr_act_two,1002
30 initr_act_three,1003
31 respr_act_one,1011
32 respr_act_two,1012
33 respr_act_three,1013
34 success,0
35 handshake_responder,1
36 handshake_responder,,my_id,33
37 handshake_responder_reply,101
38 handshake_responder_reply,,initiator_id,33
39 handshake_responder_reply,,cs,struct crypto_state
40 handshake_responder_reply,,gflen,2
41 handshake_responder_reply,,globalfeatures,gflen
42 handshake_responder_reply,,lflen,2
43 handshake_responder_reply,,localfeatures,lflen
44 handshake_initiator,2
45 handshake_initiator,,my_id,33
46 handshake_initiator,,responder_id,33
47 handshake_initiator_reply,102
48 handshake_initiator_reply,,cs,struct crypto_state
49 handshake_initiator_reply,,gflen,2
50 handshake_initiator_reply,,globalfeatures,gflen
51 handshake_initiator_reply,,lflen,2
52 handshake_initiator_reply,,localfeatures,lflen

View File

@@ -1 +0,0 @@
run-handshake

View File

@@ -1,30 +0,0 @@
check: lightningd/handshake-tests
# Note that these actually #include everything they need, except ccan/ and bitcoin/.
# That allows for unit testing of statics, and special effects.
LIGHTNINGD_HANDSHAKE_TEST_SRC := $(wildcard lightningd/handshake/test/run-*.c)
LIGHTNINGD_HANDSHAKE_TEST_OBJS := $(LIGHTNINGD_HANDSHAKE_TEST_SRC:.c=.o)
LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS := $(LIGHTNINGD_HANDSHAKE_TEST_OBJS:.o=)
LIGHTNINGD_HANDSHAKE_TEST_COMMON_OBJS := \
common/cryptomsg.o \
common/daemon_conn.o \
common/dev_disconnect.o \
common/htlc_state.o \
common/msg_queue.o \
common/pseudorand.o \
common/status.o \
common/type_to_string.o \
common/utils.o
update-mocks: $(LIGHTNINGD_HANDSHAKE_TEST_SRC:%=update-mocks/%)
$(LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS): $(LIGHTNINGD_HANDSHAKE_TEST_COMMON_OBJS) $(LIGHTNINGD_HANDSHAKE_GEN_SRC:.c=.o) $(BITCOIN_OBJS) $(WIRE_OBJS)
$(LIGHTNINGD_HANDSHAKE_TEST_OBJS): $(LIGHTNINGD_HANDSHAKE_HEADERS)
ALL_OBJS += $(LIGHTNINGD_HANDSHAKE_TEST_OBJS)
ALL_TEST_PROGRAMS += $(LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS)
lightningd/handshake-tests: $(LIGHTNINGD_HANDSHAKE_TEST_PROGRAMS:%=unittest/%)

View File

@@ -1,163 +0,0 @@
#include <assert.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <ccan/err/err.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/structeq/structeq.h>
#include <common/status.h>
/* Since we use pipes, we need different fds for read and write. */
static int read_fd, write_fd;
static bool fake_read_all(int fd, void *buf, size_t count)
{
return read_all(read_fd, buf, count);
}
static ssize_t fake_write_all(int fd, const void *buf, size_t count)
{
return write_all(write_fd, buf, count);
}
static const char *status_prefix;
/* Simply print out status updates. */
#define status_send_sync(msg) \
printf("%s:# Act %s\n", status_prefix, \
fromwire_peektype(msg) == WIRE_INITR_ACT_ONE ? "One" \
: fromwire_peektype(msg) == WIRE_INITR_ACT_TWO ? "Two" \
: fromwire_peektype(msg) == WIRE_INITR_ACT_THREE ? "Three" \
: fromwire_peektype(msg) == WIRE_RESPR_ACT_ONE ? "One" \
: fromwire_peektype(msg) == WIRE_RESPR_ACT_TWO ? "Two" \
: fromwire_peektype(msg) == WIRE_RESPR_ACT_THREE ? "Three" \
: "UNKNOWN")
#define status_failed(code, fmt, ...) \
errx(1, "%s:%s:" fmt "\n", status_prefix, #code, __VA_ARGS__)
#define status_trace(fmt, ...) \
printf("%s:" fmt "\n", status_prefix, __VA_ARGS__)
#define read_all fake_read_all
#define write_all fake_write_all
/* No randomness please, we want to replicate test vectors. */
#include <sodium/randombytes.h>
static unsigned char e_priv[32];
#define randombytes_buf(secret, len) memcpy((secret), e_priv, len)
#define TESTING
#include "../handshake.c"
#include <common/utils.h>
#include <ccan/err/err.h>
secp256k1_context *secp256k1_ctx;
const void *trc;
static struct privkey privkey;
void hsm_setup(int fd)
{
}
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
{
return secp256k1_ecdh(secp256k1_ctx, ss->data, &point->pubkey,
privkey.secret.data) == 1;
}
int main(void)
{
int fds1[2], fds2[2];
struct pubkey responder_id;
struct privkey responder_privkey;
struct secret ck, sk, rk;
const tal_t *ctx = tal_tmpctx(NULL);
trc = tal_tmpctx(ctx);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
memset(responder_privkey.secret.data, 0x21,
sizeof(responder_privkey.secret.data));
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&responder_id.pubkey,
responder_privkey.secret.data))
errx(1, "Keygen failed");
if (pipe(fds1) != 0 || pipe(fds2) != 0)
err(1, "Making pipes");
switch (fork()) {
case -1:
err(1, "fork failed");
case 0: {
struct pubkey their_id;
memset(e_priv, 0x22, sizeof(e_priv));
read_fd = fds1[0];
write_fd = fds2[1];
close(fds1[1]);
close(fds2[0]);
privkey = responder_privkey;
status_prefix = "RESPR";
status_trace("ls.priv: 0x%s",
tal_hexstr(trc, &responder_privkey,
sizeof(responder_privkey)));
status_trace("ls.pub: 0x%s",
type_to_string(trc, struct pubkey, &responder_id));
responder(-1, &responder_id, &their_id, &ck, &sk, &rk);
if (!write_all(write_fd, &ck, sizeof(ck))
|| !write_all(write_fd, &sk, sizeof(sk))
|| !write_all(write_fd, &rk, sizeof(rk)))
err(1, "writing out secrets failed");
goto out;
}
default: {
struct pubkey initiator_id;
struct privkey initiator_privkey;
struct secret their_ck, their_sk, their_rk;
read_fd = fds2[0];
write_fd = fds1[1];
close(fds2[1]);
close(fds1[0]);
memset(initiator_privkey.secret.data, 0x11,
sizeof(initiator_privkey.secret.data));
memset(e_priv, 0x12, sizeof(e_priv));
if (!secp256k1_ec_pubkey_create(secp256k1_ctx,
&initiator_id.pubkey,
initiator_privkey.secret.data))
errx(1, "Initiator keygen failed");
privkey = initiator_privkey;
status_prefix = "INITR";
status_trace("rs.pub: 0x%s",
type_to_string(trc, struct pubkey, &responder_id));
status_trace("ls.priv: 0x%s",
tal_hexstr(trc, &initiator_privkey,
sizeof(initiator_privkey)));
status_trace("ls.pub: 0x%s",
type_to_string(trc, struct pubkey, &initiator_id));
initiator(-1, &initiator_id, &responder_id, &ck, &sk, &rk);
if (!read_all(read_fd, &their_ck, sizeof(their_ck))
|| !read_all(read_fd, &their_sk, sizeof(their_sk))
|| !read_all(read_fd, &their_rk, sizeof(their_rk)))
err(1, "reading their secrets failed");
assert(structeq(&ck, &their_ck));
assert(structeq(&sk, &their_rk));
assert(structeq(&rk, &their_sk));
goto out;
}
}
out:
/* No memory leaks please */
secp256k1_context_destroy(secp256k1_ctx);
tal_free(ctx);
return 0;
}

View File

@@ -1,80 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/hsm-wrongdir:
$(MAKE) -C .. lightningd/hsm-all
default: lightningd/hsm-all
# Clients use this:
LIGHTNINGD_HSM_CLIENT_HEADERS := lightningd/hsm/client.h
LIGHTNINGD_HSM_CLIENT_SRC := lightningd/hsm/client.c lightningd/hsm/gen_hsm_client_wire.c
LIGHTNINGD_HSM_CLIENT_OBJS := $(LIGHTNINGD_HSM_CLIENT_SRC:.c=.o)
# Control daemon uses this:
LIGHTNINGD_HSM_CONTROL_HEADERS := lightningd/hsm/gen_hsm_wire.h
LIGHTNINGD_HSM_CONTROL_SRC := lightningd/hsm/gen_hsm_wire.c
LIGHTNINGD_HSM_CONTROL_OBJS := $(LIGHTNINGD_HSM_CONTROL_SRC:.c=.o)
# lightningd/hsm needs these:
LIGHTNINGD_HSM_HEADERS := lightningd/hsm/gen_hsm_client_wire.h \
lightningd/hsm/gen_hsm_wire.h
LIGHTNINGD_HSM_SRC := lightningd/hsm/hsm.c \
$(LIGHTNINGD_HSM_HEADERS:.h=.c)
LIGHTNINGD_HSM_OBJS := $(LIGHTNINGD_HSM_SRC:.c=.o)
# Common source we use.
HSMD_COMMON_OBJS := \
common/bip32.o \
common/daemon_conn.o \
common/funding_tx.o \
common/key_derive.o \
common/msg_queue.o \
common/permute_tx.o \
common/status.o \
common/utils.o \
common/utxo.o \
common/version.o \
common/withdraw_tx.o
# For checking
LIGHTNINGD_HSM_ALLSRC_NOGEN := $(filter-out lightningd/hsm/gen_%, $(LIGHTNINGD_HSM_CLIENT_SRC) $(LIGHTNINGD_HSM_SRC))
LIGHTNINGD_HSM_ALLHEADERS_NOGEN := $(filter-out lightningd/hsm/gen_%, $(LIGHTNINGD_HSM_CLIENT_HEADERS) $(LIGHTNINGD_HSM_HEADERS))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_HSM_HEADERS) $(LIGHTNINGD_HSM_CLIENT_HEADERS)
$(LIGHTNINGD_HSM_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS): $(LIGHTNINGD_HEADERS)
$(LIGHTNINGD_HSM_CONTROL_OBJS) : $(LIGHTNINGD_HSM_CONTROL_HEADERS)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_HSM_OBJS)
lightningd/hsm-all: lightningd/lightningd_hsm $(LIGHTNINGD_HSM_CLIENT_OBJS)
lightningd/lightningd_hsm: $(LIGHTNINGD_HSM_OBJS) $(LIGHTNINGD_OLD_LIB_OBJS) $(LIGHTNINGD_LIB_OBJS) $(HSMD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS)
lightningd/hsm/gen_hsm_client_wire.h: $(WIRE_GEN) lightningd/hsm/hsm_client_wire_csv
$(WIRE_GEN) --header $@ hsm_client_wire_type < lightningd/hsm/hsm_client_wire_csv > $@
lightningd/hsm/gen_hsm_client_wire.c: $(WIRE_GEN) lightningd/hsm/hsm_client_wire_csv
$(WIRE_GEN) ${@:.c=.h} hsm_client_wire_type< lightningd/hsm/hsm_client_wire_csv > $@
lightningd/hsm/gen_hsm_wire.h: $(WIRE_GEN) lightningd/hsm/hsm_wire.csv
$(WIRE_GEN) --header $@ hsm_wire_type < lightningd/hsm/hsm_wire.csv > $@
lightningd/hsm/gen_hsm_wire.c: $(WIRE_GEN) lightningd/hsm/hsm_wire.csv
$(WIRE_GEN) ${@:.c=.h} hsm_wire_type < lightningd/hsm/hsm_wire.csv > $@
check-source: $(LIGHTNINGD_HSM_ALLSRC_NOGEN:%=check-src-include-order/%) $(LIGHTNINGD_HSM_ALLHEADERS_NOGEN:%=check-hdr-include-order/%)
check-source-bolt: $(LIGHTNINGD_HSM_SRC:%=bolt-check/%) $(LIGHTNINGD_HSM_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_HSM_ALLSRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_HSM_ALLHEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/hsm-clean
lightningd/hsm-clean:
$(RM) $(LIGHTNINGD_HSM_OBJS) gen_*
-include lightningd/hsm/test/Makefile

View File

@@ -1,31 +0,0 @@
#include <lightningd/hsm/client.h>
#include <lightningd/hsm/gen_hsm_client_wire.h>
#include <wire/wire_sync.h>
static int hsm_fd = -1;
void hsm_setup(int fd)
{
hsm_fd = fd;
}
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
{
u8 *req = towire_hsm_ecdh_req(NULL, point), *resp;
size_t len;
if (!wire_sync_write(hsm_fd, req))
goto fail;
resp = wire_sync_read(req, hsm_fd);
if (!resp)
goto fail;
len = tal_count(resp);
if (!fromwire_hsm_ecdh_resp(resp, &len, ss))
goto fail;
tal_free(req);
return true;
fail:
tal_free(req);
return false;
}

View File

@@ -1,17 +0,0 @@
/* API to ask the HSM for things. */
#ifndef LIGHTNING_LIGHTNINGD_HSM_CLIENT_H
#define LIGHTNING_LIGHTNINGD_HSM_CLIENT_H
#include "config.h"
#include <ccan/endian/endian.h>
#include <ccan/short_types/short_types.h>
#include <stdbool.h>
struct pubkey;
struct secret;
/* Setup communication to the HSM */
void hsm_setup(int fd);
/* Do ECDH using this node id secret. */
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point);
#endif /* LIGHTNING_LIGHTNINGD_HSM_CLIENT_H */

View File

@@ -1,677 +0,0 @@
#include <bitcoin/address.h>
#include <bitcoin/privkey.h>
#include <bitcoin/pubkey.h>
#include <bitcoin/script.h>
#include <bitcoin/tx.h>
#include <ccan/breakpoint/breakpoint.h>
#include <ccan/container_of/container_of.h>
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
#include <ccan/endian/endian.h>
#include <ccan/fdpass/fdpass.h>
#include <ccan/io/fdpass/fdpass.h>
#include <ccan/io/io.h>
#include <ccan/noerr/noerr.h>
#include <ccan/ptrint/ptrint.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/take/take.h>
#include <common/daemon_conn.h>
#include <common/funding_tx.h>
#include <common/status.h>
#include <common/utils.h>
#include <common/version.h>
#include <common/withdraw_tx.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <lightningd/hsm/client.h>
#include <lightningd/hsm/gen_hsm_client_wire.h>
#include <lightningd/hsm/gen_hsm_wire.h>
#include <secp256k1_ecdh.h>
#include <sodium/randombytes.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wally_bip32.h>
#include <wire/gen_peer_wire.h>
#include <wire/wire_io.h>
/* Nobody will ever find it here! */
static struct {
struct secret hsm_secret;
struct ext_key bip32;
} secretstuff;
struct client {
struct daemon_conn dc;
struct daemon_conn *master;
u64 id;
struct io_plan *(*handle)(struct io_conn *, struct daemon_conn *);
};
static void node_key(struct privkey *node_privkey, struct pubkey *node_id)
{
u32 salt = 0;
struct privkey unused_s;
struct pubkey unused_k;
if (node_privkey == NULL)
node_privkey = &unused_s;
else if (node_id == NULL)
node_id = &unused_k;
do {
hkdf_sha256(node_privkey, sizeof(*node_privkey),
&salt, sizeof(salt),
&secretstuff.hsm_secret,
sizeof(secretstuff.hsm_secret),
"nodeid", 6);
salt++;
} while (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey,
node_privkey->secret.data));
}
static struct client *new_client(struct daemon_conn *master,
u64 id,
struct io_plan *(*handle)(struct io_conn *,
struct daemon_conn *),
int fd)
{
struct client *c = tal(master, struct client);
c->id = id;
c->handle = handle;
c->master = master;
daemon_conn_init(c, &c->dc, fd, handle, NULL);
/* Free the connection if we exit everything. */
tal_steal(master, c->dc.conn);
/* Free client when connection freed. */
tal_steal(c->dc.conn, c);
return c;
}
static struct io_plan *handle_ecdh(struct io_conn *conn, struct daemon_conn *dc)
{
struct client *c = container_of(dc, struct client, dc);
struct privkey privkey;
struct pubkey point;
struct secret ss;
if (!fromwire_hsm_ecdh_req(dc->msg_in, NULL, &point)) {
daemon_conn_send(c->master,
take(towire_hsmstatus_client_bad_request(c,
c->id,
dc->msg_in)));
return io_close(conn);
}
node_key(&privkey, NULL);
if (secp256k1_ecdh(secp256k1_ctx, ss.data, &point.pubkey,
privkey.secret.data) != 1) {
status_trace("secp256k1_ecdh fail for client %"PRIu64, c->id);
daemon_conn_send(c->master,
take(towire_hsmstatus_client_bad_request(c,
c->id,
dc->msg_in)));
return io_close(conn);
}
daemon_conn_send(dc, take(towire_hsm_ecdh_resp(c, &ss)));
return daemon_conn_read_next(conn, dc);
}
static struct io_plan *handle_cannouncement_sig(struct io_conn *conn,
struct daemon_conn *dc)
{
tal_t *ctx = tal_tmpctx(conn);
/* First 2 + 256 byte are the signatures and msg type, skip them */
size_t offset = 258;
struct privkey node_pkey;
secp256k1_ecdsa_signature node_sig;
struct sha256_double hash;
u8 *reply;
u8 *ca;
struct pubkey bitcoin_id;
if (!fromwire_hsm_cannouncement_sig_req(ctx, dc->msg_in, NULL,
&bitcoin_id, &ca)) {
status_trace("Failed to parse cannouncement_sig_req: %s",
tal_hex(trc, dc->msg_in));
return io_close(conn);
}
if (tal_len(ca) < offset) {
status_trace("bad cannounce length %zu", tal_len(ca));
return io_close(conn);
}
/* TODO(cdecker) Check that this is actually a valid
* channel_announcement */
node_key(&node_pkey, NULL);
sha256_double(&hash, ca + offset, tal_len(ca) - offset);
sign_hash(&node_pkey, &hash, &node_sig);
reply = towire_hsm_cannouncement_sig_reply(ca, &node_sig);
daemon_conn_send(dc, take(reply));
tal_free(ctx);
return daemon_conn_read_next(conn, dc);
}
static struct io_plan *handle_channel_update_sig(struct io_conn *conn,
struct daemon_conn *dc)
{
tal_t *tmpctx = tal_tmpctx(conn);
/* 2 bytes msg type + 64 bytes signature */
size_t offset = 66;
struct privkey node_pkey;
struct sha256_double hash;
secp256k1_ecdsa_signature sig;
struct short_channel_id scid;
u32 timestamp, fee_base_msat, fee_proportional_mill;
u64 htlc_minimum_msat;
u16 flags, cltv_expiry_delta;
struct sha256_double chain_hash;
u8 *cu;
if (!fromwire_hsm_cupdate_sig_req(tmpctx, dc->msg_in, NULL, &cu)) {
status_trace("Failed to parse %s: %s",
hsm_client_wire_type_name(fromwire_peektype(dc->msg_in)),
tal_hex(trc, dc->msg_in));
return io_close(conn);
}
if (!fromwire_channel_update(cu, NULL, &sig, &chain_hash,
&scid, &timestamp, &flags,
&cltv_expiry_delta, &htlc_minimum_msat,
&fee_base_msat, &fee_proportional_mill)) {
status_trace("Failed to parse inner channel_update: %s",
tal_hex(trc, dc->msg_in));
return io_close(conn);
}
if (tal_len(cu) < offset) {
status_trace("inner channel_update too short: %s",
tal_hex(trc, dc->msg_in));
return io_close(conn);
}
node_key(&node_pkey, NULL);
sha256_double(&hash, cu + offset, tal_len(cu) - offset);
sign_hash(&node_pkey, &hash, &sig);
cu = towire_channel_update(tmpctx, &sig, &chain_hash,
&scid, timestamp, flags,
cltv_expiry_delta, htlc_minimum_msat,
fee_base_msat, fee_proportional_mill);
daemon_conn_send(dc, take(towire_hsm_cupdate_sig_reply(tmpctx, cu)));
tal_free(tmpctx);
return daemon_conn_read_next(conn, dc);
}
static struct io_plan *handle_channeld(struct io_conn *conn,
struct daemon_conn *dc)
{
struct client *c = container_of(dc, struct client, dc);
enum hsm_client_wire_type t = fromwire_peektype(dc->msg_in);
switch (t) {
case WIRE_HSM_ECDH_REQ:
return handle_ecdh(conn, dc);
case WIRE_HSM_CANNOUNCEMENT_SIG_REQ:
return handle_cannouncement_sig(conn, dc);
case WIRE_HSM_CUPDATE_SIG_REQ:
return handle_channel_update_sig(conn, dc);
case WIRE_HSM_ECDH_RESP:
case WIRE_HSM_CANNOUNCEMENT_SIG_REPLY:
case WIRE_HSM_CUPDATE_SIG_REPLY:
break;
}
daemon_conn_send(c->master,
take(towire_hsmstatus_client_bad_request(c,
c->id,
dc->msg_in)));
return io_close(conn);
}
/* Control messages */
static void send_init_response(struct daemon_conn *master)
{
struct pubkey node_id;
struct secret peer_seed;
u8 *msg;
hkdf_sha256(&peer_seed, sizeof(peer_seed), NULL, 0,
&secretstuff.hsm_secret,
sizeof(secretstuff.hsm_secret),
"peer seed", strlen("peer seed"));
node_key(NULL, &node_id);
msg = towire_hsmctl_init_reply(master, &node_id, &peer_seed,
&secretstuff.bip32);
daemon_conn_send(master, take(msg));
}
static void populate_secretstuff(void)
{
u8 bip32_seed[BIP32_ENTROPY_LEN_256];
u32 salt = 0;
struct ext_key master_extkey, child_extkey;
/* Fill in the BIP32 tree for bitcoin addresses. */
do {
hkdf_sha256(bip32_seed, sizeof(bip32_seed),
&salt, sizeof(salt),
&secretstuff.hsm_secret,
sizeof(secretstuff.hsm_secret),
"bip32 seed", strlen("bip32 seed"));
salt++;
} while (bip32_key_from_seed(bip32_seed, sizeof(bip32_seed),
BIP32_VER_TEST_PRIVATE,
0, &master_extkey) != WALLY_OK);
/* BIP 32:
*
* The default wallet layout
*
* An HDW is organized as several 'accounts'. Accounts are numbered,
* the default account ("") being number 0. Clients are not required
* to support more than one account - if not, they only use the
* default account.
*
* Each account is composed of two keypair chains: an internal and an
* external one. The external keychain is used to generate new public
* addresses, while the internal keychain is used for all other
* operations (change addresses, generation addresses, ..., anything
* that doesn't need to be communicated). Clients that do not support
* separate keychains for these should use the external one for
* everything.
*
* - m/iH/0/k corresponds to the k'th keypair of the external chain of account number i of the HDW derived from master m.
*/
/* Hence child 0, then child 0 again to get extkey to derive from. */
if (bip32_key_from_parent(&master_extkey, 0, BIP32_FLAG_KEY_PRIVATE,
&child_extkey) != WALLY_OK)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"Can't derive child bip32 key");
if (bip32_key_from_parent(&child_extkey, 0, BIP32_FLAG_KEY_PRIVATE,
&secretstuff.bip32) != WALLY_OK)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"Can't derive private bip32 key");
}
static void bitcoin_pubkey(struct pubkey *pubkey, u32 index)
{
struct ext_key ext;
if (index >= BIP32_INITIAL_HARDENED_CHILD)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"Index %u too great", index);
if (bip32_key_from_parent(&secretstuff.bip32, index,
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"BIP32 of %u failed", index);
if (!secp256k1_ec_pubkey_parse(secp256k1_ctx, &pubkey->pubkey,
ext.pub_key, sizeof(ext.pub_key)))
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"Parse of BIP32 child %u pubkey failed", index);
}
static void bitcoin_keypair(struct privkey *privkey,
struct pubkey *pubkey,
u32 index)
{
struct ext_key ext;
if (index >= BIP32_INITIAL_HARDENED_CHILD)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"Index %u too great", index);
if (bip32_key_from_parent(&secretstuff.bip32, index,
BIP32_FLAG_KEY_PRIVATE, &ext) != WALLY_OK)
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"BIP32 of %u failed", index);
/* libwally says: The private key with prefix byte 0 */
memcpy(privkey->secret.data, ext.priv_key+1, 32);
if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &pubkey->pubkey,
privkey->secret.data))
status_failed(WIRE_HSMSTATUS_KEY_FAILED,
"BIP32 pubkey %u create failed", index);
}
static void create_new_hsm(struct daemon_conn *master)
{
int fd = open("hsm_secret", O_CREAT|O_EXCL|O_WRONLY, 0400);
if (fd < 0)
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"creating: %s", strerror(errno));
randombytes_buf(&secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret));
if (!write_all(fd, &secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret))) {
unlink_noerr("hsm_secret");
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"writing: %s", strerror(errno));
}
if (fsync(fd) != 0) {
unlink_noerr("hsm_secret");
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"fsync: %s", strerror(errno));
}
if (close(fd) != 0) {
unlink_noerr("hsm_secret");
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"closing: %s", strerror(errno));
}
fd = open(".", O_RDONLY);
if (fsync(fd) != 0) {
unlink_noerr("hsm_secret");
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"fsyncdir: %s", strerror(errno));
}
close(fd);
populate_secretstuff();
}
static void load_hsm(struct daemon_conn *master)
{
int fd = open("hsm_secret", O_RDONLY);
if (fd < 0)
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"opening: %s", strerror(errno));
if (!read_all(fd, &secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret)))
status_failed(WIRE_HSMSTATUS_INIT_FAILED,
"reading: %s", strerror(errno));
close(fd);
populate_secretstuff();
}
static void init_hsm(struct daemon_conn *master, const u8 *msg)
{
bool new;
if (!fromwire_hsmctl_init(msg, NULL, &new))
status_failed(WIRE_HSMSTATUS_BAD_REQUEST, "hsmctl_init: %s",
tal_hex(msg, msg));
if (new)
create_new_hsm(master);
else
load_hsm(master);
send_init_response(master);
}
static void pass_hsmfd_ecdh(struct daemon_conn *master, const u8 *msg)
{
int fds[2];
u64 id;
if (!fromwire_hsmctl_hsmfd_ecdh(msg, NULL, &id))
status_failed(WIRE_HSMSTATUS_BAD_REQUEST, "bad HSMFD_ECDH");
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0)
status_failed(WIRE_HSMSTATUS_FD_FAILED,
"creating fds: %s", strerror(errno));
new_client(master, id, handle_ecdh, fds[0]);
daemon_conn_send(master,
take(towire_hsmctl_hsmfd_ecdh_fd_reply(master)));
daemon_conn_send_fd(master, fds[1]);
}
/* Reply to an incoming request for an HSMFD for a channeld. */
static void pass_hsmfd_channeld(struct daemon_conn *master, const u8 *msg)
{
int fds[2];
u64 id;
if (!fromwire_hsmctl_hsmfd_channeld(msg, NULL, &id))
status_failed(WIRE_HSMSTATUS_BAD_REQUEST, "bad HSMFD_CHANNELD");
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0)
status_failed(WIRE_HSMSTATUS_FD_FAILED,
"creating fds: %s", strerror(errno));
new_client(master, id, handle_channeld, fds[0]);
daemon_conn_send(master,
take(towire_hsmctl_hsmfd_channeld_reply(master)));
daemon_conn_send_fd(master, fds[1]);
}
/* Note that it's the main daemon that asks for the funding signature so it
* can broadcast it. */
static void sign_funding_tx(struct daemon_conn *master, const u8 *msg)
{
const tal_t *tmpctx = tal_tmpctx(master);
u64 satoshi_out, change_out;
u32 change_keyindex;
struct pubkey local_pubkey, remote_pubkey;
struct utxo *inputs;
const struct utxo **utxomap;
struct bitcoin_tx *tx;
u8 *wscript;
secp256k1_ecdsa_signature *sig;
u16 outnum;
size_t i;
struct pubkey changekey;
/* FIXME: Check fee is "reasonable" */
if (!fromwire_hsmctl_sign_funding(tmpctx, msg, NULL,
&satoshi_out, &change_out,
&change_keyindex, &local_pubkey,
&remote_pubkey, &inputs))
status_failed(WIRE_HSMSTATUS_BAD_REQUEST, "Bad SIGN_FUNDING");
utxomap = to_utxoptr_arr(tmpctx, inputs);
if (change_out)
bitcoin_pubkey(&changekey, change_keyindex);
tx = funding_tx(tmpctx, &outnum, utxomap,
satoshi_out, &local_pubkey, &remote_pubkey,
change_out, &changekey,
NULL);
/* Now generate signatures. */
sig = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(inputs));
for (i = 0; i < tal_count(inputs); i++) {
struct pubkey inkey;
struct privkey inprivkey;
const struct utxo *in = utxomap[i];
u8 *subscript;
bitcoin_keypair(&inprivkey, &inkey, in->keyindex);
if (in->is_p2sh)
subscript = bitcoin_redeem_p2sh_p2wpkh(tmpctx, &inkey);
else
subscript = NULL;
wscript = p2wpkh_scriptcode(tmpctx, &inkey);
sign_tx_input(tx, i, subscript, wscript,
&inprivkey, &inkey, &sig[i]);
}
daemon_conn_send(master,
take(towire_hsmctl_sign_funding_reply(tmpctx, sig)));
tal_free(tmpctx);
}
/**
* sign_withdrawal_tx - Generate and sign a withdrawal transaction from the master
*/
static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg)
{
const tal_t *tmpctx = tal_tmpctx(master);
u64 satoshi_out, change_out;
u32 change_keyindex;
struct bitcoin_address destination;
struct utxo *utxos;
secp256k1_ecdsa_signature *sigs;
u8 *wscript;
struct bitcoin_tx *tx;
struct ext_key ext;
struct pubkey changekey;
if (!fromwire_hsmctl_sign_withdrawal(tmpctx, msg, NULL, &satoshi_out,
&change_out, &change_keyindex,
destination.addr.u.u8, &utxos)) {
status_trace("Failed to parse sign_withdrawal: %s",
tal_hex(trc, msg));
return;
}
if (bip32_key_from_parent(&secretstuff.bip32, change_keyindex,
BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) {
status_trace("Failed to parse sign_withdrawal: %s",
tal_hex(trc, msg));
return;
}
pubkey_from_der(ext.pub_key, sizeof(ext.pub_key), &changekey);
tx = withdraw_tx(
tmpctx, to_utxoptr_arr(tmpctx, utxos), &destination, satoshi_out,
&changekey, change_out, NULL);
/* Now generate signatures. */
sigs = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(utxos));
for (size_t i = 0; i < tal_count(utxos); i++) {
struct pubkey inkey;
struct privkey inprivkey;
const struct utxo *in = &utxos[i];
u8 *subscript;
bitcoin_keypair(&inprivkey, &inkey, in->keyindex);
/* We know these are p2sh since that's the only kind we handle */
subscript = bitcoin_redeem_p2sh_p2wpkh(tmpctx, &inkey);
wscript = p2wpkh_scriptcode(tmpctx, &inkey);
sign_tx_input(tx, i, subscript, wscript,
&inprivkey, &inkey, &sigs[i]);
}
daemon_conn_send(master,
take(towire_hsmctl_sign_withdrawal_reply(tmpctx, sigs)));
tal_free(tmpctx);
}
static void sign_node_announcement(struct daemon_conn *master, const u8 *msg)
{
/* 2 bytes msg type + 64 bytes signature */
size_t offset = 66;
struct sha256_double hash;
struct privkey node_pkey;
secp256k1_ecdsa_signature sig;
u8 *reply;
u8 *ann;
if (!fromwire_hsmctl_node_announcement_sig_req(msg, msg, NULL, &ann)) {
status_trace("Failed to parse node_announcement_sig_req: %s",
tal_hex(trc, msg));
return;
}
if (tal_len(ann) < offset) {
status_trace("Node announcement too short: %s", tal_hex(trc, msg));
return;
}
/* FIXME(cdecker) Check the node announcement's content */
node_key(&node_pkey, NULL);
sha256_double(&hash, ann + offset, tal_len(ann) - offset);
sign_hash(&node_pkey, &hash, &sig);
reply = towire_hsmctl_node_announcement_sig_reply(msg, &sig);
daemon_conn_send(master, take(reply));
}
static struct io_plan *control_received_req(struct io_conn *conn,
struct daemon_conn *master)
{
enum hsm_wire_type t = fromwire_peektype(master->msg_in);
status_trace("Control: type %s len %zu",
hsm_wire_type_name(t), tal_count(master->msg_in));
switch (t) {
case WIRE_HSMCTL_INIT:
init_hsm(master, master->msg_in);
return daemon_conn_read_next(conn, master);
case WIRE_HSMCTL_HSMFD_ECDH:
pass_hsmfd_ecdh(master, master->msg_in);
return daemon_conn_read_next(conn, master);
case WIRE_HSMCTL_HSMFD_CHANNELD:
pass_hsmfd_channeld(master, master->msg_in);
return daemon_conn_read_next(conn, master);
case WIRE_HSMCTL_SIGN_FUNDING:
sign_funding_tx(master, master->msg_in);
return daemon_conn_read_next(conn, master);
case WIRE_HSMCTL_SIGN_WITHDRAWAL:
sign_withdrawal_tx(master, master->msg_in);
return daemon_conn_read_next(conn, master);
case WIRE_HSMCTL_NODE_ANNOUNCEMENT_SIG_REQ:
sign_node_announcement(master, master->msg_in);
return daemon_conn_read_next(conn, master);
case WIRE_HSMCTL_INIT_REPLY:
case WIRE_HSMCTL_HSMFD_ECDH_FD_REPLY:
case WIRE_HSMCTL_HSMFD_CHANNELD_REPLY:
case WIRE_HSMCTL_SIGN_FUNDING_REPLY:
case WIRE_HSMCTL_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMSTATUS_INIT_FAILED:
case WIRE_HSMSTATUS_WRITEMSG_FAILED:
case WIRE_HSMSTATUS_BAD_REQUEST:
case WIRE_HSMSTATUS_FD_FAILED:
case WIRE_HSMSTATUS_KEY_FAILED:
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMCTL_NODE_ANNOUNCEMENT_SIG_REPLY:
break;
}
/* Control shouldn't give bad requests. */
status_failed(WIRE_HSMSTATUS_BAD_REQUEST, "%i", t);
}
#ifndef TESTING
static void master_gone(struct io_conn *unused, struct daemon_conn *dc)
{
/* Can't tell master, it's gone. */
exit(2);
}
int main(int argc, char *argv[])
{
struct daemon_conn *master;
if (argc == 2 && streq(argv[1], "--version")) {
printf("%s\n", version());
exit(0);
}
breakpoint();
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
master = tal(NULL, struct daemon_conn);
daemon_conn_init(master, master, STDIN_FILENO, control_received_req,
master_gone);
status_setup_async(master);
/* When conn closes, everything is freed. */
tal_steal(master->conn, master);
io_loop(NULL, NULL);
return 0;
}
#endif

View File

@@ -1,21 +0,0 @@
# Give me ECDH(node-id-secret,point)
hsm_ecdh_req,1
hsm_ecdh_req,,point,struct pubkey
hsm_ecdh_resp,100
hsm_ecdh_resp,,ss,struct secret
hsm_cannouncement_sig_req,2
hsm_cannouncement_sig_req,,bitcoin_id,struct pubkey
hsm_cannouncement_sig_req,,calen,u16
hsm_cannouncement_sig_req,,ca,calen
hsm_cannouncement_sig_reply,102
hsm_cannouncement_sig_reply,,node_signature,64
hsm_cupdate_sig_req,3
hsm_cupdate_sig_req,,culen,u16
hsm_cupdate_sig_req,,cu,culen
hsm_cupdate_sig_reply,103
hsm_cupdate_sig_reply,,culen,u16
hsm_cupdate_sig_reply,,cu,culen

View File

@@ -1,73 +0,0 @@
# These are fatal.
hsmstatus_init_failed,0x8000
hsmstatus_writemsg_failed,0x8001
hsmstatus_bad_request,0x8002
hsmstatus_fd_failed,0x8003
hsmstatus_key_failed,0x8004
# Clients should not give a bad request but not the HSM's decision to crash.
hsmstatus_client_bad_request,1000
hsmstatus_client_bad_request,,unique_id,8
hsmstatus_client_bad_request,,len,2
hsmstatus_client_bad_request,,msg,len*u8
# Start the HSM.
hsmctl_init,1
hsmctl_init,,new,bool
#include <common/bip32.h>
hsmctl_init_reply,101
hsmctl_init_reply,,node_id,33
hsmctl_init_reply,,peer_seed,struct secret
hsmctl_init_reply,,bip32,struct ext_key
# ECDH returns an fd.
hsmctl_hsmfd_ecdh,3
hsmctl_hsmfd_ecdh,,unique_id,8
# No contents, just an fd.
hsmctl_hsmfd_ecdh_fd_reply,103
# Return signature for a funding tx.
#include <common/utxo.h>
# FIXME: This should also take their commit sig & details, to verify.
hsmctl_sign_funding,4
hsmctl_sign_funding,,satoshi_out,8
hsmctl_sign_funding,,change_out,8
hsmctl_sign_funding,,change_keyindex,4
hsmctl_sign_funding,,our_pubkey,33
hsmctl_sign_funding,,their_pubkey,33
hsmctl_sign_funding,,num_inputs,2
hsmctl_sign_funding,,inputs,num_inputs*struct utxo
hsmctl_sign_funding_reply,104
hsmctl_sign_funding_reply,,num_sigs,2
hsmctl_sign_funding_reply,,sig,num_sigs*secp256k1_ecdsa_signature
# Request a client socket for a `channeld`, allows signing announcements
hsmctl_hsmfd_channeld,5
hsmctl_hsmfd_channeld,,unique_id,8
# Empty reply, just an fd
hsmctl_hsmfd_channeld_reply,105
# Master asks the HSM to sign a node_announcement
hsmctl_node_announcement_sig_req,6
hsmctl_node_announcement_sig_req,,annlen,2
hsmctl_node_announcement_sig_req,,announcement,annlen*u8
hsmctl_node_announcement_sig_reply,106
hsmctl_node_announcement_sig_reply,,signature,secp256k1_ecdsa_signature
# Sign a withdrawal request
hsmctl_sign_withdrawal,7
hsmctl_sign_withdrawal,,satoshi_out,8
hsmctl_sign_withdrawal,,change_out,8
hsmctl_sign_withdrawal,,change_keyindex,4
hsmctl_sign_withdrawal,,pkh,20*u8
hsmctl_sign_withdrawal,,num_inputs,2
hsmctl_sign_withdrawal,,inputs,num_inputs*struct utxo
hsmctl_sign_withdrawal_reply,107
hsmctl_sign_withdrawal_reply,,num_sigs,2
hsmctl_sign_withdrawal_reply,,sig,num_sigs*secp256k1_ecdsa_signature
1 # These are fatal.
2 hsmstatus_init_failed,0x8000
3 hsmstatus_writemsg_failed,0x8001
4 hsmstatus_bad_request,0x8002
5 hsmstatus_fd_failed,0x8003
6 hsmstatus_key_failed,0x8004
7 # Clients should not give a bad request but not the HSM's decision to crash.
8 hsmstatus_client_bad_request,1000
9 hsmstatus_client_bad_request,,unique_id,8
10 hsmstatus_client_bad_request,,len,2
11 hsmstatus_client_bad_request,,msg,len*u8
12 # Start the HSM.
13 hsmctl_init,1
14 hsmctl_init,,new,bool
15 #include <common/bip32.h>
16 hsmctl_init_reply,101
17 hsmctl_init_reply,,node_id,33
18 hsmctl_init_reply,,peer_seed,struct secret
19 hsmctl_init_reply,,bip32,struct ext_key
20 # ECDH returns an fd.
21 hsmctl_hsmfd_ecdh,3
22 hsmctl_hsmfd_ecdh,,unique_id,8
23 # No contents, just an fd.
24 hsmctl_hsmfd_ecdh_fd_reply,103
25 # Return signature for a funding tx.
26 #include <common/utxo.h>
27 # FIXME: This should also take their commit sig & details, to verify.
28 hsmctl_sign_funding,4
29 hsmctl_sign_funding,,satoshi_out,8
30 hsmctl_sign_funding,,change_out,8
31 hsmctl_sign_funding,,change_keyindex,4
32 hsmctl_sign_funding,,our_pubkey,33
33 hsmctl_sign_funding,,their_pubkey,33
34 hsmctl_sign_funding,,num_inputs,2
35 hsmctl_sign_funding,,inputs,num_inputs*struct utxo
36 hsmctl_sign_funding_reply,104
37 hsmctl_sign_funding_reply,,num_sigs,2
38 hsmctl_sign_funding_reply,,sig,num_sigs*secp256k1_ecdsa_signature
39 # Request a client socket for a `channeld`, allows signing announcements
40 hsmctl_hsmfd_channeld,5
41 hsmctl_hsmfd_channeld,,unique_id,8
42 # Empty reply, just an fd
43 hsmctl_hsmfd_channeld_reply,105
44 # Master asks the HSM to sign a node_announcement
45 hsmctl_node_announcement_sig_req,6
46 hsmctl_node_announcement_sig_req,,annlen,2
47 hsmctl_node_announcement_sig_req,,announcement,annlen*u8
48 hsmctl_node_announcement_sig_reply,106
49 hsmctl_node_announcement_sig_reply,,signature,secp256k1_ecdsa_signature
50 # Sign a withdrawal request
51 hsmctl_sign_withdrawal,7
52 hsmctl_sign_withdrawal,,satoshi_out,8
53 hsmctl_sign_withdrawal,,change_out,8
54 hsmctl_sign_withdrawal,,change_keyindex,4
55 hsmctl_sign_withdrawal,,pkh,20*u8
56 hsmctl_sign_withdrawal,,num_inputs,2
57 hsmctl_sign_withdrawal,,inputs,num_inputs*struct utxo
58 hsmctl_sign_withdrawal_reply,107
59 hsmctl_sign_withdrawal_reply,,num_sigs,2
60 hsmctl_sign_withdrawal_reply,,sig,num_sigs*secp256k1_ecdsa_signature

View File

@@ -7,8 +7,8 @@
#include <common/status.h>
#include <common/utils.h>
#include <errno.h>
#include <hsmd/gen_hsm_wire.h>
#include <inttypes.h>
#include <lightningd/hsm/gen_hsm_wire.h>
#include <lightningd/log.h>
#include <string.h>
#include <wally_bip32.h>
@@ -36,7 +36,7 @@ void hsm_init(struct lightningd *ld, bool newdir)
u8 *msg;
bool create;
ld->hsm_fd = subd_raw(ld, "lightningd_hsm");
ld->hsm_fd = subd_raw(ld, "lightning_hsmd");
if (ld->hsm_fd < 0)
err(1, "Could not subd hsm");

View File

@@ -22,8 +22,8 @@
#include <lightningd/invoice.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/log.h>
#include <lightningd/onchain/onchain_wire.h>
#include <lightningd/options.h>
#include <onchaind/onchain_wire.h>
#include <sys/types.h>
#include <unistd.h>
@@ -100,12 +100,13 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
static const char *daemons[] = {
"lightningd",
"lightningd_channel",
"lightningd_closing",
"lightningd_gossip",
"lightningd_handshake",
"lightningd_hsm",
"lightningd_opening"
"lightning_channeld",
"lightning_closingd",
"lightning_gossipd",
"lightning_handshaked",
"lightning_hsmd",
"lightning_onchaind",
"lightning_openingd"
};
/* Check we can run them, and check their versions */

View File

@@ -4,8 +4,8 @@
#include <common/cryptomsg.h>
#include <errno.h>
#include <fcntl.h>
#include <lightningd/handshake/gen_handshake_wire.h>
#include <lightningd/hsm/gen_hsm_wire.h>
#include <handshaked/gen_handshake_wire.h>
#include <hsmd/gen_hsm_wire.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
@@ -221,7 +221,7 @@ static struct io_plan *hsm_then_handshake(struct io_conn *conn,
/* Give handshake daemon the hsm fd. */
handshaked = new_subd(ld, ld,
"lightningd_handshake", NULL,
"lightning_handshaked", NULL,
handshake_wire_type_name,
NULL, NULL,
take(&hsmfd), take(&connfd), NULL);

View File

@@ -1,89 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/onchain-wrongdir:
$(MAKE) -C ../.. lightningd/onchain-all
default: lightningd/onchain-all
lightningd/onchain-all: lightningd/lightningd_onchain
lightningd/onchain/gen_onchain_types_names.h: lightningd/onchain/onchain_types.h ccan/ccan/cdump/tools/cdump-enumstr
ccan/ccan/cdump/tools/cdump-enumstr lightningd/onchain/onchain_types.h > $@
# lightningd/onchain needs these:
LIGHTNINGD_ONCHAIN_HEADERS_GEN := \
lightningd/onchain/gen_onchain_wire.h \
lightningd/onchain/gen_onchain_types_names.h
LIGHTNINGD_ONCHAIN_HEADERS_NOGEN := \
lightningd/onchain/onchain_types.h \
lightningd/onchain/onchain_wire.h
LIGHTNINGD_ONCHAIN_HEADERS := $(LIGHTNINGD_ONCHAIN_HEADERS_GEN) $(LIGHTNINGD_ONCHAIN_HEADERS_NOGEN)
LIGHTNINGD_ONCHAIN_SRC := lightningd/onchain/onchain.c \
lightningd/onchain/gen_onchain_wire.c \
lightningd/onchain/onchain_wire.c
LIGHTNINGD_ONCHAIN_OBJS := $(LIGHTNINGD_ONCHAIN_SRC:.c=.o)
# Control daemon uses this:
LIGHTNINGD_ONCHAIN_CONTROL_HEADERS := \
lightningd/onchain/gen_onchain_wire.h \
lightningd/onchain/onchain_wire.h
LIGHTNINGD_ONCHAIN_CONTROL_SRC := $(LIGHTNINGD_ONCHAIN_CONTROL_HEADERS:.h=.c)
LIGHTNINGD_ONCHAIN_CONTROL_OBJS := $(LIGHTNINGD_ONCHAIN_CONTROL_SRC:.c=.o)
LIGHTNINGD_ONCHAIN_GEN_SRC := $(filter lightningd/onchain/gen_%, $(LIGHTNINGD_ONCHAIN_SRC) $(LIGHTNINGD_ONCHAIN_CONTROL_SRC))
LIGHTNINGD_ONCHAIN_SRC_NOGEN := $(filter-out lightningd/onchain/gen_%, $(LIGHTNINGD_ONCHAIN_SRC))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_ONCHAIN_HEADERS_GEN)
LIGHTNINGD_HEADERS_NOGEN += $(LIGHTNINGD_ONCHAIN_HEADERS_NOGEN)
$(LIGHTNINGD_ONCHAIN_OBJS): $(LIGHTNINGD_HEADERS)
# Common source we use.
ONCHAIND_COMMON_OBJS := \
common/daemon_conn.o \
common/debug.o \
common/derive_basepoints.o \
common/dev_disconnect.o \
common/htlc_tx.o \
common/htlc_wire.o \
common/initial_commit_tx.o \
common/keyset.o \
common/key_derive.o \
common/msg_queue.o \
common/permute_tx.o \
common/status.o \
common/type_to_string.o \
common/utils.o \
common/version.o
lightningd/onchain/gen_onchain_wire.h: $(WIRE_GEN) lightningd/onchain/onchain_wire.csv
$(WIRE_GEN) --header $@ onchain_wire_type < lightningd/onchain/onchain_wire.csv > $@
lightningd/onchain/gen_onchain_wire.c: $(WIRE_GEN) lightningd/onchain/onchain_wire.csv
$(WIRE_GEN) ${@:.c=.h} onchain_wire_type < lightningd/onchain/onchain_wire.csv > $@
LIGHTNINGD_ONCHAIN_OBJS := $(LIGHTNINGD_ONCHAIN_SRC:.c=.o) $(LIGHTNINGD_ONCHAIN_GEN_SRC:.c=.o)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_ONCHAIN_OBJS)
lightningd/lightningd_onchain: $(LIGHTNINGD_ONCHAIN_OBJS) $(WIRE_ONION_OBJS) $(ONCHAIND_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS)
check-source: $(LIGHTNINGD_ONCHAIN_SRC_NOGEN:%=check-src-include-order/%)
check-source-bolt: $(LIGHTNINGD_ONCHAIN_SRC:%=bolt-check/%) $(LIGHTNINGD_ONCHAIN_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_ONCHAIN_SRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_ONCHAIN_HEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/onchain-clean
lightningd/onchain-clean:
$(RM) $(LIGHTNINGD_ONCHAIN_OBJS) gen_*
-include lightningd/onchain/test/Makefile

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +0,0 @@
#ifndef LIGHTNING_LIGHTNINGD_ONCHAIN_ONCHAIN_TYPES_H
#define LIGHTNING_LIGHTNINGD_ONCHAIN_ONCHAIN_TYPES_H
#include "config.h"
/* Different transactions we care about. */
enum tx_type {
/* The initial 2 of 2 funding transaction */
FUNDING_TRANSACTION,
/* A mutual close: spends funding */
MUTUAL_CLOSE,
/* Their unilateral: spends funding */
THEIR_UNILATERAL,
/* Our unilateral: spends funding */
OUR_UNILATERAL,
/* The 2 different types of HTLC transaction, each way */
THEIR_HTLC_TIMEOUT_TO_THEM,
THEIR_HTLC_FULFILL_TO_US,
OUR_HTLC_TIMEOUT_TO_US,
OUR_HTLC_FULFILL_TO_THEM,
/* When we spend the to-us output (after cltv_expiry) */
OUR_UNILATERAL_TO_US_RETURN_TO_WALLET,
/* Special type for marking outputs as resolved by self. */
SELF,
/* Shouldn't happen. */
UNKNOWN_TXTYPE
};
/* Different output types. */
enum output_type {
/* FUNDING_TRANSACTION */
FUNDING_OUTPUT,
/* THEIR_UNILATERAL */
OUTPUT_TO_US,
DELAYED_OUTPUT_TO_THEM,
/* OUR_UNILATERAL */
DELAYED_OUTPUT_TO_US,
OUTPUT_TO_THEM,
/* HTLC outputs: their offers and our offers */
THEIR_HTLC,
OUR_HTLC,
};
#endif /* LIGHTNING_LIGHTNINGD_ONCHAIN_ONCHAIN_TYPES_H */

View File

@@ -1,19 +0,0 @@
#include <ccan/structeq/structeq.h>
#include <common/htlc_wire.h>
#include <lightningd/onchain/onchain_wire.h>
#include <wire/wire.h>
void towire_htlc_stub(u8 **pptr, const struct htlc_stub *htlc_stub)
{
towire_side(pptr, htlc_stub->owner);
towire_u32(pptr, htlc_stub->cltv_expiry);
towire_ripemd160(pptr, &htlc_stub->ripemd);
}
void fromwire_htlc_stub(const u8 **cursor, size_t *max,
struct htlc_stub *htlc_stub)
{
htlc_stub->owner = fromwire_side(cursor, max);
htlc_stub->cltv_expiry = fromwire_u32(cursor, max);
fromwire_ripemd160(cursor, max, &htlc_stub->ripemd);
}

View File

@@ -1,74 +0,0 @@
# Shouldn't happen
onchain_bad_command,0x8000
onchain_internal_error,0x8003
onchain_crypto_failed,0x8004
#include <common/htlc_wire.h>
# Begin! Here's the onchain tx which spends funding tx, followed by all HTLCs.
onchain_init,1
onchain_init,,seed,struct privkey
onchain_init,,shachain,struct shachain
onchain_init,,funding_amount_satoshi,u64
# Remote per commit point for committed tx.
onchain_init,,old_remote_per_commitment_point,struct pubkey
# Remote per commit point for current tx (needed if we haven't got revoke_and_ack yet).
onchain_init,,remote_per_commitment_point,struct pubkey
onchain_init,,local_to_self_delay,u32
onchain_init,,remote_to_self_delay,u32
onchain_init,,feerate_per_kw,u64
onchain_init,,local_dust_limit_satoshi,u64
onchain_init,,remote_revocation_basepoint,struct pubkey
# Gives an easy way to tell if it's our unilateral close or theirs...
onchain_init,,our_broadcast_txid,struct sha256_double
onchain_init,,local_scriptpubkey_len,u16
onchain_init,,local_scriptpubkey,local_scriptpubkey_len*u8
onchain_init,,remote_scriptpubkey_len,u16
onchain_init,,remote_scriptpubkey,remote_scriptpubkey_len*u8
onchain_init,,ourwallet_pubkey,struct pubkey
# We need these two for commit number obscurer
onchain_init,,funder,enum side
onchain_init,,remote_payment_basepoint,struct pubkey
onchain_init,,remote_delayed_payment_basepoint,struct pubkey
onchain_init,,tx,struct bitcoin_tx
onchain_init,,tx_blockheight,u32
onchain_init,,num_htlc_sigs,u16
onchain_init,,htlc_signature,num_htlc_sigs*secp256k1_ecdsa_signature
onchain_init,,num_htlcs,u64
#include <lightningd/onchain/onchain_wire.h>
# This is all the HTLCs: one per message
onchain_htlc,2
onchain_htlc,,htlc,struct htlc_stub
# This sets what the state is, depending on tx.
onchain_init_reply,101
onchain_init_reply,,state,u8
# onchaind->master: Send out a tx.
onchain_broadcast_tx,3
onchain_broadcast_tx,,tx,struct bitcoin_tx
# master->onchaind: Notifier that an output has been spent by input_num of tx.
onchain_spent,4
onchain_spent,,tx,struct bitcoin_tx
onchain_spent,,input_num,u32
onchain_spent,,blockheight,u32
# master->onchaind: We will receive more than one of these, as depth changes.
onchain_depth,5
onchain_depth,,txid,struct sha256_double
onchain_depth,,depth,u32
# onchaind->master: We don't want to watch this tx, or its outputs
onchain_unwatch_tx,6
onchain_unwatch_tx,,txid,struct sha256_double
onchain_unwatch_tx,,num_outputs,u32
# master->onchaind: We know HTLC preimage
onchain_known_preimage,7
onchain_known_preimage,,preimage,struct preimage
# onchaind->master: We discovered HTLC preimage
onchain_extracted_preimage,8
onchain_extracted_preimage,,preimage,struct preimage
1 # Shouldn't happen
2 onchain_bad_command,0x8000
3 onchain_internal_error,0x8003
4 onchain_crypto_failed,0x8004
5 #include <common/htlc_wire.h>
6 # Begin! Here's the onchain tx which spends funding tx, followed by all HTLCs.
7 onchain_init,1
8 onchain_init,,seed,struct privkey
9 onchain_init,,shachain,struct shachain
10 onchain_init,,funding_amount_satoshi,u64
11 # Remote per commit point for committed tx.
12 onchain_init,,old_remote_per_commitment_point,struct pubkey
13 # Remote per commit point for current tx (needed if we haven't got revoke_and_ack yet).
14 onchain_init,,remote_per_commitment_point,struct pubkey
15 onchain_init,,local_to_self_delay,u32
16 onchain_init,,remote_to_self_delay,u32
17 onchain_init,,feerate_per_kw,u64
18 onchain_init,,local_dust_limit_satoshi,u64
19 onchain_init,,remote_revocation_basepoint,struct pubkey
20 # Gives an easy way to tell if it's our unilateral close or theirs...
21 onchain_init,,our_broadcast_txid,struct sha256_double
22 onchain_init,,local_scriptpubkey_len,u16
23 onchain_init,,local_scriptpubkey,local_scriptpubkey_len*u8
24 onchain_init,,remote_scriptpubkey_len,u16
25 onchain_init,,remote_scriptpubkey,remote_scriptpubkey_len*u8
26 onchain_init,,ourwallet_pubkey,struct pubkey
27 # We need these two for commit number obscurer
28 onchain_init,,funder,enum side
29 onchain_init,,remote_payment_basepoint,struct pubkey
30 onchain_init,,remote_delayed_payment_basepoint,struct pubkey
31 onchain_init,,tx,struct bitcoin_tx
32 onchain_init,,tx_blockheight,u32
33 onchain_init,,num_htlc_sigs,u16
34 onchain_init,,htlc_signature,num_htlc_sigs*secp256k1_ecdsa_signature
35 onchain_init,,num_htlcs,u64
36 #include <lightningd/onchain/onchain_wire.h>
37 # This is all the HTLCs: one per message
38 onchain_htlc,2
39 onchain_htlc,,htlc,struct htlc_stub
40 # This sets what the state is, depending on tx.
41 onchain_init_reply,101
42 onchain_init_reply,,state,u8
43 # onchaind->master: Send out a tx.
44 onchain_broadcast_tx,3
45 onchain_broadcast_tx,,tx,struct bitcoin_tx
46 # master->onchaind: Notifier that an output has been spent by input_num of tx.
47 onchain_spent,4
48 onchain_spent,,tx,struct bitcoin_tx
49 onchain_spent,,input_num,u32
50 onchain_spent,,blockheight,u32
51 # master->onchaind: We will receive more than one of these, as depth changes.
52 onchain_depth,5
53 onchain_depth,,txid,struct sha256_double
54 onchain_depth,,depth,u32
55 # onchaind->master: We don't want to watch this tx, or its outputs
56 onchain_unwatch_tx,6
57 onchain_unwatch_tx,,txid,struct sha256_double
58 onchain_unwatch_tx,,num_outputs,u32
59 # master->onchaind: We know HTLC preimage
60 onchain_known_preimage,7
61 onchain_known_preimage,,preimage,struct preimage
62 # onchaind->master: We discovered HTLC preimage
63 onchain_extracted_preimage,8
64 onchain_extracted_preimage,,preimage,struct preimage

View File

@@ -1,18 +0,0 @@
#ifndef LIGHTNING_LIGHTNINGD_ONCHAIN_ONCHAIN_WIRE_H
#define LIGHTNING_LIGHTNINGD_ONCHAIN_ONCHAIN_WIRE_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <common/htlc.h>
/* The minimal info about an htlc. */
struct htlc_stub {
enum side owner;
u32 cltv_expiry;
struct ripemd160 ripemd;
};
void towire_htlc_stub(u8 **pptr, const struct htlc_stub *htlc_stub);
void fromwire_htlc_stub(const u8 **cursor, size_t *max,
struct htlc_stub *htlc_stub);
#endif /* LIGHTNING_LIGHTNINGD_ONCHAIN_ONCHAIN_WIRE_H */

View File

@@ -1,88 +0,0 @@
#! /usr/bin/make
# Designed to be run one level up
lightningd/opening-wrongdir:
$(MAKE) -C ../.. lightningd/opening-all
default: lightningd/opening-all
lightningd/opening-all: lightningd/lightningd_opening
# lightningd/opening needs these:
LIGHTNINGD_OPENING_HEADERS_GEN := \
lightningd/opening/gen_opening_wire.h
LIGHTNINGD_OPENING_HEADERS_NOGEN :=
LIGHTNINGD_OPENING_HEADERS := $(LIGHTNINGD_OPENING_HEADERS_GEN) $(LIGHTNINGD_OPENING_HEADERS_NOGEN)
LIGHTNINGD_OPENING_SRC := lightningd/opening/opening.c \
$(LIGHTNINGD_OPENING_HEADERS:.h=.c)
LIGHTNINGD_OPENING_OBJS := $(LIGHTNINGD_OPENING_SRC:.c=.o)
# Control daemon uses this:
LIGHTNINGD_OPENING_CONTROL_HEADERS := $(LIGHTNINGD_OPENING_HEADERS)
LIGHTNINGD_OPENING_CONTROL_SRC := $(LIGHTNINGD_OPENING_HEADERS:.h=.c)
LIGHTNINGD_OPENING_CONTROL_OBJS := $(LIGHTNINGD_OPENING_CONTROL_SRC:.c=.o)
LIGHTNINGD_OPENING_GEN_SRC := $(filter lightningd/opening/gen_%, $(LIGHTNINGD_OPENING_SRC) $(LIGHTNINGD_OPENING_CONTROL_SRC))
LIGHTNINGD_OPENING_SRC_NOGEN := $(filter-out lightningd/opening/gen_%, $(LIGHTNINGD_OPENING_SRC))
# Add to headers which any object might need.
LIGHTNINGD_HEADERS_GEN += $(LIGHTNINGD_OPENING_HEADERS_GEN)
LIGHTNINGD_HEADERS_NOGEN += $(LIGHTNINGD_OPENING_HEADERS_NOGEN)
# Common source we use.
OPENINGD_COMMON_OBJS := \
common/bip32.o \
common/channel_config.o \
common/crypto_sync.o \
common/cryptomsg.o \
common/daemon_conn.o \
common/debug.o \
common/derive_basepoints.o \
common/dev_disconnect.o \
common/funding_tx.o \
common/htlc_wire.o \
common/initial_channel.o \
common/initial_commit_tx.o \
common/key_derive.o \
common/keyset.o \
common/msg_queue.o \
common/ping.o \
common/peer_failed.o \
common/permute_tx.o \
common/pseudorand.o \
common/status.o \
common/type_to_string.o \
common/utils.o \
common/utxo.o \
common/version.o
$(LIGHTNINGD_OPENING_OBJS): $(LIGHTNINGD_HEADERS)
lightningd/opening/gen_opening_wire.h: $(WIRE_GEN) lightningd/opening/opening_wire.csv
$(WIRE_GEN) --header $@ opening_wire_type < lightningd/opening/opening_wire.csv > $@
lightningd/opening/gen_opening_wire.c: $(WIRE_GEN) lightningd/opening/opening_wire.csv
$(WIRE_GEN) ${@:.c=.h} opening_wire_type < lightningd/opening/opening_wire.csv > $@
LIGHTNINGD_OPENING_OBJS := $(LIGHTNINGD_OPENING_SRC:.c=.o) $(LIGHTNINGD_OPENING_GEN_SRC:.c=.o)
# Make sure these depend on everything.
ALL_OBJS += $(LIGHTNINGD_OPENING_OBJS)
lightningd/lightningd_opening: $(LIGHTNINGD_OPENING_OBJS) $(OPENINGD_COMMON_OBJS) $(WIRE_OBJS) $(BITCOIN_OBJS) $(LIGHTNINGD_HSM_CLIENT_OBJS)
check-source: $(LIGHTNINGD_OPENING_SRC_NOGEN:%=check-src-include-order/%)
check-source-bolt: $(LIGHTNINGD_OPENING_SRC:%=bolt-check/%) $(LIGHTNINGD_OPENING_HEADERS:%=bolt-check/%)
check-whitespace: $(LIGHTNINGD_OPENING_SRC_NOGEN:%=check-whitespace/%) $(LIGHTNINGD_OPENING_HEADERS_NOGEN:%=check-whitespace/%)
clean: lightningd/opening-clean
lightningd/opening-clean:
$(RM) $(LIGHTNINGD_OPENING_OBJS) gen_*
-include lightningd/opening/test/Makefile

View File

@@ -1,766 +0,0 @@
#include <bitcoin/block.h>
#include <bitcoin/chainparams.h>
#include <bitcoin/privkey.h>
#include <bitcoin/script.h>
#include <ccan/breakpoint/breakpoint.h>
#include <ccan/fdpass/fdpass.h>
#include <ccan/structeq/structeq.h>
#include <common/crypto_sync.h>
#include <common/debug.h>
#include <common/derive_basepoints.h>
#include <common/funding_tx.h>
#include <common/initial_channel.h>
#include <common/key_derive.h>
#include <common/peer_failed.h>
#include <common/ping.h>
#include <common/pseudorand.h>
#include <common/status.h>
#include <common/type_to_string.h>
#include <common/version.h>
#include <errno.h>
#include <inttypes.h>
#include <lightningd/opening/gen_opening_wire.h>
#include <secp256k1.h>
#include <signal.h>
#include <stdio.h>
#include <wally_bip32.h>
#include <wire/gen_peer_wire.h>
#include <wire/peer_wire.h>
#include <wire/wire.h>
#include <wire/wire_sync.h>
/* stdin == requests, 3 == peer, 4 == gossip */
#define REQ_FD STDIN_FILENO
#define PEER_FD 3
#define GOSSIP_FD 4
struct state {
struct crypto_state cs;
struct pubkey next_per_commit[NUM_SIDES];
/* Funding and feerate: set by opening peer. */
u64 funding_satoshis, push_msat;
u32 feerate_per_kw;
struct sha256_double funding_txid;
u16 funding_txout;
/* Secret keys and basepoint secrets. */
struct secrets our_secrets;
/* Our shaseed for generating per-commitment-secrets. */
struct sha256 shaseed;
struct channel_config localconf, *remoteconf;
/* Limits on what remote config we accept */
u32 max_to_self_delay;
u64 min_effective_htlc_capacity_msat;
struct channel *channel;
const struct chainparams *chainparams;
};
static void check_config_bounds(struct state *state,
const struct channel_config *remoteconf)
{
u64 capacity_msat;
u64 reserve_msat;
/* BOLT #2:
*
* The receiving node MUST fail the channel if `to_self_delay` is
* unreasonably large.
*/
if (remoteconf->to_self_delay > state->max_to_self_delay)
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_CONFIG,
"to_self_delay %u larger than %u",
remoteconf->to_self_delay, state->max_to_self_delay);
/* BOLT #2:
*
* The receiver MAY fail the channel if `funding_satoshis` is too
* small, and MUST fail the channel if `push_msat` is greater than
* `funding_satoshis` * 1000. The receiving node MAY fail the channel
* if it considers `htlc_minimum_msat` too large,
* `max_htlc_value_in_flight_msat` too small, `channel_reserve_satoshis`
* too large, or `max_accepted_htlcs` too small.
*/
/* We accumulate this into an effective bandwidth minimum. */
/* Overflow check before capacity calc. */
if (remoteconf->channel_reserve_satoshis > state->funding_satoshis)
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_CONFIG,
"Invalid channel_reserve_satoshis %"PRIu64
" for funding_satoshis %"PRIu64,
remoteconf->channel_reserve_satoshis,
state->funding_satoshis);
/* Consider highest reserve. */
reserve_msat = remoteconf->channel_reserve_satoshis * 1000;
if (state->localconf.channel_reserve_satoshis * 1000 > reserve_msat)
reserve_msat = state->localconf.channel_reserve_satoshis * 1000;
capacity_msat = state->funding_satoshis * 1000 - reserve_msat;
if (remoteconf->max_htlc_value_in_flight_msat < capacity_msat)
capacity_msat = remoteconf->max_htlc_value_in_flight_msat;
if (remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat)
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_CONFIG,
"Invalid htlc_minimum_msat %"PRIu64
" for funding_satoshis %"PRIu64
" capacity_msat %"PRIu64,
remoteconf->htlc_minimum_msat,
state->funding_satoshis,
capacity_msat);
if (capacity_msat < state->min_effective_htlc_capacity_msat)
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_CONFIG,
"Channel capacity with funding %"PRIu64" msat,"
" reserves %"PRIu64"/%"PRIu64" msat,"
" max_htlc_value_in_flight_msat %"PRIu64
" is %"PRIu64" msat, which is below %"PRIu64" msat",
state->funding_satoshis * 1000,
remoteconf->channel_reserve_satoshis * 1000,
state->localconf.channel_reserve_satoshis * 1000,
remoteconf->max_htlc_value_in_flight_msat,
capacity_msat,
state->min_effective_htlc_capacity_msat);
/* We don't worry about how many HTLCs they accept, as long as > 0! */
if (remoteconf->max_accepted_htlcs == 0)
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_CONFIG,
"max_accepted_htlcs %u invalid",
remoteconf->max_accepted_htlcs);
/* BOLT #2:
*
* It MUST fail the channel if `max_accepted_htlcs` is greater
* than 483.
*/
if (remoteconf->max_accepted_htlcs > 483)
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_CONFIG,
"max_accepted_htlcs %u too large",
remoteconf->max_accepted_htlcs);
}
/* We always set channel_reserve_satoshis to 1%, rounded up. */
static void set_reserve(u64 *reserve, u64 funding)
{
*reserve = (funding + 99) / 100;
}
/* BOLT #2:
*
* A sending node MUST ensure `temporary_channel_id` is unique from any other
* channel id with the same peer.
*/
static void temporary_channel_id(struct channel_id *channel_id)
{
size_t i;
for (i = 0; i < sizeof(*channel_id); i++)
channel_id->id[i] = pseudorand(256);
}
/* We have to handle random gossip message and pings. */
static u8 *read_next_peer_msg(struct state *state, const tal_t *ctx)
{
for (;;) {
u8 *msg = sync_crypto_read(ctx, &state->cs, PEER_FD);
if (!msg)
return NULL;
if (fromwire_peektype(msg) == WIRE_PING) {
u8 *pong;
if (!check_ping_make_pong(ctx, msg, &pong)) {
status_trace("Bad ping message");
return tal_free(msg);
}
if (pong && !sync_crypto_write(&state->cs, PEER_FD,
take(pong)))
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_WRITE_FAILED,
"Sending pong");
} else if (is_gossip_msg(msg)) {
/* We relay gossip to gossipd, but don't relay from */
if (!wire_sync_write(GOSSIP_FD, take(msg)))
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_WRITE_FAILED,
"Relaying gossip message");
} else {
return msg;
}
}
}
static u8 *funder_channel(struct state *state,
const struct pubkey *our_funding_pubkey,
const struct basepoints *ours,
u32 max_minimum_depth,
u64 change_satoshis, u32 change_keyindex,
u8 channel_flags,
const struct utxo *utxos,
const struct ext_key *bip32_base)
{
struct channel_id channel_id, id_in;
u8 *msg;
struct bitcoin_tx *tx;
struct basepoints theirs;
struct pubkey their_funding_pubkey, changekey;
secp256k1_ecdsa_signature sig;
u32 minimum_depth;
const u8 *wscript;
struct bitcoin_tx *funding;
const struct utxo **utxomap;
set_reserve(&state->localconf.channel_reserve_satoshis,
state->funding_satoshis);
temporary_channel_id(&channel_id);
/* BOLT #2:
*
* The sender MUST set `funding_satoshis` to less than 2^24 satoshi. */
if (state->funding_satoshis >= 1 << 24)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
"funding_satoshis must be < 2^24");
/* BOLT #2:
*
* The sender MUST set `push_msat` to equal or less than to 1000 *
* `funding_satoshis`.
*/
if (state->push_msat > 1000 * state->funding_satoshis)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
"push-msat must be < %"PRIu64,
1000 * state->funding_satoshis);
msg = towire_open_channel(state,
&state->chainparams->genesis_blockhash,
&channel_id,
state->funding_satoshis, state->push_msat,
state->localconf.dust_limit_satoshis,
state->localconf.max_htlc_value_in_flight_msat,
state->localconf.channel_reserve_satoshis,
state->localconf.htlc_minimum_msat,
state->feerate_per_kw,
state->localconf.to_self_delay,
state->localconf.max_accepted_htlcs,
our_funding_pubkey,
&ours->revocation,
&ours->payment,
&ours->delayed_payment,
&state->next_per_commit[LOCAL],
channel_flags);
if (!sync_crypto_write(&state->cs, PEER_FD, msg))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED,
"Writing open_channel");
state->remoteconf = tal(state, struct channel_config);
msg = read_next_peer_msg(state, state);
if (!msg)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Reading accept_channel");
/* BOLT #2:
*
* The receiver MUST fail the channel if `funding_pubkey`,
* `revocation_basepoint`, `payment_basepoint` or
* `delayed_payment_basepoint` are not valid DER-encoded compressed
* secp256k1 pubkeys.
*/
if (!fromwire_accept_channel(msg, NULL, &id_in,
&state->remoteconf->dust_limit_satoshis,
&state->remoteconf
->max_htlc_value_in_flight_msat,
&state->remoteconf
->channel_reserve_satoshis,
&state->remoteconf->htlc_minimum_msat,
&minimum_depth,
&state->remoteconf->to_self_delay,
&state->remoteconf->max_accepted_htlcs,
&their_funding_pubkey,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE]))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Parsing accept_channel %s", tal_hex(msg, msg));
/* BOLT #2:
*
* The `temporary_channel_id` MUST be the same as the
* `temporary_channel_id` in the `open_channel` message. */
if (!structeq(&id_in, &channel_id))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"accept_channel ids don't match: sent %s got %s",
type_to_string(msg, struct channel_id, &id_in),
type_to_string(msg, struct channel_id, &channel_id));
/* BOLT #2:
*
* The receiver MAY reject the `minimum_depth` if it considers it
* unreasonably large.
*
* Other fields have the same requirements as their counterparts in
* `open_channel`.
*/
if (minimum_depth > max_minimum_depth)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
"minimum_depth %u larger than %u",
minimum_depth, max_minimum_depth);
check_config_bounds(state, state->remoteconf);
/* Now, ask create funding transaction to pay those two addresses. */
if (change_satoshis) {
if (!bip32_pubkey(bip32_base, &changekey, change_keyindex))
status_failed(WIRE_OPENING_BAD_PARAM,
"Bad change key %u", change_keyindex);
}
utxomap = to_utxoptr_arr(state, utxos);
funding = funding_tx(state, &state->funding_txout,
utxomap, state->funding_satoshis,
our_funding_pubkey,
&their_funding_pubkey,
change_satoshis, &changekey,
bip32_base);
bitcoin_txid(funding, &state->funding_txid);
state->channel = new_initial_channel(state,
&state->funding_txid,
state->funding_txout,
state->funding_satoshis,
state->funding_satoshis * 1000
- state->push_msat,
state->feerate_per_kw,
&state->localconf,
state->remoteconf,
ours, &theirs,
our_funding_pubkey,
&their_funding_pubkey,
LOCAL);
if (!state->channel)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
"could not create channel with given config");
/* BOLT #2:
*
* ### The `funding_created` message
*
* This message describes the outpoint which the funder has created
* for the initial commitment transactions. After receiving the
* peer's signature, it will broadcast the funding transaction.
*/
tx = initial_channel_tx(state, &wscript, state->channel,
&state->next_per_commit[REMOTE], REMOTE);
sign_tx_input(tx, 0, NULL, wscript,
&state->our_secrets.funding_privkey,
our_funding_pubkey, &sig);
status_trace("signature %s on tx %s using key %s",
type_to_string(trc, secp256k1_ecdsa_signature, &sig),
type_to_string(trc, struct bitcoin_tx, tx),
type_to_string(trc, struct pubkey, our_funding_pubkey));
msg = towire_funding_created(state, &channel_id,
&state->funding_txid.sha,
state->funding_txout,
&sig);
if (!sync_crypto_write(&state->cs, PEER_FD, msg))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED,
"Writing funding_created");
/* BOLT #2:
*
* ### The `funding_signed` message
*
* This message gives the funder the signature they need for the first
* commitment transaction, so they can broadcast it knowing they can
* redeem their funds if they need to.
*/
msg = read_next_peer_msg(state, state);
if (!msg)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Reading funding_signed");
if (!fromwire_funding_signed(msg, NULL, &id_in, &sig))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Parsing funding_signed (%s)",
wire_type_name(fromwire_peektype(msg)));
/* BOLT #2:
*
* This message introduces the `channel_id` to identify the channel, which
* is derived from the funding transaction by combining the
* `funding_txid` and the `funding_output_index` using big-endian
* exclusive-OR (ie. `funding_output_index` alters the last two
* bytes).
*/
derive_channel_id(&channel_id,
&state->funding_txid, state->funding_txout);
if (!structeq(&id_in, &channel_id))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"funding_signed ids don't match: expceted %s got %s",
type_to_string(msg, struct channel_id, &channel_id),
type_to_string(msg, struct channel_id, &id_in));
/* BOLT #2:
*
* The recipient MUST fail the channel if `signature` is incorrect.
*/
tx = initial_channel_tx(state, &wscript, state->channel,
&state->next_per_commit[LOCAL], LOCAL);
if (!check_tx_sig(tx, 0, NULL, wscript, &their_funding_pubkey, &sig)) {
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Bad signature %s on tx %s using key %s",
type_to_string(trc, secp256k1_ecdsa_signature,
&sig),
type_to_string(trc, struct bitcoin_tx, tx),
type_to_string(trc, struct pubkey,
&their_funding_pubkey));
}
/* BOLT #2:
*
* Once the channel funder receives the `funding_signed` message, they
* must broadcast the funding transaction to the Bitcoin network.
*/
return towire_opening_funder_reply(state,
state->remoteconf,
tx,
&sig,
&state->cs,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE],
minimum_depth,
&their_funding_pubkey,
&state->funding_txid,
state->feerate_per_kw);
}
/* This is handed the message the peer sent which caused gossip to stop:
* it should be an open_channel */
static u8 *fundee_channel(struct state *state,
const struct pubkey *our_funding_pubkey,
const struct basepoints *ours,
u32 minimum_depth,
u32 min_feerate, u32 max_feerate, const u8 *peer_msg)
{
struct channel_id id_in, channel_id;
struct basepoints theirs;
struct pubkey their_funding_pubkey;
secp256k1_ecdsa_signature theirsig, sig;
struct bitcoin_tx *tx;
struct sha256_double chain_hash;
u8 *msg;
const u8 *wscript;
u8 channel_flags;
state->remoteconf = tal(state, struct channel_config);
/* BOLT #2:
*
* The receiver MUST fail the channel if `funding_pubkey`,
* `revocation_basepoint`, `payment_basepoint` or
* `delayed_payment_basepoint` are not valid DER-encoded compressed
* secp256k1 pubkeys.
*/
if (!fromwire_open_channel(peer_msg, NULL, &chain_hash, &channel_id,
&state->funding_satoshis, &state->push_msat,
&state->remoteconf->dust_limit_satoshis,
&state->remoteconf->max_htlc_value_in_flight_msat,
&state->remoteconf->channel_reserve_satoshis,
&state->remoteconf->htlc_minimum_msat,
&state->feerate_per_kw,
&state->remoteconf->to_self_delay,
&state->remoteconf->max_accepted_htlcs,
&their_funding_pubkey,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE],
&channel_flags))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_BAD_INITIAL_MESSAGE,
"Parsing open_channel %s",
tal_hex(peer_msg, peer_msg));
/* BOLT #2:
*
* The receiving MUST reject the channel if the `chain_hash` value
* within the `open_channel` message is set to a hash of a chain
* unknown to the receiver.
*/
if (!structeq(&chain_hash, &state->chainparams->genesis_blockhash)) {
peer_failed(PEER_FD, &state->cs, NULL,
WIRE_OPENING_PEER_BAD_INITIAL_MESSAGE,
"Unknown chain-hash %s",
type_to_string(peer_msg, struct sha256_double,
&chain_hash));
}
/* BOLT #2 FIXME:
*
* The receiving node ... MUST fail the channel if `funding-satoshis`
* is greater than or equal to 2^24 */
if (state->funding_satoshis >= 1 << 24)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_BAD_FUNDING,
"funding_satoshis %"PRIu64" too large",
state->funding_satoshis);
/* BOLT #2:
*
* The receiving node ... MUST fail the channel if `push_msat` is
* greater than `funding_satoshis` * 1000.
*/
if (state->push_msat > state->funding_satoshis * 1000)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_BAD_FUNDING,
"push_msat %"PRIu64
" too large for funding_satoshis %"PRIu64,
state->push_msat, state->funding_satoshis);
/* BOLT #2:
*
* The receiver MUST fail the channel if it considers `feerate_per_kw`
* too small for timely processing, or unreasonably large.
*/
if (state->feerate_per_kw < min_feerate)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_BAD_FUNDING,
"feerate_per_kw %u below minimum %u",
state->feerate_per_kw, min_feerate);
if (state->feerate_per_kw > max_feerate)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_BAD_FUNDING,
"feerate_per_kw %u above maximum %u",
state->feerate_per_kw, max_feerate);
set_reserve(&state->localconf.channel_reserve_satoshis,
state->funding_satoshis);
check_config_bounds(state, state->remoteconf);
msg = towire_accept_channel(state, &channel_id,
state->localconf.dust_limit_satoshis,
state->localconf
.max_htlc_value_in_flight_msat,
state->localconf.channel_reserve_satoshis,
state->localconf.htlc_minimum_msat,
minimum_depth,
state->localconf.to_self_delay,
state->localconf.max_accepted_htlcs,
our_funding_pubkey,
&ours->revocation,
&ours->payment,
&ours->delayed_payment,
&state->next_per_commit[LOCAL]);
if (!sync_crypto_write(&state->cs, PEER_FD, take(msg)))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_WRITE_FAILED,
"Writing accept_channel");
msg = read_next_peer_msg(state, state);
if (!msg)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Reading funding_created");
if (!fromwire_funding_created(msg, NULL, &id_in,
&state->funding_txid.sha,
&state->funding_txout,
&theirsig))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Parsing funding_created");
/* BOLT #2:
*
* The sender MUST set `temporary_channel_id` the same as the
* `temporary_channel_id` in the `open_channel` message. */
if (!structeq(&id_in, &channel_id))
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"funding_created ids don't match: sent %s got %s",
type_to_string(msg, struct channel_id, &channel_id),
type_to_string(msg, struct channel_id, &id_in));
state->channel = new_initial_channel(state,
&state->funding_txid,
state->funding_txout,
state->funding_satoshis,
state->push_msat,
state->feerate_per_kw,
&state->localconf,
state->remoteconf,
ours, &theirs,
our_funding_pubkey,
&their_funding_pubkey,
REMOTE);
if (!state->channel)
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_BAD_PARAM,
"could not create channel with given config");
/* BOLT #2:
*
* The recipient MUST fail the channel if `signature` is incorrect.
*/
tx = initial_channel_tx(state, &wscript, state->channel,
&state->next_per_commit[LOCAL], LOCAL);
if (!check_tx_sig(tx, 0, NULL, wscript, &their_funding_pubkey,
&theirsig)) {
peer_failed(PEER_FD, &state->cs, NULL, WIRE_OPENING_PEER_READ_FAILED,
"Bad signature %s on tx %s using key %s",
type_to_string(trc, secp256k1_ecdsa_signature,
&theirsig),
type_to_string(trc, struct bitcoin_tx, tx),
type_to_string(trc, struct pubkey,
&their_funding_pubkey));
}
/* BOLT #2:
*
* This message introduces the `channel_id` to identify the channel,
* which is derived from the funding transaction by combining the
* `funding_txid` and the `funding_output_index` using big-endian
* exclusive-OR (ie. `funding_output_index` alters the last two
* bytes).
*/
derive_channel_id(&channel_id,
&state->funding_txid, state->funding_txout);
/* BOLT #2:
*
* ### The `funding_signed` message
*
* This message gives the funder the signature they need for the first
* commitment transaction, so they can broadcast it knowing they can
* redeem their funds if they need to.
*/
tx = initial_channel_tx(state, &wscript, state->channel,
&state->next_per_commit[REMOTE], REMOTE);
sign_tx_input(tx, 0, NULL, wscript,
&state->our_secrets.funding_privkey,
our_funding_pubkey, &sig);
/* We don't send this ourselves: channeld does, because master needs
* to save state to disk before doing so. */
msg = towire_funding_signed(state, &channel_id, &sig);
return towire_opening_fundee_reply(state,
state->remoteconf,
tx,
&theirsig,
&state->cs,
&theirs.revocation,
&theirs.payment,
&theirs.delayed_payment,
&state->next_per_commit[REMOTE],
&their_funding_pubkey,
&state->funding_txid,
state->funding_txout,
state->funding_satoshis,
state->push_msat,
channel_flags,
state->feerate_per_kw,
msg);
}
#ifndef TESTING
int main(int argc, char *argv[])
{
u8 *msg, *peer_msg;
struct state *state = tal(NULL, struct state);
struct privkey seed;
struct basepoints our_points;
struct pubkey our_funding_pubkey;
u32 minimum_depth, max_minimum_depth;
u32 min_feerate, max_feerate;
u64 change_satoshis;
u32 change_keyindex;
u8 channel_flags;
struct utxo *utxos;
struct ext_key bip32_base;
u32 network_index;
if (argc == 2 && streq(argv[1], "--version")) {
printf("%s\n", version());
exit(0);
}
subdaemon_debug(argc, argv);
/* We handle write returning errors! */
signal(SIGCHLD, SIG_IGN);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
status_setup_sync(REQ_FD);
msg = wire_sync_read(state, REQ_FD);
if (!msg)
status_failed(WIRE_OPENING_BAD_COMMAND, "%s", strerror(errno));
if (!fromwire_opening_init(msg, NULL,
&network_index,
&state->localconf,
&state->max_to_self_delay,
&state->min_effective_htlc_capacity_msat,
&state->cs,
&seed))
status_failed(WIRE_OPENING_BAD_COMMAND, "%s", strerror(errno));
tal_free(msg);
state->chainparams = chainparams_by_index(network_index);
/* We derive everything from the one secret seed. */
if (!derive_basepoints(&seed, &our_funding_pubkey,
&our_points, &state->our_secrets,
&state->shaseed))
status_failed(WIRE_OPENING_KEY_DERIVATION_FAILED,
"Secret derivation failed, secret = %s",
type_to_string(trc, struct privkey, &seed));
if (!per_commit_point(&state->shaseed, &state->next_per_commit[LOCAL],
0))
status_failed(WIRE_OPENING_KEY_DERIVATION_FAILED,
"First per_commitment_point derivation failed,"
" secret = %s",
type_to_string(trc, struct privkey, &seed));
status_trace("First per_commit_point = %s",
type_to_string(trc, struct pubkey,
&state->next_per_commit[LOCAL]));
msg = wire_sync_read(state, REQ_FD);
if (fromwire_opening_funder(state, msg, NULL,
&state->funding_satoshis,
&state->push_msat,
&state->feerate_per_kw, &max_minimum_depth,
&change_satoshis, &change_keyindex,
&channel_flags, &utxos, &bip32_base))
msg = funder_channel(state, &our_funding_pubkey, &our_points,
max_minimum_depth, change_satoshis,
change_keyindex, channel_flags,
utxos, &bip32_base);
else if (fromwire_opening_fundee(state, msg, NULL, &minimum_depth,
&min_feerate, &max_feerate, &peer_msg))
msg = fundee_channel(state, &our_funding_pubkey, &our_points,
minimum_depth, min_feerate, max_feerate,
peer_msg);
/* Write message and hand back the fd. */
wire_sync_write(REQ_FD, msg);
fdpass_send(REQ_FD, PEER_FD);
fdpass_send(REQ_FD, GOSSIP_FD);
status_trace("Sent %s with fd",
opening_wire_type_name(fromwire_peektype(msg)));
tal_free(state);
return 0;
}
#endif /* TESTING */

View File

@@ -1,86 +0,0 @@
# These shouldn't happen
opening_bad_command,0x8000
opening_key_derivation_failed,0x8001
opening_bad_param,0x8002
opening_hsm_failed,0x8003
# These are due to peer.
opening_peer_write_failed,0x8010
opening_peer_read_failed,0x8011
opening_peer_bad_funding,0x8012
opening_peer_bad_config,0x8013
opening_peer_bad_initial_message,0x8014
#include <common/cryptomsg.h>
#include <common/channel_config.h>
opening_init,0
# Which network are we configured for (as index into the chainparams)?
opening_init,,network_index,4
# Base configuration we'll offer (channel reserve will vary with amount)
opening_init,,our_config,struct channel_config
# Minimum/maximum configuration values we'll accept
opening_init,,max_to_self_delay,4
opening_init,,min_effective_htlc_capacity_msat,8
opening_init,,crypto_state,struct crypto_state
# Seed to generate all the keys from
opening_init,,seed,struct privkey
#include <common/bip32.h>
#include <common/htlc_wire.h>
# This means we offer the open.
opening_funder,1
opening_funder,,funding_satoshis,8
opening_funder,,push_msat,8
opening_funder,,feerate_per_kw,4
opening_funder,,max_minimum_depth,4
opening_funder,,change_satoshis,u64
opening_funder,,change_keyindex,u32
opening_funder,,channel_flags,u8
#include <common/utxo.h>
opening_funder,,num_inputs,u16
opening_funder,,inputs,num_inputs*struct utxo
opening_funder,,bip32,struct ext_key
# This gives their sig, means we can broadcast tx: we're done.
opening_funder_reply,101
opening_funder_reply,,their_config,struct channel_config
opening_funder_reply,,first_commit,struct bitcoin_tx
opening_funder_reply,,first_commit_sig,secp256k1_ecdsa_signature
opening_funder_reply,,crypto_state,struct crypto_state
opening_funder_reply,,revocation_basepoint,33
opening_funder_reply,,payment_basepoint,33
opening_funder_reply,,delayed_payment_basepoint,33
opening_funder_reply,,their_per_commit_point,33
opening_funder_reply,,minimum_depth,4
opening_funder_reply,,remote_fundingkey,33
opening_funder_reply,,funding_txid,struct sha256_double
opening_funder_reply,,feerate_per_kw,4
# This means they offer the open (contains their offer packet)
opening_fundee,3
opening_fundee,,minimum_depth,4
opening_fundee,,min_feerate,4
opening_fundee,,max_feerate,4
opening_fundee,,len,2
opening_fundee,,msg,len*u8
# This gives their txid and info, means we can send funding_signed: we're done.
opening_fundee_reply,103
opening_fundee_reply,,their_config,struct channel_config
opening_fundee_reply,,first_commit,struct bitcoin_tx
opening_fundee_reply,,first_commit_sig,secp256k1_ecdsa_signature
opening_fundee_reply,,crypto_state,struct crypto_state
opening_fundee_reply,,revocation_basepoint,33
opening_fundee_reply,,payment_basepoint,33
opening_fundee_reply,,delayed_payment_basepoint,33
opening_fundee_reply,,their_per_commit_point,33
opening_fundee_reply,,remote_fundingkey,33
opening_fundee_reply,,funding_txid,struct sha256_double
opening_fundee_reply,,funding_txout,u16
opening_fundee_reply,,funding_satoshis,8
opening_fundee_reply,,push_msat,8
opening_fundee_reply,,channel_flags,u8
opening_fundee_reply,,feerate_per_kw,4
# The (encrypted) funding signed message: send this and we're committed.
opening_fundee_reply,,msglen,u16
opening_fundee_reply,,funding_signed_msg,msglen*u8
1 # These shouldn't happen
2 opening_bad_command,0x8000
3 opening_key_derivation_failed,0x8001
4 opening_bad_param,0x8002
5 opening_hsm_failed,0x8003
6 # These are due to peer.
7 opening_peer_write_failed,0x8010
8 opening_peer_read_failed,0x8011
9 opening_peer_bad_funding,0x8012
10 opening_peer_bad_config,0x8013
11 opening_peer_bad_initial_message,0x8014
12 #include <common/cryptomsg.h>
13 #include <common/channel_config.h>
14 opening_init,0
15 # Which network are we configured for (as index into the chainparams)?
16 opening_init,,network_index,4
17 # Base configuration we'll offer (channel reserve will vary with amount)
18 opening_init,,our_config,struct channel_config
19 # Minimum/maximum configuration values we'll accept
20 opening_init,,max_to_self_delay,4
21 opening_init,,min_effective_htlc_capacity_msat,8
22 opening_init,,crypto_state,struct crypto_state
23 # Seed to generate all the keys from
24 opening_init,,seed,struct privkey
25 #include <common/bip32.h>
26 #include <common/htlc_wire.h>
27 # This means we offer the open.
28 opening_funder,1
29 opening_funder,,funding_satoshis,8
30 opening_funder,,push_msat,8
31 opening_funder,,feerate_per_kw,4
32 opening_funder,,max_minimum_depth,4
33 opening_funder,,change_satoshis,u64
34 opening_funder,,change_keyindex,u32
35 opening_funder,,channel_flags,u8
36 #include <common/utxo.h>
37 opening_funder,,num_inputs,u16
38 opening_funder,,inputs,num_inputs*struct utxo
39 opening_funder,,bip32,struct ext_key
40 # This gives their sig, means we can broadcast tx: we're done.
41 opening_funder_reply,101
42 opening_funder_reply,,their_config,struct channel_config
43 opening_funder_reply,,first_commit,struct bitcoin_tx
44 opening_funder_reply,,first_commit_sig,secp256k1_ecdsa_signature
45 opening_funder_reply,,crypto_state,struct crypto_state
46 opening_funder_reply,,revocation_basepoint,33
47 opening_funder_reply,,payment_basepoint,33
48 opening_funder_reply,,delayed_payment_basepoint,33
49 opening_funder_reply,,their_per_commit_point,33
50 opening_funder_reply,,minimum_depth,4
51 opening_funder_reply,,remote_fundingkey,33
52 opening_funder_reply,,funding_txid,struct sha256_double
53 opening_funder_reply,,feerate_per_kw,4
54 # This means they offer the open (contains their offer packet)
55 opening_fundee,3
56 opening_fundee,,minimum_depth,4
57 opening_fundee,,min_feerate,4
58 opening_fundee,,max_feerate,4
59 opening_fundee,,len,2
60 opening_fundee,,msg,len*u8
61 # This gives their txid and info, means we can send funding_signed: we're done.
62 opening_fundee_reply,103
63 opening_fundee_reply,,their_config,struct channel_config
64 opening_fundee_reply,,first_commit,struct bitcoin_tx
65 opening_fundee_reply,,first_commit_sig,secp256k1_ecdsa_signature
66 opening_fundee_reply,,crypto_state,struct crypto_state
67 opening_fundee_reply,,revocation_basepoint,33
68 opening_fundee_reply,,payment_basepoint,33
69 opening_fundee_reply,,delayed_payment_basepoint,33
70 opening_fundee_reply,,their_per_commit_point,33
71 opening_fundee_reply,,remote_fundingkey,33
72 opening_fundee_reply,,funding_txid,struct sha256_double
73 opening_fundee_reply,,funding_txout,u16
74 opening_fundee_reply,,funding_satoshis,8
75 opening_fundee_reply,,push_msat,8
76 opening_fundee_reply,,channel_flags,u8
77 opening_fundee_reply,,feerate_per_kw,4
78 # The (encrypted) funding signed message: send this and we're committed.
79 opening_fundee_reply,,msglen,u16
80 opening_fundee_reply,,funding_signed_msg,msglen*u8

View File

@@ -2,9 +2,9 @@
#include <bitcoin/preimage.h>
#include <ccan/str/hex/hex.h>
#include <ccan/structeq/structeq.h>
#include <channeld/gen_channel_wire.h>
#include <inttypes.h>
#include <lightningd/chaintopology.h>
#include <lightningd/channel/gen_channel_wire.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>

View File

@@ -8,6 +8,8 @@
#include <ccan/noerr/noerr.h>
#include <ccan/take/take.h>
#include <ccan/tal/str/str.h>
#include <channeld/gen_channel_wire.h>
#include <closingd/gen_closing_wire.h>
#include <common/close_tx.h>
#include <common/dev_disconnect.h>
#include <common/funding_tx.h>
@@ -17,24 +19,22 @@
#include <common/timeout.h>
#include <errno.h>
#include <fcntl.h>
#include <gossipd/gen_gossip_wire.h>
#include <hsmd/gen_hsm_wire.h>
#include <inttypes.h>
#include <lightningd/build_utxos.h>
#include <lightningd/chaintopology.h>
#include <lightningd/channel/gen_channel_wire.h>
#include <lightningd/closing/gen_closing_wire.h>
#include <lightningd/dns.h>
#include <lightningd/gen_peer_state_names.h>
#include <lightningd/gossip/gen_gossip_wire.h>
#include <lightningd/hsm/gen_hsm_wire.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/log.h>
#include <lightningd/new_connection.h>
#include <lightningd/onchain/gen_onchain_wire.h>
#include <lightningd/onchain/onchain_wire.h>
#include <lightningd/opening/gen_opening_wire.h>
#include <lightningd/peer_htlcs.h>
#include <netinet/in.h>
#include <onchaind/gen_onchain_wire.h>
#include <onchaind/onchain_wire.h>
#include <openingd/gen_opening_wire.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
@@ -1224,7 +1224,7 @@ static enum watch_result funding_spent(struct peer *peer,
peer_fail_permanent_str(peer, "Funding transaction spent");
peer->owner = new_subd(peer->ld, peer->ld,
"lightningd_onchain", peer,
"lightning_onchaind", peer,
onchain_wire_type_name,
onchain_msg,
peer_onchain_finished,
@@ -1783,7 +1783,7 @@ static void peer_start_closingd(struct peer *peer,
}
peer->owner = new_subd(peer->ld, peer->ld,
"lightningd_closing", peer,
"lightning_closingd", peer,
closing_wire_type_name,
closing_msg,
peer_owner_finished,
@@ -1970,7 +1970,7 @@ static bool peer_start_channeld(struct peer *peer,
fatal("Could not read fd from HSM: %s", strerror(errno));
peer->owner = new_subd(peer->ld, peer->ld,
"lightningd_channel", peer,
"lightning_channeld", peer,
channel_wire_type_name,
channel_msg,
peer_owner_finished,
@@ -2282,7 +2282,7 @@ static void channel_config(struct lightningd *ld,
*/
ours->max_accepted_htlcs = 483;
/* This is filled in by lightningd_opening, for consistency. */
/* This is filled in by lightning_openingd, for consistency. */
ours->channel_reserve_satoshis = 0;
};
@@ -2309,7 +2309,7 @@ void peer_fundee_open(struct peer *peer, const u8 *from_peer,
}
peer_set_condition(peer, GOSSIPD, OPENINGD);
peer->owner = new_subd(ld, ld, "lightningd_opening", peer,
peer->owner = new_subd(ld, ld, "lightning_openingd", peer,
opening_wire_type_name,
NULL, peer_owner_finished,
take(&peer_fd), take(&gossip_fd),
@@ -2393,7 +2393,7 @@ static bool gossip_peer_released(struct subd *gossip,
peer_set_condition(fc->peer, GOSSIPD, OPENINGD);
opening = new_subd(fc->peer->ld, ld,
"lightningd_opening", fc->peer,
"lightning_openingd", fc->peer,
opening_wire_type_name,
NULL, peer_owner_finished,
take(&fds[0]), take(&fds[1]), NULL);

View File

@@ -3,22 +3,22 @@
#include <ccan/crypto/ripemd160/ripemd160.h>
#include <ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <channeld/gen_channel_wire.h>
#include <common/derive_basepoints.h>
#include <common/htlc_wire.h>
#include <common/overflows.h>
#include <common/sphinx.h>
#include <gossipd/gen_gossip_wire.h>
#include <lightningd/chaintopology.h>
#include <lightningd/channel/gen_channel_wire.h>
#include <lightningd/gossip/gen_gossip_wire.h>
#include <lightningd/htlc_end.h>
#include <lightningd/invoice.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/onchain/onchain_wire.h>
#include <lightningd/pay.h>
#include <lightningd/peer_control.h>
#include <lightningd/peer_htlcs.h>
#include <lightningd/subd.h>
#include <onchaind/onchain_wire.h>
#include <wire/gen_onion_wire.h>
static bool state_update_ok(struct peer *peer,

View File

@@ -16,7 +16,7 @@ struct io_conn;
/* One of our subds. */
struct subd {
/* Name, like John, or "lightningd_hsm" */
/* Name, like John, or "lightning_hsmd" */
const char *name;
/* The Big Cheese. */
struct lightningd *ld;

View File

@@ -6,9 +6,9 @@
#include "../../common/key_derive.c"
#include "../../common/keyset.c"
#include "../../common/initial_channel.c"
#include "../channel/full_channel.c"
#include "../../channeld/full_channel.c"
#include "../../common/initial_commit_tx.c"
#include "../channel/commit_tx.c"
#include "../../channeld/commit_tx.c"
#include "../../common/htlc_tx.c"
#include <bitcoin/preimage.h>
#include <bitcoin/privkey.h>

View File

@@ -6,7 +6,7 @@ static bool print_superverbose;
#define SUPERVERBOSE(...) \
do { if (print_superverbose) printf(__VA_ARGS__); } while(0)
#define PRINT_ACTUAL_FEE
#include "../channel/commit_tx.c"
#include "../../channeld/commit_tx.c"
#include "../../common/initial_commit_tx.c"
#include "../../common/htlc_tx.c"
#include <bitcoin/preimage.h>