@@ -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 } ;
@@ -32,6 +33,7 @@ struct StoreBenchConfig {
3233
3334fn operations_benchmark ( c : & mut Criterion ) {
3435 forwarding_benchmark ( c) ;
36+ channel_open_benchmark ( c) ;
3537}
3638
3739fn forwarding_benchmark ( c : & mut Criterion ) {
@@ -79,6 +81,72 @@ fn benchmark_runtime() -> tokio::runtime::Runtime {
7981 builder. build ( ) . unwrap ( )
8082}
8183
84+ fn channel_open_benchmark ( c : & mut Criterion ) {
85+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
86+ let chain_source = TestChainSource :: BitcoindRpcSync ( & bitcoind) ;
87+ let runtime = benchmark_runtime ( ) ;
88+
89+ let mut group = c. benchmark_group ( "channel_open" ) ;
90+ group. sample_size ( 10 ) ;
91+
92+ for store_config in store_bench_configs ( ) {
93+ if !should_register_bench ( "channel_open" , store_config. name ) {
94+ continue ;
95+ }
96+ let ( node_a, node_b) =
97+ setup_two_nodes_with_store ( & chain_source, false , true , false , store_config. store_type ) ;
98+ let node_a = Arc :: new ( node_a) ;
99+ let node_b = Arc :: new ( node_b) ;
100+
101+ // connect nodes
102+ node_a
103+ . connect (
104+ node_b. node_id ( ) ,
105+ node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
106+ true ,
107+ )
108+ . unwrap ( ) ;
109+
110+ runtime. block_on ( async {
111+ let address_a = node_a. onchain_payment ( ) . new_address ( ) . unwrap ( ) ;
112+ premine_and_distribute_funds (
113+ & bitcoind. client ,
114+ & electrsd. client ,
115+ vec ! [ address_a] ,
116+ Amount :: from_sat ( 35_000_000 ) ,
117+ )
118+ . await ;
119+ node_a. sync_wallets ( ) . unwrap ( ) ;
120+ } ) ;
121+
122+ let node_a = Arc :: clone ( & node_a) ;
123+ let node_b = Arc :: clone ( & node_b) ;
124+ let bitcoind_client = & bitcoind. client ;
125+ let electrsd_ref = & electrsd;
126+
127+ group. bench_function ( store_config. name , |b| {
128+ b. to_async ( & runtime) . iter_custom ( |iter| {
129+ let node_a = Arc :: clone ( & node_a) ;
130+ let node_b = Arc :: clone ( & node_b) ;
131+
132+ async move {
133+ let mut total = Duration :: ZERO ;
134+ for _ in 0 ..iter {
135+ total += open_channel (
136+ Arc :: clone ( & node_a) ,
137+ Arc :: clone ( & node_b) ,
138+ bitcoind_client,
139+ electrsd_ref,
140+ )
141+ . await ;
142+ }
143+ total
144+ }
145+ } ) ;
146+ } ) ;
147+ }
148+ }
149+
82150/// Returns whether the benchmark identified by `group/name` matches the CLI filters.
83151///
84152/// Criterion applies its own filters after benchmark registration, but these benches do expensive
@@ -255,6 +323,38 @@ async fn wait_for_forwarding_path(nodes: &[Arc<Node>]) {
255323 panic ! ( "Timed out waiting for forwarding path readiness" ) ;
256324}
257325
326+ async fn open_channel (
327+ node_a : Arc < Node > , node_b : Arc < Node > , bitcoind : & BitcoindClient , electrsd : & electrsd:: ElectrsD ,
328+ ) -> Duration {
329+ let start = Instant :: now ( ) ;
330+
331+ node_a
332+ . open_channel (
333+ node_b. node_id ( ) ,
334+ node_b. listening_addresses ( ) . unwrap ( ) . first ( ) . unwrap ( ) . clone ( ) ,
335+ 100_000 ,
336+ None ,
337+ None ,
338+ )
339+ . unwrap ( ) ;
340+
341+ let funding_txo_a = expect_channel_pending_event ! ( node_a, node_b. node_id( ) ) ;
342+ let funding_txo_b = expect_channel_pending_event ! ( node_b, node_a. node_id( ) ) ;
343+ let duration = start. elapsed ( ) ;
344+
345+ assert_eq ! ( funding_txo_a, funding_txo_b) ;
346+ common:: wait_for_tx ( & electrsd. client , funding_txo_a. txid ) . await ;
347+
348+ generate_blocks_and_wait ( bitcoind, & electrsd. client , 6 ) . await ;
349+ node_a. sync_wallets ( ) . unwrap ( ) ;
350+ node_b. sync_wallets ( ) . unwrap ( ) ;
351+
352+ expect_channel_ready_event ! ( node_b, node_a. node_id( ) ) ;
353+ expect_channel_ready_event ! ( node_a, node_b. node_id( ) ) ;
354+
355+ duration
356+ }
357+
258358async fn wait_for_payment_success ( node : & Node , expected_payment_id : PaymentId ) {
259359 loop {
260360 match node. next_event_async ( ) . await {
0 commit comments