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 20 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
42 changes: 41 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, Secp256k1Secret,
StandardHDPathError, StandardHDPathToCoin};
use derive_more::Display;
Expand Down Expand Up @@ -44,6 +44,8 @@ cfg_native! {
use std::path::{Path, PathBuf};
}

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 +87,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 @@ -667,6 +670,43 @@ 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: u64, current_block_height: u64) -> UtxoCoinBuildResult<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 {
return MmError::err(UtxoCoinBuildError::ErrorCalculatingStartingHeight(format!(
"{} sync date must be earlier then current date",
self.ticker()
)));
};

let secs_since_date = current_time_s - date;
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 MmError::err(UtxoCoinBuildError::ErrorCalculatingStartingHeight(format!(
"{} current_block_height: {current_block_height} must be greater than blocks_to_sync: {blocks_to_sync}",
self.ticker(),
)));
}

let block_to_sync_from = current_block_height - blocks_to_sync;

Ok(block_to_sync_from)
}
}

/// Attempts to parse native daemon conf file and return rpcport, rpcuser and rpcpassword
Expand Down
37 changes: 11 additions & 26 deletions mm2src/coins/z_coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,12 @@ impl AsRef<UtxoCoinFields> for ZCoin {
fn as_ref(&self) -> &UtxoCoinFields { &self.utxo_arc }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum SyncStartPoint {
laruh marked this conversation as resolved.
Show resolved Hide resolved
Date(u64),
Height(u64),
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "rpc", content = "rpc_data")]
pub enum ZcoinRpcMode {
laruh marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -763,6 +769,9 @@ pub enum ZcoinRpcMode {
Light {
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 @@ -888,39 +897,15 @@ impl<'a> UtxoCoinBuilder for ZCoinBuilder<'a> {
);

let blocks_db = self.blocks_db().await?;
let wallet_db = WalletDbShared::new(&self)
.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).await?
},
ZcoinRpcMode::Light {
light_wallet_d_servers, ..
} => {
init_light_client(
self.ticker.into(),
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,
)
.await?
},
} => init_light_client(&self, light_wallet_d_servers.clone(), blocks_db).await?,
};
let z_fields = ZCoinFields {
dex_fee_addr,
Expand Down
74 changes: 68 additions & 6 deletions mm2src/coins/z_coin/storage/walletdb/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
use crate::utxo::utxo_builder::UtxoCoinBuildError;
use crate::z_coin::{ZCoinBuilder, ZcoinClientInitError};
use mm2_err_handle::prelude::*;

cfg_native!(
use crate::z_coin::{extended_spending_key_from_protocol_info_and_policy, ZcoinConsensusParams};
use crate::z_coin::z_rpc::create_wallet_db;
use crate::utxo::utxo_builder::{UtxoCoinBuilderCommonOps, DAY_IN_SECONDS};
use crate::z_coin::{CheckPointBlockInfo, extended_spending_key_from_protocol_info_and_policy, SyncStartPoint,
ZcoinConsensusParams, ZcoinRpcMode};
use crate::z_coin::z_rpc::{create_wallet_db, ZRpcOps};

use common::now_sec;
use hex::{FromHex, FromHexError};
use parking_lot::Mutex;
use rpc::v1::types::{Bytes, H256};
use std::str::FromStr;
use std::sync::Arc;
use zcash_client_sqlite::WalletDb;
use zcash_primitives::zip32::ExtendedFullViewingKey;
Expand All @@ -21,6 +28,14 @@ pub enum WalletDbError {
ZcoinClientInitError(ZcoinClientInitError),
ZCoinBuildError(String),
IndexedDBError(String),
GrpcError(String),
DecodeError(String),
UtxoCoinBuildError(UtxoCoinBuildError),
}

#[cfg(not(target_arch = "wasm32"))]
impl From<tonic::Status> for WalletDbError {
fn from(err: tonic::Status) -> Self { WalletDbError::GrpcError(err.to_string()) }
}

#[derive(Clone)]
Expand All @@ -33,27 +48,74 @@ pub struct WalletDbShared {
ticker: String,
}

#[cfg(not(target_arch = "wasm32"))]
async fn checkpoint_block_from_height(
artemii235 marked this conversation as resolved.
Show resolved Hide resolved
height: u64,
rpc: &mut impl ZRpcOps,
) -> MmResult<Option<CheckPointBlockInfo>, WalletDbError> {
let tree_state = rpc
.get_tree_state(height)
.await
.mm_err(|err| WalletDbError::GrpcError(err.to_string()))?;
let hash = H256::from_str(&tree_state.hash)
.map_err(|err| WalletDbError::DecodeError(err.to_string()))?
.reversed();
let sapling_tree = Bytes::new(
FromHex::from_hex(&tree_state.tree).map_err(|err: FromHexError| WalletDbError::DecodeError(err.to_string()))?,
);

Ok(Some(CheckPointBlockInfo {
height: tree_state.height as u32,
hash,
time: tree_state.time,
sapling_tree,
}))
}

#[cfg(not(target_arch = "wasm32"))]
impl<'a> WalletDbShared {
pub async fn new(zcoin_builder: &ZCoinBuilder<'a>) -> MmResult<Self, WalletDbError> {
pub async fn new(zcoin_builder: &ZCoinBuilder<'a>, rpc: &mut impl ZRpcOps) -> MmResult<Self, WalletDbError> {
let z_spending_key = match zcoin_builder.z_spending_key {
Some(ref z_spending_key) => z_spending_key.clone(),
None => extended_spending_key_from_protocol_info_and_policy(
&zcoin_builder.protocol_info,
&zcoin_builder.priv_key_policy,
)
.map_err(|err| WalletDbError::ZCoinBuildError(err.to_string()))?,
.mm_err(|err| WalletDbError::ZCoinBuildError(err.to_string()))?,
};

let current_block_height = rpc
.get_block_height()
.await
.map_err(|err| WalletDbError::GrpcError(err.to_string()))?;
let sync_block = match &zcoin_builder.z_coin_params.mode {
ZcoinRpcMode::Light { sync_params, .. } => {
let sync_height = match sync_params {
Some(SyncStartPoint::Date(date)) => zcoin_builder
.calculate_starting_height_from_date(*date, current_block_height)
.mm_err(WalletDbError::UtxoCoinBuildError)?,
Some(SyncStartPoint::Height(height)) => *height,
None => zcoin_builder
.calculate_starting_height_from_date(now_sec() - DAY_IN_SECONDS, current_block_height)
.mm_err(WalletDbError::UtxoCoinBuildError)?,
};

checkpoint_block_from_height(sync_height, rpc).await?
},

ZcoinRpcMode::Native => zcoin_builder.protocol_info.check_point_block.clone(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Native should be the same as light client as discussed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This can be done in another PR as we agreed. Please don't forget to open an issue for it.

artemii235 marked this conversation as resolved.
Show resolved Hide resolved
};

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(),
sync_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
Loading
Loading