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

make lib komodefi compatible #8

Merged
merged 43 commits into from
Nov 7, 2023
Merged
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
07ebc40
save dev state — added mm2_ext modules to sqlite_client and backend
borngraced Aug 14, 2023
d1158fe
save dev state — create async fn version of data_api functions
borngraced Aug 22, 2023
8819ec2
save dev state — modified async BlockSource trait
borngraced Aug 22, 2023
c3ab476
use aync-ware mutex
borngraced Aug 22, 2023
924c418
save dev state — ported wallet_Write and Read
borngraced Aug 25, 2023
3b1122b
save dev state — impl inner fn for WalletDbAsync
borngraced Aug 25, 2023
34799ce
save dev state — impl for_path fn for WalletDbAsync
borngraced Aug 25, 2023
9d2c681
save dev state — make BlockSource Send
borngraced Aug 25, 2023
329e249
save dev state — finish modification
borngraced Aug 27, 2023
ecb0295
save dev state — finish modification
borngraced Aug 27, 2023
624ed96
save dev state — minor changes
borngraced Aug 27, 2023
e473d79
save dev state — zcash extras
borngraced Aug 27, 2023
7fa620c
Merge remote-tracking branch 'origin/mm2_extras' into mm2_extras
borngraced Aug 27, 2023
bafac3a
make NoteRef not Copy
borngraced Aug 31, 2023
3c21128
move ShieldedOutput
borngraced Aug 31, 2023
5d5d822
fix review notes and add doc comments
borngraced Sep 5, 2023
d3d81c9
Revert "move ShieldedOutput"
borngraced Sep 5, 2023
8c12241
async init
borngraced Sep 7, 2023
e89819f
move WalletShieldedOutput
borngraced Sep 7, 2023
0c20210
make fake_compact_block and fake_compact_block_spending public
borngraced Sep 14, 2023
3d07af9
move fake_compact_block and fake_compact_block_spending public
borngraced Sep 14, 2023
9837e10
minor changes
borngraced Sep 14, 2023
6ab22ea
copy decrypt_and_store_transaction and create_spend_to_address as async
borngraced Sep 15, 2023
8f4b5e1
make db initializations async
borngraced Sep 15, 2023
809fc70
minor changes
borngraced Sep 18, 2023
985d47d
rename module
borngraced Sep 18, 2023
becd9d0
remove unused
borngraced Sep 18, 2023
ef13898
make LocalTxProver field pub
borngraced Sep 19, 2023
1901f09
move NoteId structure
borngraced Sep 25, 2023
bde9aab
fix review notes
borngraced Oct 5, 2023
37623e3
update time crate
borngraced Oct 6, 2023
496d255
fix review notes
borngraced Oct 11, 2023
af14c33
remove redundancy
borngraced Oct 11, 2023
99998ef
minor fix
borngraced Oct 11, 2023
cf057b9
change `zcash_extra` edition to 2018
borngraced Oct 11, 2023
7039054
delete NoteId from sqlite crate
borngraced Oct 11, 2023
b381253
remove redundancy crate decl
borngraced Oct 27, 2023
04e7b51
fix review notes
borngraced Nov 1, 2023
1b20142
fix review notes
borngraced Nov 1, 2023
97a64ea
make LocalTxProver fields private
borngraced Nov 2, 2023
cfbe0a0
fix sql init module review notes
borngraced Nov 2, 2023
faed2b8
remove decrypt_and_store_transaction
borngraced Nov 2, 2023
8c97f56
fix review notes
borngraced Nov 7, 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
Prev Previous commit
Next Next commit
save dev state — modified async BlockSource trait
borngraced committed Aug 22, 2023
commit 8819ec2bbc66c515f64aecc89b2de856e87d320a
231 changes: 127 additions & 104 deletions zcash_client_backend/src/with_async/data_api.rs
Original file line number Diff line number Diff line change
@@ -15,13 +15,13 @@ use zcash_primitives::zip32::ExtendedFullViewingKey;

