33use {
44 crate :: { self as cluster, client, node, smart_contract, Client , Config , EncryptionKey , Node } ,
55 derive_more:: derive:: AsRef ,
6+ libp2p_identity:: PeerId ,
67 serde:: { Deserialize , Serialize } ,
7- std:: sync:: {
8- atomic:: { self , AtomicUsize } ,
9- Arc ,
8+ std:: {
9+ net:: Ipv4Addr ,
10+ sync:: {
11+ atomic:: { self , AtomicUsize } ,
12+ Arc ,
13+ } ,
1014 } ,
1115 tap:: Tap ,
1216} ;
@@ -189,11 +193,22 @@ impl NodeOperator {
189193 }
190194}
191195
192- impl < C : Config > NodeOperator < C > {
193- pub ( super ) fn try_from_sc (
196+ impl < N > NodeOperator < N > {
197+ pub ( super ) fn from_sc (
194198 operator : smart_contract:: NodeOperator ,
195- cfg : & C ,
196- ) -> Result < NodeOperator < C :: Node > , TryFromSmartContractError > {
199+ cfg : & impl Config < Node = N > ,
200+ ) -> Self {
201+ let id = operator. id ;
202+
203+ NodeOperator :: try_from_sc ( operator, cfg)
204+ . map_err ( |err| tracing:: warn!( %id, ?err, "Invalid NodeOperator" ) )
205+ . unwrap_or_else ( |_| NodeOperator :: new_corrupted ( id, cfg) )
206+ }
207+
208+ fn try_from_sc (
209+ operator : smart_contract:: NodeOperator ,
210+ cfg : & impl Config < Node = N > ,
211+ ) -> Result < Self , TryFromSmartContractError > {
197212 use TryFromSmartContractError as Error ;
198213
199214 let data_bytes = operator. data ;
@@ -205,22 +220,57 @@ impl<C: Config> NodeOperator<C> {
205220 let schema_version = data_bytes[ 0 ] ;
206221 let bytes = & data_bytes[ 1 ..] ;
207222
208- let data = match schema_version {
209- 0 => postcard:: from_bytes :: < DataV0 > ( bytes) ,
210- ver => return Err ( Error :: UnknownSchemaVersion ( ver) ) ,
223+ match schema_version {
224+ 0 => {
225+ let data = postcard:: from_bytes :: < DataV0 > ( bytes) . map_err ( Error :: from_postcard) ?;
226+
227+ let nodes = data
228+ . nodes
229+ . into_iter ( )
230+ . map ( |v0| Node :: from ( v0) . tap_mut ( |node| node. decrypt ( cfg. as_ref ( ) ) ) )
231+ . map ( |node| cfg. new_node ( operator. id , node) )
232+ . collect ( ) ;
233+
234+ let clients = data. clients . into_iter ( ) . map ( Into :: into) . collect ( ) ;
235+
236+ Ok ( NodeOperator :: new ( operator. id , data. name , nodes, clients) ?)
237+ }
238+ 1 => {
239+ let data = postcard:: from_bytes :: < DataV1 > ( bytes) . map_err ( Error :: from_postcard) ?;
240+
241+ let nodes = data
242+ . nodes
243+ . into_iter ( )
244+ . map ( |v1| Node :: from ( v1) . tap_mut ( |node| node. decrypt ( cfg. as_ref ( ) ) ) )
245+ . map ( |node| cfg. new_node ( operator. id , node) )
246+ . collect ( ) ;
247+
248+ let clients = data. clients . into_iter ( ) . map ( Into :: into) . collect ( ) ;
249+
250+ Ok ( NodeOperator :: new ( operator. id , data. name , nodes, clients) ?)
251+ }
252+ ver => Err ( Error :: UnknownSchemaVersion ( ver) ) ,
211253 }
212- . map_err ( Error :: from_postcard ) ? ;
254+ }
213255
214- let nodes = data
215- . nodes
216- . into_iter ( )
217- . map ( |v0| Node :: from ( v0) . tap_mut ( |node| node. decrypt ( cfg. as_ref ( ) ) ) )
218- . map ( |node| cfg. new_node ( operator. id , node) )
256+ fn new_corrupted ( id : Id , cfg : & impl Config < Node = N > ) -> Self {
257+ let nodes = ( 0 ..MIN_NODES )
258+ . map ( |_| Node {
259+ peer_id : PeerId :: random ( ) ,
260+ ipv4_addr : Ipv4Addr :: UNSPECIFIED ,
261+ primary_port : 0 ,
262+ secondary_port : 0 ,
263+ } )
264+ . map ( |node| cfg. new_node ( id, node) )
219265 . collect ( ) ;
220266
221- let clients = data. clients . into_iter ( ) . map ( Into :: into) . collect ( ) ;
222-
223- Ok ( NodeOperator :: new ( operator. id , data. name , nodes, clients) ?)
267+ Self {
268+ id,
269+ name : Name ( "CORRUPTED_DATA" . to_string ( ) ) ,
270+ clients : vec ! [ ] ,
271+ nodes,
272+ counter : Default :: default ( ) ,
273+ }
224274 }
225275}
226276
@@ -234,6 +284,16 @@ struct DataV0 {
234284 clients : Vec < client:: V0 > ,
235285}
236286
287+ // NOTE: The on-chain serialization is non self-describing!
288+ // This `struct` can not be changed, a `struct` with a new schema version should
289+ // be created instead.
290+ #[ derive( Debug , Clone , Deserialize , Serialize ) ]
291+ struct DataV1 {
292+ name : Name ,
293+ nodes : Vec < node:: V1 > ,
294+ clients : Vec < client:: V0 > ,
295+ }
296+
237297#[ derive( Debug , thiserror:: Error ) ]
238298pub enum TryIntoSmartContractError {
239299 #[ error( "Codec: {0}" ) ]
0 commit comments