mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
lightningd: create new structure channel
to hold per-channel info.
This is not connected yet; during the transition, there will be a 1:1 mapping from channel to peer, so we can use channel2peer and peer2channel to shim between them. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
65c09c895d
commit
6b71654351
95
lightningd/channel.c
Normal file
95
lightningd/channel.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <ccan/crypto/hkdf_sha256/hkdf_sha256.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <gossipd/gen_gossip_wire.h>
|
||||
#include <inttypes.h>
|
||||
#include <lightningd/channel.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/peer_control.h>
|
||||
#include <lightningd/subd.h>
|
||||
|
||||
static void destroy_channel(struct channel *channel)
|
||||
{
|
||||
list_del_from(&channel->peer->channels, &channel->list);
|
||||
}
|
||||
|
||||
/* FIXME: We have no business knowing this! */
|
||||
/**
|
||||
* derive_channel_seed - Generate a unique secret for this peer's channel
|
||||
*
|
||||
* @ld: the lightning daemon to get global secret from
|
||||
* @seed: where to store the generated secret
|
||||
* @peer_id: the id node_id of the remote peer
|
||||
* @dbid: channel DBID
|
||||
*
|
||||
* This method generates a unique secret from the given parameters. It
|
||||
* is important that this secret be unique for each channel, but it
|
||||
* must be reproducible for the same channel in case of
|
||||
* reconnection. We use the DB channel ID to guarantee unique secrets
|
||||
* per channel.
|
||||
*/
|
||||
void derive_channel_seed(struct lightningd *ld, struct privkey *seed,
|
||||
const struct pubkey *peer_id,
|
||||
const u64 dbid)
|
||||
{
|
||||
u8 input[PUBKEY_DER_LEN + sizeof(dbid)];
|
||||
char *info = "per-peer seed";
|
||||
pubkey_to_der(input, peer_id);
|
||||
memcpy(input + PUBKEY_DER_LEN, &dbid, sizeof(dbid));
|
||||
|
||||
assert(dbid != 0);
|
||||
hkdf_sha256(seed, sizeof(*seed),
|
||||
input, sizeof(input),
|
||||
&ld->peer_seed, sizeof(ld->peer_seed),
|
||||
info, strlen(info));
|
||||
}
|
||||
|
||||
struct channel *new_channel(struct peer *peer, u64 dbid, u32 first_blocknum)
|
||||
{
|
||||
/* FIXME: We currently rely on it being all zero/NULL */
|
||||
struct channel *channel = talz(peer->ld, struct channel);
|
||||
|
||||
channel->dbid = dbid;
|
||||
channel->peer = peer;
|
||||
channel->first_blocknum = first_blocknum;
|
||||
channel->state = UNINITIALIZED;
|
||||
channel->local_shutdown_idx = -1;
|
||||
|
||||
/* FIXME: update log prefix when we get scid */
|
||||
channel->log = new_log(channel, peer->log_book, "%s chan #%"PRIu64":",
|
||||
log_prefix(peer->log), dbid);
|
||||
list_add_tail(&peer->channels, &channel->list);
|
||||
tal_add_destructor(channel, destroy_channel);
|
||||
if (channel->dbid != 0)
|
||||
derive_channel_seed(peer->ld, &channel->seed, &peer->id,
|
||||
channel->dbid);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
const char *channel_state_name(const struct channel *channel)
|
||||
{
|
||||
return peer_state_name(channel->state);
|
||||
}
|
||||
|
||||
struct channel *peer_active_channel(struct peer *peer)
|
||||
{
|
||||
struct channel *channel;
|
||||
|
||||
list_for_each(&peer->channels, channel, list) {
|
||||
if (channel_active(channel))
|
||||
return channel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct channel *peer2channel(const struct peer *peer)
|
||||
{
|
||||
return list_top(&peer->channels, struct channel, list);
|
||||
}
|
||||
|
||||
struct peer *channel2peer(const struct channel *channel)
|
||||
{
|
||||
return channel->peer;
|
||||
}
|
193
lightningd/channel.h
Normal file
193
lightningd/channel.h
Normal file
@ -0,0 +1,193 @@
|
||||
#ifndef LIGHTNING_LIGHTNINGD_CHANNEL_H
|
||||
#define LIGHTNING_LIGHTNINGD_CHANNEL_H
|
||||
#include "config.h"
|
||||
#include <ccan/list/list.h>
|
||||
#include <lightningd/peer_state.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
struct channel {
|
||||
/* Inside peer->channels. */
|
||||
struct list_node list;
|
||||
|
||||
/* Peer context */
|
||||
struct peer *peer;
|
||||
|
||||
/* Database ID: 0 == not in db yet */
|
||||
u64 dbid;
|
||||
|
||||
/* Error message (iff in error state) */
|
||||
u8 *error;
|
||||
|
||||
/* Their shachain. */
|
||||
struct wallet_shachain their_shachain;
|
||||
|
||||
/* What's happening. */
|
||||
enum peer_state state;
|
||||
|
||||
/* Which side offered channel? */
|
||||
enum side funder;
|
||||
|
||||
/* Command which ordered us to open channel, if any. */
|
||||
struct command *opening_cmd;
|
||||
|
||||
/* Is there a single subdaemon responsible for us? */
|
||||
struct subd *owner;
|
||||
|
||||
/* History */
|
||||
struct log *log;
|
||||
|
||||
/* Channel flags from opening message. */
|
||||
u8 channel_flags;
|
||||
|
||||
/* Our channel config. */
|
||||
struct channel_config our_config;
|
||||
|
||||
/* Minimum funding depth (specified by us if they fund). */
|
||||
u32 minimum_depth;
|
||||
|
||||
/* Tracking commitment transaction numbers. */
|
||||
u64 next_index[NUM_SIDES];
|
||||
u64 next_htlc_id;
|
||||
|
||||
/* Funding txid and amounts (once known) */
|
||||
struct bitcoin_txid *funding_txid;
|
||||
u16 funding_outnum;
|
||||
u64 funding_satoshi, push_msat;
|
||||
bool remote_funding_locked;
|
||||
/* Channel if locked locally. */
|
||||
struct short_channel_id *scid;
|
||||
|
||||
/* Amount going to us, not counting unfinished HTLCs; if we have one. */
|
||||
u64 *our_msatoshi;
|
||||
|
||||
/* Last tx they gave us (if any). */
|
||||
struct bitcoin_tx *last_tx;
|
||||
secp256k1_ecdsa_signature *last_sig;
|
||||
secp256k1_ecdsa_signature *last_htlc_sigs;
|
||||
|
||||
/* Keys for channel. */
|
||||
struct channel_info *channel_info;
|
||||
|
||||
/* Secret seed (FIXME: Move to hsm!) */
|
||||
struct privkey seed;
|
||||
|
||||
/* Their scriptpubkey if they sent shutdown. */
|
||||
u8 *remote_shutdown_scriptpubkey;
|
||||
/* Our key for shutdown (-1 if not chosen yet) */
|
||||
s64 local_shutdown_idx;
|
||||
|
||||
/* Reestablishment stuff: last sent commit and revocation details. */
|
||||
bool last_was_revoke;
|
||||
struct changed_htlc *last_sent_commit;
|
||||
|
||||
/* Blockheight at creation, scans for funding confirmations
|
||||
* will start here */
|
||||
u64 first_blocknum;
|
||||
};
|
||||
|
||||
struct channel *new_channel(struct peer *peer, u64 dbid, u32 first_blocknum);
|
||||
|
||||
const char *channel_state_name(const struct channel *channel);
|
||||
|
||||
void derive_channel_seed(struct lightningd *ld, struct privkey *seed,
|
||||
const struct pubkey *peer_id,
|
||||
const u64 dbid);
|
||||
|
||||
/* FIXME: Temporary mapping from peer to channel, while we only have one. */
|
||||
struct channel *peer2channel(const struct peer *peer);
|
||||
struct peer *channel2peer(const struct channel *channel);
|
||||
|
||||
/* Find a channel which is not onchain, if any */
|
||||
struct channel *peer_active_channel(struct peer *peer);
|
||||
|
||||
static inline bool channel_can_add_htlc(const struct channel *channel)
|
||||
{
|
||||
return channel->state == CHANNELD_NORMAL;
|
||||
}
|
||||
|
||||
static inline bool channel_fees_can_change(const struct channel *channel)
|
||||
{
|
||||
return channel->state == CHANNELD_NORMAL
|
||||
|| channel->state == CHANNELD_SHUTTING_DOWN;
|
||||
}
|
||||
|
||||
static inline bool channel_can_remove_htlc(const struct channel *channel)
|
||||
{
|
||||
return channel->state == CHANNELD_NORMAL
|
||||
|| channel->state == CHANNELD_SHUTTING_DOWN
|
||||
|| channel->state == ONCHAIND_THEIR_UNILATERAL
|
||||
|| channel->state == ONCHAIND_OUR_UNILATERAL;
|
||||
}
|
||||
|
||||
static inline bool channel_state_on_chain(enum peer_state state)
|
||||
{
|
||||
return state == ONCHAIND_CHEATED
|
||||
|| state == ONCHAIND_THEIR_UNILATERAL
|
||||
|| state == ONCHAIND_OUR_UNILATERAL
|
||||
|| state == ONCHAIND_MUTUAL;
|
||||
}
|
||||
|
||||
static inline bool channel_on_chain(const struct channel *channel)
|
||||
{
|
||||
return channel_state_on_chain(channel->state);
|
||||
}
|
||||
|
||||
static inline bool channel_active(const struct channel *channel)
|
||||
{
|
||||
return channel->state != FUNDING_SPEND_SEEN
|
||||
&& channel->state != CLOSINGD_COMPLETE
|
||||
&& !channel_on_chain(channel);
|
||||
}
|
||||
|
||||
static inline bool channel_wants_reconnect(const struct channel *channel)
|
||||
{
|
||||
return channel->state >= CHANNELD_AWAITING_LOCKIN
|
||||
&& channel->state <= CLOSINGD_COMPLETE;
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
*
|
||||
* On disconnection, the funder MUST remember the channel for
|
||||
* reconnection if it has broadcast the funding transaction, otherwise it
|
||||
* SHOULD NOT.
|
||||
*
|
||||
* On disconnection, the non-funding node MUST remember the channel for
|
||||
* reconnection if it has sent the `funding_signed` message, otherwise
|
||||
* it SHOULD NOT.
|
||||
*/
|
||||
static inline bool channel_persists(const struct channel *channel)
|
||||
{
|
||||
return channel->state >= CHANNELD_AWAITING_LOCKIN;
|
||||
}
|
||||
|
||||
/* FIXME: Obsolete */
|
||||
static inline bool peer_can_add_htlc(const struct peer *peer)
|
||||
{
|
||||
return channel_can_add_htlc(peer2channel(peer));
|
||||
}
|
||||
|
||||
static inline bool peer_fees_can_change(const struct peer *peer)
|
||||
{
|
||||
return channel_fees_can_change(peer2channel(peer));
|
||||
}
|
||||
|
||||
static inline bool peer_can_remove_htlc(const struct peer *peer)
|
||||
{
|
||||
return channel_can_remove_htlc(peer2channel(peer));
|
||||
}
|
||||
|
||||
static inline bool peer_on_chain(const struct peer *peer)
|
||||
{
|
||||
return channel_state_on_chain(peer2channel(peer)->state);
|
||||
}
|
||||
|
||||
static inline bool peer_wants_reconnect(const struct peer *peer)
|
||||
{
|
||||
return channel_wants_reconnect(peer2channel(peer));
|
||||
}
|
||||
|
||||
static inline bool peer_persists(const struct peer *peer)
|
||||
{
|
||||
return channel_persists(peer2channel(peer));
|
||||
}
|
||||
#endif /* LIGHTNING_LIGHTNINGD_CHANNEL_H */
|
Loading…
Reference in New Issue
Block a user