Skip to content

Commit

Permalink
Merge pull request #797 from fluidvanadium/save_less
Browse files Browse the repository at this point in the history
Save less
  • Loading branch information
AloeareV authored Jan 26, 2024
2 parents c008e3f + 6c03784 commit f8c914a
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 20 deletions.
92 changes: 88 additions & 4 deletions integration-tests/tests/integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ mod fast {
let wallet_dir = wallet_path.parent().unwrap();
let (wallet, config) =
zingo_testutils::load_wallet(wallet_dir.to_path_buf(), ChainType::Mainnet).await;
let client = LightClient::create_from_wallet(wallet, config);
let client = LightClient::create_from_wallet_async(wallet, config)
.await
.unwrap();
let transactions = client.do_list_transactions().await[0].clone();
//env_logger::init();
let expected_consumer_ui_note = r#"{
Expand Down Expand Up @@ -326,7 +328,10 @@ mod fast {
.unwrap();

// Create client based on config and wallet of faucet
let faucet_copy = LightClient::create_from_wallet(faucet_wallet, zingo_config.clone());
let faucet_copy =
LightClient::create_from_wallet_async(faucet_wallet, zingo_config.clone())
.await
.unwrap();
assert_eq!(
&faucet_copy.do_seed_phrase().await.unwrap(),
&faucet.do_seed_phrase().await.unwrap()
Expand Down Expand Up @@ -616,7 +621,84 @@ mod fast {
assert!(addr.transparent().is_some());
}

let client = LightClient::create_from_wallet(wallet, config);
let client = LightClient::create_from_wallet_async(wallet, config)
.await
.unwrap();
let balance = client.do_balance().await;
assert_eq!(balance.orchard_balance, Some(10342837));
}

#[tokio::test]
async fn reload_wallet_from_buffer() {
// We test that the LightWallet can be read from v28 .dat file
// A testnet wallet initiated with
// --seed "chimney better bulb horror rebuild whisper improve intact letter giraffe brave rib appear bulk aim burst snap salt hill sad merge tennis phrase raise"
// --birthday 0
// --nosync
// with 3 addresses containing all receivers.
let data = include_bytes!("zingo-wallet-v28.dat");

let config = zingoconfig::ZingoConfig::build(ChainType::Testnet).create();
let mid_wallet = LightWallet::read_internal(&data[..], &config)
.await
.map_err(|e| format!("Cannot deserialize LightWallet version 28 file: {}", e))
.unwrap();

let mid_client = LightClient::create_from_wallet_async(mid_wallet, config.clone())
.await
.unwrap();
let mid_buffer = mid_client.export_save_buffer_async().await.unwrap();
let wallet = LightWallet::read_internal(&mid_buffer[..], &config)
.await
.map_err(|e| format!("Cannot deserialize rebuffered LightWallet: {}", e))
.unwrap();
let expected_mnemonic = (
Mnemonic::from_phrase(CHIMNEY_BETTER_SEED.to_string()).unwrap(),
0,
);
assert_eq!(wallet.mnemonic(), Some(&expected_mnemonic));

let expected_wc =
WalletCapability::new_from_phrase(&config, &expected_mnemonic.0, expected_mnemonic.1)
.unwrap();
let wc = wallet.wallet_capability();

let Capability::Spend(orchard_sk) = &wc.orchard else {
panic!("Expected Orchard Spending Key");
};
assert_eq!(
orchard_sk.to_bytes(),
orchard::keys::SpendingKey::try_from(&expected_wc)
.unwrap()
.to_bytes()
);

let Capability::Spend(sapling_sk) = &wc.sapling else {
panic!("Expected Sapling Spending Key");
};
assert_eq!(
sapling_sk,
&zcash_primitives::zip32::ExtendedSpendingKey::try_from(&expected_wc).unwrap()
);

let Capability::Spend(transparent_sk) = &wc.transparent else {
panic!("Expected transparent extended private key");
};
assert_eq!(
transparent_sk,
&ExtendedPrivKey::try_from(&expected_wc).unwrap()
);

assert_eq!(wc.addresses().len(), 3);
for addr in wc.addresses().iter() {
assert!(addr.orchard().is_some());
assert!(addr.sapling().is_some());
assert!(addr.transparent().is_some());
}

let client = LightClient::create_from_wallet_async(wallet, config)
.await
.unwrap();
let balance = client.do_balance().await;
assert_eq!(balance.orchard_balance, Some(10342837));
}
Expand Down Expand Up @@ -2783,7 +2865,9 @@ mod slow {
println!("setting uri");
*conf.lightwalletd_uri.write().unwrap() = faucet.get_server_uri();
println!("creating lightclient");
let recipient = LightClient::create_from_wallet(wallet, conf);
let recipient = LightClient::create_from_wallet_async(wallet, conf)
.await
.unwrap();
println!(
"pre-sync transactions: {}",
recipient.do_list_transactions().await.pretty(2)
Expand Down
4 changes: 3 additions & 1 deletion zingo-testutils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ pub async fn build_fvk_client(fvks: &[&Fvk], zingoconfig: &ZingoConfig) -> Light
.unwrap(),
&zcash_address::Network::Regtest,
);
LightClient::create_unconnected(zingoconfig, WalletBase::Ufvk(ufvk), 0).unwrap()
LightClient::create_unconnected(zingoconfig, WalletBase::Ufvk(ufvk), 0)
.await
.unwrap()
}

async fn get_synced_wallet_height(client: &LightClient) -> Result<u32, String> {
Expand Down
46 changes: 31 additions & 15 deletions zingolib/src/lightclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ struct ZingoSaveBuffer {
pub buffer: Arc<RwLock<Vec<u8>>>,
}

impl ZingoSaveBuffer {
fn new(buffer: Vec<u8>) -> Self {
ZingoSaveBuffer {
buffer: Arc::new(RwLock::new(buffer)),
}
}
}

/// Balances that may be presented to a user in a wallet app.
/// The goal is to present a user-friendly and useful view of what the user has or can soon expect
/// *without* requiring the user to understand the details of the Zcash protocol.
Expand Down Expand Up @@ -244,16 +252,21 @@ pub struct LightClient {
impl LightClient {
/// this is the standard initializer for a LightClient.
// toDo rework ZingoConfig.
pub fn create_from_wallet(wallet: LightWallet, config: ZingoConfig) -> Self {
LightClient {
pub async fn create_from_wallet_async(
wallet: LightWallet,
config: ZingoConfig,
) -> io::Result<Self> {
let mut buffer: Vec<u8> = vec![];
wallet.write(&mut buffer).await?;
Ok(LightClient {
wallet,
config: config.clone(),
mempool_monitor: std::sync::RwLock::new(None),
sync_lock: Mutex::new(()),
bsync_data: Arc::new(RwLock::new(BlazeSyncData::new(&config))),
interrupt_sync: Arc::new(RwLock::new(false)),
save_buffer: ZingoSaveBuffer::default(),
}
save_buffer: ZingoSaveBuffer::new(buffer),
})
}
/// The wallet this fn associates with the lightclient is specifically derived from
/// a spend authority.
Expand Down Expand Up @@ -289,10 +302,11 @@ impl LightClient {
));
}
}
let lightclient = LightClient::create_from_wallet(
let lightclient = LightClient::create_from_wallet_async(
LightWallet::new(config.clone(), wallet_base, birthday)?,
config.clone(),
);
)
.await?;

lightclient.set_wallet_initial_state(birthday).await;
lightclient
Expand All @@ -304,21 +318,23 @@ impl LightClient {

Ok(lightclient)
}
pub fn create_unconnected(
pub async fn create_unconnected(
config: &ZingoConfig,
wallet_base: WalletBase,
height: u64,
) -> io::Result<Self> {
let lightclient = LightClient::create_from_wallet(
let lightclient = LightClient::create_from_wallet_async(
LightWallet::new(config.clone(), wallet_base, height)?,
config.clone(),
);
)
.await?;
Ok(lightclient)
}

fn create_with_new_wallet(config: &ZingoConfig, height: u64) -> io::Result<Self> {
Runtime::new().unwrap().block_on(async move {
let l = LightClient::create_unconnected(config, WalletBase::FreshEntropy, height)?;
let l =
LightClient::create_unconnected(config, WalletBase::FreshEntropy, height).await?;
l.set_wallet_initial_state(height).await;

debug!("Created new wallet with a new seed!");
Expand Down Expand Up @@ -399,7 +415,7 @@ impl LightClient {
}

pub async fn export_save_buffer_async(&self) -> ZingoLibResult<Vec<u8>> {
self.save_internal_rust().await?;
// self.save_internal_rust().await?;
let read_buffer = self.save_buffer.buffer.read().await;
if !read_buffer.is_empty() {
Ok(read_buffer.clone())
Expand Down Expand Up @@ -434,7 +450,7 @@ impl LightClient {
) -> io::Result<Self> {
let wallet = LightWallet::read_internal(&mut reader, config).await?;

let lc = LightClient::create_from_wallet(wallet, config.clone());
let lc = LightClient::create_from_wallet_async(wallet, config.clone()).await?;

debug!(
"Read wallet with birthday {}",
Expand Down Expand Up @@ -783,7 +799,7 @@ impl LightClient {
.wallet_capability()
.new_address(desired_receivers)?;

self.save_internal_rust().await?;
// self.save_internal_rust().await?;

Ok(array![new_address.encode(&self.config.chain)])
}
Expand All @@ -796,7 +812,7 @@ impl LightClient {
let response = self.do_sync(true).await;

if response.is_ok() {
self.save_internal_rust().await?;
// self.save_internal_rust().await?;
}

debug!("Rescan finished");
Expand Down Expand Up @@ -1689,7 +1705,7 @@ impl LightClient {

debug!("About to run save after syncing {}th batch!", batch_num);

#[cfg(not(any(target_os = "ios", target_os = "android")))]
// #[cfg(not(any(target_os = "ios", target_os = "android")))]
self.save_internal_rust().await.unwrap();

Ok(SyncResult {
Expand Down

0 comments on commit f8c914a

Please sign in to comment.