@@ -65,7 +65,9 @@ use bitcoin::secp256k1::PublicKey;
65
65
use bitcoin:: { BlockHash , Network } ;
66
66
67
67
#[ cfg( any( vss, vss_test) ) ]
68
- use bitcoin:: bip32:: ChildNumber ;
68
+ use bitcoin:: bip32:: { ChildNumber , Xpriv } ;
69
+ #[ cfg( any( vss, vss_test) ) ]
70
+ use std:: collections:: HashMap ;
69
71
use std:: convert:: TryInto ;
70
72
use std:: default:: Default ;
71
73
use std:: fmt;
@@ -74,6 +76,8 @@ use std::path::PathBuf;
74
76
use std:: sync:: atomic:: AtomicBool ;
75
77
use std:: sync:: { Arc , Mutex , RwLock } ;
76
78
use std:: time:: SystemTime ;
79
+ #[ cfg( any( vss, vss_test) ) ]
80
+ use vss_client:: headers:: { FixedHeaders , VssHeaderProvider } ;
77
81
78
82
#[ derive( Debug , Clone ) ]
79
83
enum ChainDataSourceConfig {
@@ -357,36 +361,56 @@ impl NodeBuilder {
357
361
self . build_with_store ( kv_store)
358
362
}
359
363
360
- /// Builds a [`Node`] instance with a [`VssStore` ] backend and according to the options
364
+ /// Builds a [`Node`] instance with a [VSS ] backend and according to the options
361
365
/// previously configured.
366
+ ///
367
+ /// Uses [`FixedHeaders`] as default method for authentication/authorization.
368
+ /// Given `fixed_headers` are included as it is in all the requests made to VSS.
369
+ ///
370
+ /// **Caution**: VSS support is in **alpha** and is considered experimental.
371
+ /// Using VSS (or any remote persistence) may cause LDK to panic if persistence failures are
372
+ /// unrecoverable, i.e., if they remain unresolved after internal retries are exhausted.
373
+ ///
374
+ /// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
362
375
#[ cfg( any( vss, vss_test) ) ]
363
- pub fn build_with_vss_store ( & self , url : String , store_id : String ) -> Result < Node , BuildError > {
364
- use bitcoin:: key:: Secp256k1 ;
376
+ pub fn build_with_vss_store_and_fixed_headers (
377
+ & self , vss_url : String , store_id : String , fixed_headers : HashMap < String , String > ,
378
+ ) -> Result < Node , BuildError > {
379
+ let header_provider = Arc :: new ( FixedHeaders :: new ( fixed_headers) ) ;
380
+
381
+ self . build_with_vss_store_and_header_provider ( vss_url, store_id, header_provider)
382
+ }
365
383
384
+ /// Builds a [`Node`] instance with a [VSS] backend and according to the options
385
+ /// previously configured.
386
+ ///
387
+ /// Given `header_provider` is used to attach headers to every request made
388
+ /// to VSS.
389
+ ///
390
+ /// **Caution**: VSS support is in **alpha** and is considered experimental.
391
+ /// Using VSS (or any remote persistence) may cause LDK to panic if persistence failures are
392
+ /// unrecoverable, i.e., if they remain unresolved after internal retries are exhausted.
393
+ ///
394
+ /// [VSS]: https://github.com/lightningdevkit/vss-server/blob/main/README.md
395
+ #[ cfg( any( vss, vss_test) ) ]
396
+ pub fn build_with_vss_store_and_header_provider (
397
+ & self , vss_url : String , store_id : String , header_provider : Arc < dyn VssHeaderProvider > ,
398
+ ) -> Result < Node , BuildError > {
366
399
let logger = setup_logger ( & self . config ) ?;
367
400
368
401
let seed_bytes = seed_bytes_from_config (
369
402
& self . config ,
370
403
self . entropy_source_config . as_ref ( ) ,
371
404
Arc :: clone ( & logger) ,
372
405
) ?;
373
- let config = Arc :: new ( self . config . clone ( ) ) ;
374
406
375
- let xprv = bitcoin:: bip32:: Xpriv :: new_master ( config. network , & seed_bytes) . map_err ( |e| {
376
- log_error ! ( logger, "Failed to derive master secret: {}" , e) ;
377
- BuildError :: InvalidSeedBytes
378
- } ) ?;
407
+ let config = Arc :: new ( self . config . clone ( ) ) ;
379
408
380
- let vss_xprv = xprv
381
- . derive_priv ( & Secp256k1 :: new ( ) , & [ ChildNumber :: Hardened { index : 877 } ] )
382
- . map_err ( |e| {
383
- log_error ! ( logger, "Failed to derive VSS secret: {}" , e) ;
384
- BuildError :: KVStoreSetupFailed
385
- } ) ?;
409
+ let vss_xprv = derive_vss_xprv ( config. clone ( ) , & seed_bytes, Arc :: clone ( & logger) ) ?;
386
410
387
411
let vss_seed_bytes: [ u8 ; 32 ] = vss_xprv. private_key . secret_bytes ( ) ;
388
412
389
- let vss_store = Arc :: new ( VssStore :: new ( url , store_id, vss_seed_bytes) ) ;
413
+ let vss_store = Arc :: new ( VssStore :: new ( vss_url , store_id, vss_seed_bytes, header_provider ) ) ;
390
414
build_with_store_internal (
391
415
config,
392
416
self . chain_data_source_config . as_ref ( ) ,
@@ -1079,6 +1103,23 @@ fn seed_bytes_from_config(
1079
1103
}
1080
1104
}
1081
1105
1106
+ #[ cfg( any( vss, vss_test) ) ]
1107
+ fn derive_vss_xprv (
1108
+ config : Arc < Config > , seed_bytes : & [ u8 ; 64 ] , logger : Arc < FilesystemLogger > ,
1109
+ ) -> Result < Xpriv , BuildError > {
1110
+ use bitcoin:: key:: Secp256k1 ;
1111
+
1112
+ let xprv = Xpriv :: new_master ( config. network , seed_bytes) . map_err ( |e| {
1113
+ log_error ! ( logger, "Failed to derive master secret: {}" , e) ;
1114
+ BuildError :: InvalidSeedBytes
1115
+ } ) ?;
1116
+
1117
+ xprv. derive_priv ( & Secp256k1 :: new ( ) , & [ ChildNumber :: Hardened { index : 877 } ] ) . map_err ( |e| {
1118
+ log_error ! ( logger, "Failed to derive VSS secret: {}" , e) ;
1119
+ BuildError :: KVStoreSetupFailed
1120
+ } )
1121
+ }
1122
+
1082
1123
/// Sanitize the user-provided node alias to ensure that it is a valid protocol-specified UTF-8 string.
1083
1124
pub ( crate ) fn sanitize_alias ( alias_str : & str ) -> Result < NodeAlias , BuildError > {
1084
1125
let alias = alias_str. trim ( ) ;
0 commit comments