1use bitcoin::secp256k1::{PublicKey, SecretKey};
2use bitcoin::{Transaction, TxOut};
3use lightning_signer::bitcoin;
4use lightning_signer::prelude::*;
5use log::*;
6
7use lightning_signer::invoice::{Invoice, InvoiceAttributes};
8use lightning_signer::lightning::types::payment::PaymentHash;
9use lightning_signer::node::Node;
10use lightning_signer::policy::error::ValidationErrorKind;
11use lightning_signer::util::clock::Clock;
12use lightning_signer::util::debug_utils::DebugBytes;
13use lightning_signer::util::status::Status;
14use lightning_signer::util::velocity::VelocityControl;
15use lightning_signer::wallet::Wallet;
16
17pub trait Approve: SendSync {
37 fn approve_invoice(&self, invoice: &Invoice) -> bool;
39
40 fn approve_keysend(&self, payment_hash: PaymentHash, amount_msat: u64) -> bool;
42
43 fn approve_onchain(
48 &self,
49 tx: &Transaction,
50 prev_outs: &[TxOut],
51 unknown_indices: &[usize],
52 ) -> bool;
53
54 fn handle_proposed_invoice(&self, node: &Arc<Node>, invoice: Invoice) -> Result<bool, Status> {
56 let (payment_hash, _payment_state, invoice_hash) =
57 Node::payment_state_from_invoice(&invoice)?;
58
59 if node.has_payment(&payment_hash, &invoice_hash)? {
61 debug!(
62 "node already approved invoice with payment_hash {:?} invoice_hash {:?}",
63 DebugBytes(&payment_hash.0),
64 DebugBytes(&invoice_hash)
65 );
66 return Ok(true);
67 }
68
69 let payee = invoice.payee_pub_key();
71 if node.allowlist_contains_payee(payee) {
72 debug!(
73 "node allowlist contains payee {:?} for invoice with amount {}",
74 payee,
75 invoice.amount_milli_satoshis()
76 );
77 node.add_invoice(invoice)
78 } else if self.approve_invoice(&invoice) {
79 debug!(
80 "invoice to {:?} approved with amount {}",
81 payee,
82 invoice.amount_milli_satoshis()
83 );
84 node.add_invoice(invoice)
85 } else {
86 warn!(
87 "invoice to {:?} not approved with amount {}",
88 payee,
89 invoice.amount_milli_satoshis()
90 );
91 Ok(false)
92 }
93 }
94
95 fn handle_proposed_keysend(
98 &self,
99 node: &Arc<Node>,
100 payee: PublicKey,
101 payment_hash: PaymentHash,
102 amount_msat: u64,
103 ) -> Result<bool, Status> {
104 let now = node.get_clock().now();
105 let (_payment_state, invoice_hash) =
106 Node::payment_state_from_keysend(payee, payment_hash, amount_msat, now)?;
107
108 if node.has_payment(&payment_hash, &invoice_hash)? {
110 debug!(
111 "node already approved keysend with payment_hash {:?} invoice_hash {:?}",
112 DebugBytes(&payment_hash.0),
113 DebugBytes(&invoice_hash)
114 );
115 return Ok(true);
116 }
117
118 if self.approve_keysend(payment_hash, amount_msat) {
123 debug!("keysend to {:?} approved with amount {}", payee, amount_msat);
124 node.add_keysend(payee, payment_hash, amount_msat).map_err(|err| {
125 warn!("add_keysend failed: {}", err);
126 err
127 })
128 } else {
129 warn!("keysend to {:?} not approved with amount {}", payee, amount_msat);
130 Ok(false)
131 }
132 }
133
134 fn handle_proposed_onchain(
138 &self,
139 node: &Arc<Node>,
140 tx: &Transaction,
141 segwit_flags: &[bool],
142 prev_outs: &[TxOut],
143 uniclosekeys: &[Option<(SecretKey, Vec<Vec<u8>>)>],
144 opaths: &[Vec<u32>],
145 ) -> Result<bool, Status> {
146 let check_result =
147 node.check_onchain_tx(&tx, segwit_flags, &prev_outs, &uniclosekeys, &opaths);
148 match check_result {
149 Ok(()) => {}
150 Err(ve) => match ve.kind {
151 ValidationErrorKind::UnknownDestinations(_, ref indices) => {
152 if self.approve_onchain(&tx, &prev_outs, indices) {
153 info!("approved onchain tx with unknown outputs");
154 } else {
155 info!("rejected onchain tx with unknown outputs");
156 return Ok(false);
157 }
158 }
159 _ => {
160 return Err(Status::failed_precondition(ve.to_string()))?;
161 }
162 },
163 }
164 Ok(true)
165 }
166}
167
168#[derive(Copy, Clone)]
173pub struct PositiveApprover();
174
175impl SendSync for PositiveApprover {}
176
177impl Approve for PositiveApprover {
178 fn approve_invoice(&self, _invoice: &Invoice) -> bool {
179 true
180 }
181
182 fn approve_keysend(&self, _payment_hash: PaymentHash, _amount_msat: u64) -> bool {
183 true
184 }
185
186 fn approve_onchain(
187 &self,
188 _tx: &Transaction,
189 _prev_outs: &[TxOut],
190 _unknown_indices: &[usize],
191 ) -> bool {
192 true
193 }
194}
195
196#[derive(Copy, Clone)]
201pub struct WarningPositiveApprover();
202
203impl SendSync for WarningPositiveApprover {}
204
205impl Approve for WarningPositiveApprover {
206 fn approve_invoice(&self, invoice: &Invoice) -> bool {
207 warn!("AUTOAPPROVED INVOICE {:?}", invoice);
208 true
209 }
210
211 fn approve_keysend(&self, payment_hash: PaymentHash, amount_msat: u64) -> bool {
212 warn!(
213 "AUTOAPPROVED KEYSEND of {} msat with payment_hash {:?}",
214 amount_msat,
215 DebugBytes(&payment_hash.0)
216 );
217 true
218 }
219
220 fn approve_onchain(
221 &self,
222 tx: &Transaction,
223 prev_outs: &[TxOut],
224 unknown_indices: &[usize],
225 ) -> bool {
226 warn!(
227 "AUTOAPPROVED ONCHAIN tx {:?} with values_sat {:?} and unknown_indices {:?}",
228 tx, prev_outs, unknown_indices
229 );
230 true
231 }
232}
233
234#[derive(Copy, Clone)]
236pub struct NegativeApprover();
237
238impl SendSync for NegativeApprover {}
239
240impl Approve for NegativeApprover {
241 fn approve_invoice(&self, _invoice: &Invoice) -> bool {
242 false
243 }
244
245 fn approve_keysend(&self, _payment_hash: PaymentHash, _amount_msat: u64) -> bool {
246 false
247 }
248
249 fn approve_onchain(
250 &self,
251 _tx: &Transaction,
252 _prev_outs: &[TxOut],
253 _unknown_indices: &[usize],
254 ) -> bool {
255 false
256 }
257}
258
259pub struct VelocityApprover<A: Approve> {
297 clock: Arc<dyn Clock>,
298 control: Mutex<VelocityControl>,
299 delegate: A,
300}
301
302impl<A: Approve> VelocityApprover<A> {
303 pub fn new(clock: Arc<dyn Clock>, control: VelocityControl, delegate: A) -> Self {
305 Self { control: Mutex::new(control), clock, delegate }
306 }
307
308 pub fn control(&self) -> VelocityControl {
310 self.control.lock().unwrap().clone()
311 }
312
313 pub fn set_control(&self, control: VelocityControl) {
315 *self.control.lock().unwrap() = control;
316 }
317}
318
319impl<A: Approve> SendSync for VelocityApprover<A> {}
320
321impl<A: Approve> Approve for VelocityApprover<A> {
322 fn approve_invoice(&self, invoice: &Invoice) -> bool {
323 let mut control = self.control.lock().unwrap();
324 let success = control.insert(self.clock.now().as_secs(), invoice.amount_milli_satoshis());
325 if success {
326 true
327 } else {
328 let success = self.delegate.approve_invoice(invoice);
329 if success {
330 control.clear();
333 }
334 success
335 }
336 }
337
338 fn approve_keysend(&self, payment_hash: PaymentHash, amount_msat: u64) -> bool {
339 let mut control = self.control.lock().unwrap();
340 let success = control.insert(self.clock.now().as_secs(), amount_msat);
341 if success {
342 true
343 } else {
344 let success = self.delegate.approve_keysend(payment_hash, amount_msat);
345 if success {
346 control.clear();
349 }
350 success
351 }
352 }
353
354 fn approve_onchain(
355 &self,
356 tx: &Transaction,
357 prev_outs: &[TxOut],
358 unknown_indices: &[usize],
359 ) -> bool {
360 self.delegate.approve_onchain(tx, prev_outs, unknown_indices)
361 }
362}
363
364#[derive(Debug)]
366pub enum Approval {
367 Invoice(Invoice),
369 KeySend(PaymentHash, u64),
371 Onchain(Transaction),
373}
374
375pub struct MemoApprover<A: Approve> {
381 delegate: A,
382 approvals: Mutex<Vec<Approval>>,
383}
384
385impl<A: Approve> MemoApprover<A> {
386 pub fn new(delegate: A) -> Self {
388 Self { delegate, approvals: Mutex::new(Vec::new()) }
389 }
390
391 pub fn approve(&self, approvals: Vec<Approval>) {
396 *self.approvals.lock().unwrap() = approvals;
397 }
398}
399
400impl<A: Approve> SendSync for MemoApprover<A> {}
401
402impl<A: Approve> Approve for MemoApprover<A> {
403 fn approve_invoice(&self, invoice: &Invoice) -> bool {
404 let mut approvals = self.approvals.lock().unwrap();
405 for approval in approvals.drain(..) {
406 match approval {
407 Approval::Invoice(approved_invoice) => {
408 if approved_invoice.invoice_hash() == invoice.invoice_hash() {
409 return true;
410 }
411 }
412 _ => {}
413 }
414 }
415 return self.delegate.approve_invoice(invoice);
416 }
417
418 fn approve_keysend(&self, payment_hash: PaymentHash, amount_msat: u64) -> bool {
419 let mut approvals = self.approvals.lock().unwrap();
420 for approval in approvals.drain(..) {
421 match approval {
422 Approval::KeySend(approved_payment_hash, approved_amount_msat) =>
423 if approved_payment_hash == payment_hash && approved_amount_msat == amount_msat
424 {
425 return true;
426 },
427 _ => {}
428 }
429 }
430 return self.delegate.approve_keysend(payment_hash, amount_msat);
431 }
432
433 fn approve_onchain(
434 &self,
435 tx: &Transaction,
436 prev_outs: &[TxOut],
437 unknown_indices: &[usize],
438 ) -> bool {
439 let mut approvals = self.approvals.lock().unwrap();
440 for approval in approvals.drain(..) {
441 match approval {
442 Approval::Onchain(approved_tx) =>
443 if approved_tx == *tx {
444 return true;
445 },
446 _ => {}
447 }
448 }
449 return self.delegate.approve_onchain(tx, prev_outs, unknown_indices);
450 }
451}
452
453#[cfg(test)]
454mod tests {
455 use crate::approver::{
456 Approve, NegativeApprover, PositiveApprover, VelocityApprover, WarningPositiveApprover,
457 };
458 use lightning::types::payment::PaymentHash;
459 use lightning_signer::bitcoin::secp256k1::PublicKey;
460 use lightning_signer::invoice::InvoiceAttributes;
461 use lightning_signer::lightning;
462 use lightning_signer::node::{Node, PaymentState};
463 use lightning_signer::util::clock::Clock;
464 use lightning_signer::util::clock::ManualClock;
465 use lightning_signer::util::test_utils::{
466 make_current_test_invoice, make_node, make_test_invoice,
467 };
468 use lightning_signer::util::velocity::{
469 VelocityControl, VelocityControlIntervalType::Hourly, VelocityControlSpec,
470 };
471 use std::sync::Arc;
472 use std::time::Duration;
473 use test_log::test;
474
475 #[test]
476 fn test_invoice_velocity_approver_negative() {
477 let delegate = NegativeApprover();
478 let clock = Arc::new(ManualClock::new(Duration::ZERO));
479 let spec = VelocityControlSpec { limit_msat: 1_000_000, interval_type: Hourly };
480 let control = VelocityControl::new(spec);
481 let approver = VelocityApprover::new(clock.clone(), control, delegate);
482 let amt = 600_000_u64;
483 let invoice = make_test_invoice(1, amt);
484 let success = approver.approve_invoice(&invoice);
485 assert!(success);
486
487 let invoice = make_test_invoice(2, amt);
488 let success = approver.approve_invoice(&invoice);
489 assert!(!success);
490 assert_eq!(approver.control.lock().unwrap().velocity(), amt);
491 }
492
493 #[test]
494 fn test_handle_invoice_allowlist() {
495 let (_, node, _) = make_node();
497 let approver = NegativeApprover();
498 let invoice = make_current_test_invoice(1, 600_000);
499 assert!(!approver.handle_proposed_invoice(&node, invoice.clone()).unwrap());
500
501 let allowable = format!("payee:{}", invoice.payee_pub_key());
502 node.add_allowlist(&[allowable]).unwrap();
503 assert!(approver.handle_proposed_invoice(&node, invoice).unwrap());
504 }
505
506 #[test]
507 fn test_invoice_velocity_approver_positive() {
508 let delegate = PositiveApprover();
509 let clock = Arc::new(ManualClock::new(Duration::ZERO));
510 let spec = VelocityControlSpec { limit_msat: 1_000_000, interval_type: Hourly };
511 let control = VelocityControl::new(spec);
512 let approver = VelocityApprover::new(clock.clone(), control, delegate);
513 let amt = 600_000_u64;
514 let invoice = make_test_invoice(1, amt);
515 let success = approver.approve_invoice(&invoice);
516 assert!(success);
517 assert_eq!(approver.control.lock().unwrap().velocity(), amt);
518
519 let invoice = make_test_invoice(2, amt);
520 let success = approver.approve_invoice(&invoice);
521 assert!(success);
522 assert_eq!(approver.control.lock().unwrap().velocity(), 0);
524 }
525
526 #[test]
527 fn test_keysend_velocity_approver_negative() {
528 let delegate = NegativeApprover();
529 let clock = Arc::new(ManualClock::new(Duration::ZERO));
530 let spec = VelocityControlSpec { limit_msat: 1000, interval_type: Hourly };
531 let control = VelocityControl::new(spec);
532 let approver = VelocityApprover::new(clock.clone(), control, delegate);
533 let (payment_hash, payment_state) = make_keysend_payment(1, clock.now());
534 let success = approver.approve_keysend(payment_hash, payment_state.amount_msat);
535 assert!(success);
536
537 let (payment_hash, payment_state) = make_keysend_payment(2, clock.now());
538 let success = approver.approve_keysend(payment_hash, payment_state.amount_msat);
539 assert!(!success);
540 assert_eq!(approver.control.lock().unwrap().velocity(), 600);
541 }
542
543 #[test]
544 fn test_keysend_velocity_approver_positive() {
545 let delegate = PositiveApprover();
546 let clock = Arc::new(ManualClock::new(Duration::ZERO));
547 let spec = VelocityControlSpec { limit_msat: 1000, interval_type: Hourly };
548 let control = VelocityControl::new(spec);
549 let approver = VelocityApprover::new(clock.clone(), control, delegate);
550 let (payment_hash, payment_state) = make_keysend_payment(1, clock.now());
551 let success = approver.approve_keysend(payment_hash, payment_state.amount_msat);
552 assert!(success);
553 assert_eq!(approver.control.lock().unwrap().velocity(), 600);
554
555 let (payment_hash, payment_state) = make_keysend_payment(2, clock.now());
556 let success = approver.approve_keysend(payment_hash, payment_state.amount_msat);
557 assert!(success);
558 assert_eq!(approver.control.lock().unwrap().velocity(), 0);
560 }
561
562 fn make_keysend_payment(x: u8, now: Duration) -> (PaymentHash, PaymentState) {
563 let payee = PublicKey::from_slice(&[2u8; 33]).unwrap();
564 let payment_hash = PaymentHash([x; 32]);
565 let (payment_state, _invoice_hash) =
566 Node::payment_state_from_keysend(payee, payment_hash, 600, now).unwrap();
567 (payment_hash, payment_state)
568 }
569
570 #[test]
571 fn test_invoice_approver_with_warning() {
572 let approver = WarningPositiveApprover();
573 let amt = 600_000_u64;
574 let invoice = make_test_invoice(1, amt);
575 let success = approver.approve_invoice(&invoice);
576 assert!(success);
577 }
578
579 #[test]
580 fn test_keysend_approver_with_warning() {
581 let clock = Arc::new(ManualClock::new(Duration::ZERO));
582 let approver = WarningPositiveApprover();
583 let (payment_hash, payment_state) = make_keysend_payment(1, clock.now());
584 let success = approver.approve_keysend(payment_hash, payment_state.amount_msat);
585 assert!(success);
586 }
587}