@@ -43,7 +43,7 @@ pub struct ApiMetrics {
43
43
44
44
#[ derive( Clone ) ]
45
45
pub struct ApiState {
46
- pub chains : Arc < HashMap < ChainId , BlockchainState > > ,
46
+ pub chains : Arc < RwLock < HashMap < ChainId , ApiBlockChainState > > > ,
47
47
48
48
pub metrics_registry : Arc < RwLock < Registry > > ,
49
49
@@ -53,7 +53,7 @@ pub struct ApiState {
53
53
54
54
impl ApiState {
55
55
pub async fn new (
56
- chains : HashMap < ChainId , BlockchainState > ,
56
+ chains : Arc < RwLock < HashMap < ChainId , ApiBlockChainState > > > ,
57
57
metrics_registry : Arc < RwLock < Registry > > ,
58
58
) -> ApiState {
59
59
let metrics = ApiMetrics {
@@ -68,7 +68,7 @@ impl ApiState {
68
68
) ;
69
69
70
70
ApiState {
71
- chains : Arc :: new ( chains ) ,
71
+ chains,
72
72
metrics : Arc :: new ( metrics) ,
73
73
metrics_registry,
74
74
}
@@ -94,6 +94,12 @@ pub struct BlockchainState {
94
94
pub confirmed_block_status : BlockStatus ,
95
95
}
96
96
97
+ #[ derive( Clone ) ]
98
+ pub enum ApiBlockChainState {
99
+ Uninitialized ,
100
+ Initialized ( BlockchainState ) ,
101
+ }
102
+
97
103
pub enum RestError {
98
104
/// The caller passed a sequence number that isn't within the supported range
99
105
InvalidSequenceNumber ,
@@ -108,6 +114,9 @@ pub enum RestError {
108
114
/// The server cannot currently communicate with the blockchain, so is not able to verify
109
115
/// which random values have been requested.
110
116
TemporarilyUnavailable ,
117
+ /// The server is not able to process the request because the blockchain initialization
118
+ /// has not been completed yet.
119
+ Uninitialized ,
111
120
/// A catch-all error for all other types of errors that could occur during processing.
112
121
Unknown ,
113
122
}
@@ -137,6 +146,11 @@ impl IntoResponse for RestError {
137
146
"This service is temporarily unavailable" ,
138
147
)
139
148
. into_response ( ) ,
149
+ RestError :: Uninitialized => (
150
+ StatusCode :: SERVICE_UNAVAILABLE ,
151
+ "The service is not yet initialized for this chain, please try again in a few minutes" ,
152
+ )
153
+ . into_response ( ) ,
140
154
RestError :: Unknown => (
141
155
StatusCode :: INTERNAL_SERVER_ERROR ,
142
156
"An unknown error occurred processing the request" ,
@@ -172,6 +186,7 @@ pub fn get_register_uri(base_uri: &str, chain_id: &str) -> Result<String> {
172
186
173
187
#[ cfg( test) ]
174
188
mod test {
189
+ use crate :: api:: ApiBlockChainState ;
175
190
use {
176
191
crate :: {
177
192
api:: { self , ApiState , BinaryEncoding , Blob , BlockchainState , GetRandomValueResponse } ,
@@ -228,10 +243,16 @@ mod test {
228
243
} ;
229
244
230
245
let mut chains = HashMap :: new ( ) ;
231
- chains. insert ( "ethereum" . into ( ) , eth_state) ;
232
- chains. insert ( "avalanche" . into ( ) , avax_state) ;
246
+ chains. insert (
247
+ "ethereum" . into ( ) ,
248
+ ApiBlockChainState :: Initialized ( eth_state) ,
249
+ ) ;
250
+ chains. insert (
251
+ "avalanche" . into ( ) ,
252
+ ApiBlockChainState :: Initialized ( avax_state) ,
253
+ ) ;
233
254
234
- let api_state = ApiState :: new ( chains, metrics_registry) . await ;
255
+ let api_state = ApiState :: new ( Arc :: new ( RwLock :: new ( chains) ) , metrics_registry) . await ;
235
256
236
257
let app = api:: routes ( api_state) ;
237
258
( TestServer :: new ( app) . unwrap ( ) , eth_read, avax_read)
0 commit comments