/// Decode stable memory for the ledger canister.
Decode stable memory for the ledger canister.
Decode stable memory for the ledger canister .
fn decode_ledger_stable_memory(cbor: PathBuf, output: &Path) {
    // For the same argument as above, do NOT deserialize to a specific struct.
    // This is an audit tool, we don't want any risk of dropping data.
    // So go the schema-less way.
    use serde_cbor::value::Value;
    let value_res: serde_cbor::Result<Value> =
        serde_cbor::from_reader(File::open(cbor.clone()).unwrap());
    let val = match value_res {
        Err(e) => {
            eprintln!(
                "Could not parse the cbor for the ledger stable memory: {}",
                e
            );
            return;
        }
        Ok(v) => v,
    };
    // The following is very slow and the output is very verbose. Serialization to
    // json is not a viable alternative as some keys are not strings, which is
    // allowed in cbor but not in json.
    match write!(
        File::create(output.join("ledger_stable_memory.txt")).unwrap(),
        "{:#?}",
        val
    ) {
        Ok(()) => eprintln!("Wrote ledger_stable_memory.txt"),
        Err(e) => eprintln!("Could not write ledger_stable_memory.txt: {}", e),
    };
    let ledger: ledger_canister::Ledger = match serde_cbor::from_reader(File::open(cbor).unwrap()) {
        Err(e) => {
            eprintln!(
                "Could parse the ledger stable memory as a Ledger struct: {}",
                e
            );
            return;
        }
        Ok(l) => l,
    };
    let mut records: Vec<LedgerBalanceRecord> = ledger
        .balances
        .store
        .iter()
        .map(|(key, icpts)| LedgerBalanceRecord {
            account_identitifier: key.to_string(),
            balance_e8s: icpts.get_e8s(),
        })
        .collect();
    records.sort_by_key(|record| record.account_identitifier.clone());
    let mut csv_writer =
        csv::Writer::from_path(output.join("ledger_balances_EXTRACT.csv")).unwrap();
    for r in records.into_iter() {
        csv_writer.serialize(r).unwrap();
    }
    eprintln!("Wrote ledger_balances_EXTRACT.csv");
}
fn decode_ledger_stable_memory ( cbor : PathBuf , output : & Path ) { // For the same argument as above, do NOT deserialize to a specific struct. // This is an audit tool, we don't want any risk of dropping data. // So go the schema-less way. use serde_cbor :: value :: Value ; let value_res : serde_cbor :: Result < Value > = serde_cbor :: from_reader ( File :: open ( cbor . clone ( ) ) . unwrap ( ) ) ; let val = match value_res { Err ( e ) => { eprintln ! ( " " e ) ; return ; } Ok ( v ) => v , } ; // The following is very slow and the output is very verbose. Serialization to // json is not a viable alternative as some keys are not strings, which is // allowed in cbor but not in json. match write ! ( File create ( output join ( " " ) ) unwrap ( ) " " val ) { Ok ( ( ) ) => eprintln ! ( " " ) , Err ( e ) => eprintln ! ( " " e ) , } ; let ledger : ledger_canister :: Ledger = match serde_cbor :: from_reader ( File :: open ( cbor ) . unwrap ( ) ) { Err ( e ) => { eprintln ! ( " " e ) ; return ; } Ok ( l ) => l , } ; let mut records : Vec < LedgerBalanceRecord > = ledger . balances . store . iter ( ) . map ( | ( key , icpts ) | LedgerBalanceRecord { account_identitifier : key . to_string ( ) , balance_e8s : icpts . get_e8s ( ) , } ) . collect ( ) ; records . sort_by_key ( | record | record . account_identitifier . clone ( ) ) ; let mut csv_writer = csv :: Writer :: from_path ( output . join ( " " ) ) . unwrap ( ) ; for r in records . into_iter ( ) { csv_writer . serialize ( r ) . unwrap ( ) ; } eprintln ! ( " " ) ; }
Decode stable memory for the ledger canister.
Decode stable memory for the ledger canister .
cbor
PathBuf
output
&Path