@@ -13,11 +13,12 @@ use std::time::{Duration, Instant};
1313
1414use bitcoin:: Amount ;
1515use common:: {
16- expect_event, generate_blocks_and_wait, premine_and_distribute_funds, random_config,
17- setup_bitcoind_and_electrsd, setup_node,
16+ expect_channel_pending_event, expect_channel_ready_event, expect_event,
17+ generate_blocks_and_wait, premine_and_distribute_funds, random_config,
18+ setup_bitcoind_and_electrsd, setup_node, setup_two_nodes_with_store,
1819} ;
1920use criterion:: { criterion_group, criterion_main, Criterion } ;
20- use electrsd:: corepc_node:: Node as BitcoinD ;
21+ use electrsd:: corepc_node:: { Client as BitcoindClient , Node as BitcoinD } ;
2122use ldk_node:: { Event , Node } ;
2223use lightning:: ln:: channelmanager:: PaymentId ;
2324use lightning_invoice:: { Bolt11InvoiceDescription , Description } ;
@@ -34,6 +35,7 @@ fn operations_benchmark(c: &mut Criterion) {
3435 dotenvy:: dotenv ( ) . ok ( ) ;
3536
3637 forwarding_benchmark ( c) ;
38+ channel_open_benchmark ( c) ;
3739}
3840
3941fn forwarding_benchmark ( c : & mut Criterion ) {
@@ -81,6 +83,72 @@ fn benchmark_runtime() -> tokio::runtime::Runtime {
8183 builder. build ( ) . unwrap ( )
8284}
8385
86+ fn channel_open_benchmark ( c : & mut Criterion ) {
87+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
88+ let chain_source = TestChainSource :: BitcoindRpcSync ( & bitcoind) ;
89+ let runtime = benchmark_runtime ( ) ;
90+
91+ let mut group = c. benchmark_group ( "channel_open" ) ;
92+ group. sample_size ( 10 ) ;
93+
94+ for store_config in store_bench_configs ( ) {
95+ if !should_register_bench ( "channel_open" , store_config. name ) {
96+ continue ;
97+ }
98+ let ( node_a, node_b) =
99+ setup_two_nodes_with_store ( & chain_source, false , true , false , store_config. store_type ) ;
100+ let node_a = Arc :: new ( node_a) ;
101+ let node_b = Arc :: new ( node_b) ;
102+
103+ // connect nodes
104+ node_a
105+ . connect (
106+ node_b. node_id ( ) ,
107+ node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
108+ true ,
109+ )
110+ . unwrap ( ) ;
111+
112+ runtime. block_on ( async {
113+ let address_a = node_a. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
114+ premine_and_distribute_funds (
115+ & bitcoind. client ,
116+ & electrsd. client ,
117+ vec ! [ address_a] ,
118+ Amount :: from_sat ( 35_000_000 ) ,
119+ )
120+ . await ;
121+ node_a. sync_wallets ( ) . unwrap ( ) ;
122+ } ) ;
123+
124+ let node_a = Arc :: clone ( & node_a) ;
125+ let node_b = Arc :: clone ( & node_b) ;
126+ let bitcoind_client = & bitcoind. client ;
127+ let electrsd_ref = & electrsd;
128+
129+ group. bench_function ( store_config. name , |b| {
130+ b. to_async ( & runtime) . iter_custom ( |iter| {
131+ let node_a = Arc :: clone ( & node_a) ;
132+ let node_b = Arc :: clone ( & node_b) ;
133+
134+ async move {
135+ let mut total = Duration :: ZERO ;
136+ for _ in 0 ..iter {
137+ total += open_channel (
138+ Arc :: clone ( & node_a) ,
139+ Arc :: clone ( & node_b) ,
140+ bitcoind_client,
141+ electrsd_ref,
142+ )
143+ . await ;
144+ }
145+ total
146+ }
147+ } ) ;
148+ } ) ;
149+ }
150+ }
151+
84152/// Returns whether the benchmark identified by `group/name` matches the CLI filters.
85153///
86154/// Criterion applies its own filters after benchmark registration, but these benches do expensive
@@ -257,6 +325,38 @@ async fn wait_for_forwarding_path(nodes: &[Arc<Node>]) {
257325 panic ! ( "Timed out waiting for forwarding path readiness" ) ;
258326}
259327
328+ async fn open_channel (
329+ node_a : Arc < Node > , node_b : Arc < Node > , bitcoind : & BitcoindClient , electrsd : & electrsd:: ElectrsD ,
330+ ) -> Duration {
331+ let start = Instant :: now ( ) ;
332+
333+ node_a
334+ . open_channel (
335+ node_b. node_id ( ) ,
336+ node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
337+ 100_000 ,
338+ None ,
339+ None ,
340+ )
341+ . unwrap ( ) ;
342+
343+ let funding_txo_a = expect_channel_pending_event ! ( node_a, node_b. node_id( ) ) ;
344+ let funding_txo_b = expect_channel_pending_event ! ( node_b, node_a. node_id( ) ) ;
345+ let duration = start. elapsed ( ) ;
346+
347+ assert_eq ! ( funding_txo_a, funding_txo_b) ;
348+ common:: wait_for_tx ( & electrsd. client , funding_txo_a. txid ) . await ;
349+
350+ generate_blocks_and_wait ( bitcoind, & electrsd. client , 6 ) . await ;
351+ node_a. sync_wallets ( ) . unwrap ( ) ;
352+ node_b. sync_wallets ( ) . unwrap ( ) ;
353+
354+ expect_channel_ready_event ! ( node_b, node_a. node_id( ) ) ;
355+ expect_channel_ready_event ! ( node_a, node_b. node_id( ) ) ;
356+
357+ duration
358+ }
359+
260360async fn wait_for_payment_success ( node : & Node , expected_payment_id : PaymentId ) {
261361 loop {
262362 match node. next_event_async ( ) . await {
0 commit comments