diff --git a/src/test/getchannelid.rs b/src/test/getchannelid.rs new file mode 100644 index 0000000..4891c28 --- /dev/null +++ b/src/test/getchannelid.rs @@ -0,0 +1,113 @@ +use super::*; + +const TEST_DIR_BASE: &str = "tmp/getchannelid/"; + +#[serial_test::serial] +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +#[traced_test] +async fn getchannelid_success() { + initialize(); + + let test_dir_base = format!("{TEST_DIR_BASE}success/"); + let test_dir_node1 = format!("{test_dir_base}node1"); + let test_dir_node2 = format!("{test_dir_base}node2"); + let (node1_addr, _) = start_node(&test_dir_node1, NODE1_PEER_PORT, false).await; + let (node2_addr, _) = start_node(&test_dir_node2, NODE2_PEER_PORT, false).await; + + fund_and_create_utxos(node1_addr, None).await; + fund_and_create_utxos(node2_addr, None).await; + + let asset_id = issue_asset_nia(node1_addr).await.asset_id; + + let node2_info = node_info(node2_addr).await; + let node2_pubkey = node2_info.pubkey; + + // open channel with custom temporary channel ID + println!("\nopening channel with custom temporary channel ID"); + let temporary_channel_id = + s!("0011223344556677889900112233445566778899001122334455667788990011"); + + let channel = open_channel_with_custom_data( + node1_addr, + &node2_pubkey, + Some(NODE2_PEER_PORT), + None, + None, + Some(600), + Some(&asset_id), + None, + None, + Some(&temporary_channel_id), + ) + .await; + assert_eq!(asset_balance_spendable(node1_addr, &asset_id).await, 400); + + let channels_1 = list_channels(node1_addr).await; + let channels_2 = list_channels(node2_addr).await; + assert_eq!(channels_1.len(), 1); + assert_eq!(channels_2.len(), 1); + + // get channel ID from temporary channel ID + println!("\ngetting final channel ID from temporary one"); + let chan_id = get_channel_id(node1_addr, &temporary_channel_id).await; + assert_eq!(chan_id, channel.channel_id); +} + +#[serial_test::serial] +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +#[traced_test] +async fn getchannelid_fail() { + initialize(); + + let test_dir_base = format!("{TEST_DIR_BASE}fail/"); + let test_dir_node1 = format!("{test_dir_base}node1"); + let (node1_addr, _) = start_node(&test_dir_node1, NODE1_PEER_PORT, false).await; + + // get channel ID from invalid (odd char) temporary channel ID + println!("\ngetting channel ID for an odd temporary one"); + let temporary_channel_id = s!("odd"); + let payload = GetChannelIdRequest { + temporary_channel_id, + }; + let res = reqwest::Client::new() + .post(format!("http://{}/getchannelid", node1_addr)) + .json(&payload) + .send() + .await + .unwrap(); + check_response_is_nok(res, reqwest::StatusCode::BAD_REQUEST, "Invalid channel ID").await; + + // get channel ID from invalid (short) temporary channel ID + println!("\ngetting channel ID for a short temporary one"); + let temporary_channel_id = s!("0123456789abcdef"); + let payload = GetChannelIdRequest { + temporary_channel_id, + }; + let res = reqwest::Client::new() + .post(format!("http://{}/getchannelid", node1_addr)) + .json(&payload) + .send() + .await + .unwrap(); + check_response_is_nok(res, reqwest::StatusCode::BAD_REQUEST, "Invalid channel ID").await; + + // get channel ID from unknown temporary channel ID + println!("\ngetting channel ID for an unknown temporary one"); + let temporary_channel_id = + s!("0011223344556677889900112233445566778899001122334455667788990011"); + let payload = GetChannelIdRequest { + temporary_channel_id, + }; + let res = reqwest::Client::new() + .post(format!("http://{}/getchannelid", node1_addr)) + .json(&payload) + .send() + .await + .unwrap(); + check_response_is_nok( + res, + reqwest::StatusCode::FORBIDDEN, + "Unknown temporary channel ID", + ) + .await; +} diff --git a/src/test/mod.rs b/src/test/mod.rs index cdaf0f0..e96125a 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -20,18 +20,18 @@ use crate::routes::{ BackupRequest, BtcBalanceResponse, ChangePasswordRequest, Channel, CloseChannelRequest, ConnectPeerRequest, CreateUtxosRequest, DecodeLNInvoiceRequest, DecodeLNInvoiceResponse, DecodeRGBInvoiceRequest, DecodeRGBInvoiceResponse, DisconnectPeerRequest, EmptyResponse, - GetAssetMediaRequest, GetAssetMediaResponse, HTLCStatus, InitRequest, InitResponse, - InvoiceStatus, InvoiceStatusRequest, InvoiceStatusResponse, IssueAssetCFARequest, - IssueAssetCFAResponse, IssueAssetNIARequest, IssueAssetNIAResponse, IssueAssetUDARequest, - IssueAssetUDAResponse, KeysendRequest, KeysendResponse, LNInvoiceRequest, LNInvoiceResponse, - ListAssetsRequest, ListAssetsResponse, ListChannelsResponse, ListPaymentsResponse, - ListPeersResponse, ListSwapsResponse, ListTransactionsResponse, ListTransfersRequest, - ListTransfersResponse, ListUnspentsResponse, MakerExecuteRequest, MakerInitRequest, - MakerInitResponse, NetworkInfoResponse, NodeInfoResponse, OpenChannelRequest, - OpenChannelResponse, Payment, Peer, PostAssetMediaResponse, RestoreRequest, RgbInvoiceRequest, - RgbInvoiceResponse, SendAssetRequest, SendAssetResponse, SendBtcRequest, SendBtcResponse, - SendPaymentRequest, SendPaymentResponse, SwapStatus, TakerRequest, Transaction, Transfer, - UnlockRequest, Unspent, + GetAssetMediaRequest, GetAssetMediaResponse, GetChannelIdRequest, GetChannelIdResponse, + HTLCStatus, InitRequest, InitResponse, InvoiceStatus, InvoiceStatusRequest, + InvoiceStatusResponse, IssueAssetCFARequest, IssueAssetCFAResponse, IssueAssetNIARequest, + IssueAssetNIAResponse, IssueAssetUDARequest, IssueAssetUDAResponse, KeysendRequest, + KeysendResponse, LNInvoiceRequest, LNInvoiceResponse, ListAssetsRequest, ListAssetsResponse, + ListChannelsResponse, ListPaymentsResponse, ListPeersResponse, ListSwapsResponse, + ListTransactionsResponse, ListTransfersRequest, ListTransfersResponse, ListUnspentsResponse, + MakerExecuteRequest, MakerInitRequest, MakerInitResponse, NetworkInfoResponse, + NodeInfoResponse, OpenChannelRequest, OpenChannelResponse, Payment, Peer, + PostAssetMediaResponse, RestoreRequest, RgbInvoiceRequest, RgbInvoiceResponse, + SendAssetRequest, SendAssetResponse, SendBtcRequest, SendBtcResponse, SendPaymentRequest, + SendPaymentResponse, SwapStatus, TakerRequest, Transaction, Transfer, UnlockRequest, Unspent, }; use crate::utils::{hex_str_to_vec, PROXY_ENDPOINT_REGTEST}; @@ -469,6 +469,25 @@ async fn get_asset_media(node_address: SocketAddr, digest: &str) -> String { .bytes_hex } +async fn get_channel_id(node_address: SocketAddr, temp_chan_id: &str) -> String { + println!("requesting channel ID for temporary ID {temp_chan_id} from node {node_address}"); + let payload = GetChannelIdRequest { + temporary_channel_id: temp_chan_id.to_string(), + }; + let res = reqwest::Client::new() + .post(format!("http://{}/getchannelid", node_address)) + .json(&payload) + .send() + .await + .unwrap(); + _check_response_is_ok(res) + .await + .json::() + .await + .unwrap() + .channel_id +} + async fn invoice_status(node_address: SocketAddr, invoice: &str) -> InvoiceStatus { println!("getting status of invoice {invoice} for node {node_address}"); let payload = InvoiceStatusRequest { @@ -933,7 +952,7 @@ async fn open_channel( asset_amount: Option, asset_id: Option<&str>, ) -> Channel { - open_channel_with_custom_fees( + open_channel_with_custom_data( node_address, dest_peer_pubkey, dest_peer_port, @@ -943,12 +962,13 @@ async fn open_channel( asset_id, None, None, + None, ) .await } #[allow(clippy::too_many_arguments)] -async fn open_channel_with_custom_fees( +async fn open_channel_with_custom_data( node_address: SocketAddr, dest_peer_pubkey: &str, dest_peer_port: Option, @@ -958,6 +978,7 @@ async fn open_channel_with_custom_fees( asset_id: Option<&str>, fee_base_msat: Option, fee_proportional_millionths: Option, + temporary_channel_id: Option<&str>, ) -> Channel { println!( "opening channel with {asset_amount:?} of asset {asset_id:?} from node {node_address} \ @@ -979,7 +1000,7 @@ async fn open_channel_with_custom_fees( with_anchors: true, fee_base_msat, fee_proportional_millionths, - temporary_channel_id: None, + temporary_channel_id: temporary_channel_id.map(|t| t.to_string()), }; let res = reqwest::Client::new() .post(format!("http://{}/openchannel", node_address)) @@ -1536,6 +1557,7 @@ mod close_force_nobtc_acceptor; mod close_force_other_side; mod close_force_standard; mod concurrent_btc_payments; +mod getchannelid; mod htlc_amount_checks; mod invoice; mod issue; diff --git a/src/test/openchannel_fail.rs b/src/test/openchannel_fail.rs index 8b3ad66..37b9ebe 100644 --- a/src/test/openchannel_fail.rs +++ b/src/test/openchannel_fail.rs @@ -265,6 +265,32 @@ async fn open_fail() { assert_eq!(channels_1.len(), 0); assert_eq!(channels_2.len(), 0); + // open with an invalid temporary channel id + let payload = OpenChannelRequest { + peer_pubkey_and_opt_addr: format!("{}@127.0.0.1:{}", node2_pubkey, NODE2_PEER_PORT), + capacity_sat: 100_000, + push_msat: 3_500_000, + asset_amount: Some(100), + asset_id: Some(asset_id.clone()), + public: true, + with_anchors: true, + fee_base_msat: None, + fee_proportional_millionths: None, + temporary_channel_id: Some(s!("ttoooosshhoorrtt")), + }; + let res = reqwest::Client::new() + .post(format!("http://{}/openchannel", node1_addr)) + .json(&payload) + .send() + .await + .unwrap(); + check_response_is_nok(res, reqwest::StatusCode::BAD_REQUEST, "Invalid channel ID").await; + + let channels_1 = list_channels(node1_addr).await; + let channels_2 = list_channels(node2_addr).await; + assert_eq!(channels_1.len(), 0); + assert_eq!(channels_2.len(), 0); + fund_and_create_utxos(node1_addr, Some(9)).await; // open a 1st channel (success) let payload = OpenChannelRequest { diff --git a/src/test/refuse_high_fees.rs b/src/test/refuse_high_fees.rs index 7837506..3c06863 100644 --- a/src/test/refuse_high_fees.rs +++ b/src/test/refuse_high_fees.rs @@ -52,7 +52,7 @@ async fn refuse_high_fees() { assert_eq!(asset_balance_spendable(node1_addr, &asset_id).await, 100); assert_eq!(asset_balance_spendable(node2_addr, &asset_id).await, 400); - let _channel_23 = open_channel_with_custom_fees( + let _channel_23 = open_channel_with_custom_data( node2_addr, &node3_pubkey, Some(NODE3_PEER_PORT), @@ -62,6 +62,7 @@ async fn refuse_high_fees() { Some(&asset_id), Some(2_000_000), None, + None, ) .await; assert_eq!(asset_balance_spendable(node1_addr, &asset_id).await, 100);