Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Fixes for channels + other shit #76

Merged
merged 2 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions frontend/src/routes/KitchenSink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ function App() {
const [amount, setAmount] = useState("")
const [destinationAddress, setDestinationAddress] = useState("")

const [proxyAddress, setProxyAddress] = useState("wss://websocket-tcp-proxy-fywbx.ondigitalocean.app")
const [proxyAddress, setProxyAddress] = useState("ws://127.0.0.1:3001")
const [connectPeer, setConnectPeer] = useState("")
const [disconnectPeer, setDisconnectPeer] = useState("")

function handleAmountChange(e: React.ChangeEvent<HTMLInputElement>) {
setAmount(e.target.value);
Expand All @@ -55,6 +56,10 @@ function App() {
setConnectPeer(e.target.value);
}

function handleDisconnectPeerChange(e: React.ChangeEvent<HTMLInputElement>) {
setDisconnectPeer(e.target.value);
}

function handleProxyAddressChange(e: React.ChangeEvent<HTMLInputElement>) {
setProxyAddress(e.target.value);
}
Expand All @@ -71,6 +76,16 @@ function App() {
if (nodeManager) {
try {
await nodeManager.sync()
await updateBalance()
} catch (e) {
console.error(e);
}
}
}

async function updateBalance() {
if (nodeManager) {
try {
let balance = await nodeManager.get_balance();
let str = `confirmed: ${balance.confirmed?.toLocaleString()} sats, unconfirmed: ${balance.unconfirmed?.toLocaleString()} sats, ln: ${balance.lightning.toLocaleString()} sats`
setBalance(str)
Expand Down Expand Up @@ -138,7 +153,7 @@ function App() {
async function sendKeysend(e: React.SyntheticEvent) {
e.preventDefault()
try {
await nodeManager?.keysend(currentNode, keysend, BigInt(50));
await nodeManager?.keysend(currentNode, keysend, BigInt(5000));
} catch (e) {
console.error(e);
}
Expand All @@ -153,6 +168,14 @@ function App() {
}
}

async function disconnect_peer(e: React.SyntheticEvent) {
e.preventDefault()
try {
await nodeManager?.disconnect_peer(currentNode, disconnectPeer)
} catch (e) {
console.error(e);
}
}

async function new_node() {
if (nodeManager) {
Expand Down Expand Up @@ -185,6 +208,9 @@ function App() {
<p>
{`Wallet Balance: ${balance}`}
</p>
<p>
<button onClick={async () => updateBalance()}>Update Balance</button>
</p>
<p>
<button onClick={async () => sync()}>Sync Wallet</button>
</p>
Expand Down Expand Up @@ -227,6 +253,11 @@ function App() {
<input type="text" placeholder='Peer Connection String' onChange={handleConnectPeerChange}></input>
<input type="submit" value="Connect" />
</form>
<form onSubmit={disconnect_peer} className="flex flex-col items-start gap-4 my-4">
<h2>Disconnect Peer:</h2>
<input type="text" placeholder='Peer' onChange={handleDisconnectPeerChange}></input>
<input type="submit" value="Disconnect" />
</form>
</>
<form onSubmit={openChannel} className="flex flex-col items-start gap-4 my-4">
<h2>Open Channel:</h2>
Expand Down
15 changes: 14 additions & 1 deletion node-manager/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use lightning::chain::chaininterface::{
BroadcasterInterface, ConfirmationTarget, FeeEstimator, FEERATE_FLOOR_SATS_PER_KW,
};
use lightning::chain::{Confirm, Filter, WatchedOutput};
use log::error;
use log::{debug, error, info, warn};
use std::collections::HashSet;
use std::sync::{Arc, Mutex};
use wasm_bindgen_futures::spawn_local;
Expand Down Expand Up @@ -171,6 +171,10 @@ impl MutinyChain {
unconfirmed_registered_txs: HashSet<Txid>,
unspent_registered_outputs: HashSet<WatchedOutput>,
) {
for c in &confirmed_txs {
debug!("confirming tx! {}", c.tx.txid())
}

for ctx in confirmed_txs {
for c in confirmables {
c.transactions_confirmed(
Expand Down Expand Up @@ -202,10 +206,14 @@ impl MutinyChain {
// Remember all registered but unconfirmed transactions for future processing.
let mut unconfirmed_registered_txs = HashSet::new();

info!("registered tx size: {}", registered_txs.len());
for txid in registered_txs {
info!("registered tx: {}", txid);
if let Some(confirmed_tx) = self.get_confirmed_tx(&txid, None, None).await? {
info!("confirmed tx: {}", txid);
confirmed_txs.push(confirmed_tx);
} else {
warn!("unconfirmed tx: {}", txid);
unconfirmed_registered_txs.insert(txid);
}
}
Expand Down Expand Up @@ -311,11 +319,14 @@ impl MutinyChain {
.iter()
.flat_map(|c| c.get_relevant_txids())
.collect::<Vec<Txid>>();
let mut to_watch: HashSet<Txid> = HashSet::new();
for txid in relevant_txids {
debug!("unconfirmed: {}", txid);
match client.get_tx_status(&txid).await {
Ok(Some(status)) => {
// Skip if the tx in question is still confirmed.
if status.confirmed {
to_watch.insert(txid);
continue;
}
}
Expand All @@ -330,6 +341,8 @@ impl MutinyChain {
}
}

*self.watched_transactions.lock().unwrap() = to_watch;

Ok(())
}
}
Expand Down
12 changes: 9 additions & 3 deletions node-manager/src/invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use bitcoin::bech32::ToBase32;
use bitcoin_hashes::Hash;
use core::ops::Deref;
use core::time::Duration;
use instant::SystemTime;
use lightning::chain::keysinterface::{KeysInterface, Recipient, Sign};
use lightning::ln::channelmanager::{ChannelDetails, MIN_FINAL_CLTV_EXPIRY};
use lightning::ln::channelmanager::{PhantomRouteHints, MIN_CLTV_EXPIRY_DELTA};
Expand Down Expand Up @@ -56,6 +57,11 @@ where
));
}

let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();

let invoice = InvoiceBuilder::new(network).description(description);

// If we ever see performance here being too slow then we should probably take this ExpandedKey as a parameter instead.
Expand All @@ -66,7 +72,7 @@ where
amt_msat,
payment_hash,
invoice_expiry_delta_secs,
1000 * instant::now() as u64,
now,
)
.map_err(|_| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
(payment_hash, payment_secret)
Expand All @@ -76,13 +82,13 @@ where
amt_msat,
invoice_expiry_delta_secs,
&keys_manager,
1000 * instant::now() as u64,
now,
)
.map_err(|_| SignOrCreationError::CreationError(CreationError::InvalidAmount))?
};

let mut invoice = invoice
.duration_since_epoch(Duration::from_secs(1000 * instant::now() as u64))
.duration_since_epoch(Duration::from_secs(now))
.payment_hash(Hash::from_slice(&payment_hash.0).unwrap())
.payment_secret(payment_secret)
.min_final_cltv_expiry(MIN_FINAL_CLTV_EXPIRY.into())
Expand Down
11 changes: 8 additions & 3 deletions node-manager/src/keymanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::error::MutinyError;
use bip32::XPrv;
use bip39::Mnemonic;
use bitcoin::secp256k1::{PublicKey, Secp256k1};
use instant::SystemTime;
use lightning::chain::keysinterface::{KeysInterface, PhantomKeysManager, Recipient};

pub(crate) fn generate_seed(num_words: u8) -> Result<Mnemonic, MutinyError> {
Expand Down Expand Up @@ -43,11 +44,15 @@ pub(crate) fn create_keys_manager(mnemonic: Mnemonic, child_index: u32) -> Phant
.unwrap()
.derive_child(bip32::ChildNumber::new(child_index, true).unwrap())
.unwrap();
let current_time = instant::now();

let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();

PhantomKeysManager::new(
&xpriv.to_bytes(),
(current_time / 1000.0).round() as u64,
(current_time * 1000.0).round() as u32,
now.as_secs(),
now.as_nanos() as u32,
&shared_key.to_bytes(),
)
}
Expand Down
6 changes: 3 additions & 3 deletions node-manager/src/ldkstorage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ impl MutinyNodePersister {
mutiny_logger: Arc<MutinyLogger>,
keys_manager: Arc<PhantomKeysManager>,
mut channel_monitors: Vec<(BlockHash, ChannelMonitor<InMemorySigner>)>,
) -> Result<PhantomChannelManager, MutinyError> {
) -> Result<(PhantomChannelManager, bool), MutinyError> {
match self.read_value(CHANNEL_MANAGER_KEY) {
Ok(kv_value) => {
let mut channel_monitor_mut_references = Vec::new();
Expand All @@ -184,7 +184,7 @@ impl MutinyNodePersister {
let Ok((_, channel_manager)) = <(BlockHash, PhantomChannelManager)>::read(&mut readable_kv_value, read_args) else {
return Err(MutinyError::ReadError { source: error::MutinyStorageError::Other(anyhow!("could not read manager")) })
};
Ok(channel_manager)
Ok((channel_manager, true))
}
Err(_) => {
// no key manager stored, start a new one
Expand Down Expand Up @@ -212,7 +212,7 @@ impl MutinyNodePersister {
chain_params,
);

Ok(fresh_channel_manager)
Ok((fresh_channel_manager, false))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion node-manager/src/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl Logger for MutinyLogger {

match record.level {
Level::Gossip => trace!("{}", log),
Level::Trace => trace!("{}", log),
Level::Trace => debug!("{}", log),
Level::Debug => debug!("{}", log),
Level::Info => info!("{}", log),
Level::Warn => warn!("{}", log),
Expand Down
49 changes: 44 additions & 5 deletions node-manager/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bitcoin::hashes::Hash;
use bitcoin::Network;
use futures::StreamExt;
use gloo_net::websocket::Message;
use lightning::chain::{chainmonitor, Filter};
use lightning::chain::{chainmonitor, Filter, Watch};
use lightning::ln::channelmanager::PhantomRouteHints;
use lightning::ln::msgs::NetAddress;
use lightning::ln::PaymentHash;
Expand All @@ -32,6 +32,7 @@ use anyhow::Context;
use bip39::Mnemonic;
use bitcoin::blockdata::constants::genesis_block;
use bitcoin::secp256k1::PublicKey;
use instant::SystemTime;
use lightning::chain::keysinterface::{
InMemorySigner, KeysInterface, PhantomKeysManager, Recipient,
};
Expand Down Expand Up @@ -132,7 +133,7 @@ impl Node {
})?;

// init channel manager
let channel_manager = persister
let (channel_manager, restarting_node) = persister
.read_channel_manager(
network,
chain_monitor.clone(),
Expand Down Expand Up @@ -167,6 +168,41 @@ impl Node {
logger.clone(),
));

// fixme dont read from storage twice lol
// read channelmonitor state from disk again
let mut channel_monitors = persister
.read_channel_monitors(keys_manager.clone())
.map_err(|e| MutinyError::ReadError {
source: MutinyStorageError::Other(e.into()),
})?;

// sync to chain tip
let mut chain_listener_channel_monitors = Vec::new();
if restarting_node {
for (blockhash, channel_monitor) in channel_monitors.drain(..) {
let outpoint = channel_monitor.get_funding_txo().0;
chain_listener_channel_monitors.push((
blockhash,
(
channel_monitor,
chain.clone(),
chain.clone(),
logger.clone(),
),
outpoint,
));
}
}

// give channel monitors to chain monitor
for item in chain_listener_channel_monitors.drain(..) {
let channel_monitor = item.1 .0;
let funding_outpoint = item.2;
chain_monitor
.clone()
.watch_channel(funding_outpoint, channel_monitor);
}

// todo use RGS
// get network graph
let genesis_hash = genesis_block(network).block_hash();
Expand Down Expand Up @@ -273,7 +309,7 @@ impl Node {
route_hints: Vec<PhantomRouteHints>,
) -> Result<Invoice, MutinyError> {
let invoice = match create_phantom_invoice::<InMemorySigner, Arc<PhantomKeysManager>>(
Some(amount_sat * 1000),
Some(amount_sat * 1),
None,
description,
1500,
Expand Down Expand Up @@ -462,15 +498,18 @@ pub(crate) fn create_peer_manager(
lightning_msg_handler: MessageHandler,
logger: Arc<MutinyLogger>,
) -> PeerManager {
let current_time = instant::now();
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
let mut ephemeral_bytes = [0u8; 32];
getrandom::getrandom(&mut ephemeral_bytes).expect("Failed to generate entropy");

PeerManager::new(
lightning_msg_handler,
km.get_node_secret(Recipient::Node)
.expect("Failed to get node secret"),
current_time as u32,
now as u32,
&ephemeral_bytes,
logger,
Arc::new(IgnoringMessageHandler {}),
Expand Down
Loading