1- use std:: path:: Path ;
1+ use std:: path:: { Path , PathBuf } ;
22
33use figment:: {
44 providers:: { Format , Toml } ,
55 Figment ,
66} ;
77
88use serde:: { Deserialize , Serialize } ;
9+ use topos_wallet:: SecretManager ;
10+ use tracing:: { debug, error} ;
911
1012use crate :: {
1113 base:: BaseConfig , certificate_producer:: CertificateProducerConfig , edge:: EdgeConfig ,
@@ -26,28 +28,86 @@ pub struct NodeConfig {
2628 pub tce : Option < TceConfig > ,
2729 pub certificate_producer : Option < CertificateProducerConfig > ,
2830 pub edge : Option < EdgeConfig > ,
31+
32+ #[ serde( skip) ]
33+ pub home_path : PathBuf ,
34+
35+ #[ serde( skip) ]
36+ pub node_path : PathBuf ,
37+
38+ #[ serde( skip) ]
39+ pub edge_path : PathBuf ,
2940}
3041
3142impl NodeConfig {
32- pub fn new < S : Serialize > ( home : & Path , config : Option < S > ) -> Self {
33- let base = load_config :: < BaseConfig , _ > ( home, config) ;
43+ /// Try to create a new node config struct from the given home path and node name.
44+ /// It expects a config file to be present in the node's folder.
45+ ///
46+ /// This `config.toml` can be generated using: `topos node init` command
47+ pub fn try_from < S : Serialize > (
48+ home_path : & Path ,
49+ node_name : & str ,
50+ config : Option < S > ,
51+ ) -> Result < Self , std:: io:: Error > {
52+ let node_path = home_path. join ( "node" ) . join ( node_name) ;
53+ let config_path = node_path. join ( "config.toml" ) ;
54+
55+ // TODO: Move this to `topos-node` when migrated
56+ if !Path :: new ( & config_path) . exists ( ) {
57+ error ! (
58+ "Please run 'topos node init --name {node_name}' to create a config file first \
59+ for {node_name}."
60+ ) ;
61+ std:: process:: exit ( 1 ) ;
62+ }
63+
64+ Ok ( Self :: build_config ( node_path, home_path, config) )
65+ }
66+
67+ /// Create a new node config struct from the given home path and node name.
68+ ///
69+ /// It doesn't check the existence of the config file.
70+ /// It's useful for creating a config file for a new node, relying on the default values.
71+ pub fn create < S : Serialize > ( home_path : & Path , node_name : & str , config : Option < S > ) -> Self {
72+ let node_path = home_path. join ( "node" ) . join ( node_name) ;
73+
74+ Self :: build_config ( node_path, home_path, config)
75+ }
76+
77+ /// Common function to build a node config struct from the given home path and node name.
78+ fn build_config < S : Serialize > ( node_path : PathBuf , home_path : & Path , config : Option < S > ) -> Self {
79+ let node_folder = node_path. as_path ( ) ;
80+ let base = load_config :: < BaseConfig , _ > ( node_folder, config) ;
81+
82+ // Load genesis pointed by the local config
83+ let edge_path = home_path
84+ . join ( "subnet" )
85+ . join ( base. subnet . clone ( ) )
86+ . join ( "genesis.json" ) ;
3487
3588 let mut config = NodeConfig {
89+ node_path : node_path. to_path_buf ( ) ,
90+ edge_path,
91+ home_path : home_path. to_path_buf ( ) ,
3692 base : base. clone ( ) ,
3793 certificate_producer : base
3894 . need_certificate_producer ( )
39- . then ( || load_config :: < CertificateProducerConfig , ( ) > ( home , None ) ) ,
95+ . then ( || load_config :: < CertificateProducerConfig , ( ) > ( node_folder , None ) ) ,
4096 tce : base
4197 . need_tce ( )
42- . then ( || load_config :: < TceConfig , ( ) > ( home , None ) ) ,
98+ . then ( || load_config :: < TceConfig , ( ) > ( node_folder , None ) ) ,
4399 edge : base
44100 . need_edge ( )
45- . then ( || load_config :: < EdgeConfig , ( ) > ( home , None ) ) ,
101+ . then ( || load_config :: < EdgeConfig , ( ) > ( node_folder , None ) ) ,
46102 } ;
47103
48104 // Make the TCE DB path relative to the folder
49105 if let Some ( config) = config. tce . as_mut ( ) {
50- config. db_path = home. join ( & config. db_path ) ;
106+ config. db_path = node_folder. join ( & config. db_path ) ;
107+ debug ! (
108+ "Maked TCE DB path relative to the node folder -> {:?}" ,
109+ config. db_path
110+ ) ;
51111 }
52112
53113 config
@@ -71,3 +131,12 @@ impl Config for NodeConfig {
71131 "default" . to_string ( )
72132 }
73133}
134+
135+ impl From < & NodeConfig > for SecretManager {
136+ fn from ( val : & NodeConfig ) -> Self {
137+ match val. base . secrets_config . as_ref ( ) {
138+ Some ( secrets_config) => SecretManager :: from_aws ( secrets_config) ,
139+ None => SecretManager :: from_fs ( val. node_path . clone ( ) ) ,
140+ }
141+ }
142+ }
0 commit comments