forked from LNP-WG/lnp-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommand.rs
167 lines (152 loc) · 6.61 KB
/
command.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// LNP Node: node running lightning network protocol and generalized lightning
// channels.
// Written in 2020-2022 by
// Dr. Maxim Orlovsky <[email protected]>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the MIT License along with this software.
// If not, see <https://opensource.org/licenses/MIT>.
use std::str::FromStr;
use internet2::addr::NodeId;
use lnp::p2p::bolt::{ChannelId, LNP2P_BOLT_PORT};
use lnp_rpc::{self, Client, CreateChannel, Error, ListenAddr, PayInvoice, RpcMsg, ServiceId};
use microservices::shell::Exec;
use crate::{Command, Opts};
impl Command {
pub fn action_string(&self) -> String {
match self {
Command::Listen { .. } => s!("Binding to port"),
Command::Connect { .. } => s!("Connecting to remore peer"),
Command::Ping { .. } => s!("Pinging peer"),
Command::Info { .. } => s!("Getting info"),
Command::Funds => s!("Retrieving information about funds"),
Command::Peers => s!("Retrieving information about peers"),
Command::Channels => s!("Retrieving information about channels"),
Command::Open { .. } => s!("Opening channel"),
Command::Invoice { .. } => s!("Creating invoice"),
Command::Pay { .. } => s!("Paying invoice"),
}
}
}
impl Exec for Opts {
type Client = Client;
type Error = Error;
fn exec(self, runtime: &mut Self::Client) -> Result<(), Self::Error> {
println!("{}...", self.command.action_string());
match self.command {
Command::Info { subject, bolt, bifrost } => {
if let Some(subj) = subject {
if let Ok(node_id) = NodeId::from_str(&subj) {
let service_id = match (bolt, bifrost) {
(true, false) => ServiceId::PeerBolt(node_id),
(false, true) => ServiceId::PeerBifrost(node_id),
_ => unreachable!(),
};
runtime.request(service_id, RpcMsg::GetInfo)?;
} else if let Ok(channel_id) = ChannelId::from_str(&subj) {
// TODO: Support bifrost channels as above
runtime.request(ServiceId::Channel(channel_id), RpcMsg::GetInfo)?;
} else {
return Err(Error::Other(s!("Subject parameter must be either remote \
node address or channel id represented by \
a hex string")));
}
} else {
runtime.request(ServiceId::LnpBroker, RpcMsg::GetInfo)?;
}
match runtime.response()? {
RpcMsg::NodeInfo(info) => println!("{}", info),
RpcMsg::PeerInfo(info) => println!("{}", info),
RpcMsg::ChannelInfo(info) => println!("{}", info),
_ => {
return Err(Error::Other(
"Server returned unrecognizable response".to_string(),
))
}
}
}
Command::Peers => {
runtime.request(ServiceId::LnpBroker, RpcMsg::ListPeers)?;
runtime.report_response()?;
}
Command::Channels => {
runtime.request(ServiceId::LnpBroker, RpcMsg::ListChannels)?;
runtime.report_response()?;
}
Command::Funds => {
runtime.request(ServiceId::LnpBroker, RpcMsg::ListFunds)?;
runtime.report_response()?;
}
Command::Listen { ip_addr, port, bolt, bifrost } => {
let listen_addr = match (bolt, bifrost) {
(true, false) => ListenAddr::bolt(ip_addr, port),
(false, true) => ListenAddr::bifrost(ip_addr, port),
_ => unreachable!(),
};
runtime.request(ServiceId::LnpBroker, RpcMsg::Listen(listen_addr))?;
runtime.report_progress()?;
}
Command::Connect { peer } => {
runtime.request(ServiceId::LnpBroker, RpcMsg::ConnectPeer(peer))?;
runtime.report_progress()?;
}
Command::Ping { peer, bolt, bifrost } => {
let service_id = match (bolt, bifrost) {
(true, false) => ServiceId::PeerBolt(peer),
(false, true) => ServiceId::PeerBifrost(peer),
_ => unreachable!(),
};
runtime.request(service_id, RpcMsg::PingPeer)?;
}
Command::Open {
peer,
funding_sat,
push_msat,
fee_rate,
announce_channel,
channel_type,
dust_limit,
to_self_delay,
htlc_max_count,
htlc_min_value,
htlc_max_total_value,
channel_reserve,
} => {
// TODO: Change this to the use of LnpAddr
let node_addr = peer.node_addr(LNP2P_BOLT_PORT);
runtime.request(
ServiceId::LnpBroker,
RpcMsg::CreateChannel(CreateChannel {
funding_sat,
push_msat: push_msat.unwrap_or_default(),
fee_rate,
announce_channel,
channel_type,
dust_limit,
to_self_delay,
htlc_max_count,
htlc_min_value,
htlc_max_total_value,
remote_peer: node_addr,
report_to: Some(runtime.identity()),
channel_reserve,
}),
)?;
runtime.report_progress()?;
}
Command::Invoice { .. } => todo!("Implement invoice generation"),
Command::Pay { invoice, channel: channel_id, amount_msat } => {
runtime.request(
ServiceId::Router,
RpcMsg::PayInvoice(PayInvoice { invoice, channel_id, amount_msat }),
)?;
runtime.report_progress()?;
}
}
Ok(())
}
}