Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(engine)!: substate address based on entity id prefix #951

Merged
merged 8 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 12 additions & 23 deletions applications/tari_dan_wallet_daemon/src/handlers/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ use tari_template_builtin::ACCOUNT_TEMPLATE_ADDRESS;
use tari_template_lib::{
args,
crypto::RistrettoPublicKeyBytes,
models::{Amount, NonFungibleAddress, UnclaimedConfidentialOutputAddress},
models::{Amount, UnclaimedConfidentialOutputAddress},
prelude::{ComponentAddress, ResourceType, CONFIDENTIAL_TARI_RESOURCE_ADDRESS},
Hash,
};
use tari_transaction::{SubstateRequirement, Transaction};
use tari_wallet_daemon_client::{
Expand Down Expand Up @@ -118,8 +117,6 @@ pub async fn handle_create(

let owner_key = key_manager_api.next_key(key_manager::TRANSACTION_BRANCH)?;
let owner_pk = PublicKey::from_secret_key(&owner_key.key);
let owner_token =
NonFungibleAddress::from_public_key(RistrettoPublicKeyBytes::from_bytes(owner_pk.as_bytes()).unwrap());

info!(
target: LOG_TARGET,
Expand All @@ -132,7 +129,7 @@ pub async fn handle_create(
let max_fee = req.max_fee.unwrap_or(DEFAULT_FEE);
let transaction = Transaction::builder()
.fee_transaction_pay_from_component(default_account.address.as_component_address().unwrap(), max_fee)
.call_function(ACCOUNT_TEMPLATE_ADDRESS, "create", args![owner_token])
.create_account(owner_pk.clone())
.with_input_refs(
input_refs
.iter()
Expand Down Expand Up @@ -705,13 +702,9 @@ async fn finish_claiming<T: WalletStore>(
args: args![Workspace("bucket")],
});
} else {
let owner_token = NonFungibleAddress::from_public_key(
RistrettoPublicKeyBytes::from_bytes(account_public_key.as_bytes()).unwrap(),
);
instructions.push(Instruction::CallFunction {
template_address: ACCOUNT_TEMPLATE_ADDRESS,
function: "create_with_bucket".to_string(),
args: args![owner_token, Workspace("bucket")],
instructions.push(Instruction::CreateAccount {
owner_public_key: account_public_key.clone(),
workspace_bucket: Some("bucket".to_string()),
});
}
instructions.push(Instruction::CallMethod {
Expand Down Expand Up @@ -863,8 +856,8 @@ fn get_or_create_account<T: WalletStore>(
.unwrap_or_else(|| sdk.key_manager_api().next_key(key_manager::TRANSACTION_BRANCH))?;
let account_pk = PublicKey::from_secret_key(&account_secret_key.key);

let component_id = Hash::try_from(account_pk.as_bytes())?;
let account_address = new_component_address_from_parts(&ACCOUNT_TEMPLATE_ADDRESS, &component_id);
let account_pk_bytes = RistrettoPublicKeyBytes::from_bytes(account_pk.as_bytes())?;
let account_address = new_component_address_from_parts(&ACCOUNT_TEMPLATE_ADDRESS, &account_pk_bytes);

// We have no involved substate addresses, so we need to add an output
(account_address.into(), account_secret_key, Some(name.to_string()))
Expand Down Expand Up @@ -1022,8 +1015,8 @@ async fn get_or_create_account_address(
instructions: &mut Vec<Instruction>,
) -> Result<ComponentAddress, anyhow::Error> {
// calculate the account component address from the public key
let component_id = Hash::try_from(public_key.as_bytes())?;
let account_address = new_component_address_from_parts(&ACCOUNT_TEMPLATE_ADDRESS, &component_id);
let public_key_bytes = RistrettoPublicKeyBytes::try_from(public_key.as_bytes())?;
let account_address = new_component_address_from_parts(&ACCOUNT_TEMPLATE_ADDRESS, &public_key_bytes);

let account_scan = sdk
.substate_api()
Expand All @@ -1040,13 +1033,9 @@ async fn get_or_create_account_address(
None => {
// the account does not exists, so we must add a instruction to create it, matching the public key
debug!(target: LOG_TARGET, "Account does not exist. Adding create instruction");
let owner_token = NonFungibleAddress::from_public_key(
RistrettoPublicKeyBytes::from_bytes(public_key.as_bytes()).unwrap(),
);
instructions.insert(0, Instruction::CallFunction {
template_address: ACCOUNT_TEMPLATE_ADDRESS,
function: "create".to_string(),
args: args![owner_token],
instructions.insert(0, Instruction::CreateAccount {
owner_public_key: public_key.clone(),
workspace_bucket: None,
});
},
};
Expand Down
3 changes: 1 addition & 2 deletions applications/tari_dan_wallet_daemon/src/handlers/nfts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ pub async fn handle_mint_account_nft(
&ACCOUNT_NFT_TEMPLATE_ADDRESS,
&owner_token
.to_public_key()
.unwrap_or_else(|| panic!("owner_token is not a valid public key: {}", owner_token))
.as_hash(),
.unwrap_or_else(|| panic!("owner_token is not a valid public key: {}", owner_token)),
);

let mut accrued_fee = Amount::new(0);
Expand Down
60 changes: 35 additions & 25 deletions applications/tari_dan_wallet_daemon/src/services/account_monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use tari_engine_types::{
use tari_shutdown::ShutdownSignal;
use tari_template_builtin::ACCOUNT_TEMPLATE_ADDRESS;
use tari_template_lib::{
models::VaultId,
prelude::{NonFungibleId, ResourceAddress},
resource::TOKEN_SYMBOL,
};
Expand Down Expand Up @@ -177,11 +178,11 @@ where
.filter(|s| s.substate_id.is_vault())
.map(|s| (s.substate_id, s.version))
.collect::<HashMap<_, _>>();
for vault in vaults_value.vault_ids() {
let vault_addr = SubstateId::Vault(*vault);
let maybe_vault_version = known_child_vaults.get(&vault_addr).copied();
for vault_id in vaults_value.vault_ids() {
let vault_substate_id = SubstateId::Vault(*vault_id);
let maybe_vault_version = known_child_vaults.get(&vault_substate_id).copied();
let scan_result = substate_api
.scan_for_substate(&vault_addr, maybe_vault_version)
.scan_for_substate(&vault_substate_id, maybe_vault_version)
.await
.optional()?;
let Some(ValidatorScanResult {
Expand All @@ -190,21 +191,21 @@ where
created_by_tx,
}) = scan_result
else {
warn!(target: LOG_TARGET, "Vault {} for account {} does not exist according to validator node", vault_addr, versioned_account_address);
warn!(target: LOG_TARGET, "Vault {} for account {} does not exist according to validator node", vault_substate_id, versioned_account_address);
continue;
};

if let Some(vault_version) = maybe_vault_version {
// The first time a vault is found, know about the vault substate from the tx result but never added
// it to the database.
if versioned_addr.version == vault_version && accounts_api.has_vault(&vault_addr)? {
if versioned_addr.version == vault_version && accounts_api.has_vault(&vault_substate_id)? {
info!(target: LOG_TARGET, "Vault {} is up to date", versioned_addr.substate_id);
continue;
}
}

let SubstateValue::Vault(vault) = substate else {
error!(target: LOG_TARGET, "Substate {} is not a vault. This should be impossible.", vault_addr);
error!(target: LOG_TARGET, "Substate {} is not a vault. This should be impossible.", vault_substate_id);
continue;
};

Expand All @@ -216,10 +217,15 @@ where
versioned_addr,
)?;

self.add_vault_to_account_if_not_exist(&versioned_account_address.substate_id, &vault)
.await?;
self.refresh_vault(&versioned_account_address.substate_id, &vault, &HashMap::new())
self.add_vault_to_account_if_not_exist(&versioned_account_address.substate_id, *vault_id, &vault)
.await?;
self.refresh_vault(
&versioned_account_address.substate_id,
*vault_id,
&vault,
&HashMap::new(),
)
.await?;
}

Ok(is_updated)
Expand All @@ -228,14 +234,15 @@ where
async fn refresh_vault(
&self,
account_address: &SubstateId,
vault_id: VaultId,
vault: &Vault,
nfts: &HashMap<&NonFungibleId, &NonFungibleContainer>,
) -> Result<(), AccountMonitorError> {
let accounts_api = self.wallet_sdk.accounts_api();
let non_fungibles_api = self.wallet_sdk.non_fungible_api();

let balance = vault.balance();
let vault_addr = SubstateId::Vault(*vault.vault_id());
let vault_addr = SubstateId::Vault(vault_id);
if !accounts_api.exists_by_address(account_address)? {
// This is not our account
return Ok(());
Expand All @@ -247,7 +254,7 @@ where
info!(
target: LOG_TARGET,
"🔒️ NEW vault {} in account {}",
vault.vault_id(),
vault_id,
account_address
);
accounts_api.add_vault(
Expand All @@ -265,15 +272,15 @@ where
info!(
target: LOG_TARGET,
"🔒️ vault {} in account {} has new balance {}",
vault.vault_id(),
vault_id,
account_address,
balance
);
if let Some(commitments) = vault.get_confidential_commitments() {
info!(
target: LOG_TARGET,
"🔒️ vault {} in account {} has {} confidential commitments",
vault.vault_id(),
vault_id,
account_address,
commitments.len()
);
Expand Down Expand Up @@ -315,7 +322,7 @@ where

let non_fungible = NonFungibleToken {
is_burned,
vault_id: *vault.vault_id(),
vault_id,
nft_id: id.clone(),
metadata,
};
Expand Down Expand Up @@ -389,16 +396,17 @@ where
for vault_id in value.vault_ids() {
// Any vaults we process here do not need to be reprocesed later
if let Some(vault) = vaults.remove(vault_id).and_then(|s| s.substate_value().vault()) {
self.add_vault_to_account_if_not_exist(account_addr, vault).await?;
self.refresh_vault(account_addr, vault, &nfts).await?;
self.add_vault_to_account_if_not_exist(account_addr, *vault_id, vault)
.await?;
self.refresh_vault(account_addr, *vault_id, vault, &nfts).await?;
}
}
}

let mut updated_accounts = vec![];
// Process all existing vaults that belong to an account
for (vault_addr, substate) in vaults {
let vault_addr = SubstateId::Vault(vault_addr);
for (vault_id, substate) in vaults {
let vault_addr = SubstateId::Vault(vault_id);
let SubstateValue::Vault(vault) = substate.substate_value() else {
error!(target: LOG_TARGET, "👁️‍🗨️ Substate {} is not a vault. This should be impossible.", vault_addr);
continue;
Expand All @@ -422,15 +430,16 @@ where
info!(
target: LOG_TARGET,
"👁️‍🗨️ Vault {} not in any known account",
vault.vault_id(),
vault_addr,
);
continue;
}

self.add_vault_to_account_if_not_exist(&account_addr, vault).await?;
self.add_vault_to_account_if_not_exist(&account_addr, vault_id, vault)
.await?;

// Update the vault balance / confidential outputs
self.refresh_vault(&account_addr, vault, &nfts).await?;
self.refresh_vault(&account_addr, vault_id, vault, &nfts).await?;
updated_accounts.push(account_addr);
}

Expand Down Expand Up @@ -467,9 +476,10 @@ where
async fn add_vault_to_account_if_not_exist(
&self,
account_addr: &SubstateId,
vault_id: VaultId,
vault: &Vault,
) -> Result<(), AccountMonitorError> {
let vault_addr = SubstateId::Vault(*vault.vault_id());
let vault_addr = SubstateId::Vault(vault_id);
let accounts_api = self.wallet_sdk.accounts_api();
if !accounts_api.exists_by_address(account_addr)? {
// This is not our account
Expand All @@ -484,7 +494,7 @@ where
warn!(
target: LOG_TARGET,
"👁️‍🗨️ Failed to scan vault {} from VN: {}",
vault.vault_id(),
vault_id,
e
);
None
Expand All @@ -495,7 +505,7 @@ where
info!(
target: LOG_TARGET,
"👁️‍🗨️ New {} in account {}",
vault.vault_id(),
vault_id,
account_addr
);
accounts_api.add_vault(
Expand Down
Loading
Loading