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

feat(zcoin): allow ARRR to sync using a start date #1922

Merged
merged 46 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
e7b459b
save dev state — impl LightWalletSyncParams for block synchronization…
borngraced Jul 19, 2023
eefe9d4
save dev state — add docs and minor changes
borngraced Jul 19, 2023
7585df2
save dev state — more changes to get_tree_state and coin params
borngraced Jul 19, 2023
f260b7a
save dev state — minor changes
borngraced Jul 19, 2023
56621c7
save dev state — minor changes to fnand variable namings
borngraced Jul 19, 2023
aabd924
fix review notes
borngraced Jul 21, 2023
0de4fbf
fix import error
borngraced Jul 21, 2023
5e4ab78
use appropriate error handling instead of unwrap and minor changes to…
borngraced Jul 24, 2023
8e9f78a
rename buffer -> avg_blocktime
borngraced Jul 24, 2023
3693272
fix review notes — refactoring
borngraced Jul 26, 2023
6b33b54
remove get_minimum_header_from_cache
borngraced Aug 1, 2023
c4b0426
Merge branch 'dev' into zcoin_light_client_opt
borngraced Aug 2, 2023
58748d9
fix buffer calculation and minor changes
borngraced Aug 3, 2023
b00ee84
add SyncConfError error type for UtxoConfError
borngraced Aug 3, 2023
7dde1c0
rename LightClientSyncParams to SyncStartPoint
borngraced Aug 3, 2023
3edb9de
remove ZcoinRpcError and fix review notes
borngraced Aug 4, 2023
dd55663
test github zcash param workflow for winx86 and linux
borngraced Aug 4, 2023
bf529d5
test github zcash param workflow for winx86
borngraced Aug 4, 2023
0aec022
add wget64 install path
borngraced Aug 4, 2023
86e7b50
Merge branch 'dev' into zcoin_light_client_opt
borngraced Aug 4, 2023
b7ebdaf
fix review notes and refactored WalletDbShared initialization
borngraced Aug 10, 2023
ea2a5f3
Merge remote-tracking branch 'origin/zcoin_light_client_opt' into zco…
borngraced Aug 10, 2023
d975aeb
ignore activate_pirate_light
borngraced Aug 10, 2023
5c62f87
allow activate_z_coin_light and ignore activate_pirate_light
borngraced Aug 13, 2023
4cd0c7c
remove dead code and add doc comment for checkpoint_block_from_height fn
borngraced Aug 14, 2023
617d595
remove GrpcError from WalletDbError
borngraced Aug 15, 2023
a79dff0
extend sync feature to modified sync height if it's pre-sapling and i…
borngraced Aug 16, 2023
4b2b3bb
fix wasm lint
borngraced Aug 16, 2023
4f6ee57
replaced additional_info with FirstSyncBlock
borngraced Aug 16, 2023
cdfa1a5
minor fix
borngraced Aug 17, 2023
d360972
fix older sync date bug
borngraced Aug 17, 2023
ed2279d
fix wasm lint
borngraced Aug 17, 2023
2d4eb0e
use sapling_activation_height if current block height is lesser than …
borngraced Aug 18, 2023
f5ca4f7
fix new sync height
borngraced Aug 18, 2023
3269c8e
fix integration test
borngraced Aug 18, 2023
8e2e622
make first_sync_block Optional in ZCoinActivationResult struct
borngraced Aug 18, 2023
bda9470
polish
borngraced Aug 18, 2023
f0cc28b
impl enable_z_coin_light_with_changing_height unit test
borngraced Aug 21, 2023
b7ea7df
fix non-blockers
borngraced Aug 22, 2023
a0fe7ea
use flatten in get_earliest_block
borngraced Aug 22, 2023
3470c93
using alias for ZcoinRpcMode::Light and use replace info! with log! i…
borngraced Aug 23, 2023
de50159
add alias for electrum_servers
borngraced Aug 29, 2023
75a807a
Merge remote-tracking branch 'origin/dev' into zcoin_light_client_opt
borngraced Sep 4, 2023
ca0dbdc
fix merge conflicts
borngraced Sep 4, 2023
04b8f6c
add doc comments
borngraced Sep 5, 2023
1b7c689
add remaining doc comments
borngraced Sep 6, 2023
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
9 changes: 7 additions & 2 deletions .github/workflows/test.yml
borngraced marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ jobs:
uses: ./.github/actions/cargo-cache

