From e131cb840d09dea658cb418bec11c4d0c5c2f803 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 22 Oct 2024 16:32:54 +0800 Subject: [PATCH 01/31] add invoice currency check with chain network --- src/rpc/invoice.rs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/rpc/invoice.rs b/src/rpc/invoice.rs index 61a3583cb..2fc352088 100644 --- a/src/rpc/invoice.rs +++ b/src/rpc/invoice.rs @@ -1,3 +1,4 @@ +use crate::fiber::config::CkbNetwork; use crate::fiber::hash_algorithm::HashAlgorithm; use crate::fiber::serde_utils::{U128Hex, U64Hex}; use crate::fiber::types::{Hash256, Privkey}; @@ -65,11 +66,12 @@ trait InvoiceRpc { pub(crate) struct InvoiceRpcServerImpl { store: S, keypair: Option<(PublicKey, SecretKey)>, + currency: Option, } impl InvoiceRpcServerImpl { pub(crate) fn new(store: S, config: Option) -> Self { - let keypair = config.map(|config| { + let config = config.map(|config| { let kp = config .read_or_generate_secret_key() .expect("read or generate secret key"); @@ -81,9 +83,25 @@ impl InvoiceRpcServerImpl { PublicKey::from_slice(secio_kp.public_key().inner_ref()).expect("valid public key"), private_key.into(), ); - keypair + + // restrict currency to be the same as network + let currency = match config.network { + Some(CkbNetwork::Mainnet) => Some(Currency::Fibb), + Some(CkbNetwork::Testnet) => Some(Currency::Fibt), + Some(_) => Some(Currency::Fibd), + _ => None, + }; + + (keypair, currency) }); - Self { store, keypair } + Self { + store, + keypair: config.as_ref().map(|(kp, _)| kp.clone()), + currency: config + .as_ref() + .map(|(_, currency)| *currency) + .unwrap_or_default(), + } } } @@ -96,6 +114,15 @@ where &self, params: NewInvoiceParams, ) -> Result { + if let Some(currency) = self.currency { + if currency != params.currency { + return Err(ErrorObjectOwned::owned( + CALL_EXECUTION_FAILED_CODE, + format!("Currency must be {:?} with the chain network", currency), + Some(params), + )); + } + } let mut invoice_builder = InvoiceBuilder::new(params.currency) .amount(Some(params.amount)) .payment_preimage(params.payment_preimage); From e2bd3dc00188bd32c1fff725f3321d639448bc5b Mon Sep 17 00:00:00 2001 From: YI Date: Tue, 22 Oct 2024 14:48:21 +0800 Subject: [PATCH 02/31] Return channel outpoint for rpc list_channels --- src/fiber/channel.rs | 46 ++++++++++--------- src/rpc/channel.rs | 10 +++- .../03-get-auto-accepted-channel.bru | 1 + 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/fiber/channel.rs b/src/fiber/channel.rs index 64a1475d8..5525efd2d 100644 --- a/src/fiber/channel.rs +++ b/src/fiber/channel.rs @@ -411,12 +411,12 @@ where .collect(); debug!( "Updating funding tx witnesses of {:?} to {:?}", - state.get_funding_transaction().calc_tx_hash(), + state.must_get_funding_transaction().calc_tx_hash(), new_witnesses.iter().map(|x| hex::encode(x.as_slice())) ); state.funding_tx = Some( state - .get_funding_transaction() + .must_get_funding_transaction() .as_advanced_builder() .set_witnesses(new_witnesses) .build() @@ -425,8 +425,8 @@ where self.network .send_message(NetworkActorMessage::new_event( NetworkActorEvent::FundingTransactionPending( - state.get_funding_transaction().clone(), - state.get_funding_transaction_outpoint(), + state.must_get_funding_transaction().clone(), + state.must_get_funding_transaction_outpoint(), state.get_id(), ), )) @@ -731,7 +731,7 @@ where }; TlcErr::new_channel_fail( error_code, - state.get_funding_transaction_outpoint(), + state.must_get_funding_transaction_outpoint(), channel_update, ) } @@ -1829,7 +1829,7 @@ where NetworkActorEvent::ChannelReady( channel.get_id(), channel.get_remote_peer_id(), - channel.get_funding_transaction_outpoint(), + channel.must_get_funding_transaction_outpoint(), ), )) .expect(ASSUME_NETWORK_ACTOR_ALIVE); @@ -2487,7 +2487,7 @@ impl ChannelActorState { Some(x) => x, // We have not created a channel announcement yet. None => { - let channel_outpoint = self.get_funding_transaction_outpoint(); + let channel_outpoint = self.must_get_funding_transaction_outpoint(); let capacity = if self.funding_udt_type_script.is_some() { self.get_total_udt_amount() } else { @@ -2672,7 +2672,7 @@ impl ChannelActorState { Some(fee_proportional_millionths), ) => Some(ChannelUpdate::new_unsigned( Default::default(), - self.get_funding_transaction_outpoint(), + self.must_get_funding_transaction_outpoint(), std::time::UNIX_EPOCH.elapsed().unwrap().as_secs(), message_flags, 0, @@ -3028,7 +3028,7 @@ impl ChannelActorState { let key_agg_ctx = self.get_musig2_agg_context(); let channel_id = self.get_id(); let peer_id = self.get_remote_peer_id(); - let channel_outpoint = self.get_funding_transaction_outpoint(); + let channel_outpoint = self.must_get_funding_transaction_outpoint(); let partial_signature: PartialSignature = sign_partial( &key_agg_ctx, @@ -3624,20 +3624,22 @@ impl ChannelActorState { self.remote_channel_public_keys.as_ref().unwrap() } - pub fn get_funding_transaction(&self) -> &Transaction { + pub fn must_get_funding_transaction(&self) -> &Transaction { self.funding_tx .as_ref() .expect("Funding transaction is present") } - pub fn get_funding_transaction_outpoint(&self) -> OutPoint { - let tx = self.get_funding_transaction(); - debug!( - "Funding transaction lock args: {:?}", - tx.raw().outputs().get(0).unwrap().lock().args() - ); - // By convention, the funding tx output for the channel is the first output. - OutPoint::new(tx.calc_tx_hash(), 0) + pub fn get_funding_transaction_outpoint(&self) -> Option { + self.funding_tx.as_ref().map(|tx| { + // By convention, the funding tx output for the channel is the first output. + OutPoint::new(tx.calc_tx_hash(), 0) + }) + } + + pub fn must_get_funding_transaction_outpoint(&self) -> OutPoint { + self.get_funding_transaction_outpoint() + .expect("Funding transaction outpoint is present") } pub fn get_funding_transaction_block_number(&self) -> BlockNumber { @@ -4087,7 +4089,7 @@ impl ChannelActorState { partial_signatures: [PartialSignature; 2], tx: &TransactionView, ) -> Result { - let funding_out_point = self.get_funding_transaction_outpoint(); + let funding_out_point = self.must_get_funding_transaction_outpoint(); debug_assert_eq!( tx.input_pts_iter().next().as_ref(), Some(&funding_out_point), @@ -4656,7 +4658,7 @@ impl ChannelActorState { NetworkActorEvent::ChannelReady( self.get_id(), peer_id.clone(), - self.get_funding_transaction_outpoint(), + self.must_get_funding_transaction_outpoint(), ), )) .expect(ASSUME_NETWORK_ACTOR_ALIVE); @@ -5091,7 +5093,7 @@ impl ChannelActorState { let cell_deps = get_cell_deps(vec![Contract::FundingLock], &self.funding_udt_type_script); let tx_builder = TransactionBuilder::default().cell_deps(cell_deps).input( CellInput::new_builder() - .previous_output(self.get_funding_transaction_outpoint()) + .previous_output(self.must_get_funding_transaction_outpoint()) .build(), ); @@ -5178,7 +5180,7 @@ impl ChannelActorState { local: bool, ) -> (TransactionView, TransactionView) { let commitment_tx = { - let funding_out_point = self.get_funding_transaction_outpoint(); + let funding_out_point = self.must_get_funding_transaction_outpoint(); let cell_deps = get_cell_deps(vec![Contract::FundingLock], &self.funding_udt_type_script); let (output, output_data) = self.build_commitment_transaction_output(local); diff --git a/src/rpc/channel.rs b/src/rpc/channel.rs index cc369e818..91aded08c 100644 --- a/src/rpc/channel.rs +++ b/src/rpc/channel.rs @@ -6,13 +6,16 @@ use crate::fiber::{ graph::PaymentSessionStatus, hash_algorithm::HashAlgorithm, network::{AcceptChannelCommand, OpenChannelCommand, SendPaymentCommand}, - serde_utils::{U128Hex, U64Hex}, + serde_utils::{EntityHex, U128Hex, U64Hex}, types::{Hash256, LockTime, Pubkey, RemoveTlcFulfill, TlcErr, TlcErrPacket, TlcErrorCode}, NetworkActorCommand, NetworkActorMessage, }; use crate::{handle_actor_call, handle_actor_cast, log_and_error}; use ckb_jsonrpc_types::{EpochNumberWithFraction, Script}; -use ckb_types::core::{EpochNumberWithFraction as EpochNumberWithFractionCore, FeeRate}; +use ckb_types::{ + core::{EpochNumberWithFraction as EpochNumberWithFractionCore, FeeRate}, + packed::OutPoint, +}; use jsonrpsee::{ core::async_trait, proc_macros::rpc, @@ -95,6 +98,8 @@ pub(crate) struct ListChannelsResult { #[derive(Clone, Serialize)] pub(crate) struct Channel { channel_id: Hash256, + #[serde_as(as = "Option")] + channel_outpoint: Option, #[serde_as(as = "DisplayFromStr")] peer_id: PeerId, funding_udt_type_script: Option