4
4
use starcoin_crypto:: HashValue ;
5
5
use starcoin_statedb:: { ChainStateDB , ChainStateReader , ChainStateWriter } ;
6
6
use starcoin_storage:: { db_storage:: DBStorage , storage:: StorageInstance , Storage , StorageVersion } ;
7
+ use starcoin_types:: state_set:: StateSet ;
7
8
use starcoin_types:: {
8
9
account_address:: AccountAddress ,
9
10
state_set:: { AccountStateSet , ChainStateSet } ,
10
11
} ;
11
12
use std:: path:: Path ;
12
13
use std:: sync:: Arc ;
13
14
14
- pub fn import ( csv_path : & Path , db_path : & Path ) -> anyhow:: Result < ( ) > {
15
+ pub fn import ( csv_path : & Path , db_path : & Path , expect_root_hash : HashValue ) -> anyhow:: Result < ( ) > {
15
16
let db_storage = DBStorage :: open_with_cfs (
16
17
db_path,
17
18
StorageVersion :: current_version ( )
@@ -24,42 +25,63 @@ pub fn import(csv_path: &Path, db_path: &Path) -> anyhow::Result<()> {
24
25
let storage = Storage :: new ( StorageInstance :: new_db_instance ( db_storage) ) ?;
25
26
let storage = Arc :: new ( storage) ;
26
27
let statedb = ChainStateDB :: new ( storage. clone ( ) , None ) ;
27
- import_from_statedb ( & statedb, csv_path)
28
+ import_from_statedb ( & statedb, csv_path, expect_root_hash )
28
29
}
29
30
30
31
/// Import resources and code from CSV file to a new statedb
31
- pub fn import_from_statedb ( statedb : & ChainStateDB , csv_path : & Path ) -> anyhow:: Result < ( ) > {
32
+ pub fn import_from_statedb (
33
+ statedb : & ChainStateDB ,
34
+ csv_path : & Path ,
35
+ expect_state_root_hash : HashValue ,
36
+ ) -> anyhow:: Result < ( ) > {
32
37
// Read CSV file
33
38
let mut csv_reader = csv:: Reader :: from_path ( csv_path) ?;
34
- let mut expected_state_root = None ;
35
- let mut state_sets = Vec :: new ( ) ;
39
+ let mut chain_state_set_data = Vec :: new ( ) ;
36
40
37
41
for result in csv_reader. records ( ) {
38
42
let record = result?;
39
- let address: AccountAddress = serde_json:: from_str ( & record[ 0 ] ) ?;
40
- let state_root: HashValue = serde_json:: from_str ( & record[ 1 ] ) ?;
41
- let account_state: AccountStateSet = serde_json:: from_str ( & record[ 2 ] ) ?;
43
+ let account_address: AccountAddress = serde_json:: from_str ( & record[ 0 ] ) ?;
44
+ println ! ( "record len: {:?}" , record. len( ) ) ;
42
45
43
- // Store the first state root as expected
44
- if expected_state_root. is_none ( ) {
45
- expected_state_root = Some ( state_root) ;
46
- }
46
+ let code_state_set = if !record[ 1 ] . is_empty ( ) && !record[ 2 ] . is_empty ( ) {
47
+ let code_state_hash: String = serde_json:: from_str ( & record[ 1 ] ) ?;
48
+ let code_state_set_str = & record[ 2 ] ;
49
+ assert_eq ! (
50
+ code_state_hash,
51
+ HashValue :: sha3_256_of( code_state_set_str. as_bytes( ) ) . to_hex_literal( )
52
+ ) ;
53
+ Some ( serde_json:: from_str :: < StateSet > ( code_state_set_str) ?)
54
+ } else {
55
+ None
56
+ } ;
57
+
58
+ let resource_state_set = if !record[ 3 ] . is_empty ( ) && !record[ 4 ] . is_empty ( ) {
59
+ let resrouce_blob_hash: String = serde_json:: from_str ( & record[ 3 ] ) ?;
60
+ let resource_state_set_str = & record[ 4 ] ;
61
+ assert_eq ! (
62
+ resrouce_blob_hash,
63
+ HashValue :: sha3_256_of( resource_state_set_str. as_bytes( ) ) . to_hex_literal( )
64
+ ) ;
65
+ Some ( serde_json:: from_str ( resource_state_set_str) ?)
66
+ } else {
67
+ None
68
+ } ;
47
69
48
- // Add to state sets
49
- state_sets. push ( ( address, account_state) ) ;
70
+ chain_state_set_data. push ( (
71
+ account_address,
72
+ AccountStateSet :: new ( vec ! [ code_state_set, resource_state_set] ) ,
73
+ ) ) ;
50
74
}
51
75
52
- // Create chain state set and apply it
53
- let chain_state_set = ChainStateSet :: new ( state_sets) ;
54
- statedb. apply ( chain_state_set) ?;
76
+ statedb. apply ( ChainStateSet :: new ( chain_state_set_data) ) ?;
55
77
56
78
// Get new state root
57
79
let new_state_root = statedb. state_root ( ) ;
58
80
59
81
// Verify state root matches
60
- if let Some ( expected ) = expected_state_root {
82
+ {
61
83
assert_eq ! (
62
- new_state_root , expected ,
84
+ expect_state_root_hash , new_state_root ,
63
85
"Imported state root does not match expected state root"
64
86
) ;
65
87
println ! ( "Import successful! State root: {}" , new_state_root) ;
@@ -91,7 +113,7 @@ mod test {
91
113
// Export data
92
114
{
93
115
let mut csv_writer = csv:: WriterBuilder :: new ( ) . from_path ( & export_path) ?;
94
- export_from_statedb ( & export_chain_statedb, export_state_root , & mut csv_writer) ?;
116
+ export_from_statedb ( & export_chain_statedb, & mut csv_writer) ?;
95
117
}
96
118
97
119
//////////////////////////////////////////////////////
@@ -113,14 +135,7 @@ mod test {
113
135
let storage = Storage :: new ( StorageInstance :: new_db_instance ( db_storage) ) ?;
114
136
let storage = Arc :: new ( storage) ;
115
137
let imported_statedb = ChainStateDB :: new ( storage. clone ( ) , None ) ;
116
- import_from_statedb ( & imported_statedb, & export_path) ?;
117
-
118
- // Verify state root matches
119
- assert_eq ! (
120
- imported_statedb. state_root( ) ,
121
- export_state_root,
122
- "Imported state root does not match genesis state root"
123
- ) ;
138
+ import_from_statedb ( & imported_statedb, & export_path, export_state_root) ?;
124
139
125
140
Ok ( ( ) )
126
141
}
0 commit comments