- name: Test
run: cargo test --test 'mm2_tests_main' --no-fail-fast
run: |
wget -O - https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params-alt.sh | bash
cargo test --test 'mm2_tests_main' --no-fail-fast
Comment on lines +120 to +122
Copy link
Collaborator

Choose a reason for hiding this comment

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

sec-review


# https://docs.github.com/en/actions/learn-github-actions/usage-limits-billing-and-administration#usage-limits
# https://github.com/KomodoPlatform/atomicDEX-API/actions/runs/4419618128/jobs/7748266141#step:4:1790
Expand Down Expand Up @@ -161,7 +163,10 @@ jobs:
uses: ./.github/actions/cargo-cache

- name: Test
run: cargo test --test 'mm2_tests_main' --no-fail-fast
run: |
Invoke-WebRequest -Uri https://github.com/KomodoPlatform/komodo/raw/d456be35acd1f8584e1e4f971aea27bd0644d5c5/zcutil/wget64.exe -OutFile \wget64.exe
Invoke-WebRequest -Uri https://raw.githubusercontent.com/KomodoPlatform/komodo/master/zcutil/fetch-params-alt.bat -OutFile \cmd.bat && \cmd.bat
cargo test --test 'mm2_tests_main' --no-fail-fast
Copy link
Collaborator

Choose a reason for hiding this comment

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

sec-review


docker-tests:
timeout-minutes: 90
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/utxo/utxo_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod utxo_conf_builder;
pub use utxo_arc_builder::{MergeUtxoArcOps, UtxoArcBuilder};
pub use utxo_coin_builder::{UtxoCoinBuildError, UtxoCoinBuildResult, UtxoCoinBuilder, UtxoCoinBuilderCommonOps,
UtxoFieldsWithGlobalHDBuilder, UtxoFieldsWithHardwareWalletBuilder,
UtxoFieldsWithIguanaSecretBuilder};
UtxoFieldsWithIguanaSecretBuilder, DAY_IN_SECONDS};
pub use utxo_conf_builder::{UtxoConfBuilder, UtxoConfError, UtxoConfResult};

#[cfg(test)]
Expand Down
44 changes: 43 additions & 1 deletion mm2src/coins/utxo/utxo_builder/utxo_coin_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use common::custom_futures::repeatable::{Ready, Retry};
use common::executor::{abortable_queue::AbortableQueue, AbortSettings, AbortableSystem, AbortedError, SpawnAbortable,
Timer};
use common::log::{error, info, LogOnError};
use common::small_rng;
use common::{now_sec, small_rng};
use crypto::{Bip32DerPathError, CryptoCtx, CryptoCtxError, GlobalHDAccountArc, HwWalletType, StandardHDPathError,
StandardHDPathToCoin};
use derive_more::Display;
Expand Down Expand Up @@ -44,6 +44,9 @@ cfg_native! {
use std::path::{Path, PathBuf};
}

/// Number of seconds in a day (24 hours * 60 * 60)
pub const DAY_IN_SECONDS: u64 = 86400;
laruh marked this conversation as resolved.
Show resolved Hide resolved

pub type UtxoCoinBuildResult<T> = Result<T, MmError<UtxoCoinBuildError>>;

#[derive(Debug, Display)]
Expand Down Expand Up @@ -85,6 +88,7 @@ pub enum UtxoCoinBuildError {
Internal(String),
#[display(fmt = "SPV params verificaiton failed. Error: {_0}")]
SPVError(SPVError),
ErrorCalculatingStartingHeight(String),
}

impl From<UtxoConfError> for UtxoCoinBuildError {
Expand Down Expand Up @@ -685,6 +689,44 @@ pub trait UtxoCoinBuilderCommonOps {

(None, None)
}

/// Calculates the starting block height based on a given date and the current block height.
///
/// # Arguments
/// * `date`: The date in seconds representing the desired starting date.
/// * `current_block_height`: The current block height at the time of calculation.
///
fn calculate_starting_height_from_date(
&self,
date_s: u64,
current_block_height: u64,
) -> UtxoCoinBuildResult<Option<u64>> {
let avg_blocktime = self.conf()["avg_blocktime"]
.as_u64()
.ok_or_else(|| format!("avg_blocktime not specified in {} coin config", self.ticker()))
.map_to_mm(UtxoCoinBuildError::ErrorCalculatingStartingHeight)?;
let blocks_per_day = DAY_IN_SECONDS / avg_blocktime;
let current_time_s = now_sec();

if current_time_s < date_s {
return MmError::err(UtxoCoinBuildError::ErrorCalculatingStartingHeight(format!(
"{} sync date must be earlier then current date",
self.ticker()
)));
};

let secs_since_date = current_time_s - date_s;
let days_since_date = (secs_since_date / DAY_IN_SECONDS) - 1;
let blocks_to_sync = (days_since_date * blocks_per_day) + blocks_per_day;

if current_block_height < blocks_to_sync {
return Ok(None);
}

let block_to_sync_from = current_block_height - blocks_to_sync;

Ok(Some(block_to_sync_from))
}
}

