Skip to content

Commit

Permalink
ut: add derive_sub_accounts test
Browse files Browse the repository at this point in the history
  • Loading branch information
XuNeal committed Dec 12, 2023
1 parent 8f262f0 commit a893caf
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 24 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
build-tcx-proto:
cargo build -p tcx-proto

check-tcx:
cd token-core; cargo check

build-tcx:
cd token-core; cargo build

test-tcx:
cd token-core; cargo test
2 changes: 0 additions & 2 deletions token-core/tcx-keystore/src/keystore/hd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ impl HdKeystore {

fn cache_mnemonic(&mut self, mnemonic_bytes: Vec<u8>) -> Result<()> {
let mnemonic_str = String::from_utf8(mnemonic_bytes)?;
println!("mnemonic_str: {}", mnemonic_str);
let _mnemonic = Mnemonic::from_phrase(&mnemonic_str, Language::English)
.map_err(transform_mnemonic_error)?;

Expand Down Expand Up @@ -199,7 +198,6 @@ impl HdKeystore {
let public_key = private_key.public_key();

let address = A::from_public_key(&public_key, coin_info)?;
// todo: ext_pub_key
let ext_pub_key = match coin_info.curve {
CurveType::SubSr25519 | CurveType::BLS | CurveType::ED25519 => "".to_owned(),
_ => root
Expand Down
5 changes: 2 additions & 3 deletions token-core/tcx-migration/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,10 @@ impl LegacyKeystore {
#[cfg(test)]
mod tests {
use serde_json::Value;
use tcx_common::hex_to_bytes;
use tcx_common::FromHex;
use tcx_constants::{CoinInfo, TEST_MNEMONIC};
use tcx_constants::{TEST_PASSWORD, TEST_PRIVATE_KEY};
use tcx_crypto::crypto::SCryptParams;
use tcx_crypto::hex;
use tcx_crypto::Crypto;
use tcx_crypto::Pbkdf2Params;
use tcx_crypto::{EncPair, Key};
Expand Down Expand Up @@ -544,7 +543,7 @@ mod tests {

#[test]
fn test_export_v3_keystore() {
let private_key_bytes = hex_to_bytes(TEST_PRIVATE_KEY).unwrap();
let private_key_bytes = &Vec::<u8>::from_hex(TEST_PRIVATE_KEY).unwrap();
let v3_keystore =
LegacyKeystore::new_v3(&private_key_bytes, TEST_PASSWORD).expect("v3 keystore");
let keystore_json = serde_json::to_string(&v3_keystore).expect("serde v3");
Expand Down
9 changes: 5 additions & 4 deletions token-core/tcx-proto/src/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ message AccountResponse {
string chainType = 1;
string address = 2;
string path = 3;
string extendedPublicKey = 4;
string curve = 4;
string publicKey = 5;
string curve = 6;
string extendedPublicKey = 6;
string encryptedExtendedPublicKey = 7;
}

message DeriveAccountsResult {
Expand Down Expand Up @@ -163,7 +164,7 @@ message SignParam {
string path = 5;
string curve = 6;
string network = 7;
string seg_wit = 8;
string segWit = 8;
google.protobuf.Any input = 9;
}

Expand All @@ -173,7 +174,7 @@ message DeriveSubAccountsParam {
string curve = 3;
string network = 4;
string segWit = 5;
repeated string paths = 6;
repeated string relativePaths = 6;
string extendedPublicKey = 7;
}

Expand Down
8 changes: 5 additions & 3 deletions token-core/tcx/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,13 @@ pub struct AccountResponse {
#[prost(string, tag = "3")]
pub path: ::prost::alloc::string::String,
#[prost(string, tag = "4")]
pub extended_public_key: ::prost::alloc::string::String,
pub curve: ::prost::alloc::string::String,
#[prost(string, tag = "5")]
pub public_key: ::prost::alloc::string::String,
#[prost(string, tag = "6")]
pub curve: ::prost::alloc::string::String,
pub extended_public_key: ::prost::alloc::string::String,
#[prost(string, tag = "7")]
pub encrypted_extended_public_key: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down Expand Up @@ -446,7 +448,7 @@ pub struct DeriveSubAccountsParam {
#[prost(string, tag = "5")]
pub seg_wit: ::prost::alloc::string::String,
#[prost(string, repeated, tag = "6")]
pub paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
pub relative_paths: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
#[prost(string, tag = "7")]
pub extended_public_key: ::prost::alloc::string::String,
}
Expand Down
17 changes: 11 additions & 6 deletions token-core/tcx/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ pub(crate) fn derive_accounts(data: &[u8]) -> Result<Vec<u8>> {
chain_type: derivation.chain_type.to_owned(),
address: account.address.to_owned(),
path: account.derivation_path.to_owned(),
extended_public_key: enc_xpub,
extended_public_key: account.ext_pub_key.to_string(),
encrypted_extended_public_key: enc_xpub,
public_key: account.public_key,
curve: account.curve.as_str().to_string(),
};
Expand Down Expand Up @@ -989,22 +990,26 @@ pub(crate) fn derive_sub_accounts(data: &[u8]) -> Result<Vec<u8>> {
let xpub = TypedDeterministicPublicKey::from_hex(curve, &param.extended_public_key)?;

let account_ret: Vec<Result<AccountResponse>> = param
.paths
.relative_paths
.iter()
.map(|path| {
.map(|relative_path| {
let coin_info = CoinInfo {
coin: param.chain_type.to_string(),
derivation_path: path.to_string(),
derivation_path: relative_path.to_string(),
curve,
network: param.network.to_string(),
seg_wit: param.seg_wit.to_string(),
};
let acc = derive_sub_account(&xpub, &coin_info)?;
let acc: Account = derive_sub_account(&xpub, &coin_info)?;

let enc_xpub = encrypt_xpub(&param.extended_public_key.to_string(), &acc.network)?;

let acc_rsp = AccountResponse {
chain_type: param.chain_type.to_string(),
address: acc.address.to_string(),
path: path.to_string(),
path: relative_path.to_string(),
extended_public_key: param.extended_public_key.to_string(),
encrypted_extended_public_key: enc_xpub,
public_key: acc.public_key,
curve: param.curve.to_string(),
};
Expand Down
132 changes: 126 additions & 6 deletions token-core/tcx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,13 @@ mod tests {

use crate::api::{
sign_param, CreateKeystoreParam, DeriveAccountsParam, DeriveAccountsResult,
DerivedKeyResult, ExistsKeystoreResult, ExportPrivateKeyParam, ExportResult, GeneralResult,
GenerateMnemonicResult, GetPublicKeysParam, GetPublicKeysResult, ImportMnemonicParam,
ImportPrivateKeyParam, InitTokenCoreXParam, KeyType, KeystoreCommonAccountsParam,
KeystoreCommonExistsParam, KeystoreResult, PrivateKeyStoreExportParam, PublicKeyDerivation,
PublicKeyParam, PublicKeyResult, SignHashesParam, SignHashesResult, SignParam,
WalletKeyParam, ZksyncPrivateKeyFromSeedParam, ZksyncPrivateKeyFromSeedResult,
DeriveSubAccountsParam, DeriveSubAccountsResult, DerivedKeyResult, ExistsKeystoreResult,
ExportPrivateKeyParam, ExportResult, GeneralResult, GenerateMnemonicResult,
GetPublicKeysParam, GetPublicKeysResult, ImportMnemonicParam, ImportPrivateKeyParam,
InitTokenCoreXParam, KeyType, KeystoreCommonAccountsParam, KeystoreCommonExistsParam,
KeystoreResult, PrivateKeyStoreExportParam, PublicKeyDerivation, PublicKeyParam,
PublicKeyResult, SignHashesParam, SignHashesResult, SignParam, WalletKeyParam,
ZksyncPrivateKeyFromSeedParam, ZksyncPrivateKeyFromSeedResult,
ZksyncPrivateKeyToPubkeyHashParam, ZksyncPrivateKeyToPubkeyHashResult,
ZksyncSignMusigParam, ZksyncSignMusigResult,
};
Expand Down Expand Up @@ -3475,6 +3476,125 @@ mod tests {
})
}

#[test]
pub fn test_derive_btc_legacy_sub_accounts() {
run_test(|| {
let derivation = Derivation {
chain_type: "BITCOIN".to_string(),
path: "m/44'/0'/0'/0/0".to_string(),
network: "MAINNET".to_string(),
seg_wit: "NONE".to_string(),
chain_id: "".to_string(),
curve: "SECP256k1".to_string(),
bech32_prefix: "".to_string(),
};

let (wallet, accounts) = import_and_derive(derivation);
let params = DeriveSubAccountsParam {
id: wallet.id.to_string(),
chain_type: "BITCOIN".to_string(),
curve: "SECP256k1".to_string(),
network: "MAINNET".to_string(),
seg_wit: "NONE".to_string(),
relative_paths: vec!["0/0".to_string(), "0/1".to_string(), "1/0".to_string()],
extended_public_key: accounts.accounts[0].extended_public_key.to_string(),
};

let result_bytes = derive_sub_accounts(&encode_message(params).unwrap()).unwrap();
let result = DeriveSubAccountsResult::decode(result_bytes.as_slice()).unwrap();
assert_eq!(
"12z6UzsA3tjpaeuvA2Zr9jwx19Azz74D6g",
result.accounts[0].address
);
assert_eq!(
"1962gsZ8PoPUYHneFakkCTrukdFMVQ4i4T",
result.accounts[1].address
);
assert_eq!(
"19vddWhyq637bqDfuKadsoy5mTNRgfb3hr",
result.accounts[2].address
);
})
}

#[test]
pub fn test_derive_btc_p2wpkh_sub_accounts() {
run_test(|| {
let derivation = Derivation {
chain_type: "BITCOIN".to_string(),
path: "m/49'/0'/0'/0/0".to_string(),
network: "MAINNET".to_string(),
seg_wit: "P2WPKH".to_string(),
chain_id: "".to_string(),
curve: "SECP256k1".to_string(),
bech32_prefix: "".to_string(),
};

let (wallet, accounts) = import_and_derive(derivation);
let params = DeriveSubAccountsParam {
id: wallet.id.to_string(),
chain_type: "BITCOIN".to_string(),
curve: "SECP256k1".to_string(),
network: "MAINNET".to_string(),
seg_wit: "P2WPKH".to_string(),
relative_paths: vec!["0/0".to_string(), "0/1".to_string(), "1/0".to_string()],
extended_public_key: accounts.accounts[0].extended_public_key.to_string(),
};

let result_bytes = derive_sub_accounts(&encode_message(params).unwrap()).unwrap();
let result = DeriveSubAccountsResult::decode(result_bytes.as_slice()).unwrap();
assert_eq!(
"3JmreiUEKn8P3SyLYmZ7C1YCd4r2nFy3Dp",
result.accounts[0].address
);
assert_eq!(
"33xJxujVGf4qBmPTnGW9P8wrKCmT7Nwt3t",
result.accounts[1].address
);
assert_eq!(
"33K4nJ6HuM4fuJct11xPPHH65dnGrN5Ggt",
result.accounts[2].address
);
})
}

#[test]
pub fn test_derive_eth_sub_accounts() {
run_test(|| {
let derivation = Derivation {
chain_type: "ETHEREUM".to_string(),
path: "m/44'/60'/0'/0/0".to_string(),
network: "MAINNET".to_string(),
seg_wit: "".to_string(),
chain_id: "".to_string(),
curve: "SECP256k1".to_string(),
bech32_prefix: "".to_string(),
};

let (wallet, accounts) = import_and_derive(derivation);
let params = DeriveSubAccountsParam {
id: wallet.id.to_string(),
chain_type: "ETHEREUM".to_string(),
curve: "SECP256k1".to_string(),
network: "MAINNET".to_string(),
seg_wit: "".to_string(),
relative_paths: vec!["0/0".to_string(), "0/1".to_string()],
extended_public_key: accounts.accounts[0].extended_public_key.to_string(),
};

let result_bytes = derive_sub_accounts(&encode_message(params).unwrap()).unwrap();
let result = DeriveSubAccountsResult::decode(result_bytes.as_slice()).unwrap();
assert_eq!(
"0x6031564e7b2F5cc33737807b2E58DaFF870B590b",
result.accounts[0].address
);
assert_eq!(
"0x80427Ae1f55bCf60ee4CD2db7549b8BC69a74303",
result.accounts[1].address
);
})
}

// #[test]
// pub fn test_eth_ec_sign() {
// run_test(|| {
Expand Down

0 comments on commit a893caf

Please sign in to comment.