1
+ use chrono:: Local ;
1
2
use clap:: Parser ;
3
+ use semver:: { Version , VersionReq } ;
2
4
use slog:: { o, Drain , Level , Logger } ;
3
- use slog_scope:: debug;
5
+ use slog_scope:: { debug, warn} ;
6
+ use sqlite:: Connection ;
4
7
use std:: sync:: Arc ;
5
8
use std:: time:: Duration ;
6
9
use std:: { error:: Error , path:: PathBuf } ;
7
10
11
+ use mithril_common:: database:: {
12
+ ApplicationNodeType , ApplicationVersion , VersionProvider , VersionUpdaterProvider ,
13
+ } ;
8
14
use mithril_signer:: {
9
15
Config , ProductionServiceBuilder , ServiceBuilder , SignerRunner , SignerState , StateMachine ,
10
16
} ;
@@ -60,6 +66,43 @@ fn build_logger(min_level: Level) -> Logger {
60
66
Logger :: root ( Arc :: new ( drain) , o ! ( ) )
61
67
}
62
68
69
+ fn check_database ( filepath : & PathBuf ) -> Result < ( ) , Box < dyn Error > > {
70
+ let connection = Connection :: open ( filepath) ?;
71
+ let provider = VersionProvider :: new ( & connection) ;
72
+ provider. create_table_if_not_exists ( ) ?;
73
+ let application_type = ApplicationNodeType :: new ( "aggregator" ) ?;
74
+ let maybe_option = provider. get_application_version ( & application_type) ?;
75
+ let current_version = ApplicationVersion {
76
+ semver : Version :: parse ( env ! ( "CARGO_PKG_VERSION" ) ) ?,
77
+ application_type,
78
+ updated_at : Local :: now ( ) . naive_local ( ) ,
79
+ } ;
80
+
81
+ match maybe_option {
82
+ None => {
83
+ let provider = VersionUpdaterProvider :: new ( & connection) ;
84
+ let _ = provider. save ( current_version) ?;
85
+ debug ! ( "application version saved in database" ) ;
86
+ }
87
+ Some ( version) => {
88
+ let req = VersionReq :: parse ( & current_version. semver . to_string ( ) ) . unwrap ( ) ;
89
+
90
+ if !req. matches ( & version. semver ) {
91
+ warn ! (
92
+ "application version '{}' is out of date, new version is '{}'. Upgrading database…" ,
93
+ version. semver, current_version. semver
94
+ ) ;
95
+ let upgrader_provider = VersionUpdaterProvider :: new ( & connection) ;
96
+ upgrader_provider. save ( current_version) ?;
97
+ debug ! ( "database updated" ) ;
98
+ } else {
99
+ debug ! ( "database up to date" ) ;
100
+ }
101
+ }
102
+ } ;
103
+ Ok ( ( ) )
104
+ }
105
+
63
106
#[ tokio:: main]
64
107
async fn main ( ) -> Result < ( ) , Box < dyn Error > > {
65
108
// Load args
@@ -81,14 +124,13 @@ async fn main() -> Result<(), Box<dyn Error>> {
81
124
. map_err ( |e| format ! ( "configuration build error: {}" , e) ) ?
82
125
. try_deserialize ( )
83
126
. map_err ( |e| format ! ( "configuration deserialize error: {}" , e) ) ?;
127
+ let services = ProductionServiceBuilder :: new ( & config) . build ( ) ?;
128
+ check_database ( & config. data_stores_directory ) ?;
84
129
debug ! ( "Started" ; "run_mode" => & args. run_mode, "config" => format!( "{:?}" , config) ) ;
85
130
86
131
let mut state_machine = StateMachine :: new (
87
132
SignerState :: Unregistered ( None ) ,
88
- Box :: new ( SignerRunner :: new (
89
- config. clone ( ) ,
90
- ProductionServiceBuilder :: new ( & config) . build ( ) ?,
91
- ) ) ,
133
+ Box :: new ( SignerRunner :: new ( config. clone ( ) , services) ) ,
92
134
Duration :: from_millis ( config. run_interval ) ,
93
135
) ;
94
136
state_machine. run ( ) . await
0 commit comments