/// Attempts to parse native daemon conf file and return rpcport, rpcuser and rpcpassword
Expand Down
57 changes: 35 additions & 22 deletions mm2src/coins/z_coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ use z_htlc::{z_p2sh_spend, z_send_dex_fee, z_send_htlc};

mod z_rpc;
use z_rpc::init_light_client;
pub use z_rpc::SyncStatus;
pub use z_rpc::{FirstSyncBlock, SyncStatus};

cfg_native!(
use crate::{NumConversError, TransactionDetails, TxFeeDetails};
Expand Down Expand Up @@ -305,9 +305,15 @@ impl ZCoin {
#[inline]
pub fn consensus_params_ref(&self) -> &ZcoinConsensusParams { &self.z_fields.consensus_params }

/// Asynchronously checks the synchronization status and returns `true` if
/// the Sapling state has finished synchronizing, meaning that the block number is available.
/// Otherwise, it returns `false`.
#[inline]
pub async fn is_sapling_state_synced(&self) -> bool {
laruh marked this conversation as resolved.
Show resolved Hide resolved
matches!(self.sync_status().await, Ok(SyncStatus::Finished { block_number: _ }))
matches!(
self.sync_status().await,
Ok(SyncStatus::Finished { block_number: _, .. })
)
}

#[inline]
Expand Down Expand Up @@ -755,14 +761,34 @@ impl AsRef<UtxoCoinFields> for ZCoin {
fn as_ref(&self) -> &UtxoCoinFields { &self.utxo_arc }
}

/// SyncStartPoint represents the starting point for synchronizing a wallet's blocks and transaction history.
/// This can be specified as a date, a block height, or starting from the earliest available data.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum SyncStartPoint {
laruh marked this conversation as resolved.
Show resolved Hide resolved
/// Synchronize from a specific date (in Unix timestamp format).
Date(u64),
/// Synchronize from a specific block height.
Height(u64),
/// Synchronize from the earliest available data(`sapling_activation_height` from coin config).
Earliest,
shamardy marked this conversation as resolved.
Show resolved Hide resolved
}

// ZcoinRpcMode reprs available RPC modes for interacting with the Zcoin network. It includes
/// modes for both native and light client, each with their own configuration options.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "rpc", content = "rpc_data")]
pub enum ZcoinRpcMode {
laruh marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(not(target_arch = "wasm32"))]
Native,
#[serde(alias = "Electrum")]
Light {
#[serde(alias = "servers")]
electrum_servers: Vec<ElectrumRpcRequest>,
shamardy marked this conversation as resolved.
Show resolved Hide resolved
light_wallet_d_servers: Vec<String>,
/// Specifies the parameters for synchronizing the wallet from a specific block. This overrides the
/// `CheckPointBlockInfo` configuration in the coin settings.
sync_params: Option<SyncStartPoint>,
},
}

Expand Down Expand Up @@ -894,36 +920,23 @@ impl<'a> UtxoCoinBuilder for ZCoinBuilder<'a> {
);

let blocks_db = self.blocks_db().await?;
let wallet_db = WalletDbShared::new(&self, &z_spending_key)
.await
.map_err(|err| ZCoinBuildError::ZcashDBError(err.to_string()))?;