/// This trait provides sequential access to raw blockchain data via a callback-oriented
/// API.
#[async_trait::async_trait]
#[async_trait::async_trait(?Send)]
pub trait BlockSource {
type Error;

/// Scan the specified `limit` number of blocks from the blockchain, starting at
/// `from_height`, applying the provided callback to each block.
fn with_blocks<F>(
async fn with_blocks<F>(
&self,
from_height: BlockHeight,
limit: Option<u32>,
@@ -31,6 +31,25 @@ pub trait BlockSource {
F: FnMut(CompactBlock) -> Result<(), Self::Error>;
}

struct BlockSourceCaged;

#[async_trait::async_trait(?Send)]
impl BlockSource for BlockSourceCaged {
type Error = String;

async fn with_blocks<F>(
&self,
from_height: BlockHeight,
limit: Option<u32>,
with_row: Box<F>,
) -> Result<(), Self::Error>
where
F: FnMut(CompactBlock) -> Result<(), Self::Error>,
{
todo!()
}
}

pub async fn validate_chain<'a, N, E, P, C>(
parameters: &P,
cache: &C,
@@ -56,29 +75,31 @@ where
let mut prev_height = from_height;
let mut prev_hash: Option<BlockHash> = validate_from.map(|(_, hash)| hash);

cache.with_blocks(
from_height,
None,
Box::new(|block: CompactBlock| {
let current_height = block.height();
let result = if current_height != prev_height + 1 {
Err(ChainInvalid::block_height_discontinuity(
prev_height + 1,
current_height,
))
} else {
match prev_hash {
None => Ok(()),
Some(h) if h == block.prev_hash() => Ok(()),
Some(_) => Err(ChainInvalid::prev_hash_mismatch(current_height)),
}
};

prev_height = current_height;
prev_hash = Some(block.hash());
result.map_err(E::from)
}),
)
cache
.with_blocks(
from_height,
None,
Box::new(|block: CompactBlock| {
let current_height = block.height();
let result = if current_height != prev_height + 1 {
Err(ChainInvalid::block_height_discontinuity(
prev_height + 1,
current_height,
))
} else {
match prev_hash {
None => Ok(()),
Some(h) if h == block.prev_hash() => Ok(()),
Some(_) => Err(ChainInvalid::prev_hash_mismatch(current_height)),
}
};

prev_height = current_height;
prev_hash = Some(block.hash());
result.map_err(E::from)
}),
)
.await
}

pub async fn scan_cached_blocks<'a, E, N, P, C, D>(
@@ -121,87 +142,89 @@ where
// Get the nullifiers for the notes we are tracking
let mut nullifiers = data_guard.get_nullifiers()?;

cache.with_blocks(
last_height,
limit,
Box::new(|block: CompactBlock| {
let current_height = block.height();

// Scanned blocks MUST be height-sequential.
if current_height != (last_height + 1) {
return Err(ChainInvalid::block_height_discontinuity(
last_height + 1,
current_height,
)
.into());
}

let block_hash = BlockHash::from_slice(&block.hash);
let block_time = block.time;

let txs: Vec<WalletTx<Nullifier>> = {
let mut witness_refs: Vec<_> = witnesses.iter_mut().map(|w| &mut w.1).collect();

scan_block(
params,
block,
&extfvks,
&nullifiers,
&mut tree,
&mut witness_refs[..],
)
};

// Enforce that all roots match. This is slow, so only include in debug builds.
#[cfg(debug_assertions)]
{
let cur_root = tree.root();
for row in &witnesses {
if row.1.root() != cur_root {
return Err(Error::InvalidWitnessAnchor(row.0, current_height).into());
}
cache
.with_blocks(
last_height,
limit,
Box::new(|block: CompactBlock| {
let current_height = block.height();

// Scanned blocks MUST be height-sequential.
if current_height != (last_height + 1) {
return Err(ChainInvalid::block_height_discontinuity(
last_height + 1,
current_height,
)
.into());
}
for tx in &txs {
for output in tx.shielded_outputs.iter() {
if output.witness.root() != cur_root {
return Err(Error::InvalidNewWitnessAnchor(
output.index,
tx.txid,
current_height,
output.witness.root(),
)
.into());

let block_hash = BlockHash::from_slice(&block.hash);
let block_time = block.time;

let txs: Vec<WalletTx<Nullifier>> = {
let mut witness_refs: Vec<_> = witnesses.iter_mut().map(|w| &mut w.1).collect();

scan_block(
params,
block,
&extfvks,
&nullifiers,
&mut tree,
&mut witness_refs[..],
)
};

// Enforce that all roots match. This is slow, so only include in debug builds.
#[cfg(debug_assertions)]
{
let cur_root = tree.root();
for row in &witnesses {
if row.1.root() != cur_root {
return Err(Error::InvalidWitnessAnchor(row.0, current_height).into());
}
}
for tx in &txs {
for output in tx.shielded_outputs.iter() {
if output.witness.root() != cur_root {
return Err(Error::InvalidNewWitnessAnchor(
output.index,
tx.txid,
current_height,
output.witness.root(),
)
.into());
}
}
}
}
}

let new_witnesses = data_guard.advance_by_block(
&(PrunedBlock {
block_height: current_height,
block_hash,
block_time,
commitment_tree: &tree,
transactions: &txs,
}),
&witnesses,
)?;

let spent_nf: Vec<Nullifier> = txs
.iter()
.flat_map(|tx| tx.shielded_spends.iter().map(|spend| spend.nf))
.collect();
nullifiers.retain(|(_, nf)| !spent_nf.contains(nf));
nullifiers.extend(
txs.iter()
.flat_map(|tx| tx.shielded_outputs.iter().map(|out| (out.account, out.nf))),
);

witnesses.extend(new_witnesses);

last_height = current_height;

Ok(())
}),
)

let new_witnesses = data_guard.advance_by_block(
&(PrunedBlock {
block_height: current_height,
block_hash,
block_time,
commitment_tree: &tree,
transactions: &txs,
}),
&witnesses,
)?;

let spent_nf: Vec<Nullifier> = txs
.iter()
.flat_map(|tx| tx.shielded_spends.iter().map(|spend| spend.nf))
.collect();
nullifiers.retain(|(_, nf)| !spent_nf.contains(nf));
nullifiers
.extend(txs.iter().flat_map(|tx| {
tx.shielded_outputs.iter().map(|out| (out.account, out.nf))
}));

witnesses.extend(new_witnesses);

last_height = current_height;

Ok(())
}),
)
.await
}