Skip to content

Backport v0.9 various fixes to v0.8 #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
**/*.rs.bk

.idea
.vscode

# Temporary directory for debug data storage
/data
Expand Down
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ microservices = { version = "0.8.10", default-features = false, features = ["nod
# Bitcoin
bitcoin = { version = "0.28.1", features = ["rand"] }
miniscript = "7.0.0"
electrum-client = "0.10.1"
electrum-client = "0.10.2"
lightning-invoice = "0.16.0"
# OS
serde = "1"
serde_json = "1"
chrono = "0.4"
nix = "0.24"
log = { version = "0.4", features = ["max_level_trace", "release_max_level_debug"] }
Expand Down
4 changes: 2 additions & 2 deletions cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ impl Exec for Opts {

Command::Listen { ip_addr, port, bolt, bifrost } => {
let listen_addr = match (bolt, bifrost) {
(false, true) => ListenAddr::bolt(ip_addr, port),
(true, false) => ListenAddr::bifrost(ip_addr, port),
(true, false) => ListenAddr::bolt(ip_addr, port),
(false, true) => ListenAddr::bifrost(ip_addr, port),
_ => unreachable!(),
};
runtime.request(ServiceId::LnpBroker, RpcMsg::Listen(listen_addr))?;
Expand Down
19 changes: 14 additions & 5 deletions rpc/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use microservices::util::OptionDetails;
#[cfg(feature = "serde")]
use serde_with::{DisplayFromStr, DurationSeconds, Same};
use strict_encoding::{StrictDecode, StrictEncode};
use wallet::address::AddressCompat;

use crate::error::FailureCode;
use crate::{ListenAddr, ServiceId};
Expand Down Expand Up @@ -122,7 +121,7 @@ pub enum RpcMsg {

#[display("peer_list({0})", alt = "{0:#}")]
#[from]
PeerList(List<NodeId>),
PeerList(ListPeerInfo),

#[display("channel_list({0})", alt = "{0:#}")]
#[from]
Expand Down Expand Up @@ -270,8 +269,7 @@ pub struct NodeInfo {
#[serde_as(as = "DurationSeconds")]
pub uptime: Duration,
pub since: u64,
#[serde_as(as = "Vec<DisplayFromStr>")]
pub peers: Vec<NodeId>,
pub peers: ListPeerInfo,
#[serde_as(as = "Vec<DisplayFromStr>")]
pub channels: Vec<ChannelId>,
}
Expand Down Expand Up @@ -315,11 +313,20 @@ pub struct ChannelInfo {
#[display(FundsInfo::to_yaml_string)]
pub struct FundsInfo {
#[serde_as(as = "BTreeMap<DisplayFromStr, Same>")]
pub bitcoin_funds: BTreeMap<AddressCompat, u64>,
pub bitcoin_funds: BTreeMap<Address, u64>,
pub asset_funds: AssetsBalance,
pub next_address: Address,
}

#[cfg_attr(feature = "serde", serde_as)]
#[derive(Clone, PartialEq, Eq, Debug, Display, NetworkEncode, NetworkDecode)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))]
#[display(ListPeerInfo::to_yaml_string)]
pub struct ListPeerInfo {
pub bolt: Vec<NodeId>,
pub bifrost: Vec<NodeId>,
}

#[cfg(feature = "serde")]
impl ToYamlString for NodeInfo {}
#[cfg(feature = "serde")]
Expand All @@ -328,6 +335,8 @@ impl ToYamlString for PeerInfo {}
impl ToYamlString for ChannelInfo {}
#[cfg(feature = "serde")]
impl ToYamlString for FundsInfo {}
#[cfg(feature = "serde")]
impl ToYamlString for ListPeerInfo {}

#[derive(Wrapper, Clone, PartialEq, Eq, Debug, From, NetworkEncode, NetworkDecode)]
#[wrapper(IndexRange)]
Expand Down
34 changes: 23 additions & 11 deletions src/bus/ctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// You should have received a copy of the MIT License along with this software.
// If not, see <https://opensource.org/licenses/MIT>.

use amplify::num::u24;
use amplify::Slice32;
use bitcoin::Txid;
use internet2::addr::{NodeAddr, NodeId};
Expand Down Expand Up @@ -74,7 +73,9 @@ pub enum CtlMsg {

// On-chain tracking API
// ---------------------
/// Asks on-chain tracking service to send updates on the transaction mining status
/// Asks on-chain tracking service to send updates on the transaction mining status.
///
/// Depth 0 indicates that a transaction must be tracked in a mempool.
#[display("track({txid}, {depth})")]
Track { txid: Txid, depth: u32 },

Expand Down Expand Up @@ -225,22 +226,33 @@ pub struct FundChannel {
pub feerate_per_kw: Option<u32>,
}

/// TODO: Move to descriptor wallet
/// Information about block position and transaction position in a block
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[derive(NetworkEncode, NetworkDecode)]
#[display("{depth}, {height}, {pos}")]
pub struct BlockPos {
/// Depths from the chain tip; always greater than 0
pub depth: u32,

/// Height of the block containing transaction
pub height: u32,

/// Transaction position within the block
pub pos: u32,
}

/// TODO: Move to descriptor wallet
/// Update on a transaction mining status
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[derive(NetworkEncode, NetworkDecode)]
#[display("{txid}, {depth}")]
#[display("{txid}, ...")]
pub struct TxStatus {
/// Id of a transaction previously requested to be tracked
pub txid: Txid,

/// Depths from the chain tip
pub depth: u24,

/// Height of the block containing transaction
pub height: u24,

/// Transaction position within the block
pub pos: u24,
/// Optional block position given only if the depth is greater than 0 zero
pub block_pos: Option<BlockPos>,
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display, NetworkEncode, NetworkDecode)]
Expand Down
2 changes: 1 addition & 1 deletion src/channeld/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub struct Runtime {
pub(super) state: ChannelState,
pub(super) file: fs::File,
started: SystemTime,
/// Client which is made an equiry starting the current workflow run by the active state
/// Client which is made an enquiry starting the current workflow run by the active state
/// machine. It is not a part of the state of the machine since it should not persist.
enquirer: Option<ClientId>,
storage: Box<dyn storage::Driver>,
Expand Down
1 change: 1 addition & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub enum Error {
Bridge(transport::Error),

/// unable to connect Electrum server
#[from(electrum_client::Error)]
ElectrumConnectivity,

/// message `{1}` is not supported on {0} message bus
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub mod watchd;

pub use config::Config;
pub use error::Error;
pub use service::{Endpoints, Responder, Service, TryToServiceId};
pub use service::{BridgeHandler, Endpoints, Responder, Service, TryToServiceId};

pub const LNP_NODE_MASTER_KEY_FILE: &str = "master.key";
pub const LNP_NODE_FUNDING_WALLET: &str = "funding.wallet";
Expand Down
3 changes: 2 additions & 1 deletion src/lnpd/daemons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ pub fn read_node_key_file(key_file: &Path) -> LocalNode {
let mut file = fs::File::open(key_file).unwrap_or_else(|_| {
panic!(
"Unable to open key file '{}';\nplease check that the file exists and the daemon has \
access rights to it",
access rights to it. If you have not created a key file before, run \"lnpd init\". \
for more info you can run \"lnpd --help\"",
key_file.display()
)
});
Expand Down
4 changes: 3 additions & 1 deletion src/lnpd/funding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,13 @@ impl FundingWallet {
}

pub fn next_funding_address(&self) -> Result<Address, Error> {
let address = DescriptorExt::<bitcoin::PublicKey>::address(
let spk = DescriptorExt::<bitcoin::PublicKey>::script_pubkey(
&self.wallet_data.descriptor,
&self.secp,
&[UnhardenedIndex::zero(), self.wallet_data.last_normal_index],
)?;
let address = Address::from_script(&spk, self.network)
.expect("Incorrect scriptPubkey to represents address");
Ok(address)
}

Expand Down
25 changes: 14 additions & 11 deletions src/lnpd/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::path::PathBuf;
use std::time::{Duration, SystemTime};

use amplify::{DumbDefault, Wrapper};
use bitcoin::Txid;
use bitcoin::{Address, Txid};
use internet2::addr::{NodeAddr, NodeId};
use lnp::addr::LnpAddr;
use lnp::channel::bolt::{CommonParams, LocalKeyset, PeerParams, Policy};
Expand All @@ -31,7 +31,6 @@ use microservices::esb::{self, ClientId, Handler};
use microservices::peer::PeerSocket;
use microservices::util::OptionDetails;
use microservices::{DaemonHandle, LauncherError};
use wallet::address::AddressCompat;

use crate::automata::{Event, StateMachine};
use crate::bus::{
Expand All @@ -40,7 +39,7 @@ use crate::bus::{
use crate::lnpd::automata::ChannelLauncher;
use crate::lnpd::daemons::{read_node_key_file, Daemon};
use crate::lnpd::funding::{self, FundingWallet};
use crate::rpc::{Failure, FundsInfo, NodeInfo, RpcMsg, ServiceId};
use crate::rpc::{Failure, FundsInfo, ListPeerInfo, NodeInfo, RpcMsg, ServiceId};
use crate::{Config, Endpoints, Error, Responder, Service, LNP_NODE_FUNDING_WALLET};

pub fn run<'a>(
Expand Down Expand Up @@ -257,14 +256,20 @@ impl Runtime {
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_else(|_| Duration::from_secs(0))
.as_secs(),
peers: self.bolt_connections.iter().copied().collect(),
peers: ListPeerInfo {
bolt: self.bolt_connections.iter().copied().collect(),
bifrost: self.bifrost_connections.iter().copied().collect(),
},
channels: self.channels.iter().cloned().collect(),
});
self.send_rpc(endpoints, client_id, node_info)?;
}

RpcMsg::ListPeers => {
let peer_list = self.bolt_connections.iter().copied().collect();
let peer_list = ListPeerInfo {
bolt: self.bolt_connections.iter().copied().collect(),
bifrost: self.bifrost_connections.iter().copied().collect(),
};
self.send_rpc(endpoints, client_id, RpcMsg::PeerList(peer_list))?;
}

Expand Down Expand Up @@ -589,15 +594,13 @@ impl Runtime {
Ok(format!("Launched new instance of {}", handle))
}

fn available_funding(&mut self) -> Result<BTreeMap<AddressCompat, u64>, Error> {
fn available_funding(&mut self) -> Result<BTreeMap<Address, u64>, Error> {
self.funding_wallet.list_funds()?.into_iter().try_fold(
bmap! {},
|mut acc, f| -> Result<_, Error> {
*acc.entry(
AddressCompat::from_script(&f.script_pubkey, self.funding_wallet.network())
.ok_or(funding::Error::NoAddressRepresentation)?,
)
.or_insert(0) += f.amount;
let addr = Address::from_script(&f.script_pubkey, self.funding_wallet.network())
.ok_or(funding::Error::NoAddressRepresentation)?;
*acc.entry(addr).or_insert(0) += f.amount;
Ok(acc)
},
)
Expand Down
2 changes: 1 addition & 1 deletion src/peerd/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl Opts {
} else if let Some(bind_addr) = self.listen {
let addr = InetSocketAddr::socket(
bind_addr.unwrap_or(IpAddr::V4(Ipv4Addr::UNSPECIFIED)).into(),
self.port(),
self.port.unwrap_or(self.port()),
);
PeerSocket::Listen(NodeAddr::new(node_id, addr))
} else {
Expand Down
31 changes: 1 addition & 30 deletions src/peerd/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use microservices::ZMQ_CONTEXT;

use crate::bus::{BusMsg, CtlMsg, ServiceBus};
use crate::rpc::{PeerInfo, ServiceId};
use crate::{Config, Endpoints, Error, Responder, Service};
use crate::{BridgeHandler, Config, Endpoints, Error, Responder, Service};

pub fn run(
connection: PeerConnection,
Expand Down Expand Up @@ -113,35 +113,6 @@ pub fn run(
unreachable!()
}

pub struct BridgeHandler;

impl esb::Handler<ServiceBus> for BridgeHandler {
type Request = BusMsg;
type Error = Error;

fn identity(&self) -> ServiceId { ServiceId::Loopback }

fn handle(
&mut self,
_: &mut Endpoints,
_: ServiceBus,
_: ServiceId,
_: BusMsg,
) -> Result<(), Error> {
// Bridge does not receive replies for now
Ok(())
}

fn handle_err(
&mut self,
_: &mut Endpoints,
err: esb::Error<ServiceId>,
) -> Result<(), Self::Error> {
// We simply propagate the error since it's already being reported
Err(err.into())
}
}

pub struct ListenerRuntime {
identity: ServiceId,
bridge: esb::Controller<ServiceBus, BusMsg, BridgeHandler>,
Expand Down
30 changes: 30 additions & 0 deletions src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,36 @@ use crate::bus::{self, BusMsg, CtlMsg, Report, ServiceBus};
use crate::rpc::{Failure, ServiceId};
use crate::{Config, Error};

/// An empty handler used for bridge interfaces in watcher and peer daemons
pub struct BridgeHandler;

impl esb::Handler<ServiceBus> for BridgeHandler {
type Request = BusMsg;
type Error = Error;

fn identity(&self) -> ServiceId { ServiceId::Loopback }

fn handle(
&mut self,
_: &mut Endpoints,
_: ServiceBus,
_: ServiceId,
_: BusMsg,
) -> Result<(), Error> {
// Bridge does not receive replies for now
Ok(())
}

fn handle_err(
&mut self,
_: &mut Endpoints,
err: esb::Error<ServiceId>,
) -> Result<(), Self::Error> {
// We simply propagate the error since it's already being reported
Err(err.into())
}
}

pub struct Service<Runtime>
where
Runtime: esb::Handler<ServiceBus, Request = BusMsg>,
Expand Down
2 changes: 2 additions & 0 deletions src/watchd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#[cfg(feature = "server")]
mod opts;
mod runtime;
mod worker;

#[cfg(feature = "server")]
pub use opts::Opts;
pub use runtime::run;
pub use worker::{ElectrumUpdate, ElectrumWorker, WatcherChannelFailure};
Loading