mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-08 16:23:12 +00:00
fix: clearing and renaming
This commit is contained in:
parent
74f0c983d3
commit
35b636a27d
@ -4,8 +4,7 @@ members = [
|
|||||||
"integration_tests",
|
"integration_tests",
|
||||||
"sequencer_runner",
|
"sequencer_runner",
|
||||||
"storage",
|
"storage",
|
||||||
"accounts",
|
"key_protocol",
|
||||||
"utxo",
|
|
||||||
"sequencer_rpc",
|
"sequencer_rpc",
|
||||||
"mempool",
|
"mempool",
|
||||||
"wallet",
|
"wallet",
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
pub mod account_core;
|
|
||||||
pub mod key_management;
|
|
||||||
@ -36,5 +36,5 @@ path = "../wallet"
|
|||||||
[dependencies.common]
|
[dependencies.common]
|
||||||
path = "../common"
|
path = "../common"
|
||||||
|
|
||||||
[dependencies.accounts]
|
[dependencies.key_protocol]
|
||||||
path = "../accounts"
|
path = "../key_protocol"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "accounts"
|
name = "key_protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
@ -18,9 +18,6 @@ aes-gcm.workspace = true
|
|||||||
lazy_static.workspace = true
|
lazy_static.workspace = true
|
||||||
tiny-keccak.workspace = true
|
tiny-keccak.workspace = true
|
||||||
|
|
||||||
[dependencies.utxo]
|
|
||||||
path = "../utxo"
|
|
||||||
|
|
||||||
[dependencies.common]
|
[dependencies.common]
|
||||||
path = "../common"
|
path = "../common"
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ use rand::{rngs::OsRng, Rng};
|
|||||||
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::account_core::PublicKey;
|
use crate::key_protocol_core::PublicKey;
|
||||||
pub type PublicAccountSigningKey = [u8; 32];
|
pub type PublicAccountSigningKey = [u8; 32];
|
||||||
use nssa::{self};
|
use nssa::{self};
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ pub mod secret_holders;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
///Entrypoint to key management
|
///Entrypoint to key management
|
||||||
pub struct AddressKeyHolder {
|
pub struct KeyChain {
|
||||||
top_secret_key_holder: TopSecretKeyHolder,
|
top_secret_key_holder: TopSecretKeyHolder,
|
||||||
pub utxo_secret_key_holder: UTXOSecretKeyHolder,
|
pub utxo_secret_key_holder: UTXOSecretKeyHolder,
|
||||||
pub_account_signing_key: nssa::PrivateKey,
|
pub_account_signing_key: nssa::PrivateKey,
|
||||||
@ -25,7 +25,7 @@ pub struct AddressKeyHolder {
|
|||||||
pub viewing_public_key: PublicKey,
|
pub viewing_public_key: PublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddressKeyHolder {
|
impl KeyChain {
|
||||||
pub fn new_os_random() -> Self {
|
pub fn new_os_random() -> Self {
|
||||||
//Currently dropping SeedHolder at the end of initialization.
|
//Currently dropping SeedHolder at the end of initialization.
|
||||||
//Now entirely sure if we need it in the future.
|
//Now entirely sure if we need it in the future.
|
||||||
@ -127,8 +127,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_os_random() {
|
fn test_new_os_random() {
|
||||||
// Ensure that a new AddressKeyHolder instance can be created without errors.
|
// Ensure that a new KeyChain instance can be created without errors.
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Check that key holder fields are initialized with expected types
|
// Check that key holder fields are initialized with expected types
|
||||||
assert!(!Into::<bool>::into(
|
assert!(!Into::<bool>::into(
|
||||||
@ -141,7 +141,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_shared_secret_receiver() {
|
fn test_calculate_shared_secret_receiver() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Generate a random ephemeral public key sender
|
// Generate a random ephemeral public key sender
|
||||||
let scalar = Scalar::random(&mut OsRng);
|
let scalar = Scalar::random(&mut OsRng);
|
||||||
@ -157,7 +157,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_decrypt_data() {
|
fn test_decrypt_data() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Generate an ephemeral key and shared secret
|
// Generate an ephemeral key and shared secret
|
||||||
let ephemeral_public_key_sender =
|
let ephemeral_public_key_sender =
|
||||||
@ -188,8 +188,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_os_random_initialization() {
|
fn test_new_os_random_initialization() {
|
||||||
// Ensure that AddressKeyHolder is initialized correctly
|
// Ensure that KeyChain is initialized correctly
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Check that key holder fields are initialized with expected types and values
|
// Check that key holder fields are initialized with expected types and values
|
||||||
assert!(!Into::<bool>::into(
|
assert!(!Into::<bool>::into(
|
||||||
@ -202,7 +202,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_shared_secret_with_identity_point() {
|
fn test_calculate_shared_secret_with_identity_point() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Use identity point as ephemeral public key
|
// Use identity point as ephemeral public key
|
||||||
let identity_point = AffinePoint::identity();
|
let identity_point = AffinePoint::identity();
|
||||||
@ -217,7 +217,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_decrypt_data_with_incorrect_nonce() {
|
fn test_decrypt_data_with_incorrect_nonce() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Generate ephemeral public key and shared secret
|
// Generate ephemeral public key and shared secret
|
||||||
let scalar = Scalar::random(OsRng);
|
let scalar = Scalar::random(OsRng);
|
||||||
@ -250,7 +250,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_decrypt_data_with_incorrect_ciphertext() {
|
fn test_decrypt_data_with_incorrect_ciphertext() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Generate ephemeral public key and shared secret
|
// Generate ephemeral public key and shared secret
|
||||||
let scalar = Scalar::random(OsRng);
|
let scalar = Scalar::random(OsRng);
|
||||||
@ -285,7 +285,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encryption_decryption_round_trip() {
|
fn test_encryption_decryption_round_trip() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
|
|
||||||
// Generate ephemeral key and shared secret
|
// Generate ephemeral key and shared secret
|
||||||
let scalar = Scalar::random(OsRng);
|
let scalar = Scalar::random(OsRng);
|
||||||
@ -303,7 +303,7 @@ mod tests {
|
|||||||
.encrypt(nonce, plaintext.as_ref())
|
.encrypt(nonce, plaintext.as_ref())
|
||||||
.expect("encryption failure");
|
.expect("encryption failure");
|
||||||
|
|
||||||
// Decrypt the data using the `AddressKeyHolder` instance
|
// Decrypt the data using the `KeyChain` instance
|
||||||
let decrypted_data = address_key_holder
|
let decrypted_data = address_key_holder
|
||||||
.decrypt_data(
|
.decrypt_data(
|
||||||
ephemeral_public_key_sender,
|
ephemeral_public_key_sender,
|
||||||
@ -318,7 +318,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_public_account_signing_key() {
|
fn test_get_public_account_signing_key() {
|
||||||
let address_key_holder = AddressKeyHolder::new_os_random();
|
let address_key_holder = KeyChain::new_os_random();
|
||||||
let signing_key = address_key_holder.get_pub_account_signing_key();
|
let signing_key = address_key_holder.get_pub_account_signing_key();
|
||||||
assert_eq!(signing_key, &address_key_holder.pub_account_signing_key);
|
assert_eq!(signing_key, &address_key_holder.pub_account_signing_key);
|
||||||
}
|
}
|
||||||
@ -1,83 +1,68 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use common::{merkle_tree_public::TreeHashType, transaction::Tag};
|
use common::transaction::Tag;
|
||||||
use k256::AffinePoint;
|
use k256::AffinePoint;
|
||||||
use log::info;
|
use log::info;
|
||||||
use nssa::Address;
|
use nssa::Address;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use utxo::utxo_core::UTXO;
|
|
||||||
|
|
||||||
use crate::key_management::{
|
use crate::key_management::{
|
||||||
constants_types::{CipherText, Nonce},
|
constants_types::{CipherText, Nonce},
|
||||||
ephemeral_key_holder::EphemeralKeyHolder,
|
ephemeral_key_holder::EphemeralKeyHolder,
|
||||||
AddressKeyHolder,
|
KeyChain,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type PublicKey = AffinePoint;
|
pub type PublicKey = AffinePoint;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Account {
|
pub struct NSSAUserData {
|
||||||
pub key_holder: AddressKeyHolder,
|
pub key_holder: KeyChain,
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
pub balance: u64,
|
pub balance: u64,
|
||||||
pub utxos: HashMap<TreeHashType, UTXO>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct AccountForSerialization {
|
pub struct NSSAUserDataForSerialization {
|
||||||
pub key_holder: AddressKeyHolder,
|
pub key_holder: KeyChain,
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
pub balance: u64,
|
pub balance: u64,
|
||||||
pub utxos: HashMap<String, UTXO>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Account> for AccountForSerialization {
|
impl From<NSSAUserData> for NSSAUserDataForSerialization {
|
||||||
fn from(value: Account) -> Self {
|
fn from(value: NSSAUserData) -> Self {
|
||||||
AccountForSerialization {
|
NSSAUserDataForSerialization {
|
||||||
key_holder: value.key_holder,
|
key_holder: value.key_holder,
|
||||||
address: value.address,
|
address: value.address,
|
||||||
balance: value.balance,
|
balance: value.balance,
|
||||||
utxos: value
|
|
||||||
.utxos
|
|
||||||
.into_iter()
|
|
||||||
.map(|(key, val)| (hex::encode(key), val))
|
|
||||||
.collect(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AccountForSerialization> for Account {
|
impl From<NSSAUserDataForSerialization> for NSSAUserData {
|
||||||
fn from(value: AccountForSerialization) -> Self {
|
fn from(value: NSSAUserDataForSerialization) -> Self {
|
||||||
Account {
|
NSSAUserData {
|
||||||
key_holder: value.key_holder,
|
key_holder: value.key_holder,
|
||||||
address: value.address,
|
address: value.address,
|
||||||
balance: value.balance,
|
balance: value.balance,
|
||||||
utxos: value
|
|
||||||
.utxos
|
|
||||||
.into_iter()
|
|
||||||
.map(|(key, val)| (hex::decode(key).unwrap().try_into().unwrap(), val))
|
|
||||||
.collect(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for Account {
|
impl Serialize for NSSAUserData {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
let account_for_serialization: AccountForSerialization = From::from(self.clone());
|
let account_for_serialization: NSSAUserDataForSerialization = From::from(self.clone());
|
||||||
account_for_serialization.serialize(serializer)
|
account_for_serialization.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Account {
|
impl<'de> Deserialize<'de> for NSSAUserData {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let account_for_serialization = <AccountForSerialization>::deserialize(deserializer)?;
|
let account_for_serialization = <NSSAUserDataForSerialization>::deserialize(deserializer)?;
|
||||||
Ok(account_for_serialization.into())
|
Ok(account_for_serialization.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,21 +73,21 @@ impl<'de> Deserialize<'de> for Account {
|
|||||||
///
|
///
|
||||||
/// Main usage is to encode data for other account
|
/// Main usage is to encode data for other account
|
||||||
#[derive(Serialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
pub struct AccountPublicMask {
|
pub struct NSSAUserDataPublicMask {
|
||||||
pub nullifier_public_key: AffinePoint,
|
pub nullifier_public_key: AffinePoint,
|
||||||
pub viewing_public_key: AffinePoint,
|
pub viewing_public_key: AffinePoint,
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
pub balance: u64,
|
pub balance: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccountPublicMask {
|
impl NSSAUserDataPublicMask {
|
||||||
pub fn encrypt_data(
|
pub fn encrypt_data(
|
||||||
ephemeral_key_holder: &EphemeralKeyHolder,
|
ephemeral_key_holder: &EphemeralKeyHolder,
|
||||||
viewing_public_key_receiver: AffinePoint,
|
viewing_public_key_receiver: AffinePoint,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> (CipherText, Nonce) {
|
) -> (CipherText, Nonce) {
|
||||||
//Using of parent Account fuction
|
//Using of parent NSSAUserData fuction
|
||||||
Account::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data)
|
NSSAUserData::encrypt_data(ephemeral_key_holder, viewing_public_key_receiver, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_tag(&self) -> Tag {
|
pub fn make_tag(&self) -> Tag {
|
||||||
@ -110,35 +95,31 @@ impl AccountPublicMask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Account {
|
impl NSSAUserData {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let key_holder = AddressKeyHolder::new_os_random();
|
let key_holder = KeyChain::new_os_random();
|
||||||
let public_key =
|
let public_key =
|
||||||
nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key());
|
nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key());
|
||||||
let address = nssa::Address::from(&public_key);
|
let address = nssa::Address::from(&public_key);
|
||||||
let balance = 0;
|
let balance = 0;
|
||||||
let utxos = HashMap::new();
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
key_holder,
|
key_holder,
|
||||||
address,
|
address,
|
||||||
balance,
|
balance,
|
||||||
utxos,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_balance(balance: u64) -> Self {
|
pub fn new_with_balance(balance: u64) -> Self {
|
||||||
let key_holder = AddressKeyHolder::new_os_random();
|
let key_holder = KeyChain::new_os_random();
|
||||||
let public_key =
|
let public_key =
|
||||||
nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key());
|
nssa::PublicKey::new_from_private_key(key_holder.get_pub_account_signing_key());
|
||||||
let address = nssa::Address::from(&public_key);
|
let address = nssa::Address::from(&public_key);
|
||||||
let utxos = HashMap::new();
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
key_holder,
|
key_holder,
|
||||||
address,
|
address,
|
||||||
balance,
|
balance,
|
||||||
utxos,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,42 +141,14 @@ impl Account {
|
|||||||
.decrypt_data(ephemeral_public_key_sender, ciphertext, nonce)
|
.decrypt_data(ephemeral_public_key_sender, ciphertext, nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_new_utxo_outputs(&mut self, utxos: Vec<UTXO>) -> Result<()> {
|
|
||||||
for utxo in utxos {
|
|
||||||
if self.utxos.contains_key(&utxo.hash) {
|
|
||||||
return Err(anyhow::anyhow!("UTXO already exists"));
|
|
||||||
}
|
|
||||||
self.utxos.insert(utxo.hash, utxo);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_public_balance(&mut self, new_balance: u64) {
|
pub fn update_public_balance(&mut self, new_balance: u64) {
|
||||||
self.balance = new_balance;
|
self.balance = new_balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_asset<Asset: Serialize>(
|
|
||||||
&mut self,
|
|
||||||
asset: Asset,
|
|
||||||
amount: u128,
|
|
||||||
privacy_flag: bool,
|
|
||||||
) -> Result<()> {
|
|
||||||
let asset_utxo = UTXO::new(
|
|
||||||
*self.address.value(),
|
|
||||||
serde_json::to_vec(&asset)?,
|
|
||||||
amount,
|
|
||||||
privacy_flag,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.utxos.insert(asset_utxo.hash, asset_utxo);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn log(&self) {
|
pub fn log(&self) {
|
||||||
info!("Keys generated");
|
info!("Keys generated");
|
||||||
info!("Account address is {:?}", hex::encode(self.address));
|
info!("NSSAUserData address is {:?}", hex::encode(self.address));
|
||||||
info!("Account balance is {:?}", self.balance);
|
info!("NSSAUserData balance is {:?}", self.balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_tag(&self) -> Tag {
|
pub fn make_tag(&self) -> Tag {
|
||||||
@ -203,8 +156,8 @@ impl Account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///Produce account public mask
|
///Produce account public mask
|
||||||
pub fn make_account_public_mask(&self) -> AccountPublicMask {
|
pub fn make_account_public_mask(&self) -> NSSAUserDataPublicMask {
|
||||||
AccountPublicMask {
|
NSSAUserDataPublicMask {
|
||||||
nullifier_public_key: self.key_holder.nullifer_public_key,
|
nullifier_public_key: self.key_holder.nullifer_public_key,
|
||||||
viewing_public_key: self.key_holder.viewing_public_key,
|
viewing_public_key: self.key_holder.viewing_public_key,
|
||||||
address: self.address,
|
address: self.address,
|
||||||
@ -213,7 +166,7 @@ impl Account {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Account {
|
impl Default for NSSAUserData {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
@ -223,52 +176,24 @@ impl Default for Account {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn generate_dummy_utxo(address: TreeHashType, amount: u128) -> UTXO {
|
|
||||||
UTXO::new(address, vec![], amount, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_account() {
|
fn test_new_account() {
|
||||||
let account = Account::new();
|
let account = NSSAUserData::new();
|
||||||
|
|
||||||
assert_eq!(account.balance, 0);
|
assert_eq!(account.balance, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_add_new_utxo_outputs() {
|
|
||||||
let mut account = Account::new();
|
|
||||||
let utxo1 = generate_dummy_utxo(*account.address.value(), 100);
|
|
||||||
let utxo2 = generate_dummy_utxo(*account.address.value(), 200);
|
|
||||||
|
|
||||||
let result = account.add_new_utxo_outputs(vec![utxo1.clone(), utxo2.clone()]);
|
|
||||||
|
|
||||||
assert!(result.is_ok());
|
|
||||||
assert_eq!(account.utxos.len(), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_update_public_balance() {
|
fn test_update_public_balance() {
|
||||||
let mut account = Account::new();
|
let mut account = NSSAUserData::new();
|
||||||
account.update_public_balance(500);
|
account.update_public_balance(500);
|
||||||
|
|
||||||
assert_eq!(account.balance, 500);
|
assert_eq!(account.balance, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_add_asset() {
|
|
||||||
let mut account = Account::new();
|
|
||||||
let asset = "dummy_asset";
|
|
||||||
let amount = 1000u128;
|
|
||||||
|
|
||||||
let result = account.add_asset(asset, amount, false);
|
|
||||||
|
|
||||||
assert!(result.is_ok());
|
|
||||||
assert_eq!(account.utxos.len(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn accounts_accounts_mask_tag_consistency() {
|
fn accounts_accounts_mask_tag_consistency() {
|
||||||
let account = Account::new();
|
let account = NSSAUserData::new();
|
||||||
|
|
||||||
let account_mask = account.make_account_public_mask();
|
let account_mask = account.make_account_public_mask();
|
||||||
|
|
||||||
2
key_protocol/src/lib.rs
Normal file
2
key_protocol/src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod key_protocol_core;
|
||||||
|
pub mod key_management;
|
||||||
@ -22,8 +22,8 @@ path = "../storage"
|
|||||||
[dependencies.mempool]
|
[dependencies.mempool]
|
||||||
path = "../mempool"
|
path = "../mempool"
|
||||||
|
|
||||||
[dependencies.accounts]
|
[dependencies.key_protocol]
|
||||||
path = "../accounts"
|
path = "../key_protocol"
|
||||||
|
|
||||||
[dependencies.common]
|
[dependencies.common]
|
||||||
path = "../common"
|
path = "../common"
|
||||||
|
|||||||
@ -22,8 +22,8 @@ tokio.workspace = true
|
|||||||
[dependencies.mempool]
|
[dependencies.mempool]
|
||||||
path = "../mempool"
|
path = "../mempool"
|
||||||
|
|
||||||
[dependencies.accounts]
|
[dependencies.key_protocol]
|
||||||
path = "../accounts"
|
path = "../key_protocol"
|
||||||
|
|
||||||
[dependencies.sequencer_core]
|
[dependencies.sequencer_core]
|
||||||
path = "../sequencer_core"
|
path = "../sequencer_core"
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "utxo"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow.workspace = true
|
|
||||||
serde_json.workspace = true
|
|
||||||
env_logger.workspace = true
|
|
||||||
log.workspace = true
|
|
||||||
serde.workspace = true
|
|
||||||
sha2.workspace = true
|
|
||||||
hex.workspace = true
|
|
||||||
rand.workspace = true
|
|
||||||
|
|
||||||
[dependencies.common]
|
|
||||||
path = "../common"
|
|
||||||
@ -1 +0,0 @@
|
|||||||
pub mod utxo_core;
|
|
||||||
@ -1,162 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
use common::{merkle_tree_public::TreeHashType, AccountId};
|
|
||||||
use log::info;
|
|
||||||
use rand::{rngs::OsRng, RngCore};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use sha2::{digest::FixedOutput, Digest};
|
|
||||||
|
|
||||||
///Raw asset data
|
|
||||||
pub type Asset = Vec<u8>;
|
|
||||||
pub type Randomness = [u8; 32];
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
|
||||||
///Container for raw utxo payload
|
|
||||||
pub struct UTXO {
|
|
||||||
pub hash: TreeHashType,
|
|
||||||
pub owner: AccountId,
|
|
||||||
pub asset: Asset,
|
|
||||||
// TODO: change to u256
|
|
||||||
pub amount: u128,
|
|
||||||
pub privacy_flag: bool,
|
|
||||||
pub randomness: Randomness,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct UTXOPayload {
|
|
||||||
pub owner: AccountId,
|
|
||||||
pub asset: Asset,
|
|
||||||
// TODO: change to u256
|
|
||||||
pub amount: u128,
|
|
||||||
pub privacy_flag: bool,
|
|
||||||
pub randomness: Randomness,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UTXOPayload {
|
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
|
||||||
let mut result = Vec::new();
|
|
||||||
result.extend_from_slice(&self.owner);
|
|
||||||
result.extend_from_slice(&self.asset);
|
|
||||||
result.extend_from_slice(&self.amount.to_be_bytes());
|
|
||||||
result.push(self.privacy_flag as u8);
|
|
||||||
result.extend_from_slice(&self.randomness);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UTXO {
|
|
||||||
pub fn new(owner: AccountId, asset: Asset, amount: u128, privacy_flag: bool) -> Self {
|
|
||||||
let mut randomness = Randomness::default();
|
|
||||||
OsRng.fill_bytes(&mut randomness);
|
|
||||||
let payload = UTXOPayload {
|
|
||||||
owner,
|
|
||||||
asset,
|
|
||||||
amount,
|
|
||||||
privacy_flag,
|
|
||||||
randomness,
|
|
||||||
};
|
|
||||||
Self::create_utxo_from_payload(payload)
|
|
||||||
}
|
|
||||||
pub fn create_utxo_from_payload(payload_with_asset: UTXOPayload) -> Self {
|
|
||||||
let mut hasher = sha2::Sha256::new();
|
|
||||||
hasher.update(payload_with_asset.to_bytes());
|
|
||||||
let hash = <TreeHashType>::from(hasher.finalize_fixed());
|
|
||||||
|
|
||||||
Self {
|
|
||||||
hash,
|
|
||||||
owner: payload_with_asset.owner,
|
|
||||||
asset: payload_with_asset.asset,
|
|
||||||
amount: payload_with_asset.amount,
|
|
||||||
privacy_flag: payload_with_asset.privacy_flag,
|
|
||||||
randomness: payload_with_asset.randomness,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn interpret_asset<'de, ToInterpret: Deserialize<'de>>(&'de self) -> Result<ToInterpret> {
|
|
||||||
Ok(serde_json::from_slice(&self.asset)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_payload(&self) -> UTXOPayload {
|
|
||||||
UTXOPayload {
|
|
||||||
owner: self.owner,
|
|
||||||
asset: self.asset.clone(),
|
|
||||||
amount: self.amount,
|
|
||||||
privacy_flag: self.privacy_flag,
|
|
||||||
randomness: self.randomness,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn log(&self) {
|
|
||||||
info!("UTXO hash is {:?}", hex::encode(self.hash));
|
|
||||||
info!("UTXO owner is {:?}", hex::encode(self.owner));
|
|
||||||
info!("UTXO asset is {:?}", hex::encode(self.asset.clone()));
|
|
||||||
info!("UTXO amount is {:?}", self.amount);
|
|
||||||
info!("UTXO privacy_flag is {:?}", self.privacy_flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
||||||
struct TestAsset {
|
|
||||||
id: u32,
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sample_account() -> AccountId {
|
|
||||||
AccountId::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sample_payload() -> UTXOPayload {
|
|
||||||
UTXOPayload {
|
|
||||||
owner: sample_account(),
|
|
||||||
asset: serde_json::to_vec(&TestAsset {
|
|
||||||
id: 1,
|
|
||||||
name: "Test".to_string(),
|
|
||||||
})
|
|
||||||
.unwrap(),
|
|
||||||
amount: 10,
|
|
||||||
privacy_flag: false,
|
|
||||||
randomness: Randomness::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_create_utxo_from_payload() {
|
|
||||||
let payload = sample_payload();
|
|
||||||
let utxo = UTXO::create_utxo_from_payload(payload.clone());
|
|
||||||
|
|
||||||
// Ensure hash is created and the UTXO fields are correctly assigned
|
|
||||||
assert_eq!(utxo.owner, payload.owner);
|
|
||||||
assert_eq!(utxo.asset, payload.asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_interpret_asset() {
|
|
||||||
let payload = sample_payload();
|
|
||||||
let utxo = UTXO::create_utxo_from_payload(payload);
|
|
||||||
|
|
||||||
// Interpret asset as TestAsset
|
|
||||||
let interpreted: TestAsset = utxo.interpret_asset().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
interpreted,
|
|
||||||
TestAsset {
|
|
||||||
id: 1,
|
|
||||||
name: "Test".to_string()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_interpret_invalid_asset() {
|
|
||||||
let mut payload = sample_payload();
|
|
||||||
payload.asset = vec![0, 1, 2, 3]; // Invalid data for deserialization
|
|
||||||
let utxo = UTXO::create_utxo_from_payload(payload);
|
|
||||||
|
|
||||||
// This should fail because the asset is not valid JSON for TestAsset
|
|
||||||
let result: Result<TestAsset> = utxo.interpret_asset();
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -23,11 +23,8 @@ hex.workspace = true
|
|||||||
actix-rt.workspace = true
|
actix-rt.workspace = true
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
|
|
||||||
[dependencies.accounts]
|
[dependencies.key_protocol]
|
||||||
path = "../accounts"
|
path = "../key_protocol"
|
||||||
|
|
||||||
[dependencies.utxo]
|
|
||||||
path = "../utxo"
|
|
||||||
|
|
||||||
[dependencies.nssa]
|
[dependencies.nssa]
|
||||||
path = "../nssa"
|
path = "../nssa"
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
use accounts::account_core::Account;
|
//TODO: NOT NSSA USER DATA, ACCOUNT
|
||||||
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
use nssa::Address;
|
use nssa::Address;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct WalletAccountsStore {
|
pub struct WalletAccountsStore {
|
||||||
pub accounts: HashMap<Address, Account>,
|
pub accounts: HashMap<Address, NSSAUserData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WalletAccountsStore {
|
impl WalletAccountsStore {
|
||||||
@ -13,7 +14,7 @@ impl WalletAccountsStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_account(&mut self, account: Account) {
|
pub fn register_account(&mut self, account: NSSAUserData) {
|
||||||
self.accounts.insert(account.address, account);
|
self.accounts.insert(account.address, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,10 +32,10 @@ impl Default for WalletAccountsStore {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use accounts::account_core::Account;
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
/// Helper function to create a sample account
|
/// Helper function to create a sample account
|
||||||
fn create_sample_account(balance: u64) -> Account {
|
fn create_sample_account(balance: u64) -> NSSAUserData {
|
||||||
Account::new_with_balance(balance)
|
NSSAUserData::new_with_balance(balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pad_to_32(slice: &[u8]) -> [u8; 32] {
|
fn pad_to_32(slice: &[u8]) -> [u8; 32] {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use accounts::account_core::Account;
|
//TODO: NOT USER DATA, ACCOUNT
|
||||||
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree;
|
use common::merkle_tree_public::merkle_tree::UTXOCommitmentsMerkleTree;
|
||||||
use nssa::Address;
|
use nssa::Address;
|
||||||
@ -12,11 +13,11 @@ pub mod accounts_store;
|
|||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct AccMap {
|
pub struct AccMap {
|
||||||
pub acc_map: HashMap<String, Account>,
|
pub acc_map: HashMap<String, NSSAUserData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<HashMap<[u8; 32], Account>> for AccMap {
|
impl From<HashMap<[u8; 32], NSSAUserData>> for AccMap {
|
||||||
fn from(value: HashMap<[u8; 32], Account>) -> Self {
|
fn from(value: HashMap<[u8; 32], NSSAUserData>) -> Self {
|
||||||
AccMap {
|
AccMap {
|
||||||
acc_map: value
|
acc_map: value
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -26,7 +27,7 @@ impl From<HashMap<[u8; 32], Account>> for AccMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AccMap> for HashMap<[u8; 32], Account> {
|
impl From<AccMap> for HashMap<[u8; 32], NSSAUserData> {
|
||||||
fn from(value: AccMap) -> Self {
|
fn from(value: AccMap) -> Self {
|
||||||
value
|
value
|
||||||
.acc_map
|
.acc_map
|
||||||
@ -37,7 +38,7 @@ impl From<AccMap> for HashMap<[u8; 32], Account> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct WalletChainStore {
|
pub struct WalletChainStore {
|
||||||
pub acc_map: HashMap<Address, Account>,
|
pub acc_map: HashMap<Address, NSSAUserData>,
|
||||||
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
|
pub utxo_commitments_store: UTXOCommitmentsMerkleTree,
|
||||||
pub wallet_config: WalletConfig,
|
pub wallet_config: WalletConfig,
|
||||||
}
|
}
|
||||||
@ -58,11 +59,11 @@ impl WalletChainStore {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use accounts::account_core::Account;
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
fn create_initial_accounts() -> Vec<Account> {
|
fn create_initial_accounts() -> Vec<NSSAUserData> {
|
||||||
let initial_acc1 = serde_json::from_str(r#"{
|
let initial_acc1 = serde_json::from_str(r#"{
|
||||||
"address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
"address": "1b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f",
|
||||||
"balance": 100,
|
"balance": 100,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use accounts::account_core::Account;
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@ -32,5 +32,7 @@ pub struct WalletConfig {
|
|||||||
///Sequencer polling duration for new blocks in seconds
|
///Sequencer polling duration for new blocks in seconds
|
||||||
pub seq_poll_timeout_secs: u64,
|
pub seq_poll_timeout_secs: u64,
|
||||||
///Initial accounts for wallet
|
///Initial accounts for wallet
|
||||||
pub initial_accounts: Vec<Account>,
|
///
|
||||||
|
/// TODO: NOT USRE DATA, ACCOUNT
|
||||||
|
pub initial_accounts: Vec<NSSAUserData>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr};
|
use std::{fs::File, io::BufReader, path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
use accounts::account_core::Account;
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use nssa::Address;
|
use nssa::Address;
|
||||||
|
|
||||||
@ -28,7 +28,9 @@ pub fn produce_account_addr_from_hex(hex_str: String) -> Result<Address> {
|
|||||||
///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json`
|
///Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json`
|
||||||
///
|
///
|
||||||
/// If file not present, it is considered as empty list of persistent accounts
|
/// If file not present, it is considered as empty list of persistent accounts
|
||||||
pub fn fetch_persistent_accounts() -> Result<Vec<Account>> {
|
///
|
||||||
|
/// ToDo: NOT USER DATA, ACCOUNT
|
||||||
|
pub fn fetch_persistent_accounts() -> Result<Vec<NSSAUserData>> {
|
||||||
let home = get_home()?;
|
let home = get_home()?;
|
||||||
let accs_path = home.join("curr_accounts.json");
|
let accs_path = home.join("curr_accounts.json");
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use common::{
|
|||||||
ExecutionFailureKind,
|
ExecutionFailureKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
use accounts::account_core::Account;
|
use key_protocol::key_protocol_core::NSSAUserData;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chain_storage::WalletChainStore;
|
use chain_storage::WalletChainStore;
|
||||||
use config::WalletConfig;
|
use config::WalletConfig;
|
||||||
@ -54,7 +54,7 @@ impl WalletCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_new_account(&mut self) -> Address {
|
pub async fn create_new_account(&mut self) -> Address {
|
||||||
let account = Account::new();
|
let account = NSSAUserData::new();
|
||||||
account.log();
|
account.log();
|
||||||
|
|
||||||
let addr = account.address;
|
let addr = account.address;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user