mirror of
https://github.com/stakwork/sphinx-key.git
synced 2025-12-19 00:04:25 +01:00
policy stored in flash, more FlashPersister impls, handle_control_response util, ControlResponse::Error, simple policy
This commit is contained in:
@@ -4,6 +4,33 @@ use sphinx_auther::nonce;
|
|||||||
use sphinx_auther::secp256k1::{PublicKey, SecretKey};
|
use sphinx_auther::secp256k1::{PublicKey, SecretKey};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub enum ControlMessage {
|
||||||
|
Nonce,
|
||||||
|
ResetWifi,
|
||||||
|
ResetKeys,
|
||||||
|
ResetAll,
|
||||||
|
QueryPolicy,
|
||||||
|
UpdatePolicy(Policy),
|
||||||
|
QueryAllowlist,
|
||||||
|
UpdateAllowlist(Vec<String>),
|
||||||
|
Ota(OtaParams),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub enum ControlResponse {
|
||||||
|
Nonce(u64),
|
||||||
|
ResetWifi,
|
||||||
|
ResetKeys,
|
||||||
|
ResetAll,
|
||||||
|
PolicyCurrent(Policy),
|
||||||
|
PolicyUpdated(Policy),
|
||||||
|
AllowlistCurrent(Vec<String>),
|
||||||
|
AllowlistUpdated(Vec<String>),
|
||||||
|
OtaConfirm(OtaParams),
|
||||||
|
Error(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
|
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub broker: String,
|
pub broker: String,
|
||||||
@@ -13,27 +40,27 @@ pub struct Config {
|
|||||||
// pub seed: [u8; 32],
|
// pub seed: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub enum ControlMessage {
|
|
||||||
Nonce,
|
|
||||||
ResetWifi,
|
|
||||||
QueryPolicy,
|
|
||||||
UpdatePolicy(Policy),
|
|
||||||
Ota(OtaParams),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
||||||
pub enum ControlResponse {
|
|
||||||
Nonce(u64),
|
|
||||||
ResetWifi,
|
|
||||||
PolicyCurrent(Policy),
|
|
||||||
PolicyUpdated(Policy),
|
|
||||||
OtaConfirm(OtaParams),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Policy {
|
pub struct Policy {
|
||||||
pub sats_per_day: u64,
|
pub sat_limit: u64,
|
||||||
|
pub interval: Interval,
|
||||||
|
pub htlc_limit: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Policy {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
sat_limit: 1_000_000,
|
||||||
|
interval: Interval::Daily,
|
||||||
|
htlc_limit: 1_000_000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
|
||||||
|
pub enum Interval {
|
||||||
|
Hourly,
|
||||||
|
Daily,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
@@ -103,11 +130,40 @@ impl Controller {
|
|||||||
let res = match msg.clone() {
|
let res = match msg.clone() {
|
||||||
ControlMessage::Nonce => ControlResponse::Nonce(self.2),
|
ControlMessage::Nonce => ControlResponse::Nonce(self.2),
|
||||||
ControlMessage::ResetWifi => {
|
ControlMessage::ResetWifi => {
|
||||||
store.reset();
|
store.remove_config()?;
|
||||||
ControlResponse::ResetWifi
|
ControlResponse::ResetWifi
|
||||||
}
|
}
|
||||||
ControlMessage::UpdatePolicy(np) => ControlResponse::PolicyUpdated(np),
|
ControlMessage::ResetKeys => {
|
||||||
_ => ControlResponse::Nonce(self.2),
|
store.remove_seed()?;
|
||||||
|
ControlResponse::ResetKeys
|
||||||
|
}
|
||||||
|
ControlMessage::ResetAll => {
|
||||||
|
store.remove_config()?;
|
||||||
|
store.remove_seed()?;
|
||||||
|
store.remove_policy()?;
|
||||||
|
store.set_nonce(0)?;
|
||||||
|
ControlResponse::ResetAll
|
||||||
|
}
|
||||||
|
ControlMessage::QueryPolicy => {
|
||||||
|
let p = store.read_policy().unwrap_or_default();
|
||||||
|
ControlResponse::PolicyCurrent(p)
|
||||||
|
}
|
||||||
|
ControlMessage::UpdatePolicy(np) => {
|
||||||
|
store.write_policy(np.clone())?;
|
||||||
|
ControlResponse::PolicyUpdated(np)
|
||||||
|
}
|
||||||
|
ControlMessage::QueryAllowlist => {
|
||||||
|
// this response is overwritten in the event handler
|
||||||
|
ControlResponse::AllowlistCurrent(vec![])
|
||||||
|
}
|
||||||
|
ControlMessage::UpdateAllowlist(na) => {
|
||||||
|
// the actual writing happens in the event handler
|
||||||
|
ControlResponse::AllowlistUpdated(na)
|
||||||
|
}
|
||||||
|
ControlMessage::Ota(params) => {
|
||||||
|
// ...
|
||||||
|
ControlResponse::OtaConfirm(params)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let response = self.build_response(res)?;
|
let response = self.build_response(res)?;
|
||||||
Ok((response, msg))
|
Ok((response, msg))
|
||||||
@@ -119,6 +175,7 @@ pub enum FlashKey {
|
|||||||
Config,
|
Config,
|
||||||
Seed,
|
Seed,
|
||||||
Nonce,
|
Nonce,
|
||||||
|
Policy,
|
||||||
}
|
}
|
||||||
impl FlashKey {
|
impl FlashKey {
|
||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
@@ -126,24 +183,28 @@ impl FlashKey {
|
|||||||
FlashKey::Config => "config",
|
FlashKey::Config => "config",
|
||||||
FlashKey::Seed => "seed",
|
FlashKey::Seed => "seed",
|
||||||
FlashKey::Nonce => "nonce",
|
FlashKey::Nonce => "nonce",
|
||||||
|
FlashKey::Policy => "policy",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ControlPersist: Sync + Send {
|
pub trait ControlPersist: Sync + Send {
|
||||||
fn reset(&mut self);
|
|
||||||
fn read_nonce(&self) -> Result<u64>;
|
fn read_nonce(&self) -> Result<u64>;
|
||||||
fn set_nonce(&mut self, nonce: u64) -> Result<()>;
|
fn set_nonce(&mut self, nonce: u64) -> Result<()>;
|
||||||
fn read_config(&self) -> Result<Config>;
|
fn read_config(&self) -> Result<Config>;
|
||||||
fn write_config(&mut self, c: Config) -> Result<()>;
|
fn write_config(&mut self, c: Config) -> Result<()>;
|
||||||
|
fn remove_config(&mut self) -> Result<()>;
|
||||||
fn read_seed(&self) -> Result<[u8; 32]>;
|
fn read_seed(&self) -> Result<[u8; 32]>;
|
||||||
fn write_seed(&mut self, s: [u8; 32]) -> Result<()>;
|
fn write_seed(&mut self, s: [u8; 32]) -> Result<()>;
|
||||||
|
fn remove_seed(&mut self) -> Result<()>;
|
||||||
|
fn read_policy(&self) -> Result<Policy>;
|
||||||
|
fn write_policy(&mut self, s: Policy) -> Result<()>;
|
||||||
|
fn remove_policy(&mut self) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DummyPersister;
|
pub struct DummyPersister;
|
||||||
|
|
||||||
impl ControlPersist for DummyPersister {
|
impl ControlPersist for DummyPersister {
|
||||||
fn reset(&mut self) {}
|
|
||||||
fn read_nonce(&self) -> Result<u64> {
|
fn read_nonce(&self) -> Result<u64> {
|
||||||
Ok(0u64)
|
Ok(0u64)
|
||||||
}
|
}
|
||||||
@@ -156,10 +217,25 @@ impl ControlPersist for DummyPersister {
|
|||||||
fn write_config(&mut self, _conf: Config) -> Result<()> {
|
fn write_config(&mut self, _conf: Config) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn remove_config(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
fn read_seed(&self) -> Result<[u8; 32]> {
|
fn read_seed(&self) -> Result<[u8; 32]> {
|
||||||
Ok([0; 32])
|
Ok([0; 32])
|
||||||
}
|
}
|
||||||
fn write_seed(&mut self, _s: [u8; 32]) -> Result<()> {
|
fn write_seed(&mut self, _s: [u8; 32]) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn remove_seed(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn read_policy(&self) -> Result<Policy> {
|
||||||
|
Ok(Default::default())
|
||||||
|
}
|
||||||
|
fn write_policy(&mut self, _s: Policy) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn remove_policy(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
mod derive;
|
mod derive;
|
||||||
|
mod policy;
|
||||||
mod randomstartingtime;
|
mod randomstartingtime;
|
||||||
|
|
||||||
use lightning_signer::bitcoin::blockdata::constants::ChainHash;
|
use lightning_signer::bitcoin::blockdata::constants::ChainHash;
|
||||||
use lightning_signer::node::NodeServices;
|
use lightning_signer::node::NodeServices;
|
||||||
use lightning_signer::persist::Persist;
|
use lightning_signer::persist::Persist;
|
||||||
use lightning_signer::policy::filter::PolicyFilter;
|
use lightning_signer::policy::simple_validator::SimpleValidatorFactory;
|
||||||
use lightning_signer::policy::simple_validator::{make_simple_policy, SimpleValidatorFactory};
|
|
||||||
use lightning_signer::util::clock::StandardClock;
|
use lightning_signer::util::clock::StandardClock;
|
||||||
use lightning_signer::util::velocity::{VelocityControlIntervalType, VelocityControlSpec};
|
|
||||||
use randomstartingtime::RandomStartingTimeFactory;
|
use randomstartingtime::RandomStartingTimeFactory;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vls_protocol::model::{PubKey, Secret};
|
use vls_protocol::model::{PubKey, Secret};
|
||||||
use vls_protocol::msgs::{self, read_serial_request_header, write_serial_response_header, Message};
|
use vls_protocol::msgs::{self, read_serial_request_header, write_serial_response_header, Message};
|
||||||
use vls_protocol::serde_bolt::WireString;
|
use vls_protocol::serde_bolt::WireString;
|
||||||
use vls_protocol_signer::handler::{Handler, RootHandler};
|
pub use vls_protocol_signer::handler::{Handler, RootHandler};
|
||||||
pub use vls_protocol_signer::lightning_signer;
|
pub use vls_protocol_signer::lightning_signer;
|
||||||
use vls_protocol_signer::lightning_signer::bitcoin::Network;
|
use vls_protocol_signer::lightning_signer::bitcoin::Network;
|
||||||
use vls_protocol_signer::lightning_signer::wallet::Wallet;
|
use vls_protocol_signer::lightning_signer::wallet::Wallet;
|
||||||
pub use vls_protocol_signer::vls_protocol;
|
pub use vls_protocol_signer::vls_protocol;
|
||||||
|
|
||||||
pub use derive::node_keys as derive_node_keys;
|
pub use derive::node_keys as derive_node_keys;
|
||||||
|
pub use policy::{get_allowlist, make_policy, set_allowlist, set_policy};
|
||||||
pub use sphinx_key_parser::{control, topics, MsgDriver};
|
pub use sphinx_key_parser::{control, topics, MsgDriver};
|
||||||
pub use sphinx_key_persister::FsPersister;
|
pub use sphinx_key_persister::FsPersister;
|
||||||
pub struct InitResponse {
|
pub struct InitResponse {
|
||||||
@@ -29,24 +29,11 @@ pub struct InitResponse {
|
|||||||
|
|
||||||
pub const ROOT_STORE: &str = "/sdcard/store";
|
pub const ROOT_STORE: &str = "/sdcard/store";
|
||||||
|
|
||||||
pub fn set_policies(
|
pub fn init(
|
||||||
root_handler: &RootHandler,
|
bytes: Vec<u8>,
|
||||||
network: Network,
|
network: Network,
|
||||||
sats_per_day: u64,
|
po: &control::Policy,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<InitResponse> {
|
||||||
let mut policy = make_simple_policy(network);
|
|
||||||
policy.filter = PolicyFilter::new_permissive();
|
|
||||||
let velocity_spec = VelocityControlSpec {
|
|
||||||
limit: sats_per_day,
|
|
||||||
interval_type: VelocityControlIntervalType::Daily,
|
|
||||||
};
|
|
||||||
policy.global_velocity_control = velocity_spec;
|
|
||||||
let validator_factory = Arc::new(SimpleValidatorFactory::new_with_policy(policy));
|
|
||||||
root_handler.node.set_validator_factory(validator_factory);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(bytes: Vec<u8>, network: Network) -> anyhow::Result<InitResponse> {
|
|
||||||
// let persister: Arc<dyn Persist> = Arc::new(DummyPersister);
|
// let persister: Arc<dyn Persist> = Arc::new(DummyPersister);
|
||||||
let mut md = MsgDriver::new(bytes);
|
let mut md = MsgDriver::new(bytes);
|
||||||
let (sequence, dbid) = read_serial_request_header(&mut md).expect("read init header");
|
let (sequence, dbid) = read_serial_request_header(&mut md).expect("read init header");
|
||||||
@@ -62,13 +49,7 @@ pub fn init(bytes: Vec<u8>, network: Network) -> anyhow::Result<InitResponse> {
|
|||||||
.map(|s| from_wire_string(s))
|
.map(|s| from_wire_string(s))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
log::info!("allowlist {:?}", allowlist);
|
log::info!("allowlist {:?}", allowlist);
|
||||||
let mut policy = make_simple_policy(network);
|
let policy = make_policy(network, po);
|
||||||
policy.filter = PolicyFilter::new_permissive();
|
|
||||||
let velocity_spec = VelocityControlSpec {
|
|
||||||
limit: 1_000_000, // default a million sats per day
|
|
||||||
interval_type: VelocityControlIntervalType::Daily,
|
|
||||||
};
|
|
||||||
policy.global_velocity_control = velocity_spec;
|
|
||||||
let validator_factory = Arc::new(SimpleValidatorFactory::new_with_policy(policy));
|
let validator_factory = Arc::new(SimpleValidatorFactory::new_with_policy(policy));
|
||||||
let random_time_factory = RandomStartingTimeFactory::new();
|
let random_time_factory = RandomStartingTimeFactory::new();
|
||||||
let persister: Arc<dyn Persist> = Arc::new(FsPersister::new(ROOT_STORE));
|
let persister: Arc<dyn Persist> = Arc::new(FsPersister::new(ROOT_STORE));
|
||||||
@@ -79,7 +60,6 @@ pub fn init(bytes: Vec<u8>, network: Network) -> anyhow::Result<InitResponse> {
|
|||||||
persister,
|
persister,
|
||||||
clock,
|
clock,
|
||||||
};
|
};
|
||||||
|
|
||||||
log::info!("create root handler now");
|
log::info!("create root handler now");
|
||||||
let root_handler = RootHandler::new(network, 0, Some(seed), allowlist, services);
|
let root_handler = RootHandler::new(network, 0, Some(seed), allowlist, services);
|
||||||
log::info!("root_handler created");
|
log::info!("root_handler created");
|
||||||
|
|||||||
50
signer/src/policy.rs
Normal file
50
signer/src/policy.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use lightning_signer::policy::filter::PolicyFilter;
|
||||||
|
use lightning_signer::policy::simple_validator::{
|
||||||
|
make_simple_policy, SimplePolicy, SimpleValidatorFactory,
|
||||||
|
};
|
||||||
|
use lightning_signer::util::velocity::{VelocityControlIntervalType, VelocityControlSpec};
|
||||||
|
use sphinx_key_parser::control::{Interval, Policy};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use vls_protocol_signer::handler::RootHandler;
|
||||||
|
use vls_protocol_signer::lightning_signer;
|
||||||
|
use vls_protocol_signer::lightning_signer::bitcoin::Network;
|
||||||
|
|
||||||
|
fn policy_interval(int: Interval) -> VelocityControlIntervalType {
|
||||||
|
match int {
|
||||||
|
Interval::Hourly => VelocityControlIntervalType::Hourly,
|
||||||
|
Interval::Daily => VelocityControlIntervalType::Daily,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_policy(root_handler: &RootHandler, network: Network, po: Policy) -> anyhow::Result<()> {
|
||||||
|
let policy = make_policy(network, &po);
|
||||||
|
let validator_factory = Arc::new(SimpleValidatorFactory::new_with_policy(policy));
|
||||||
|
root_handler.node.set_validator_factory(validator_factory);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_allowlist(root_handler: &RootHandler, allowlist: &Vec<String>) -> anyhow::Result<()> {
|
||||||
|
if let Err(e) = root_handler.node.set_allowlist(allowlist) {
|
||||||
|
return Err(anyhow::anyhow!("error setting allowlist {:?}", e));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_allowlist(root_handler: &RootHandler) -> anyhow::Result<Vec<String>> {
|
||||||
|
match root_handler.node.allowlist() {
|
||||||
|
Ok(al) => Ok(al),
|
||||||
|
Err(e) => Err(anyhow::anyhow!("error setting allowlist {:?}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_policy(network: Network, po: &Policy) -> SimplePolicy {
|
||||||
|
let mut p = make_simple_policy(network);
|
||||||
|
p.max_htlc_value_sat = po.htlc_limit;
|
||||||
|
p.filter = PolicyFilter::new_permissive();
|
||||||
|
let velocity_spec = VelocityControlSpec {
|
||||||
|
limit: po.sat_limit,
|
||||||
|
interval_type: policy_interval(po.interval),
|
||||||
|
};
|
||||||
|
p.global_velocity_control = velocity_spec;
|
||||||
|
p
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ use embedded_svc::storage::RawStorage;
|
|||||||
use embedded_svc::storage::StorageBase;
|
use embedded_svc::storage::StorageBase;
|
||||||
use esp_idf_svc::nvs::EspDefaultNvs;
|
use esp_idf_svc::nvs::EspDefaultNvs;
|
||||||
use esp_idf_svc::nvs_storage::EspNvsStorage;
|
use esp_idf_svc::nvs_storage::EspNvsStorage;
|
||||||
use sphinx_key_signer::control::{Config, ControlPersist, Controller, FlashKey};
|
use sphinx_key_signer::control::{Config, ControlPersist, Controller, FlashKey, Policy};
|
||||||
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
@@ -28,11 +28,6 @@ impl FlashPersister {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ControlPersist for FlashPersister {
|
impl ControlPersist for FlashPersister {
|
||||||
fn reset(&mut self) {
|
|
||||||
self.0
|
|
||||||
.remove(FlashKey::Config.as_str())
|
|
||||||
.expect("couldnt remove config 1");
|
|
||||||
}
|
|
||||||
fn read_nonce(&self) -> Result<u64> {
|
fn read_nonce(&self) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
let existing = self.0.get_raw(FlashKey::Nonce.as_str(), &mut buf)?;
|
let existing = self.0.get_raw(FlashKey::Nonce.as_str(), &mut buf)?;
|
||||||
@@ -60,6 +55,10 @@ impl ControlPersist for FlashPersister {
|
|||||||
self.0.put_raw(FlashKey::Config.as_str(), &conf1[..])?;
|
self.0.put_raw(FlashKey::Config.as_str(), &conf1[..])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn remove_config(&mut self) -> Result<()> {
|
||||||
|
self.0.remove(FlashKey::Config.as_str())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
fn read_seed(&self) -> Result<[u8; 32]> {
|
fn read_seed(&self) -> Result<[u8; 32]> {
|
||||||
let mut buf = [0u8; 32];
|
let mut buf = [0u8; 32];
|
||||||
let s = self.0.get_raw(FlashKey::Seed.as_str(), &mut buf)?;
|
let s = self.0.get_raw(FlashKey::Seed.as_str(), &mut buf)?;
|
||||||
@@ -73,4 +72,25 @@ impl ControlPersist for FlashPersister {
|
|||||||
self.0.put_raw(FlashKey::Seed.as_str(), &s[..])?;
|
self.0.put_raw(FlashKey::Seed.as_str(), &s[..])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn remove_seed(&mut self) -> Result<()> {
|
||||||
|
self.0.remove(FlashKey::Seed.as_str())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn read_policy(&self) -> Result<Policy> {
|
||||||
|
let mut buf = [0u8; 250];
|
||||||
|
let existing = self.0.get_raw(FlashKey::Policy.as_str(), &mut buf)?;
|
||||||
|
if let None = existing {
|
||||||
|
return Err(anyhow!("no existing config"));
|
||||||
|
}
|
||||||
|
Ok(rmp_serde::from_slice(existing.unwrap().0)?)
|
||||||
|
}
|
||||||
|
fn write_policy(&mut self, pol: Policy) -> Result<()> {
|
||||||
|
let pol1 = rmp_serde::to_vec(&pol)?;
|
||||||
|
self.0.put_raw(FlashKey::Policy.as_str(), &pol1[..])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn remove_policy(&mut self) -> Result<()> {
|
||||||
|
self.0.remove(FlashKey::Policy.as_str())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use crate::conn::mqtt::QOS;
|
use crate::conn::mqtt::QOS;
|
||||||
use crate::core::control::{controller_from_seed, FlashPersister};
|
use crate::core::control::{controller_from_seed, FlashPersister};
|
||||||
|
|
||||||
use sphinx_key_signer::control::{Config, ControlMessage};
|
use sphinx_key_signer::control::{Config, ControlMessage, ControlResponse, Policy};
|
||||||
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
||||||
use sphinx_key_signer::topics;
|
|
||||||
use sphinx_key_signer::vls_protocol::model::PubKey;
|
use sphinx_key_signer::vls_protocol::model::PubKey;
|
||||||
use sphinx_key_signer::{self, make_init_msg, InitResponse};
|
use sphinx_key_signer::{self, make_init_msg, topics, InitResponse, RootHandler};
|
||||||
use std::sync::{mpsc, Arc, Mutex};
|
use std::sync::{mpsc, Arc, Mutex};
|
||||||
|
|
||||||
use embedded_svc::httpd::Result;
|
use embedded_svc::httpd::Result;
|
||||||
@@ -46,6 +45,7 @@ pub fn make_event_loop(
|
|||||||
led_tx: mpsc::Sender<Status>,
|
led_tx: mpsc::Sender<Status>,
|
||||||
config: Config,
|
config: Config,
|
||||||
seed: [u8; 32],
|
seed: [u8; 32],
|
||||||
|
policy: &Policy,
|
||||||
flash: Arc<Mutex<FlashPersister>>,
|
flash: Arc<Mutex<FlashPersister>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
while let Ok(event) = rx.recv() {
|
while let Ok(event) = rx.recv() {
|
||||||
@@ -70,7 +70,7 @@ pub fn make_event_loop(
|
|||||||
let InitResponse {
|
let InitResponse {
|
||||||
root_handler,
|
root_handler,
|
||||||
init_reply: _,
|
init_reply: _,
|
||||||
} = sphinx_key_signer::init(init_msg, network).expect("failed to init signer");
|
} = sphinx_key_signer::init(init_msg, network, policy).expect("failed to init signer");
|
||||||
|
|
||||||
// make the controller to validate Control messages
|
// make the controller to validate Control messages
|
||||||
let mut ctrlr = controller_from_seed(&network, &seed[..], flash);
|
let mut ctrlr = controller_from_seed(&network, &seed[..], flash);
|
||||||
@@ -111,20 +111,11 @@ pub fn make_event_loop(
|
|||||||
}
|
}
|
||||||
Event::Control(ref msg_bytes) => {
|
Event::Control(ref msg_bytes) => {
|
||||||
log::info!("GOT A CONTROL MSG");
|
log::info!("GOT A CONTROL MSG");
|
||||||
match ctrlr.handle(msg_bytes) {
|
let cres = ctrlr.handle(msg_bytes);
|
||||||
Ok((response, parsed_msg)) => {
|
if let Some(res_data) = handle_control_response(&root_handler, cres, network) {
|
||||||
// log::info!("CONTROL MSG {:?}", response);
|
mqtt.publish(topics::CONTROL_RETURN, QOS, false, &res_data)
|
||||||
match parsed_msg {
|
.expect("could not publish control response");
|
||||||
ControlMessage::UpdatePolicy(new_policy) => {
|
}
|
||||||
// update here
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
mqtt.publish(topics::CONTROL_RETURN, QOS, false, &response)
|
|
||||||
.expect("could not publish control response");
|
|
||||||
}
|
|
||||||
Err(e) => log::warn!("error parsing ctrl msg {:?}", e),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,6 +123,49 @@ pub fn make_event_loop(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_control_response(
|
||||||
|
root_handler: &RootHandler,
|
||||||
|
cres: anyhow::Result<(Vec<u8>, ControlMessage)>,
|
||||||
|
network: Network,
|
||||||
|
) -> Option<Vec<u8>> {
|
||||||
|
match cres {
|
||||||
|
Ok((mut response, parsed_msg)) => {
|
||||||
|
// the following msg types require other actions besides Flash persistence
|
||||||
|
match parsed_msg {
|
||||||
|
ControlMessage::UpdatePolicy(new_policy) => {
|
||||||
|
if let Err(e) =
|
||||||
|
sphinx_key_signer::set_policy(&root_handler, network, new_policy)
|
||||||
|
{
|
||||||
|
log::error!("set policy failed {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ControlMessage::UpdateAllowlist(al) => {
|
||||||
|
if let Err(e) = sphinx_key_signer::set_allowlist(&root_handler, &al) {
|
||||||
|
log::error!("set allowlist failed {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// overwrite the real Allowlist response, loaded from Node
|
||||||
|
ControlMessage::QueryAllowlist => {
|
||||||
|
if let Ok(al) = sphinx_key_signer::get_allowlist(&root_handler) {
|
||||||
|
response = rmp_serde::to_vec(&ControlResponse::AllowlistCurrent(al))
|
||||||
|
.expect("couldnt build ControlResponse::AllowlistCurrent");
|
||||||
|
} else {
|
||||||
|
log::error!("read allowlist failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
Some(response)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
let response = rmp_serde::to_vec(&ControlResponse::Error(e.to_string()))
|
||||||
|
.expect("couldnt build ControlResponse::Error");
|
||||||
|
log::warn!("error parsing ctrl msg {:?}", e);
|
||||||
|
Some(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "pingpong")]
|
#[cfg(feature = "pingpong")]
|
||||||
pub fn make_event_loop(
|
pub fn make_event_loop(
|
||||||
mut mqtt: EspMqttClient<ConnState<MessageImpl, EspError>>,
|
mut mqtt: EspMqttClient<ConnState<MessageImpl, EspError>>,
|
||||||
@@ -139,7 +173,10 @@ pub fn make_event_loop(
|
|||||||
_network: Network,
|
_network: Network,
|
||||||
do_log: bool,
|
do_log: bool,
|
||||||
led_tx: mpsc::Sender<Status>,
|
led_tx: mpsc::Sender<Status>,
|
||||||
|
_config: Config,
|
||||||
_seed: [u8; 32],
|
_seed: [u8; 32],
|
||||||
|
_policy: &Policy,
|
||||||
|
_flash: Arc<Mutex<FlashPersister>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
log::info!("About to subscribe to the mpsc channel");
|
log::info!("About to subscribe to the mpsc channel");
|
||||||
while let Ok(event) = rx.recv() {
|
while let Ok(event) = rx.recv() {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use std::time::SystemTime;
|
|||||||
use esp_idf_hal::peripherals::Peripherals;
|
use esp_idf_hal::peripherals::Peripherals;
|
||||||
use esp_idf_svc::nvs::*;
|
use esp_idf_svc::nvs::*;
|
||||||
|
|
||||||
use sphinx_key_signer::control::{Config, ControlPersist};
|
use sphinx_key_signer::control::{Config, ControlPersist, Policy};
|
||||||
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
use sphinx_key_signer::lightning_signer::bitcoin::Network;
|
||||||
|
|
||||||
#[cfg(not(feature = "pingpong"))]
|
#[cfg(not(feature = "pingpong"))]
|
||||||
@@ -56,6 +56,7 @@ fn main() -> Result<()> {
|
|||||||
let mut flash = FlashPersister::new(default_nvs.clone());
|
let mut flash = FlashPersister::new(default_nvs.clone());
|
||||||
if let Ok(exist) = flash.read_config() {
|
if let Ok(exist) = flash.read_config() {
|
||||||
let seed = flash.read_seed().expect("no seed...");
|
let seed = flash.read_seed().expect("no seed...");
|
||||||
|
let policy = flash.read_policy().unwrap_or_default();
|
||||||
println!(
|
println!(
|
||||||
"=============> START CLIENT NOW <============== {:?}",
|
"=============> START CLIENT NOW <============== {:?}",
|
||||||
exist
|
exist
|
||||||
@@ -85,9 +86,13 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let flash_arc = Arc::new(Mutex::new(flash));
|
let flash_arc = Arc::new(Mutex::new(flash));
|
||||||
loop {
|
loop {
|
||||||
if let Ok(()) =
|
if let Ok(()) = make_and_launch_client(
|
||||||
make_and_launch_client(exist.clone(), seed, led_tx.clone(), flash_arc.clone())
|
exist.clone(),
|
||||||
{
|
seed,
|
||||||
|
&policy,
|
||||||
|
led_tx.clone(),
|
||||||
|
flash_arc.clone(),
|
||||||
|
) {
|
||||||
println!("Exited out of the event loop, trying again in 5 seconds...");
|
println!("Exited out of the event loop, trying again in 5 seconds...");
|
||||||
thread::sleep(Duration::from_secs(5));
|
thread::sleep(Duration::from_secs(5));
|
||||||
} else {
|
} else {
|
||||||
@@ -112,6 +117,7 @@ fn main() -> Result<()> {
|
|||||||
fn make_and_launch_client(
|
fn make_and_launch_client(
|
||||||
config: Config,
|
config: Config,
|
||||||
seed: [u8; 32],
|
seed: [u8; 32],
|
||||||
|
policy: &Policy,
|
||||||
led_tx: mpsc::Sender<Status>,
|
led_tx: mpsc::Sender<Status>,
|
||||||
flash: Arc<Mutex<FlashPersister>>,
|
flash: Arc<Mutex<FlashPersister>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
@@ -140,6 +146,7 @@ fn make_and_launch_client(
|
|||||||
led_tx,
|
led_tx,
|
||||||
config,
|
config,
|
||||||
seed,
|
seed,
|
||||||
|
policy,
|
||||||
flash,
|
flash,
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -134,7 +134,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let InitResponse {
|
let InitResponse {
|
||||||
root_handler,
|
root_handler,
|
||||||
init_reply: _,
|
init_reply: _,
|
||||||
} = sphinx_key_signer::init(init_msg, network).expect("failed to init signer");
|
} = sphinx_key_signer::init(init_msg, network, &Default::default())
|
||||||
|
.expect("failed to init signer");
|
||||||
// the actual handler loop
|
// the actual handler loop
|
||||||
loop {
|
loop {
|
||||||
match eventloop.poll().await {
|
match eventloop.poll().await {
|
||||||
|
|||||||
Reference in New Issue
Block a user