mirror of
https://github.com/stakwork/sphinx-key.git
synced 2025-12-16 23:14:18 +01:00
org persister, fsdb 0.1.9
This commit is contained in:
@@ -31,6 +31,7 @@ Password: password of the wifi from the previous step
|
||||
- In window B, launch `aliced`. This launches alice, a generic regtest CLN node.
|
||||
- In window C, run `alice-cli newaddr`.
|
||||
- In the same window, run `touchwallet && genbtc {address of previous step} && blkdump`
|
||||
- export BITCOIND_RPC_URL=http://localhost
|
||||
- In window D, launch `bobd`. This launches bob, our MQTT remote signer node.
|
||||
- On the ESP32, the LED should blink white when the signer is ready to sign for the node.
|
||||
- Once its pubkey is logged, copy it.
|
||||
|
||||
@@ -10,4 +10,4 @@ lightning-signer-core = { git = "https://gitlab.com/Evanfeenstra/validating-ligh
|
||||
lightning-signer-server = { git = "https://gitlab.com/Evanfeenstra/validating-lightning-signer", branch = "patch-sign-chan", default-features = false, features = ["persist"] }
|
||||
serde = { version = "1.0.105" }
|
||||
hex = "0.4.3"
|
||||
fsdb = "0.1.8"
|
||||
fsdb = "0.1.9"
|
||||
@@ -1 +1,182 @@
|
||||
pub mod persist_fs;
|
||||
use fsdb::{Bucket, DoubleBucket, Fsdb};
|
||||
use lightning_signer::bitcoin::secp256k1::PublicKey;
|
||||
use lightning_signer::chain::tracker::ChainTracker;
|
||||
use lightning_signer::channel::{Channel, ChannelId, ChannelStub};
|
||||
use lightning_signer::monitor::ChainMonitor;
|
||||
use lightning_signer::node::NodeConfig;
|
||||
use lightning_signer::persist::Persist;
|
||||
use lightning_signer::policy::validator::EnforcementState;
|
||||
use lightning_signer_server::persist::model::{
|
||||
AllowlistItemEntry, ChainTrackerEntry, ChannelEntry, NodeEntry,
|
||||
};
|
||||
use std::string::String;
|
||||
|
||||
use lightning_signer::persist::model::{
|
||||
ChannelEntry as CoreChannelEntry, NodeEntry as CoreNodeEntry,
|
||||
};
|
||||
|
||||
const FAT32_MAXFILENAMESIZE: usize = 8;
|
||||
|
||||
pub struct FsPersister {
|
||||
nodes: Bucket<NodeEntry>,
|
||||
channels: DoubleBucket<ChannelEntry>,
|
||||
allowlist: Bucket<AllowlistItemEntry>,
|
||||
chaintracker: Bucket<ChainTrackerEntry>,
|
||||
pubkeys: Bucket<PublicKey>,
|
||||
}
|
||||
|
||||
impl FsPersister {
|
||||
pub fn new(dir: &str) -> Self {
|
||||
let db = Fsdb::new(dir).expect("could not create db");
|
||||
let max = Some(FAT32_MAXFILENAMESIZE);
|
||||
Self {
|
||||
nodes: db.bucket("nodes", max).expect("fail nodes"),
|
||||
channels: db.double_bucket("channel", max).expect("fail channel"),
|
||||
allowlist: db.bucket("allowlis", max).expect("fail allowlis"),
|
||||
chaintracker: db.bucket("chaintra", max).expect("fail chaintra"),
|
||||
pubkeys: db.bucket("pubkey", max).expect("fail pubkey"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_channel_key(channel_id: &[u8]) -> &[u8] {
|
||||
let length = channel_id.len();
|
||||
channel_id.get(length - 11..length - 7).unwrap()
|
||||
}
|
||||
|
||||
impl Persist for FsPersister {
|
||||
fn new_node(&self, node_id: &PublicKey, config: &NodeConfig, seed: &[u8]) {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let entry = NodeEntry {
|
||||
seed: seed.to_vec(),
|
||||
key_derivation_style: config.key_derivation_style as u8,
|
||||
network: config.network.to_string(),
|
||||
};
|
||||
let _ = self.nodes.put(&pk, entry);
|
||||
let _ = self.pubkeys.put(&pk, node_id.clone());
|
||||
}
|
||||
fn delete_node(&self, node_id: &PublicKey) {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
// clear all channel entries within "pk" sub-bucket
|
||||
let _ = self.channels.clear(&pk);
|
||||
let _ = self.nodes.remove(&pk);
|
||||
let _ = self.pubkeys.remove(&pk);
|
||||
}
|
||||
fn new_channel(&self, node_id: &PublicKey, stub: &ChannelStub) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let chan_id = hex::encode(get_channel_key(stub.id0.as_slice()));
|
||||
// should not exist
|
||||
if let Ok(_) = self.channels.get(&pk, &chan_id) {
|
||||
return Err(()); // already exists
|
||||
}
|
||||
let entry = ChannelEntry {
|
||||
id: Some(stub.id0.clone()),
|
||||
channel_value_satoshis: 0,
|
||||
channel_setup: None,
|
||||
enforcement_state: EnforcementState::new(0),
|
||||
};
|
||||
let _ = self.channels.put(&pk, &chan_id, entry);
|
||||
Ok(())
|
||||
}
|
||||
fn new_chain_tracker(&self, node_id: &PublicKey, tracker: &ChainTracker<ChainMonitor>) {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let _ = self.chaintracker.put(&pk, tracker.into());
|
||||
}
|
||||
fn update_tracker(
|
||||
&self,
|
||||
node_id: &PublicKey,
|
||||
tracker: &ChainTracker<ChainMonitor>,
|
||||
) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let _ = self.chaintracker.put(&pk, tracker.into());
|
||||
Ok(())
|
||||
}
|
||||
fn get_tracker(&self, node_id: &PublicKey) -> Result<ChainTracker<ChainMonitor>, ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let ret: ChainTrackerEntry = match self.chaintracker.get(&pk) {
|
||||
Ok(ct) => ct,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
Ok(ret.into())
|
||||
}
|
||||
fn update_channel(&self, node_id: &PublicKey, channel: &Channel) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let chan_id = hex::encode(get_channel_key(channel.id0.as_slice()));
|
||||
// should exist
|
||||
if let Err(_) = self.channels.get(&pk, &chan_id) {
|
||||
return Err(()); // not found
|
||||
}
|
||||
let entry = ChannelEntry {
|
||||
id: Some(channel.id0.clone()),
|
||||
channel_value_satoshis: channel.setup.channel_value_sat,
|
||||
channel_setup: Some(channel.setup.clone()),
|
||||
enforcement_state: channel.enforcement_state.clone(),
|
||||
};
|
||||
let _ = self.channels.put(&pk, &chan_id, entry);
|
||||
Ok(())
|
||||
}
|
||||
fn get_channel(
|
||||
&self,
|
||||
node_id: &PublicKey,
|
||||
channel_id: &ChannelId,
|
||||
) -> Result<CoreChannelEntry, ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let chan_id = hex::encode(get_channel_key(channel_id.as_slice()));
|
||||
let ret: ChannelEntry = match self.channels.get(&pk, &chan_id) {
|
||||
Ok(ce) => ce,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
Ok(ret.into())
|
||||
}
|
||||
fn get_node_channels(&self, node_id: &PublicKey) -> Vec<(ChannelId, CoreChannelEntry)> {
|
||||
let mut res = Vec::new();
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let list = match self.channels.list(&pk) {
|
||||
Ok(l) => l,
|
||||
Err(_) => return res,
|
||||
};
|
||||
for channel in list {
|
||||
if let Ok(entry) = self.channels.get(&pk, &channel) {
|
||||
let id = entry.id.clone().unwrap();
|
||||
res.push((id, entry.into()));
|
||||
};
|
||||
}
|
||||
res
|
||||
}
|
||||
fn update_node_allowlist(&self, node_id: &PublicKey, allowlist: Vec<String>) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let entry = AllowlistItemEntry { allowlist };
|
||||
let _ = self.allowlist.put(&pk, entry);
|
||||
Ok(())
|
||||
}
|
||||
fn get_node_allowlist(&self, node_id: &PublicKey) -> Vec<String> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let entry: AllowlistItemEntry = match self.allowlist.get(&pk) {
|
||||
Ok(e) => e,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
entry.allowlist
|
||||
}
|
||||
fn get_nodes(&self) -> Vec<(PublicKey, CoreNodeEntry)> {
|
||||
let mut res = Vec::new();
|
||||
let list = match self.nodes.list() {
|
||||
Ok(ns) => ns,
|
||||
Err(_) => return res,
|
||||
};
|
||||
for pk in list {
|
||||
if let Ok(pubkey) = self.pubkeys.get(&pk) {
|
||||
if let Ok(node) = self.nodes.get(&pk) {
|
||||
res.push((pubkey, node.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
fn clear_database(&self) {
|
||||
let _ = self.nodes.clear();
|
||||
let _ = self.channels.clear_all();
|
||||
let _ = self.allowlist.clear();
|
||||
let _ = self.chaintracker.clear();
|
||||
let _ = self.pubkeys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
use fsdb::{Bucket, DoubleBucket, Fsdb};
|
||||
use lightning_signer::bitcoin::secp256k1::PublicKey;
|
||||
use lightning_signer::chain::tracker::ChainTracker;
|
||||
use lightning_signer::channel::{Channel, ChannelId, ChannelStub};
|
||||
use lightning_signer::monitor::ChainMonitor;
|
||||
use lightning_signer::node::NodeConfig;
|
||||
use lightning_signer::persist::Persist;
|
||||
use lightning_signer::policy::validator::EnforcementState;
|
||||
use lightning_signer_server::persist::model::{
|
||||
AllowlistItemEntry, ChainTrackerEntry, ChannelEntry, NodeEntry,
|
||||
};
|
||||
use std::string::String;
|
||||
|
||||
use lightning_signer::persist::model::{
|
||||
ChannelEntry as CoreChannelEntry, NodeEntry as CoreNodeEntry,
|
||||
};
|
||||
|
||||
const FAT32_MAXFILENAMESIZE: usize = 8;
|
||||
|
||||
pub struct FsPersister {
|
||||
nodes: Bucket<NodeEntry>,
|
||||
channels: DoubleBucket<ChannelEntry>,
|
||||
allowlist: Bucket<AllowlistItemEntry>,
|
||||
chaintracker: Bucket<ChainTrackerEntry>,
|
||||
pubkeys: Bucket<PublicKey>,
|
||||
}
|
||||
|
||||
impl FsPersister {
|
||||
pub fn new(dir: &str) -> Self {
|
||||
let db = Fsdb::new(dir).expect("could not create db");
|
||||
let max = Some(FAT32_MAXFILENAMESIZE);
|
||||
Self {
|
||||
nodes: db.bucket("nodes", max).expect("fail nodes"),
|
||||
channels: db.double_bucket("channel", max).expect("fail channel"),
|
||||
allowlist: db.bucket("allowlis", max).expect("fail allowlis"),
|
||||
chaintracker: db.bucket("chaintra", max).expect("fail chaintra"),
|
||||
pubkeys: db.bucket("pubkey", max).expect("fail pubkey"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_channel_key(channel_id: &[u8]) -> &[u8] {
|
||||
let length = channel_id.len();
|
||||
channel_id.get(length - 11..length - 7).unwrap()
|
||||
}
|
||||
|
||||
impl Persist for FsPersister {
|
||||
fn new_node(&self, node_id: &PublicKey, config: &NodeConfig, seed: &[u8]) {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let entry = NodeEntry {
|
||||
seed: seed.to_vec(),
|
||||
key_derivation_style: config.key_derivation_style as u8,
|
||||
network: config.network.to_string(),
|
||||
};
|
||||
let _ = self.nodes.put(&pk, entry);
|
||||
let _ = self.pubkeys.put(&pk, node_id.clone());
|
||||
}
|
||||
fn delete_node(&self, node_id: &PublicKey) {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
// clear all channel entries within "pk" sub-bucket
|
||||
let _ = self.channels.clear(&pk);
|
||||
let _ = self.nodes.remove(&pk);
|
||||
let _ = self.pubkeys.remove(&pk);
|
||||
}
|
||||
fn new_channel(&self, node_id: &PublicKey, stub: &ChannelStub) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let chan_id = hex::encode(get_channel_key(stub.id0.as_slice()));
|
||||
// should not exist
|
||||
if let Ok(_) = self.channels.get(&pk, &chan_id) {
|
||||
return Err(()); // already exists
|
||||
}
|
||||
let entry = ChannelEntry {
|
||||
id: Some(stub.id0.clone()),
|
||||
channel_value_satoshis: 0,
|
||||
channel_setup: None,
|
||||
enforcement_state: EnforcementState::new(0),
|
||||
};
|
||||
let _ = self.channels.put(&pk, &chan_id, entry);
|
||||
Ok(())
|
||||
}
|
||||
fn new_chain_tracker(&self, node_id: &PublicKey, tracker: &ChainTracker<ChainMonitor>) {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let _ = self.chaintracker.put(&pk, tracker.into());
|
||||
}
|
||||
fn update_tracker(
|
||||
&self,
|
||||
node_id: &PublicKey,
|
||||
tracker: &ChainTracker<ChainMonitor>,
|
||||
) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let _ = self.chaintracker.put(&pk, tracker.into());
|
||||
Ok(())
|
||||
}
|
||||
fn get_tracker(&self, node_id: &PublicKey) -> Result<ChainTracker<ChainMonitor>, ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let ret: ChainTrackerEntry = match self.chaintracker.get(&pk) {
|
||||
Ok(ct) => ct,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
Ok(ret.into())
|
||||
}
|
||||
fn update_channel(&self, node_id: &PublicKey, channel: &Channel) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let chan_id = hex::encode(get_channel_key(channel.id0.as_slice()));
|
||||
// should exist
|
||||
if let Err(_) = self.channels.get(&pk, &chan_id) {
|
||||
return Err(()); // not found
|
||||
}
|
||||
let entry = ChannelEntry {
|
||||
id: Some(channel.id0.clone()),
|
||||
channel_value_satoshis: channel.setup.channel_value_sat,
|
||||
channel_setup: Some(channel.setup.clone()),
|
||||
enforcement_state: channel.enforcement_state.clone(),
|
||||
};
|
||||
let _ = self.channels.put(&pk, &chan_id, entry);
|
||||
Ok(())
|
||||
}
|
||||
fn get_channel(
|
||||
&self,
|
||||
node_id: &PublicKey,
|
||||
channel_id: &ChannelId,
|
||||
) -> Result<CoreChannelEntry, ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let chan_id = hex::encode(get_channel_key(channel_id.as_slice()));
|
||||
let ret: ChannelEntry = match self.channels.get(&pk, &chan_id) {
|
||||
Ok(ce) => ce,
|
||||
Err(_) => return Err(()),
|
||||
};
|
||||
Ok(ret.into())
|
||||
}
|
||||
fn get_node_channels(&self, node_id: &PublicKey) -> Vec<(ChannelId, CoreChannelEntry)> {
|
||||
let mut res = Vec::new();
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let list = match self.channels.list(&pk) {
|
||||
Ok(l) => l,
|
||||
Err(_) => return res,
|
||||
};
|
||||
for channel in list {
|
||||
if let Ok(entry) = self.channels.get(&pk, &channel) {
|
||||
let id = entry.id.clone().unwrap();
|
||||
res.push((id, entry.into()));
|
||||
};
|
||||
}
|
||||
res
|
||||
}
|
||||
fn update_node_allowlist(&self, node_id: &PublicKey, allowlist: Vec<String>) -> Result<(), ()> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let entry = AllowlistItemEntry { allowlist };
|
||||
let _ = self.allowlist.put(&pk, entry);
|
||||
Ok(())
|
||||
}
|
||||
fn get_node_allowlist(&self, node_id: &PublicKey) -> Vec<String> {
|
||||
let pk = hex::encode(node_id.serialize());
|
||||
let entry: AllowlistItemEntry = match self.allowlist.get(&pk) {
|
||||
Ok(e) => e,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
entry.allowlist
|
||||
}
|
||||
fn get_nodes(&self) -> Vec<(PublicKey, CoreNodeEntry)> {
|
||||
let mut res = Vec::new();
|
||||
let list = match self.nodes.list() {
|
||||
Ok(ns) => ns,
|
||||
Err(_) => return res,
|
||||
};
|
||||
for pk in list {
|
||||
if let Ok(pubkey) = self.pubkeys.get(&pk) {
|
||||
if let Ok(node) = self.nodes.get(&pk) {
|
||||
res.push((pubkey, node.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
fn clear_database(&self) {
|
||||
let _ = self.nodes.clear();
|
||||
let _ = self.channels.clear_all();
|
||||
let _ = self.allowlist.clear();
|
||||
let _ = self.chaintracker.clear();
|
||||
let _ = self.pubkeys.clear();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ pub use vls_protocol_signer::lightning_signer;
|
||||
pub use vls_protocol_signer::lightning_signer::bitcoin::Network;
|
||||
pub use vls_protocol_signer::vls_protocol;
|
||||
pub use sphinx_key_parser::MsgDriver;
|
||||
pub use sphinx_key_persister::persist_fs::FsPersister;
|
||||
pub use sphinx_key_persister::FsPersister;
|
||||
|
||||
pub struct InitResponse {
|
||||
pub root_handler: RootHandler,
|
||||
|
||||
Reference in New Issue
Block a user