Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
42 changes: 15 additions & 27 deletions src/backend_task/identity/register_identity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::backend_task::identity::{IdentityRegistrationInfo, RegisterIdentityFundingMethod};
use crate::backend_task::{BackendTaskSuccessResult, FeeResult};
use crate::context::AppContext;
use crate::context::{AppContext, get_transaction_info_via_dapi};
use crate::model::fee_estimation::PlatformFeeEstimator;
use crate::model::proof_log_item::{ProofLogItem, RequestType};
use crate::model::qualified_identity::{IdentityStatus, IdentityType, QualifiedIdentity};
Expand Down Expand Up @@ -53,30 +53,23 @@ impl AppContext {
RegisterIdentityFundingMethod::UseAssetLock(address, asset_lock_proof, transaction) => {
let tx_id = transaction.txid();

// eprintln!("UseAssetLock: transaction id for {:#?} is {}", transaction, tx_id);
let wallet = wallet.read().unwrap();
wallet_id = wallet.seed_hash();
let private_key = wallet
.private_key_for_address(&address, self.network)?
.ok_or("Asset Lock not valid for wallet")?;
// Scope the read guard so it's dropped before the async DAPI call below
let private_key = {
let wallet = wallet.read().unwrap();
wallet_id = wallet.seed_hash();
wallet
.private_key_for_address(&address, self.network)?
.ok_or("Asset Lock not valid for wallet")?
};
let asset_lock_proof = if let AssetLockProof::Instant(instant_asset_lock_proof) =
asset_lock_proof.as_ref()
{
// we need to make sure the instant send asset lock is recent
let raw_transaction_info = self
.core_client
.read()
.expect("Core client lock was poisoned")
.get_raw_transaction_info(&tx_id, None)
.map_err(|e| e.to_string())?;
let tx_info = get_transaction_info_via_dapi(&sdk, &tx_id).await?;

if raw_transaction_info.chainlock
&& raw_transaction_info.height.is_some()
&& raw_transaction_info.confirmations.is_some()
&& raw_transaction_info.confirmations.unwrap() > 8
{
if tx_info.is_chain_locked && tx_info.height > 0 && tx_info.confirmations > 8 {
// Transaction is old enough that instant lock may have expired
let tx_block_height = raw_transaction_info.height.unwrap() as u32;
let tx_block_height = tx_info.height;

if tx_block_height <= metadata.core_chain_locked_height {
// Platform has verified this Core block, use chain lock proof
Expand Down Expand Up @@ -488,15 +481,10 @@ impl AppContext {
|| e.contains("wasn't created recently")
{
// Try to use chain asset lock proof instead
let raw_transaction_info = self
.core_client
.read()
.expect("Core client lock was poisoned")
.get_raw_transaction_info(&tx_id, None)
.map_err(|e| e.to_string())?;
let tx_info = get_transaction_info_via_dapi(&sdk, &tx_id).await?;

if raw_transaction_info.chainlock && raw_transaction_info.height.is_some() {
let tx_block_height = raw_transaction_info.height.unwrap() as u32;
if tx_info.is_chain_locked && tx_info.height > 0 {
let tx_block_height = tx_info.height;

if tx_block_height <= metadata.core_chain_locked_height {
// Platform has verified this Core block, use chain lock proof
Expand Down
41 changes: 16 additions & 25 deletions src/backend_task/identity/top_up_identity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::backend_task::identity::{IdentityTopUpInfo, TopUpIdentityFundingMethod};
use crate::backend_task::{BackendTaskSuccessResult, FeeResult};
use crate::context::AppContext;
use crate::context::{AppContext, get_transaction_info_via_dapi};
use crate::model::fee_estimation::PlatformFeeEstimator;
use crate::model::proof_log_item::{ProofLogItem, RequestType};
use dash_sdk::Error;
Expand Down Expand Up @@ -47,30 +47,26 @@ impl AppContext {
) => {
let tx_id = transaction.txid();

// eprintln!("UseAssetLock: transaction id for {:#?} is {}", transaction, tx_id);
let wallet = wallet.read().unwrap();
let private_key = wallet
.private_key_for_address(&address, self.network)?
.ok_or("Asset Lock not valid for wallet")?;
// Scope the read guard so it's dropped before the async DAPI call below
let private_key = {
let wallet = wallet.read().unwrap();
wallet
.private_key_for_address(&address, self.network)?
.ok_or("Asset Lock not valid for wallet")?
};
let asset_lock_proof = if let AssetLockProof::Instant(
instant_asset_lock_proof,
) = asset_lock_proof.as_ref()
{
// we need to make sure the instant send asset lock is recent
let raw_transaction_info = self
.core_client
.read()
.expect("Core client lock was poisoned")
.get_raw_transaction_info(&tx_id, None)
.map_err(|e| e.to_string())?;
let tx_info = get_transaction_info_via_dapi(&sdk, &tx_id).await?;

if raw_transaction_info.chainlock
&& raw_transaction_info.height.is_some()
&& raw_transaction_info.confirmations.is_some()
&& raw_transaction_info.confirmations.unwrap() > 8
if tx_info.is_chain_locked
&& tx_info.height > 0
&& tx_info.confirmations > 8
{
// Transaction is old enough that instant lock may have expired
let tx_block_height = raw_transaction_info.height.unwrap() as u32;
let tx_block_height = tx_info.height;

if tx_block_height <= metadata.core_chain_locked_height {
// Platform has verified this Core block, use chain lock proof
Expand Down Expand Up @@ -410,15 +406,10 @@ impl AppContext {
|| error_string.contains("wasn't created recently")
{
// Try to use chain asset lock proof instead
let raw_transaction_info = self
.core_client
.read()
.expect("Core client lock was poisoned")
.get_raw_transaction_info(&tx_id, None)
.map_err(|e| e.to_string())?;
let tx_info = get_transaction_info_via_dapi(&sdk, &tx_id).await?;

if raw_transaction_info.chainlock && raw_transaction_info.height.is_some() {
let tx_block_height = raw_transaction_info.height.unwrap() as u32;
if tx_info.is_chain_locked && tx_info.height > 0 {
let tx_block_height = tx_info.height;

if tx_block_height <= metadata.core_chain_locked_height {
// Platform has verified this Core block, use chain lock proof
Expand Down
21 changes: 6 additions & 15 deletions src/backend_task/wallet/fund_platform_address_from_asset_lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl AppContext {
};

// Check if we need to convert an old instant lock proof to a chain lock proof
use dash_sdk::dashcore_rpc::RpcApi;
use crate::context::get_transaction_info_via_dapi;
use dash_sdk::dpp::block::extended_epoch_info::ExtendedEpochInfo;
use dash_sdk::platform::Fetch;

Expand All @@ -56,21 +56,12 @@ impl AppContext {
// Get the transaction ID from the instant lock proof
let tx_id = instant_asset_lock_proof.transaction().txid();

// Query the core client to check if the transaction has been chain-locked
let raw_transaction_info = self
.core_client
.read()
.expect("Core client lock was poisoned")
.get_raw_transaction_info(&tx_id, None)
.map_err(|e| format!("Failed to get transaction info: {}", e))?;

if raw_transaction_info.chainlock
&& raw_transaction_info.height.is_some()
&& raw_transaction_info.confirmations.is_some()
&& raw_transaction_info.confirmations.unwrap() > 8
{
// Query DAPI to check if the transaction has been chain-locked
let tx_info = get_transaction_info_via_dapi(&sdk, &tx_id).await?;

if tx_info.is_chain_locked && tx_info.height > 0 && tx_info.confirmations > 8 {
// Transaction has been chain-locked with sufficient confirmations
let tx_block_height = raw_transaction_info.height.unwrap() as u32;
let tx_block_height = tx_info.height;

// Check if the platform has caught up to this block height
let (_, metadata) = ExtendedEpochInfo::fetch_with_metadata(&sdk, 0, None)
Expand Down
33 changes: 33 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1708,6 +1708,39 @@ impl AppContext {
}
}

pub(crate) struct DapiTransactionInfo {
pub is_chain_locked: bool,
pub height: u32,
pub confirmations: u32,
}

/// Query transaction info from DAPI. Works in both SPV and RPC modes
/// since DAPI (platform gRPC) is always available via the SDK.
pub(crate) async fn get_transaction_info_via_dapi(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just name it get_transaction_info. Caller doesn't really want to know which method is used,to me it's just an implementation detail.

sdk: &Sdk,
tx_id: &Txid,
) -> Result<DapiTransactionInfo, String> {
use dash_sdk::dapi_client::{DapiRequestExecutor, IntoInner, RequestSettings};
use dash_sdk::dapi_grpc::core::v0::GetTransactionRequest;

let response = sdk
.execute(
GetTransactionRequest {
id: tx_id.to_string(),
},
RequestSettings::default(),
)
.await
.into_inner()
.map_err(|e| format!("DAPI GetTransaction failed: {}", e))?;

Ok(DapiTransactionInfo {
is_chain_locked: response.is_chain_locked,
height: response.height,
confirmations: response.confirmations,
})
}

/// Returns the default platform version for the given network.
pub(crate) const fn default_platform_version(network: &Network) -> &'static PlatformVersion {
// TODO: Use self.sdk.read().unwrap().version() instead of hardcoding
Expand Down
Loading