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