1
1
use bitflags:: bitflags;
2
+ use gcs:: http:: objects:: upload as gcs_upload;
3
+ use google_cloud_auth:: credentials:: CredentialsFile as GcpCredentialsFile ;
4
+ use google_cloud_storage as gcs;
2
5
use mina_p2p_messages:: v2:: { self } ;
3
6
use node:: core:: { channels:: mpsc, thread} ;
4
7
use node:: ledger:: write:: BlockApplyResult ;
@@ -84,7 +87,21 @@ impl ArchiveStorageOptions {
84
87
// }
85
88
}
86
89
87
- // TODO(adonagy): Add GCP precomputed storage validation
90
+ if self . uses_gcp_precomputed_storage ( ) {
91
+ if env:: var ( "GCP_CREDENTIALS_JSON" ) . is_err ( ) {
92
+ return Err (
93
+ "GCP_CREDENTIALS_JSON is required when GCP_PRECOMPUTED_STORAGE is enabled"
94
+ . to_string ( ) ,
95
+ ) ;
96
+ }
97
+
98
+ if env:: var ( "GCP_BUCKET_NAME" ) . is_err ( ) {
99
+ return Err (
100
+ "GCP_BUCKET_NAME is required when GCP_PRECOMPUTED_STORAGE is enabled"
101
+ . to_string ( ) ,
102
+ ) ;
103
+ }
104
+ }
88
105
89
106
Ok ( ( ) )
90
107
}
@@ -112,7 +129,7 @@ pub struct ArchiveService {
112
129
113
130
struct ArchiveServiceClients {
114
131
aws_client : Option < ArchiveAWSClient > ,
115
- gcp_client : Option < ( ) > ,
132
+ gcp_client : Option < ArchiveGCPClient > ,
116
133
local_path : Option < String > ,
117
134
}
118
135
@@ -122,6 +139,11 @@ struct ArchiveAWSClient {
122
139
bucket_path : String ,
123
140
}
124
141
142
+ struct ArchiveGCPClient {
143
+ client : gcs:: client:: Client ,
144
+ bucket_name : String ,
145
+ }
146
+
125
147
impl ArchiveServiceClients {
126
148
async fn new ( options : & ArchiveStorageOptions , work_dir : String ) -> Self {
127
149
let aws_client = if options. uses_aws_precomputed_storage ( ) {
@@ -137,6 +159,23 @@ impl ArchiveServiceClients {
137
159
None
138
160
} ;
139
161
162
+ let gcp_client = if options. uses_gcp_precomputed_storage ( ) {
163
+ let cred_file = env:: var ( "GCP_CREDENTIALS_JSON" ) . unwrap_or_default ( ) ;
164
+ let bucket_name = env:: var ( "GCP_BUCKET_NAME" ) . unwrap_or_default ( ) ;
165
+ let credentials = GcpCredentialsFile :: new_from_file ( cred_file) . await . unwrap ( ) ;
166
+ let config = gcs:: client:: ClientConfig :: default ( )
167
+ . with_credentials ( credentials)
168
+ . await
169
+ . unwrap ( ) ;
170
+ let client = gcs:: client:: Client :: new ( config) ;
171
+ Some ( ArchiveGCPClient {
172
+ client,
173
+ bucket_name,
174
+ } )
175
+ } else {
176
+ None
177
+ } ;
178
+
140
179
let local_path = if options. uses_local_precomputed_storage ( ) {
141
180
let env_path = env:: var ( "OPENMINA_LOCAL_PRECOMPUTED_STORAGE_PATH" ) ;
142
181
let default = format ! ( "{}/archive-precomputed" , work_dir) ;
@@ -147,7 +186,7 @@ impl ArchiveServiceClients {
147
186
148
187
Self {
149
188
aws_client,
150
- gcp_client : None ,
189
+ gcp_client,
151
190
local_path,
152
191
}
153
192
}
@@ -156,7 +195,7 @@ impl ArchiveServiceClients {
156
195
self . aws_client . as_ref ( )
157
196
}
158
197
159
- pub fn gcp_client ( & self ) -> Option < & ( ) > {
198
+ pub fn gcp_client ( & self ) -> Option < & ArchiveGCPClient > {
160
199
self . gcp_client . as_ref ( )
161
200
}
162
201
@@ -268,7 +307,34 @@ impl ArchiveService {
268
307
}
269
308
270
309
if options. uses_gcp_precomputed_storage ( ) {
271
- // TODO(adonagy): Implement GCP precomputed storage
310
+ if let Some ( client) = clients. gcp_client ( ) {
311
+ // TODO(adonagy): Serialize just once?
312
+ let json = serde_json:: to_string ( & precomputed_block) . unwrap ( ) ;
313
+ let upload_type =
314
+ gcs_upload:: UploadType :: Simple ( gcs_upload:: Media :: new ( key. clone ( ) ) ) ;
315
+ let uploaded = client
316
+ . client
317
+ . upload_object (
318
+ & gcs_upload:: UploadObjectRequest {
319
+ bucket : client. bucket_name . clone ( ) ,
320
+ ..Default :: default ( )
321
+ } ,
322
+ json. as_bytes ( ) . to_vec ( ) ,
323
+ & upload_type,
324
+ )
325
+ . await ;
326
+
327
+ if let Err ( e) = uploaded {
328
+ node:: core:: warn!(
329
+ summary = "Failed to upload precomputed block to GCP" ,
330
+ error = e. to_string( )
331
+ ) ;
332
+ } else {
333
+ node:: core:: warn!(
334
+ summary = "Successfully uploaded precomputed block to GCP"
335
+ ) ;
336
+ }
337
+ }
272
338
}
273
339
274
340
if options. uses_aws_precomputed_storage ( ) {
0 commit comments