let (sync_state_connector, light_wallet_db) = match &self.z_coin_params.mode {
#[cfg(not(target_arch = "wasm32"))]
ZcoinRpcMode::Native => {
let native_client = self.native_client()?;
init_native_client(
self.ticker.into(),
native_client,
blocks_db,
wallet_db,
self.protocol_info.consensus_params.clone(),
self.z_coin_params.scan_blocks_per_iteration,
self.z_coin_params.scan_interval_ms,
)
.await?
init_native_client(&self, native_client, blocks_db, &z_spending_key).await?
},
ZcoinRpcMode::Light {
light_wallet_d_servers, ..
light_wallet_d_servers,
sync_params,
..
} => {
init_light_client(
self.ticker.into(),
&self,
light_wallet_d_servers.clone(),
blocks_db,
wallet_db,
self.protocol_info.consensus_params.clone(),
self.z_coin_params.scan_blocks_per_iteration,
self.z_coin_params.scan_interval_ms,
sync_params,
&z_spending_key,
)
.await?
},
Expand Down
11 changes: 11 additions & 0 deletions mm2src/coins/z_coin/storage/blockdb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,17 @@ impl BlockDbImpl {

Ok(())
}

pub(crate) async fn get_earliest_block(&self) -> Result<u32, ZcashClientError> {
Ok(query_single_row(
&self.db.lock().unwrap(),
"SELECT MIN(height) from compactblocks",
[],
|row| row.get::<_, Option<u32>>(0),
)?
.flatten()
.unwrap_or(0))
}
Comment on lines +146 to +155
Copy link
Collaborator

Choose a reason for hiding this comment

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

sec-review

}

#[cfg(not(target_arch = "wasm32"))]
Expand Down
7 changes: 4 additions & 3 deletions mm2src/coins/z_coin/storage/walletdb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use mm2_err_handle::prelude::*;
use zcash_primitives::zip32::ExtendedSpendingKey;

cfg_native!(
use crate::z_coin::{ZcoinConsensusParams};
use crate::z_coin::{CheckPointBlockInfo, ZcoinConsensusParams};
use crate::z_coin::z_rpc::create_wallet_db;

use parking_lot::Mutex;
Expand Down Expand Up @@ -38,18 +38,19 @@ pub struct WalletDbShared {
impl<'a> WalletDbShared {
pub async fn new(
zcoin_builder: &ZCoinBuilder<'a>,
checkpoint_block: Option<CheckPointBlockInfo>,
z_spending_key: &ExtendedSpendingKey,
) -> MmResult<Self, WalletDbError> {
let wallet_db = create_wallet_db(
zcoin_builder
.db_dir_path
.join(format!("{}_wallet.db", zcoin_builder.ticker)),
zcoin_builder.protocol_info.consensus_params.clone(),
zcoin_builder.protocol_info.check_point_block.clone(),
checkpoint_block,
ExtendedFullViewingKey::from(z_spending_key),
)
.await
.map_err(|err| MmError::new(WalletDbError::ZcoinClientInitError(err.into_inner())))?;
.mm_err(WalletDbError::ZcoinClientInitError)?;

Ok(Self {
db: Arc::new(Mutex::new(wallet_db)),
Expand Down
12 changes: 12 additions & 0 deletions mm2src/coins/z_coin/z_coin_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use rpc::v1::types::{Bytes as BytesJson, H256 as H256Json};
use zcash_client_sqlite::error::SqliteClientError;
use zcash_primitives::transaction::builder::Error as ZTxBuilderError;

/// Represents possible errors that might occur while interacting with Zcoin rpc.
#[derive(Debug, Display)]
#[non_exhaustive]
pub enum UpdateBlocksCacheErr {
Expand All @@ -27,6 +28,7 @@ pub enum UpdateBlocksCacheErr {
JsonRpcError(JsonRpcError),
laruh marked this conversation as resolved.
Show resolved Hide resolved
GetLiveLightClientError(String),
ZcashDBError(String),
DecodeError(String),
}

#[cfg(not(target_arch = "wasm32"))]
Expand All @@ -52,13 +54,23 @@ impl From<JsonRpcError> for UpdateBlocksCacheErr {
fn from(err: JsonRpcError) -> Self { UpdateBlocksCacheErr::JsonRpcError(err) }
}

/// This enum encompasses various error scenarios that may arise
/// when configuring and activating a Zcoin, such as invalid
/// configuration settings, network connectivity issues, or other
/// initialization failures.
#[derive(Debug, Display)]
#[non_exhaustive]
pub enum ZcoinClientInitError {
ZcashDBError(String),
EmptyLightwalletdUris,
laruh marked this conversation as resolved.
Show resolved Hide resolved
#[display(fmt = "Fail to init clients while iterating lightwalletd urls {:?}", _0)]
UrlIterFailure(Vec<UrlIterError>),
UpdateBlocksCacheErr(UpdateBlocksCacheErr),
UtxoCoinBuildError(UtxoCoinBuildError),
}

impl From<UpdateBlocksCacheErr> for ZcoinClientInitError {
fn from(err: UpdateBlocksCacheErr) -> Self { ZcoinClientInitError::UpdateBlocksCacheErr(err) }
}

#[cfg(not(target_arch = "wasm32"))]
Expand Down
Loading
Loading