@@ -44,6 +44,10 @@ use manta_pay::{
4444 AssetMetadata , TokenType ,
4545 } ,
4646} ;
47+
48+ /// previous version of manta-pay state. Should use versioning system for SignerState
49+ use previous_state_manta_pay:: signer:: base:: SignerState as OldSignerState ;
50+
4751use manta_util:: { from_variant, serde:: Serialize } ;
4852use parking_lot:: Mutex ;
4953use std:: {
@@ -436,7 +440,7 @@ where
436440 } ;
437441 let existing_signer = Signer :: from_parts (
438442 parameters. clone ( ) ,
439- Self :: load_state ( existing_state_path, password_hash)
443+ Self :: load_state ( existing_state_path, password_hash, & parameters )
440444 . await
441445 . expect ( "Unable to get dolphin state" ) ?,
442446 ) ;
@@ -474,7 +478,7 @@ where
474478 . expect ( "Unable to recreate signer instance from existing mnemonic." ) ;
475479 Ok ( Some ( state) )
476480 } else {
477- Self :: load_state ( data_path, password_hash) . await
481+ Self :: load_state ( data_path, password_hash, parameters ) . await
478482 }
479483 }
480484
@@ -557,17 +561,51 @@ where
557561 async fn load_state (
558562 data_path : & Path ,
559563 password_hash : & PasswordHash < Argon2 > ,
564+ parameters : & SignerParameters ,
560565 ) -> Result < Option < SignerState > > {
561566 info ! ( "loading signer state from disk" ) ?;
562- let data_path = data_path. to_owned ( ) ;
567+ let data_path_buf = data_path. to_owned ( ) ;
568+ let password_hash_bytes = password_hash. as_bytes ( ) ;
569+
570+ let state_result = task:: spawn_blocking ( move || {
571+ File :: load :: < _ , SignerState > ( & data_path_buf, & password_hash_bytes)
572+ } )
573+ . await ?;
574+
575+ if let Ok ( correct_state) = state_result {
576+ Ok ( Some ( correct_state) )
577+ } else {
578+ // fallback to try from old state version
579+ Self :: new_state_from_old_state ( data_path, password_hash, parameters) . await
580+ }
581+ }
582+
583+ /// Attempts to create new signer state from the old signer state version
584+ #[ inline]
585+ async fn new_state_from_old_state (
586+ data_path : & Path ,
587+ password_hash : & PasswordHash < Argon2 > ,
588+ parameters : & SignerParameters ,
589+ ) -> Result < Option < SignerState > > {
590+ info ! ( "loading mnemonic from old state" ) ?;
591+ let data_path_buf = data_path. to_owned ( ) ;
563592 let password_hash_bytes = password_hash. as_bytes ( ) ;
564593
565594 if let Ok ( state) = task:: spawn_blocking ( move || {
566- File :: load :: < _ , SignerState > ( & data_path , & password_hash_bytes)
595+ File :: load :: < _ , OldSignerState > ( & data_path_buf , & password_hash_bytes)
567596 } )
568597 . await ?
569598 {
570- Ok ( Some ( state) )
599+ let mnemonic = state. accounts ( ) . keys ( ) . expose_mnemonic ( ) . clone ( ) ;
600+
601+ let encoded: Vec < u8 > = bincode:: serialize ( & mnemonic) . expect ( "encoding mnenomic failed" ) ;
602+ let new_mnemonic: Mnemonic =
603+ bincode:: deserialize ( & encoded[ ..] ) . expect ( "decoding mnenomic failed" ) ;
604+
605+ let new_state =
606+ Self :: create_state ( data_path, password_hash, new_mnemonic, parameters) . await ?;
607+
608+ Ok ( Some ( new_state) )
571609 } else {
572610 Ok ( None )
573611 }
0 commit comments