Skip to content

Commit

Permalink
feat: add scan_legacy_keystores
Browse files Browse the repository at this point in the history
  • Loading branch information
XuNeal committed Jan 10, 2024
1 parent 4f7d7cd commit c260c9f
Show file tree
Hide file tree
Showing 23 changed files with 949 additions and 1,461 deletions.
868 changes: 48 additions & 820 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ build-tcx:
cd token-core; cargo build

test-tcx:
cd token-core; cargo test
cd token-core; KDF_ROUNDS=1 cargo test
1 change: 1 addition & 0 deletions token-core/tcx-constants/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tcx-common = { path = "../tcx-common" }
failure = "=0.1.8"
lazy_static = "=1.4.0"
serde_json = "=1.0.89"
Expand Down
26 changes: 22 additions & 4 deletions token-core/tcx-constants/src/coin_info.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
use crate::curve::CurveType;
use crate::Result;
use failure::format_err;
use tcx_common::FromHex;

use parking_lot::RwLock;

// pub enum Coin {
// Ethereum { path: String, chain_id: i32 },
// }

pub fn get_xpub_prefix(network: &str, derivation_path: &str) -> Vec<u8> {
if derivation_path.starts_with("m/49'") {
if network == "MAINNET" {
Vec::from_hex("049d7cb2").unwrap()
} else {
Vec::from_hex("044a5262").unwrap()
}
} else if derivation_path.starts_with("m/84'") {
if network == "MAINNET" {
Vec::from_hex("04b24746").unwrap()
} else {
Vec::from_hex("045f1cf6").unwrap()
}
} else {
if network == "MAINNET" {
Vec::from_hex("0488b21e").unwrap()
} else {
Vec::from_hex("043587cf").unwrap()
}
}
}
/// Blockchain basic config
#[derive(Clone)]
pub struct CoinInfo {
Expand Down
26 changes: 2 additions & 24 deletions token-core/tcx-keystore/src/keystore/hd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{transform_mnemonic_error, Account, Address, Error, Metadata, Result,
use std::collections::{hash_map::Entry, HashMap};

use tcx_common::{FromHex, ToHex};
use tcx_constants::{CoinInfo, CurveType};
use tcx_constants::{coin_info::get_xpub_prefix, CoinInfo, CurveType};
use tcx_crypto::{Crypto, Key};
use tcx_primitive::{
generate_mnemonic, get_account_path, Bip32DeterministicPrivateKey, Derive,
Expand Down Expand Up @@ -183,28 +183,6 @@ impl HdKeystore {
})
}

pub fn get_ext_version(network: &str, derivation_path: &str) -> Vec<u8> {
if derivation_path.starts_with("m/49'") {
if network == "MAINNET" {
Vec::from_hex("049d7cb2").unwrap()
} else {
Vec::from_hex("044a5262").unwrap()
}
} else if derivation_path.starts_with("m/84'") {
if network == "MAINNET" {
Vec::from_hex("04b24746").unwrap()
} else {
Vec::from_hex("045f1cf6").unwrap()
}
} else {
if network == "MAINNET" {
Vec::from_hex("0488b21e").unwrap()
} else {
Vec::from_hex("043587cf").unwrap()
}
}
}

pub fn derive_coin<A: Address>(&mut self, coin_info: &CoinInfo) -> Result<Account> {
let cache = self.cache.as_ref().ok_or(Error::KeystoreLocked)?;

Expand All @@ -219,7 +197,7 @@ impl HdKeystore {
_ => root
.derive(&get_account_path(&coin_info.derivation_path)?)?
.deterministic_public_key()
.to_ss58check_with_version(&Self::get_ext_version(
.to_ss58check_with_version(&get_xpub_prefix(
&coin_info.network,
&coin_info.derivation_path,
)),
Expand Down
102 changes: 82 additions & 20 deletions token-core/tcx-migration/src/keystore_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use tcx_keystore::{
mnemonic_to_seed, HdKeystore, Keystore, PrivateKeystore, Result, Source,
};

pub(crate) fn mapping_curve_name(old_curve_name: &str) -> String {
pub fn mapping_curve_name(old_curve_name: &str) -> String {
let new_curve_name = match old_curve_name {
"ED25519" => CurveType::ED25519,
"SECP256k1" => CurveType::SECP256k1,
Expand Down Expand Up @@ -38,7 +38,7 @@ impl KeystoreUpgrade {
&& self.json["imTokenMeta"].is_object()
}

pub fn upgrade(&self, key: &Key) -> Result<Keystore> {
pub fn upgrade(&self, key: &Key, identity_network: &IdentityNetwork) -> Result<Keystore> {
let version = self.json["version"].as_i64().unwrap_or(0);

let mut json = self.json.clone();
Expand Down Expand Up @@ -74,11 +74,6 @@ impl KeystoreUpgrade {
}?;
json["sourceFingerprint"] = json!(fingerprint);

let identity_network = match json["meta"]["network"].as_str().unwrap_or("") {
"TESTNET" => IdentityNetwork::Testnet,
_ => IdentityNetwork::Mainnet,
};

match version {
11001 => {
json["version"] = json!(PrivateKeystore::VERSION);
Expand Down Expand Up @@ -130,7 +125,7 @@ mod tests {
use tcx_constants::CurveType;
use tcx_crypto::Error::PasswordIncorrect;
use tcx_crypto::Key;
use tcx_keystore::{Keystore, Source};
use tcx_keystore::{keystore::IdentityNetwork, Keystore, Source};

fn pk_json(version: i64, source: &str, name: &str) -> Value {
json!(
Expand Down Expand Up @@ -182,7 +177,7 @@ mod tests {
let upgrade_keystore = super::KeystoreUpgrade::new(hd_json(t.0, t.1, "Unknown"));
let key = Key::DerivedKey(hd_derived_key());

let upgraded = upgrade_keystore.upgrade(&key);
let upgraded = upgrade_keystore.upgrade(&key, &IdentityNetwork::Mainnet);

assert!(!upgrade_keystore.need_upgrade());
assert_eq!(upgraded.err().unwrap().to_string(), "invalid version");
Expand All @@ -195,7 +190,9 @@ mod tests {
super::KeystoreUpgrade::new(hd_json(11000, "NEW_IDENTITY", "Unknown"));
let key = Key::Password("imtoken1".to_owned());

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();

assert!(upgrade_keystore.need_upgrade());
assert_eq!(upgraded.store().version, 12000);
Expand All @@ -208,7 +205,9 @@ mod tests {
super::KeystoreUpgrade::new(hd_json(11000, "NEW_IDENTITY", "Unknown"));
let key = Key::DerivedKey("9e6c4391999f0f578105284fe25eb9cf1b60ab75473ac155c83091ae36bf2bb64eb6ec5cbe39dab3a100f87442ee580619700291c15e84961fec2a259c808e69".to_owned());

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();

assert!(upgrade_keystore.need_upgrade());
assert_eq!(upgraded.store().version, 12000);
Expand All @@ -230,14 +229,41 @@ mod tests {
let upgrade_keystore = super::KeystoreUpgrade::new(hd_json(11000, t.0, "Unknown"));
let key = Key::DerivedKey(hd_derived_key());

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();

assert!(upgrade_keystore.need_upgrade());
assert_eq!(upgraded.store().version, 12000);
assert_eq!(upgraded.store().meta.source, t.1);
}
}

#[test]
fn test_upgrade_hd_identity_network() {
let upgrade_keystore =
super::KeystoreUpgrade::new(hd_json(11000, "NEW_IDENTITY", "Unknown"));
let key = Key::DerivedKey(hd_derived_key());

let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();

assert_eq!(
upgraded.identity().identifier,
"im18MDKM8hcTykvMmhLnov9m2BaFqsdjoA7cwNg"
);

let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Mainnet)
.unwrap();

assert_eq!(
upgraded.identity().identifier,
"im14x5GXsdME4JsrHYe2wvznqRz4cUhx2pA4HPf"
);
}

#[test]
fn test_private_keystore_upgrade() {
let tests = [
Expand All @@ -253,20 +279,46 @@ mod tests {
let upgrade_keystore = super::KeystoreUpgrade::new(pk_json(11001, t.0, "vvvvvv"));
let key = Key::DerivedKey(private_derived_key());

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();

assert!(upgrade_keystore.need_upgrade());
assert_eq!(upgraded.store().version, 12001);
assert_eq!(upgraded.store().meta.source, t.1);
}
}

#[test]
fn test_upgrade_pk_identity_network() {
let upgrade_keystore = super::KeystoreUpgrade::new(pk_json(11001, "WIF", "vvvvvv"));
let key = Key::DerivedKey(private_derived_key());

let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();

assert_eq!(
upgraded.identity().identifier,
"im18MDUZKTuAALuXb1Wait1XBb984rdjVpFeBgu"
);

let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Mainnet)
.unwrap();

assert_eq!(
upgraded.identity().identifier,
"im14x5UPbCXmU2HMQ8jfeKcCDrQYhDppRYaa5C6"
);
}

#[test]
fn test_invalid_version() {
let upgrade_keystore = super::KeystoreUpgrade::new(pk_json(11002, "PRIVATE", "SSS"));
let key = Key::DerivedKey(hd_derived_key());

let upgraded = upgrade_keystore.upgrade(&key);
let upgraded = upgrade_keystore.upgrade(&key, &IdentityNetwork::Testnet);
assert!(upgraded.is_err());
}

Expand Down Expand Up @@ -332,7 +384,7 @@ mod tests {
let upgrade_keystore = super::KeystoreUpgrade::new(pk_json(11001, "PRIVATE", "vvvvvv"));
let key = Key::Password("imtoken2".to_owned());

let upgraded = upgrade_keystore.upgrade(&key);
let upgraded = upgrade_keystore.upgrade(&key, &IdentityNetwork::Testnet);
assert_eq!(
upgraded.err().unwrap().to_string(),
PasswordIncorrect.to_string()
Expand Down Expand Up @@ -398,30 +450,40 @@ mod tests {
let upgrade_keystore =
super::KeystoreUpgrade::new(pk_json_with_bls(11001, "PRIVATE", "vvvvvv"));

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();
assert_eq!(upgraded.store().curve, Some(CurveType::BLS));

let upgrade_keystore =
super::KeystoreUpgrade::new(pk_json_with_ed25519(11001, "PRIVATE", "vvvvvv"));

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();
assert_eq!(upgraded.store().curve, Some(CurveType::ED25519));

let upgrade_keystore =
super::KeystoreUpgrade::new(pk_json_with_subsr25519(11001, "PRIVATE", "vvvvvv"));

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();
assert_eq!(upgraded.store().curve, Some(CurveType::SR25519));

let upgrade_keystore =
super::KeystoreUpgrade::new(pk_json_with_secp256k1(11001, "PRIVATE", "vvvvvv"));

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();
assert_eq!(upgraded.store().curve, Some(CurveType::SECP256k1));

let upgrade_keystore = super::KeystoreUpgrade::new(hd_json(11000, "MNEMONIC", "vvvvvv"));

let upgraded = upgrade_keystore.upgrade(&key).unwrap();
let upgraded = upgrade_keystore
.upgrade(&key, &IdentityNetwork::Testnet)
.unwrap();
assert_eq!(upgraded.store().curve, None);
}
}
Loading

0 comments on commit c260c9f

Please sign in to comment.