mirror of
https://github.com/stakwork/sphinx-key.git
synced 2025-12-17 15:24:32 +01:00
broker: cache preapproves
largely copied from https://gitlab.com/lightning-signer/validating-lightning-signer/-/merge_requests/564
This commit is contained in:
12
broker/Cargo.lock
generated
12
broker/Cargo.lock
generated
@@ -1687,6 +1687,15 @@ dependencies = [
|
|||||||
"hashbrown 0.14.0",
|
"hashbrown 0.14.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.14.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lss-connector"
|
name = "lss-connector"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -3316,6 +3325,7 @@ dependencies = [
|
|||||||
"fern",
|
"fern",
|
||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
|
"lru 0.12.1",
|
||||||
"lss-connector",
|
"lss-connector",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
@@ -4149,7 +4159,7 @@ dependencies = [
|
|||||||
"hyper",
|
"hyper",
|
||||||
"lightning-storage-server",
|
"lightning-storage-server",
|
||||||
"log",
|
"log",
|
||||||
"lru",
|
"lru 0.11.0",
|
||||||
"nix",
|
"nix",
|
||||||
"prost",
|
"prost",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ confy = "0.4.0"
|
|||||||
fern = { version = "0.6", features = ["colored"] }
|
fern = { version = "0.6", features = ["colored"] }
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
lru = "0.12.1"
|
||||||
once_cell = "1.12.0"
|
once_cell = "1.12.0"
|
||||||
pretty_env_logger = "0.4.0"
|
pretty_env_logger = "0.4.0"
|
||||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||||
|
|||||||
@@ -4,11 +4,24 @@ use crate::conn::{ChannelRequest, LssReq};
|
|||||||
use crate::handle::handle_message;
|
use crate::handle::handle_message;
|
||||||
use crate::secp256k1::PublicKey;
|
use crate::secp256k1::PublicKey;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use lru::LruCache;
|
||||||
use rocket::tokio::sync::mpsc;
|
use rocket::tokio::sync::mpsc;
|
||||||
|
use sphinx_signer::lightning_signer::bitcoin::hashes::{sha256::Hash as Sha256Hash, Hash};
|
||||||
|
use std::num::NonZeroUsize;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::time::SystemTime;
|
||||||
use vls_protocol::{msgs, msgs::Message, Error, Result};
|
use vls_protocol::{msgs, msgs::Message, Error, Result};
|
||||||
use vls_proxy::client::Client;
|
use vls_proxy::client::Client;
|
||||||
|
|
||||||
|
const PREAPPROVE_CACHE_TTL: Duration = Duration::from_secs(60);
|
||||||
|
const PREAPPROVE_CACHE_SIZE: usize = 6;
|
||||||
|
|
||||||
|
struct PreapprovalCacheEntry {
|
||||||
|
tstamp: SystemTime,
|
||||||
|
reply_bytes: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ClientId {
|
pub struct ClientId {
|
||||||
pub peer_id: PublicKey,
|
pub peer_id: PublicKey,
|
||||||
@@ -22,6 +35,7 @@ pub struct SignerLoop<C: 'static + Client> {
|
|||||||
vls_tx: mpsc::Sender<ChannelRequest>,
|
vls_tx: mpsc::Sender<ChannelRequest>,
|
||||||
lss_tx: mpsc::Sender<LssReq>,
|
lss_tx: mpsc::Sender<LssReq>,
|
||||||
client_id: Option<ClientId>,
|
client_id: Option<ClientId>,
|
||||||
|
preapproval_cache: LruCache<Sha256Hash, PreapprovalCacheEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: 'static + Client> SignerLoop<C> {
|
impl<C: 'static + Client> SignerLoop<C> {
|
||||||
@@ -32,12 +46,14 @@ impl<C: 'static + Client> SignerLoop<C> {
|
|||||||
lss_tx: mpsc::Sender<LssReq>,
|
lss_tx: mpsc::Sender<LssReq>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let log_prefix = format!("{}/{}", std::process::id(), client.id());
|
let log_prefix = format!("{}/{}", std::process::id(), client.id());
|
||||||
|
let preapproval_cache = LruCache::new(NonZeroUsize::new(PREAPPROVE_CACHE_SIZE).unwrap());
|
||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
log_prefix,
|
log_prefix,
|
||||||
vls_tx,
|
vls_tx,
|
||||||
lss_tx,
|
lss_tx,
|
||||||
client_id: None,
|
client_id: None,
|
||||||
|
preapproval_cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,12 +65,14 @@ impl<C: 'static + Client> SignerLoop<C> {
|
|||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let log_prefix = format!("{}/{}", std::process::id(), client.id());
|
let log_prefix = format!("{}/{}", std::process::id(), client.id());
|
||||||
|
let preapproval_cache = LruCache::new(NonZeroUsize::new(PREAPPROVE_CACHE_SIZE).unwrap());
|
||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
log_prefix,
|
log_prefix,
|
||||||
vls_tx,
|
vls_tx,
|
||||||
lss_tx,
|
lss_tx,
|
||||||
client_id: Some(client_id),
|
client_id: Some(client_id),
|
||||||
|
preapproval_cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +116,7 @@ impl<C: 'static + Client> SignerLoop<C> {
|
|||||||
self.client.write(reply)?;
|
self.client.write(reply)?;
|
||||||
}
|
}
|
||||||
msg => {
|
msg => {
|
||||||
if let Message::HsmdInit(m) = msg {
|
if let Message::HsmdInit(ref m) = msg {
|
||||||
if let Some(net) = network {
|
if let Some(net) = network {
|
||||||
if ChainHash::using_genesis_block(net).as_bytes()
|
if ChainHash::using_genesis_block(net).as_bytes()
|
||||||
!= m.chain_params.as_ref()
|
!= m.chain_params.as_ref()
|
||||||
@@ -109,10 +127,65 @@ impl<C: 'static + Client> SignerLoop<C> {
|
|||||||
log::error!("No Network provided");
|
log::error!("No Network provided");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let reply =
|
// check if we got the same preapprove message less than PREAPPROVE_CACHE_TTL seconds ago
|
||||||
handle_message(&self.client_id, raw_msg, &self.vls_tx, &self.lss_tx);
|
if let Message::PreapproveInvoice(_) | Message::PreapproveKeysend(_) = msg {
|
||||||
// Write the reply to CLN
|
let now = SystemTime::now();
|
||||||
|
let req_hash = Sha256Hash::hash(&raw_msg);
|
||||||
|
if let Some(entry) = self.preapproval_cache.get(&req_hash) {
|
||||||
|
let age = now.duration_since(entry.tstamp).expect("age");
|
||||||
|
if age < PREAPPROVE_CACHE_TTL {
|
||||||
|
debug!("{} found in preapproval cache", self.log_prefix);
|
||||||
|
let reply = entry.reply_bytes.clone();
|
||||||
self.client.write_vec(reply)?;
|
self.client.write_vec(reply)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let reply_bytes = handle_message(
|
||||||
|
&self.client_id,
|
||||||
|
raw_msg.clone(),
|
||||||
|
&self.vls_tx,
|
||||||
|
&self.lss_tx,
|
||||||
|
);
|
||||||
|
|
||||||
|
// post signer response processing
|
||||||
|
let reply = msgs::from_vec(reply_bytes.clone()).expect("parse reply failed");
|
||||||
|
match reply {
|
||||||
|
// did we just preapprove a keysend ? if so add it to the cache
|
||||||
|
Message::PreapproveKeysendReply(pkr) => {
|
||||||
|
if pkr.result {
|
||||||
|
debug!("{} adding keysend to preapproval cache", self.log_prefix);
|
||||||
|
let now = SystemTime::now();
|
||||||
|
let req_hash = Sha256Hash::hash(&raw_msg);
|
||||||
|
self.preapproval_cache.put(
|
||||||
|
req_hash,
|
||||||
|
PreapprovalCacheEntry {
|
||||||
|
tstamp: now,
|
||||||
|
reply_bytes: reply_bytes.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// did we just preapprove an invoice ? if so add it to the cache
|
||||||
|
Message::PreapproveInvoiceReply(pir) => {
|
||||||
|
if pir.result {
|
||||||
|
debug!("{} adding invoice to preapproval cache", self.log_prefix);
|
||||||
|
let now = SystemTime::now();
|
||||||
|
let req_hash = Sha256Hash::hash(&raw_msg);
|
||||||
|
self.preapproval_cache.put(
|
||||||
|
req_hash,
|
||||||
|
PreapprovalCacheEntry {
|
||||||
|
tstamp: now,
|
||||||
|
reply_bytes: reply_bytes.clone(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {} // for future messages needing post signer response processing
|
||||||
|
}
|
||||||
|
// write the reply to CLN
|
||||||
|
self.client.write_vec(reply_bytes)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user