1use amplify::{DumbDefault, Slice32, Wrapper};
15use bitcoin::blockdata::opcodes::all::*;
16use bitcoin::blockdata::script;
17use bitcoin::hashes::{sha256, Hash, HashEngine};
18use bitcoin::secp256k1::PublicKey;
19use bitcoin::{Network, TxOut};
20use bitcoin_scripts::hlc::HashLock;
21use bitcoin_scripts::{LockScript, PubkeyScript, WitnessScript};
22use internet2::addr::NodeId;
23use internet2::presentation::sphinx::{self, Hop, Onion, OnionPacket};
24use lnp2p::bolt::{
25 AcceptChannel, ActiveChannelId, ChannelId, Messages, OpenChannel,
26 TempChannelId,
27};
28use lnpbp::chain::Chain;
29use p2p::bolt::{
30 ChannelReestablish, FundingLocked, PaymentOnion, UpdateAddHtlc,
31};
32use secp256k1::ecdsa::Signature;
33use secp256k1::Secp256k1;
34use strict_encoding::StrictDecode;
35use wallet::lex_order::LexOrder;
36use wallet::psbt;
37use wallet::psbt::Psbt;
38
39use super::keyset::{LocalKeyset, LocalPubkey, RemoteKeyset};
40use super::policy::{CommonParams, PeerParams, Policy};
41use super::{AnchorOutputs, BoltExt, ChannelState, Lifecycle};
42use crate::channel::bolt::util::UpdateReq;
43use crate::channel::bolt::PolicyError;
44use crate::channel::funding::{self, Funding, PsbtLnpFunding};
45use crate::channel::tx_graph::TxGraph;
46use crate::extension::ChannelConstructor;
47use crate::router::gossip::LocalChannelInfo;
48use crate::{Channel, ChannelExtension, Extension};
49
50#[derive(Clone, PartialEq, Eq, Hash, Debug, Display, Error, From)]
53#[display(doc_comments)]
54pub enum Error {
55 #[from]
57 Funding(funding::Error),
58
59 #[display(inner)]
61 #[from]
62 ChannelReestablish(ReestablishError),
63
64 #[from]
66 Route(sphinx::EncodeError),
67
68 #[display(inner)]
71 Htlc(String),
72
73 #[from]
75 #[display(inner)]
76 Policy(PolicyError),
77
78 #[display(doc_comments)]
81 LifecycleMismatch {
82 current: Lifecycle,
83 required: &'static [Lifecycle],
84 },
85
86 NoChanelId,
88
89 NoTemporaryId,
92}
93
94#[derive(
96 Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error
97)]
98#[display(doc_comments)]
99pub enum ReestablishError {
100 NoPermanentId,
104
105 ChannelIdMismatch { remote: ChannelId, local: ChannelId },
108}
109
110#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
112#[derive(StrictEncode, StrictDecode)]
113#[cfg_attr(
114 feature = "serde",
115 derive(Serialize, Deserialize),
116 serde(crate = "serde_crate")
117)]
118pub enum Direction {
119 #[display("inbound")]
123 Inbound,
124
125 #[display("outbound")]
129 Outbount,
130}
131
132impl Direction {
133 #[inline]
135 pub fn is_inbound(self) -> bool {
136 self == Direction::Inbound
137 }
138
139 #[inline]
141 pub fn is_outbound(self) -> bool {
142 self == Direction::Outbount
143 }
144}
145
146impl Channel<BoltExt> {
147 pub fn with(
152 temp_channel_id: TempChannelId,
153 chain_hash: Slice32,
154 policy: Policy,
155 common_params: CommonParams,
156 local_params: PeerParams,
157 mut local_keys: LocalKeyset,
158 ) -> Self {
159 let mut channel = Self::default();
160
161 let channel_type = common_params.channel_type;
162 if channel_type.has_static_remotekey() {
163 local_keys.static_remotekey = true;
164 }
165 if channel_type.has_anchor_outputs() {
166 channel.add_extender(AnchorOutputs::new());
167 }
168
169 let core = channel.constructor_mut();
170 core.set_temp_channel_id(temp_channel_id);
171 core.set_chain_hash(chain_hash);
172 core.set_policy(policy);
173 core.set_common_params(common_params);
174 core.set_local_params(local_params);
175 core.set_local_keys(local_keys);
176
177 channel
178 }
179
180 #[inline]
185 pub fn set_policy(&mut self, policy: Policy) {
186 self.constructor_mut().set_policy(policy)
187 }
188
189 #[inline]
195 pub fn set_common_params(&mut self, params: CommonParams) {
196 self.constructor_mut().set_common_params(params)
197 }
198
199 #[inline]
205 pub fn set_local_params(&mut self, params: PeerParams) {
206 self.constructor_mut().set_local_params(params)
207 }
208
209 #[inline]
211 pub fn active_channel_id(&self) -> ActiveChannelId {
212 self.constructor().active_channel_id()
213 }
214
215 #[inline]
217 pub fn channel_id(&self) -> Option<ChannelId> {
218 self.active_channel_id().channel_id()
219 }
220
221 #[inline]
224 pub fn try_channel_id(&self) -> Result<ChannelId, Error> {
225 self.channel_id().ok_or(Error::NoChanelId)
226 }
227
228 #[inline]
231 pub fn temp_channel_id(&self) -> Option<TempChannelId> {
232 self.active_channel_id().temp_channel_id()
233 }
234
235 pub fn compose_open_channel(
244 &mut self,
245 funding_sat: u64,
246 push_msat: u64,
247 policy: Policy,
248 common_params: CommonParams,
249 local_params: PeerParams,
250 local_keys: LocalKeyset,
251 ) -> Result<OpenChannel, Error> {
252 self.set_funding_amount(funding_sat);
253 self.constructor_mut().compose_open_channel(
254 funding_sat,
255 push_msat,
256 policy,
257 common_params,
258 local_params,
259 local_keys,
260 )
261 }
262
263 pub fn compose_accept_channel(&mut self) -> Result<AcceptChannel, Error> {
272 self.constructor_mut().compose_accept_channel()
273 }
274
275 #[inline]
276 pub fn compose_funding_locked(&mut self) -> FundingLocked {
277 self.constructor_mut().compose_funding_locked()
278 }
279
280 pub fn compose_reestablish_channel(
281 &mut self,
282 remote_channel_reestablish: &ChannelReestablish,
283 ) -> Result<ChannelReestablish, Error> {
284 self.constructor_mut()
285 .compose_reestablish_channel(remote_channel_reestablish)
286 .map_err(Error::from)
287 }
288
289 pub fn compose_add_update_htlc(
290 &mut self,
291 amount_msat: u64,
292 payment_hash: HashLock,
293 cltv_expiry: u32,
294 route: Vec<Hop<PaymentOnion>>,
295 ) -> Result<Messages, Error> {
296 self.constructor_mut().compose_add_update_htlc(
297 amount_msat,
298 payment_hash,
299 cltv_expiry,
300 route,
301 )
302 }
303
304 #[inline]
305 pub fn chain_hash(&self) -> Slice32 {
306 self.constructor().chain_hash()
307 }
308
309 #[inline]
312 pub fn network(&self) -> Option<Network> {
313 let chain_hash = self.constructor().chain_hash();
314 for chain in Chain::all_standard() {
315 if chain.as_genesis_hash().as_inner() == chain_hash.as_inner() {
316 return Network::try_from(chain).ok();
317 }
318 }
319 None
320 }
321
322 pub fn channel_info(&self, remote_node: NodeId) -> LocalChannelInfo {
323 LocalChannelInfo {
325 remote_node,
326 channel_id: self
327 .channel_id()
328 .expect("channel id must be known at this stage"),
329 short_channel_id: Default::default(),
330 chain_hash: self.chain_hash(),
331 inbound_capacity_msat: self.remote_amount_msat(),
332 outbound_capacity_msat: self.local_amount_msat(),
333 cltv_expiry: 0,
334 htlc_minimum_msat: self
335 .constructor()
336 .local_params()
337 .htlc_minimum_msat,
338 htlc_maximum_msat: 0,
339 }
340 }
341
342 #[inline]
343 pub fn funding_pubkey(&self) -> PublicKey {
344 self.constructor().local_keys().funding_pubkey.key
345 }
346
347 #[inline]
348 pub fn funding_script_pubkey(&self) -> PubkeyScript {
349 let funding = self.funding();
350 let core = self.constructor();
351 PubkeyScript::ln_funding(
352 funding.amount(),
353 &core.local_keys().funding_pubkey,
354 core.remote_keys().funding_pubkey,
355 )
356 }
357
358 #[inline]
359 pub fn feerate_per_kw(&self) -> u32 {
360 let core = self.constructor();
361 core.common_params().feerate_per_kw
362 }
363
364 #[inline]
365 pub fn local_amount_msat(&self) -> u64 {
366 self.constructor().local_amount_msat()
367 }
368
369 #[inline]
370 pub fn remote_amount_msat(&self) -> u64 {
371 self.constructor().remote_amount_msat()
372 }
373}
374
375#[derive(Getters, Clone, PartialEq, Eq, Debug, StrictEncode, StrictDecode)]
382#[getter(as_copy)]
383pub struct BoltChannel {
385 #[getter(as_copy)]
387 stage: Lifecycle,
388
389 #[getter(as_copy)]
398 chain_hash: Slice32,
399
400 #[getter(as_copy)]
407 active_channel_id: ActiveChannelId,
408
409 #[getter(as_copy)]
411 local_amount_msat: u64,
412
413 #[getter(as_copy)]
415 remote_amount_msat: u64,
416
417 #[getter(as_copy)]
418 commitment_number: u64,
419
420 commitment_sigs: Vec<Signature>,
421
422 #[getter(as_ref)]
424 policy: Policy,
425
426 #[getter(as_copy)]
428 common_params: CommonParams,
429
430 #[getter(as_copy)]
433 local_params: PeerParams,
434
435 #[getter(as_copy)]
437 remote_params: PeerParams,
438
439 local_keys: LocalKeyset,
441
442 remote_keys: RemoteKeyset,
444
445 remote_per_commitment_point: PublicKey,
446
447 local_per_commitment_point: PublicKey,
448
449 #[getter(as_copy)]
451 direction: Direction,
452}
453
454impl Default for BoltChannel {
455 fn default() -> Self {
456 let direction = Direction::Outbount;
457 let dumb_keys = RemoteKeyset::dumb_default();
458 BoltChannel {
459 stage: Lifecycle::Initial,
460 chain_hash: default!(),
461 active_channel_id: ActiveChannelId::random(),
462 local_amount_msat: 0,
463 remote_amount_msat: 0,
464 commitment_number: 0,
465 commitment_sigs: vec![],
466 policy: default!(),
467 common_params: default!(),
468 local_params: default!(),
469 remote_params: default!(),
470 local_keys: LocalKeyset::dumb_default(),
471 remote_keys: dumb_keys,
472 remote_per_commitment_point: dumb_pubkey!(),
473 local_per_commitment_point: dumb_pubkey!(),
474 direction,
475 }
476 }
477}
478
479impl BoltChannel {
480 #[inline]
482 pub fn channel_id(&self) -> Option<ChannelId> {
483 self.active_channel_id.channel_id()
484 }
485
486 #[inline]
489 pub fn temp_channel_id(&self) -> Option<TempChannelId> {
490 self.active_channel_id.temp_channel_id()
491 }
492
493 #[inline]
496 pub fn try_channel_id(&self) -> Result<ChannelId, Error> {
497 self.channel_id().ok_or(Error::NoChanelId)
498 }
499
500 #[inline]
502 pub fn set_temp_channel_id(&mut self, temp_channel_id: TempChannelId) {
503 self.active_channel_id = ActiveChannelId::Temporary(temp_channel_id)
504 }
505
506 #[inline]
508 pub fn set_inbound(&mut self) {
509 self.direction = Direction::Inbound;
510 }
511
512 #[inline]
514 pub fn set_outbound(&mut self) {
515 self.direction = Direction::Outbount;
516 }
517
518 #[inline]
520 pub fn set_chain_hash(&mut self, chain_hash: Slice32) {
521 self.chain_hash = chain_hash
522 }
523
524 #[inline]
526 pub fn set_policy(&mut self, policy: Policy) {
527 self.policy = policy
528 }
529
530 #[inline]
532 pub fn set_common_params(&mut self, params: CommonParams) {
533 self.common_params = params
534 }
535
536 #[inline]
538 pub fn set_local_params(&mut self, params: PeerParams) {
539 self.local_params = params
540 }
541
542 #[inline]
544 pub fn set_local_keys(&mut self, keys: LocalKeyset) {
545 self.local_keys = keys
546 }
547
548 #[inline]
550 pub fn set_static_remotekey(&mut self, static_remotekey: bool) {
551 self.local_keys.static_remotekey = static_remotekey
552 }
553}
554
555impl Extension<BoltExt> for BoltChannel {
556 fn identity(&self) -> BoltExt {
557 BoltExt::Bolt3
558 }
559
560 fn update_from_local(&mut self, _message: &()) -> Result<(), Error> {
561 Ok(())
563 }
564
565 fn update_from_peer(&mut self, message: &Messages) -> Result<(), Error> {
566 match message {
568 Messages::OpenChannel(open_channel) => {
569 self.stage = Lifecycle::Proposed;
570
571 self.direction = Direction::Inbound;
572 self.active_channel_id =
573 ActiveChannelId::from(open_channel.temporary_channel_id);
574 self.remote_amount_msat = open_channel.funding_satoshis * 1000
575 - open_channel.push_msat;
576 self.local_amount_msat = open_channel.push_msat;
577
578 self.remote_params =
580 self.policy.validate_inbound(open_channel)?;
581
582 self.remote_keys.funding_pubkey = open_channel.funding_pubkey;
596 self.remote_keys.payment_basepoint = open_channel.payment_point;
597 self.remote_keys.revocation_basepoint =
598 open_channel.revocation_basepoint;
599 self.remote_keys.delayed_payment_basepoint =
600 open_channel.delayed_payment_basepoint;
601 self.remote_keys.first_per_commitment_point =
602 open_channel.first_per_commitment_point;
603 self.remote_per_commitment_point =
604 open_channel.first_per_commitment_point;
605 }
606 Messages::AcceptChannel(accept_channel) => {
607 self.stage = Lifecycle::Accepted;
608
609 self.remote_params = self
610 .policy
611 .confirm_outbound(self.local_params, accept_channel)?;
612
613 self.remote_keys.funding_pubkey = accept_channel.funding_pubkey;
624 self.remote_keys.payment_basepoint =
625 accept_channel.payment_point;
626 self.remote_keys.revocation_basepoint =
627 accept_channel.revocation_basepoint;
628 self.remote_keys.delayed_payment_basepoint =
629 accept_channel.delayed_payment_basepoint;
630 self.remote_keys.first_per_commitment_point =
631 accept_channel.first_per_commitment_point;
632 self.remote_per_commitment_point =
633 accept_channel.first_per_commitment_point;
634 }
635 Messages::FundingCreated(funding_created) => {
636 self.stage = Lifecycle::Funding;
637
638 self.active_channel_id = ActiveChannelId::with(
639 funding_created.funding_txid,
640 funding_created.funding_output_index,
641 );
642 }
643 Messages::FundingSigned(funding_signed) => {
644 self.stage = Lifecycle::Funded;
645
646 self.active_channel_id =
647 ActiveChannelId::from(funding_signed.channel_id);
648 self.commitment_sigs.push(funding_signed.signature);
649 }
651 Messages::FundingLocked(funding_locked) => {
652 self.stage = Lifecycle::Locked; self.remote_per_commitment_point =
654 funding_locked.next_per_commitment_point;
655 }
656 Messages::Shutdown(_) => {}
657 Messages::ClosingSigned(_) => {}
658 Messages::UpdateAddHtlc(_message) => {
659 }
669 Messages::UpdateFulfillHtlc(_) => {}
670 Messages::UpdateFailHtlc(_) => {}
671 Messages::UpdateFailMalformedHtlc(_) => {}
672 Messages::CommitmentSigned(_) => {}
673 Messages::RevokeAndAck(_) => {}
674 Messages::ChannelReestablish(_) => {}
675 _ => {}
676 }
677 Ok(())
678 }
679
680 fn load_state(&mut self, state: &ChannelState) {
681 self.stage = state.stage;
682 self.chain_hash = state.chain_hash;
683 self.active_channel_id = state.active_channel_id;
684 self.local_amount_msat = state.local_amount_msat;
685 self.remote_amount_msat = state.remote_amount_msat;
686 self.commitment_number = state.commitment_number;
687 self.commitment_sigs = state.commitment_sigs.clone();
688 self.policy = state.policy.clone();
689 self.common_params = state.common_params;
690 self.local_params = state.local_params;
691 self.remote_params = state.remote_params;
692 self.local_keys = state.local_keys.clone();
693 self.remote_keys = state.remote_keys.clone();
694 self.remote_per_commitment_point = state.remote_per_commitment_point;
695 self.local_per_commitment_point = state.local_per_commitment_point;
696 self.direction = state.direction;
697 }
698
699 fn store_state(&self, state: &mut ChannelState) {
700 state.stage = self.stage;
701 state.chain_hash = self.chain_hash;
702 state.active_channel_id = self.active_channel_id;
703 state.local_amount_msat = self.local_amount_msat;
704 state.remote_amount_msat = self.remote_amount_msat;
705 state.commitment_number = self.commitment_number;
706 state.commitment_sigs = self.commitment_sigs.clone();
707 state.policy = self.policy.clone();
708 state.common_params = self.common_params;
709 state.local_params = self.local_params;
710 state.remote_params = self.remote_params;
711 state.local_keys = self.local_keys.clone();
712 state.remote_keys = self.remote_keys.clone();
713 state.remote_per_commitment_point = self.remote_per_commitment_point;
714 state.local_per_commitment_point = self.local_per_commitment_point;
715 state.direction = self.direction;
716 }
717}
718
719impl BoltChannel {
720 fn commitment_fee(&self) -> u64 {
721 724 * self.common_params.feerate_per_kw as u64 / 1000
722 }
723
724 fn obscured_commitment_number(&self) -> u64 {
725 const LOWER_48_BITS: u64 = 0x00_00_FF_FF_FF_FF_FF_FF;
726
727 let mut engine = sha256::Hash::engine();
728 if self.direction.is_inbound() {
729 engine.input(&self.remote_keys.payment_basepoint.serialize());
730 engine.input(&self.local_keys.payment_basepoint.key.serialize());
731 } else {
732 engine.input(&self.local_keys.payment_basepoint.key.serialize());
733 engine.input(&self.remote_keys.payment_basepoint.serialize());
734 }
735 let obscuring_hash = sha256::Hash::from_engine(engine);
736
737 let mut buf = [0u8; 8];
738 buf.copy_from_slice(&obscuring_hash[24..]);
739 let obscuring_factor = u64::from_be_bytes(buf) & LOWER_48_BITS;
740
741 (self.commitment_number & LOWER_48_BITS) ^ obscuring_factor
744 }
745
746 fn compose_open_channel(
747 &mut self,
748 funding_sat: u64,
749 push_msat: u64,
750 policy: Policy,
751 common_params: CommonParams,
752 local_params: PeerParams,
753 local_keyset: LocalKeyset,
754 ) -> Result<OpenChannel, Error> {
755 if self.stage != Lifecycle::Initial
756 && self.stage != Lifecycle::Reestablishing
757 {
758 return Err(Error::LifecycleMismatch {
759 current: self.stage,
760 required: &[Lifecycle::Initial, Lifecycle::Reestablishing],
761 });
762 }
763
764 self.direction = Direction::Outbount;
765 self.policy = policy;
766 self.common_params = common_params;
767 self.local_params = local_params;
768 self.local_keys = local_keyset.clone();
769 self.local_amount_msat = funding_sat * 1000 - push_msat;
770 self.remote_amount_msat = push_msat;
771 self.local_per_commitment_point =
772 local_keyset.first_per_commitment_point.key;
773
774 Ok(OpenChannel {
775 chain_hash: self.chain_hash(),
776 temporary_channel_id: self.temp_channel_id().expect(
777 "initial channel state must always have a temporary channel id",
778 ),
779 funding_satoshis: funding_sat,
780 push_msat,
781 dust_limit_satoshis: local_params.dust_limit_satoshis,
782 max_htlc_value_in_flight_msat: local_params
783 .max_htlc_value_in_flight_msat,
784 channel_reserve_satoshis: local_params.channel_reserve_satoshis,
785 htlc_minimum_msat: local_params.htlc_minimum_msat,
786 feerate_per_kw: common_params.feerate_per_kw,
787 to_self_delay: local_params.to_self_delay,
788 max_accepted_htlcs: local_params.max_accepted_htlcs,
789 funding_pubkey: local_keyset.funding_pubkey.key,
790 revocation_basepoint: local_keyset.revocation_basepoint.key,
791 payment_point: local_keyset.payment_basepoint.key,
792 delayed_payment_basepoint: local_keyset
793 .delayed_payment_basepoint
794 .key,
795 htlc_basepoint: local_keyset.htlc_basepoint.key,
796 first_per_commitment_point: self.local_per_commitment_point,
797 shutdown_scriptpubkey: local_keyset.shutdown_scriptpubkey,
798 channel_flags: u8::from(common_params.announce_channel),
799 channel_type: common_params.channel_type.into_option(),
800 unknown_tlvs: none!(),
801 })
802 }
803
804 fn compose_accept_channel(&mut self) -> Result<AcceptChannel, Error> {
805 if self.stage != Lifecycle::Initial
806 && self.stage != Lifecycle::Proposed
807 && self.stage != Lifecycle::Reestablishing
808 {
809 return Err(Error::LifecycleMismatch {
810 current: self.stage,
811 required: &[
812 Lifecycle::Initial,
813 Lifecycle::Proposed,
814 Lifecycle::Reestablishing,
815 ],
816 });
817 }
818
819 Ok(AcceptChannel {
820 temporary_channel_id: self.temp_channel_id().expect(
821 "initial channel state must always have a temporary channel id",
822 ),
823 dust_limit_satoshis: self.local_params.dust_limit_satoshis,
824 max_htlc_value_in_flight_msat: self
825 .local_params
826 .max_htlc_value_in_flight_msat,
827 channel_reserve_satoshis: self
828 .local_params
829 .channel_reserve_satoshis,
830 htlc_minimum_msat: self.local_params.htlc_minimum_msat,
831 minimum_depth: self.policy.minimum_depth,
832 to_self_delay: self.local_params.to_self_delay,
833 max_accepted_htlcs: self.local_params.max_accepted_htlcs,
834 funding_pubkey: self.local_keys.funding_pubkey.key,
835 revocation_basepoint: self.local_keys.revocation_basepoint.key,
836 payment_point: self.local_keys.payment_basepoint.key,
837 delayed_payment_basepoint: self
838 .local_keys
839 .delayed_payment_basepoint
840 .key,
841 htlc_basepoint: self.local_keys.htlc_basepoint.key,
842 first_per_commitment_point: self
843 .local_keys
844 .first_per_commitment_point
845 .key,
846 shutdown_scriptpubkey: self
847 .local_keys
848 .shutdown_scriptpubkey
849 .clone(),
850 channel_type: self.common_params.channel_type.into_option(),
851 unknown_tlvs: none!(),
852 })
853 }
854
855 fn compose_reestablish_channel(
856 &mut self,
857 remote_channel_reestablish: &ChannelReestablish,
858 ) -> Result<ChannelReestablish, ReestablishError> {
859 let channel_id = if let Some(channel_id) = self.channel_id() {
860 channel_id
861 } else {
862 return Err(ReestablishError::NoPermanentId);
863 };
864
865 if remote_channel_reestablish.channel_id != channel_id {
866 return Err(ReestablishError::ChannelIdMismatch {
867 remote: remote_channel_reestablish.channel_id,
868 local: channel_id,
869 });
870 }
871
872 Ok(ChannelReestablish {
875 channel_id,
876 next_commitment_number: remote_channel_reestablish
877 .next_commitment_number,
878 next_revocation_number: remote_channel_reestablish
879 .next_revocation_number,
880 your_last_per_commitment_secret: Slice32::default(),
882 my_current_per_commitment_point: self.local_per_commitment_point,
883 })
884 }
885
886 fn compose_funding_locked(&mut self) -> FundingLocked {
887 FundingLocked {
888 channel_id: self
889 .active_channel_id
890 .channel_id()
891 .expect("channel id must be known at FUNDING_LOCKED stage"),
892 next_per_commitment_point: self.next_per_commitment_point(),
893 }
894 }
895
896 pub fn compose_add_update_htlc(
897 &mut self,
898 amount_msat: u64,
899 payment_hash: HashLock,
900 cltv_expiry: u32,
901 route: Vec<Hop<PaymentOnion>>,
902 ) -> Result<Messages, Error> {
903 let secp = Secp256k1::new();
905 let onion_packet =
906 OnionPacket::with(&secp, &route, payment_hash.as_ref())?;
907 let mut message = Messages::UpdateAddHtlc(UpdateAddHtlc {
908 channel_id: self.try_channel_id()?,
909 htlc_id: 0,
910 amount_msat,
911 payment_hash,
912 cltv_expiry,
913 onion_routing_packet: Onion::Onion(onion_packet),
914 unknown_tlvs: none!(),
915 });
916 self.state_change(&UpdateReq::PayBolt(route), &mut message)?;
917 Ok(message)
918 }
919
920 fn next_per_commitment_point(&mut self) -> PublicKey {
921 self.local_per_commitment_point
923 }
924
925 fn remote_paymentpubkey(&self, as_remote_node: bool) -> PublicKey {
926 let secp = Secp256k1::verification_only();
928
929 let per_commitment_point = if as_remote_node {
930 self.remote_per_commitment_point
931 } else {
932 self.local_per_commitment_point
933 };
934 let payment_basepoint = if as_remote_node {
935 self.local_keys.payment_basepoint.key
936 } else {
937 self.remote_keys.payment_basepoint
938 };
939
940 let mut engine = sha256::Hash::engine();
941 engine.input(&per_commitment_point.serialize());
942 engine.input(&payment_basepoint.serialize());
943 let tweak = sha256::Hash::from_engine(engine);
944 let tweak = secp256k1::Scalar::from_be_bytes(tweak.into_inner())
945 .expect("negligible probability");
946
947 let payment_pubkey = payment_basepoint;
948 payment_pubkey
949 .add_exp_tweak(&secp, &tweak)
950 .expect("negligible probability")
951 }
952
953 fn local_delayedpubkey(&self, as_remote_node: bool) -> PublicKey {
954 let secp = Secp256k1::verification_only();
956
957 let per_commitment_point = if as_remote_node {
958 self.local_per_commitment_point
959 } else {
960 self.remote_per_commitment_point
961 };
962 let delayed_payment_basepoint = if as_remote_node {
963 self.remote_keys.delayed_payment_basepoint
964 } else {
965 self.local_keys.delayed_payment_basepoint.key
966 };
967
968 let mut engine = sha256::Hash::engine();
969 engine.input(&per_commitment_point.serialize());
970 engine.input(&delayed_payment_basepoint.serialize());
971 let tweak = sha256::Hash::from_engine(engine);
972 let tweak = secp256k1::Scalar::from_be_bytes(tweak.into_inner())
973 .expect("negligible probability");
974
975 let delayed_pubkey = delayed_payment_basepoint;
976 delayed_pubkey
977 .add_exp_tweak(&secp, &tweak)
978 .expect("negligible probability")
979 }
980
981 fn remote_revocationpubkey(&self, as_remote_node: bool) -> PublicKey {
982 let secp = Secp256k1::verification_only();
984
985 let revocation_basepoint = if as_remote_node {
986 self.local_keys.revocation_basepoint.key
987 } else {
988 self.remote_keys.revocation_basepoint
989 };
990 let per_commitment_point = if as_remote_node {
991 self.remote_per_commitment_point
992 } else {
993 self.local_per_commitment_point
994 };
995
996 let mut tweaked_revocation_basepoint = revocation_basepoint;
997 let mut engine = sha256::Hash::engine();
998 engine.input(&revocation_basepoint.serialize());
999 engine.input(&per_commitment_point.serialize());
1000 let revocation_tweak = sha256::Hash::from_engine(engine);
1001 let revocation_tweak =
1002 secp256k1::Scalar::from_be_bytes(revocation_tweak.into_inner())
1003 .expect("negligible probability");
1004 tweaked_revocation_basepoint = tweaked_revocation_basepoint
1005 .mul_tweak(&secp, &revocation_tweak)
1006 .expect("negligible probability");
1007
1008 let mut tweaked_per_commitment_point = self.remote_per_commitment_point;
1009 let mut engine = sha256::Hash::engine();
1010 engine.input(&per_commitment_point.serialize());
1011 engine.input(&revocation_basepoint.serialize());
1012 let per_commitment_tweak = sha256::Hash::from_engine(engine);
1013 let per_commitment_tweak =
1014 secp256k1::Scalar::from_be_bytes(per_commitment_tweak.into_inner())
1015 .expect("negligible probability");
1016 tweaked_per_commitment_point = tweaked_per_commitment_point
1017 .mul_tweak(&secp, &per_commitment_tweak)
1018 .expect("negligible probability");
1019
1020 tweaked_revocation_basepoint
1021 .combine(&tweaked_per_commitment_point)
1022 .expect("negligible probability")
1023 }
1024}
1025
1026impl ChannelExtension<BoltExt> for BoltChannel {
1027 #[inline]
1028 fn new() -> Box<dyn ChannelExtension<BoltExt>> {
1029 Box::default() as Box<BoltChannel>
1030 }
1031
1032 fn build_graph(
1033 &self,
1034 tx_graph: &mut TxGraph,
1035 as_remote_node: bool,
1036 ) -> Result<(), Error> {
1037 let obscured_commitment = self.obscured_commitment_number();
1038 let lock_time =
1039 (0x20u32 << 24) | (obscured_commitment as u32 & 0x00_FF_FF_FF);
1040 let sequence = (0x80u32 << 24) | (obscured_commitment >> 24) as u32;
1041
1042 let fee = self.commitment_fee();
1043 let (to_remote_fee, to_local_fee) =
1044 if self.direction == Direction::Outbount {
1045 (fee, 0)
1046 } else {
1047 (0, fee)
1048 };
1049
1050 tx_graph.cmt_version = 2;
1051 tx_graph.cmt_locktime = lock_time;
1052 tx_graph.cmt_sequence = sequence;
1053 tx_graph.cmt_outs = Vec::with_capacity(2);
1055
1056 let to_local_amount = if as_remote_node {
1057 self.remote_amount_msat
1058 } else {
1059 self.local_amount_msat
1060 };
1061 let to_remote_amount = if as_remote_node {
1062 self.local_amount_msat
1063 } else {
1064 self.remote_amount_msat
1065 };
1066 let to_self_delay = if as_remote_node {
1067 self.remote_params.to_self_delay
1068 } else {
1069 self.local_params.to_self_delay
1070 };
1071 if to_local_amount > 0 {
1072 tx_graph.cmt_outs.push(ScriptGenerators::ln_to_local(
1073 to_local_amount / 1000 - to_local_fee,
1074 self.remote_revocationpubkey(as_remote_node),
1075 self.local_delayedpubkey(as_remote_node),
1076 to_self_delay,
1077 ));
1078 }
1079 if to_remote_amount > 0 {
1080 tx_graph.cmt_outs.push(ScriptGenerators::ln_to_remote_v1(
1081 to_remote_amount / 1000 - to_remote_fee,
1082 self.remote_paymentpubkey(as_remote_node),
1083 ));
1084 }
1085
1086 Ok(())
1087 }
1088}
1089
1090impl ChannelConstructor<BoltExt> for BoltChannel {
1091 fn enrich_funding(
1092 &self,
1093 psbt: &mut Psbt,
1094 funding: &Funding,
1095 ) -> Result<(), Error> {
1096 let vout = psbt
1097 .channel_funding_output()
1098 .ok_or(funding::Error::NoFundingOutput)?;
1099 psbt.outputs[vout].witness_script = Some(WitnessScript::ln_funding(
1100 funding.amount(),
1101 &self.local_keys.funding_pubkey,
1102 self.remote_keys.funding_pubkey,
1103 ));
1104 psbt.outputs[vout].bip32_derivation =
1105 self.local_keys.funding_pubkey.to_bip32_derivation_map();
1106 Ok(())
1107 }
1108}
1109
1110pub trait ScriptGenerators {
1111 fn ln_funding(
1112 amount: u64,
1113 local_pubkey: &LocalPubkey,
1114 remote_pubkey: PublicKey,
1115 ) -> Self;
1116
1117 fn ln_to_local(
1121 amount: u64,
1122 revocationpubkey: PublicKey,
1123 local_delayedpubkey: PublicKey,
1124 to_self_delay: u16,
1125 ) -> Self;
1126
1127 fn ln_to_remote_v1(amount: u64, remote_pubkey: PublicKey) -> Self;
1131
1132 fn ln_to_remote_v2(amount: u64, remote_pubkey: PublicKey) -> Self;
1136}
1137
1138impl ScriptGenerators for LockScript {
1139 fn ln_funding(
1140 _: u64,
1141 local_pubkey: &LocalPubkey,
1142 remote_pubkey: PublicKey,
1143 ) -> Self {
1144 let pk = vec![
1145 local_pubkey.to_bitcoin_pk(),
1146 bitcoin::PublicKey::new(remote_pubkey),
1147 ]
1148 .lex_ordered();
1149
1150 script::Builder::new()
1151 .push_int(2)
1152 .push_key(&pk[0])
1153 .push_key(&pk[1])
1154 .push_int(2)
1155 .push_opcode(OP_CHECKMULTISIG)
1156 .into_script()
1157 .into()
1158 }
1159
1160 fn ln_to_local(
1161 _: u64,
1162 revocationpubkey: PublicKey,
1163 local_delayedpubkey: PublicKey,
1164 to_self_delay: u16,
1165 ) -> Self {
1166 script::Builder::new()
1167 .push_opcode(OP_IF)
1168 .push_key(&bitcoin::PublicKey::new(revocationpubkey))
1169 .push_opcode(OP_ELSE)
1170 .push_int(to_self_delay as i64)
1171 .push_opcode(OP_CSV)
1172 .push_opcode(OP_DROP)
1173 .push_key(&bitcoin::PublicKey::new(local_delayedpubkey))
1174 .push_opcode(OP_ENDIF)
1175 .push_opcode(OP_CHECKSIG)
1176 .into_script()
1177 .into()
1178 }
1179
1180 fn ln_to_remote_v1(_: u64, _: PublicKey) -> Self {
1181 unimplemented!("LockScript can't be generated for to_remote v1 output")
1182 }
1183
1184 fn ln_to_remote_v2(_: u64, remote_pubkey: PublicKey) -> Self {
1185 script::Builder::new()
1186 .push_key(&bitcoin::PublicKey::new(remote_pubkey))
1187 .push_opcode(OP_CHECKSIGVERIFY)
1188 .push_int(1)
1189 .push_opcode(OP_CSV)
1190 .into_script()
1191 .into()
1192 }
1193}
1194
1195impl ScriptGenerators for WitnessScript {
1196 #[inline]
1197 fn ln_funding(
1198 amount: u64,
1199 local_pubkey: &LocalPubkey,
1200 remote_pubkey: PublicKey,
1201 ) -> Self {
1202 LockScript::ln_funding(amount, local_pubkey, remote_pubkey).into()
1203 }
1204
1205 #[inline]
1206 fn ln_to_local(
1207 amount: u64,
1208 revocationpubkey: PublicKey,
1209 local_delayedpubkey: PublicKey,
1210 to_self_delay: u16,
1211 ) -> Self {
1212 LockScript::ln_to_local(
1213 amount,
1214 revocationpubkey,
1215 local_delayedpubkey,
1216 to_self_delay,
1217 )
1218 .into()
1219 }
1220
1221 #[inline]
1222 fn ln_to_remote_v1(_: u64, _: PublicKey) -> Self {
1223 unimplemented!(
1224 "WitnessScript can't be generated for to_remote v1 output"
1225 )
1226 }
1227
1228 fn ln_to_remote_v2(amount: u64, remote_pubkey: PublicKey) -> Self {
1229 LockScript::ln_to_remote_v2(amount, remote_pubkey).into()
1230 }
1231}
1232
1233impl ScriptGenerators for PubkeyScript {
1234 #[inline]
1235 fn ln_funding(
1236 amount: u64,
1237 local_pubkey: &LocalPubkey,
1238 remote_pubkey: PublicKey,
1239 ) -> Self {
1240 WitnessScript::ln_funding(amount, local_pubkey, remote_pubkey)
1241 .to_p2wsh()
1242 }
1243
1244 #[inline]
1245 fn ln_to_local(
1246 amount: u64,
1247 revocationpubkey: PublicKey,
1248 local_delayedpubkey: PublicKey,
1249 to_self_delay: u16,
1250 ) -> Self {
1251 WitnessScript::ln_to_local(
1252 amount,
1253 revocationpubkey,
1254 local_delayedpubkey,
1255 to_self_delay,
1256 )
1257 .to_p2wsh()
1258 }
1259
1260 #[inline]
1261 fn ln_to_remote_v1(_: u64, remote_pubkey: PublicKey) -> Self {
1262 bitcoin::PublicKey::new(remote_pubkey)
1263 .wpubkey_hash()
1264 .expect("We just generated non-compressed key")
1265 .into()
1266 }
1267
1268 #[inline]
1269 fn ln_to_remote_v2(amount: u64, remote_pubkey: PublicKey) -> Self {
1270 WitnessScript::ln_to_remote_v2(amount, remote_pubkey).to_p2wsh()
1271 }
1272}
1273
1274impl ScriptGenerators for psbt::Output {
1275 #[inline]
1276 fn ln_funding(
1277 amount: u64,
1278 local_pubkey: &LocalPubkey,
1279 remote_pubkey: PublicKey,
1280 ) -> Self {
1281 let witness_script =
1282 WitnessScript::ln_funding(amount, local_pubkey, remote_pubkey)
1283 .into();
1284 let script_pubkey =
1285 PubkeyScript::ln_funding(amount, local_pubkey, remote_pubkey)
1286 .into();
1287 let txout = TxOut {
1288 value: amount,
1289 script_pubkey,
1290 };
1291 let output = bitcoin::psbt::Output {
1292 witness_script: Some(witness_script),
1293 bip32_derivation: local_pubkey.to_bip32_derivation_map(),
1294 ..Default::default()
1295 };
1296 psbt::Output::with(0, output, txout)
1297 }
1298
1299 #[inline]
1300 fn ln_to_local(
1301 amount: u64,
1302 revocationpubkey: PublicKey,
1303 local_delayedpubkey: PublicKey,
1304 to_self_delay: u16,
1305 ) -> Self {
1306 let witness_script = WitnessScript::ln_to_local(
1307 amount,
1308 revocationpubkey,
1309 local_delayedpubkey,
1310 to_self_delay,
1311 )
1312 .into();
1313 let script_pubkey = PubkeyScript::ln_to_local(
1314 amount,
1315 revocationpubkey,
1316 local_delayedpubkey,
1317 to_self_delay,
1318 )
1319 .into();
1320 let txout = TxOut {
1321 value: amount,
1322 script_pubkey,
1323 };
1324 let output = bitcoin::psbt::Output {
1325 witness_script: Some(witness_script),
1326 ..Default::default()
1327 };
1328 psbt::Output::with(1, output, txout)
1329 }
1330
1331 #[inline]
1332 fn ln_to_remote_v1(amount: u64, remote_pubkey: PublicKey) -> Self {
1333 let txout = TxOut {
1334 value: amount,
1335 script_pubkey: PubkeyScript::ln_to_remote_v1(amount, remote_pubkey)
1336 .into(),
1337 };
1338 psbt::Output::new(2, txout)
1339 }
1340
1341 #[inline]
1342 fn ln_to_remote_v2(amount: u64, remote_pubkey: PublicKey) -> Self {
1343 let witness_script =
1344 WitnessScript::ln_to_remote_v2(amount, remote_pubkey).into();
1345 let script_pubkey =
1346 PubkeyScript::ln_to_remote_v2(amount, remote_pubkey).into();
1347 let txout = TxOut {
1348 value: amount,
1349 script_pubkey,
1350 };
1351 let output = bitcoin::psbt::Output {
1352 witness_script: Some(witness_script),
1353 ..Default::default()
1354 };
1355 psbt::Output::with(3, output, txout)
1356 }
1357}
1358
1359#[cfg(test)]
1360mod test {
1361 use std::str::FromStr;
1362
1363 use amplify::hex::ToHex;
1364 use bitcoin::hashes::hex::FromHex;
1365 use bitcoin::{OutPoint, Script, Transaction, TxIn, Txid};
1366 use wallet::psbt::PsbtVersion;
1367
1368 use super::*;
1369 use crate::channel::shared_ext::Bip96;
1370
1371 macro_rules! pk {
1372 ($hex:expr) => {
1373 PublicKey::from_str($hex).unwrap()
1374 };
1375 }
1376 macro_rules! lk {
1377 ($pk:expr) => {
1378 LocalPubkey {
1379 key: $pk,
1380 ..LocalPubkey::dumb_default()
1381 }
1382 };
1383 }
1384
1385 fn core_for_tests() -> BoltChannel {
1386 let local_payment_basepoint = pk!("034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa");
1387 let remote_payment_basepoint = pk!("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991");
1388 let mut core = BoltChannel::default();
1389
1390 core.direction = Direction::Outbount;
1391 core.commitment_number = 42;
1392 core.local_keys.payment_basepoint = lk!(local_payment_basepoint);
1393 core.remote_keys.payment_basepoint = remote_payment_basepoint;
1394 core.local_params.to_self_delay = 144;
1395 core.local_params.dust_limit_satoshis = 546;
1396
1397 core
1398 }
1399
1400 fn tx_for_tests() -> Transaction {
1401 let local_funding_pubkey = pk!("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb");
1402 let remote_funding_pubkey = pk!("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1");
1403
1404 let output = psbt::Output::ln_funding(
1405 10000000,
1406 &LocalPubkey {
1407 key: local_funding_pubkey,
1408 ..LocalPubkey::dumb_default()
1409 },
1410 remote_funding_pubkey,
1411 );
1412
1413 Transaction {
1414 version: 2,
1415 lock_time: bitcoin::PackedLockTime(0),
1416 input: vec![TxIn {
1417 previous_output: OutPoint::new(Txid::from_str(
1418 "fd2105607605d2302994ffea703b09f66b6351816ee737a93e42a841ea20bbad"
1419 ).unwrap(), 0),
1420 script_sig: Script::from_str(
1421 "48304502210090587b6201e166ad6af0227d3036a9454223d49a1f11839\
1422 c1a362184340ef0240220577f7cd5cca78719405cbf1de7414ac027f023\
1423 9ef6e214c90fcaab0454d84b3b012103535b32d5eb0a6ed0982a0479bba\
1424 dc9868d9836f6ba94dd5a63be16d875069184"
1425 ).unwrap(),
1426 sequence: bitcoin::Sequence(4294967295),
1427 witness: empty!(),
1428 }],
1429 output: vec![
1430 TxOut {
1431 value: output.amount,
1432 script_pubkey: output.script.into_inner(),
1433 },
1434 TxOut {
1435 value: 4989986080,
1436 script_pubkey: Script::from_str("00143ca33c2e4446f4a305f23c80df8ad1afdcf652f9").unwrap()
1437 }
1438 ],
1439 }
1440 }
1441
1442 #[test]
1443 fn bolt3_funding_witness_script() {
1444 let local_funding_pubkey = pk!("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb");
1445 let remote_funding_pubkey = pk!("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1");
1446 let witness_script = WitnessScript::ln_funding(
1447 0,
1448 &LocalPubkey {
1449 key: local_funding_pubkey,
1450 ..LocalPubkey::dumb_default()
1451 },
1452 remote_funding_pubkey,
1453 );
1454 assert_eq!(
1455 witness_script.to_hex(),
1456 "5221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f\
1457 54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa\
1458 711c152ae"
1459 );
1460 }
1461
1462 #[test]
1463 fn bolt3_obscured_commitment_no() {
1464 let core = core_for_tests();
1465 assert_eq!(0x2bb038521914 ^ 42, core.obscured_commitment_number());
1466 }
1467
1468 #[test]
1469 fn bolt3_funding() {
1470 let tx = tx_for_tests();
1476 assert_eq!(tx.txid(), Txid::from_str("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap());
1477 }
1478
1479 #[test]
1480 fn bolt3_commitment_tx() {
1481 let mut core = core_for_tests();
1482
1483 core.direction = Direction::Outbount;
1484 core.local_amount_msat = 7000000000;
1485 core.remote_amount_msat = 3000000000;
1486 core.common_params.feerate_per_kw = 15000;
1487
1488 let remotepubkey = pk!("0394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b");
1496 let local_delayedpubkey = pk!("03fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c");
1497 let local_revocation_pubkey = pk!("0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19");
1498
1499 let mut funding_tx = tx_for_tests();
1500 funding_tx.input[0].script_sig = Script::default();
1501 let mut funding_psbt = Psbt::with(funding_tx, PsbtVersion::V0).unwrap();
1502 funding_psbt.set_channel_funding_output(0).unwrap();
1503
1504 let mut channel =
1505 Channel::<BoltExt>::new(core.clone(), [], [Bip96::new()]);
1506 let psbt = channel.refund_tx(funding_psbt, true).unwrap();
1507 let mut tx = psbt.into_unsigned_tx();
1508
1509 let mut testvec_tx: Transaction = bitcoin::consensus::deserialize(&Vec::from_hex(
1510 "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b\
1511 820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aab\
1512 ee14bb40fa3851ab2301de84311054a56a00000000002200204adb4e2f00643db396\
1513 dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022051b75c73\
1514 198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c41937\
1515 9c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c3836939014830450221\
1516 00f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e796802\
1517 2041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c001\
1518 475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f\
1519 54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa7\
1520 11c152ae3e195220"
1521 ).unwrap()).unwrap();
1522 testvec_tx.input[0].witness = empty!();
1524 tx.input[0].previous_output = testvec_tx.input[0].previous_output;
1525 tx.output[1].script_pubkey = PubkeyScript::ln_to_local(
1528 0,
1529 local_revocation_pubkey,
1530 local_delayedpubkey,
1531 core.local_params.to_self_delay,
1532 )
1533 .into();
1534 tx.output[0].script_pubkey =
1535 PubkeyScript::ln_to_remote_v1(0, remotepubkey).into();
1536
1537 assert_eq!(tx, testvec_tx);
1538 }
1539
1540 #[test]
1541 fn bolt3_localkey_derivation() {
1542 let base_point = pk!("036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2");
1543 let per_commitment_point = pk!("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486");
1544 let mut core = core_for_tests();
1545 core.remote_keys.payment_basepoint = base_point;
1546 core.local_per_commitment_point = per_commitment_point;
1547 assert_eq!(
1548 core.remote_paymentpubkey(false),
1549 pk!("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5")
1550 );
1551
1552 core.local_keys.payment_basepoint = lk!(base_point);
1553 core.remote_per_commitment_point = per_commitment_point;
1554 assert_eq!(
1555 core.remote_paymentpubkey(true),
1556 pk!("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5")
1557 );
1558
1559 core.local_keys.delayed_payment_basepoint = lk!(base_point);
1560 core.remote_per_commitment_point = per_commitment_point;
1561 assert_eq!(
1562 core.local_delayedpubkey(false),
1563 pk!("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5")
1564 );
1565
1566 core.remote_keys.delayed_payment_basepoint = base_point;
1567 core.local_per_commitment_point = per_commitment_point;
1568 assert_eq!(
1569 core.local_delayedpubkey(true),
1570 pk!("0235f2dbfaa89b57ec7b055afe29849ef7ddfeb1cefdb9ebdc43f5494984db29e5")
1571 );
1572 }
1573
1574 #[test]
1575 fn bolt3_revocationkey_derivation() {
1576 let base_point = pk!("036d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2");
1577 let per_commitment_point = pk!("025f7117a78150fe2ef97db7cfc83bd57b2e2c0d0dd25eaf467a4a1c2a45ce1486");
1578 let mut core = core_for_tests();
1579
1580 core.local_keys.revocation_basepoint = lk!(base_point);
1581 core.remote_per_commitment_point = per_commitment_point;
1582 assert_eq!(
1583 core.remote_revocationpubkey(true),
1584 pk!("02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0")
1585 );
1586
1587 core.remote_keys.revocation_basepoint = base_point;
1588 core.local_per_commitment_point = per_commitment_point;
1589 assert_eq!(
1590 core.remote_revocationpubkey(false),
1591 pk!("02916e326636d19c33f13e8c0c3a03dd157f332f3e99c317c141dd865eb01f8ff0")
1592 );
1593 }
1594}