Skip to content

Commit

Permalink
do not store commitments in spent_index
Browse files Browse the repository at this point in the history
just use the order of the inputs in the block
  • Loading branch information
antiochp committed Feb 21, 2020
1 parent f61ec98 commit 73e13fc
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 45 deletions.
4 changes: 2 additions & 2 deletions chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::store;
use crate::txhashset;
use crate::txhashset::{PMMRHandle, TxHashSet};
use crate::types::{
BlockStatus, ChainAdapter, NoStatus, Options, OutputPos, Tip, TxHashsetWriteStatus,
BlockStatus, ChainAdapter, CommitPos, NoStatus, Options, Tip, TxHashsetWriteStatus,
};
use crate::util::secp::pedersen::{Commitment, RangeProof};
use crate::util::RwLock;
Expand Down Expand Up @@ -504,7 +504,7 @@ impl Chain {
/// spent. This querying is done in a way that is consistent with the
/// current chain state, specifically the current winning (valid, most
/// work) fork.
pub fn is_unspent(&self, output_ref: &OutputIdentifier) -> Result<OutputPos, Error> {
pub fn is_unspent(&self, output_ref: &OutputIdentifier) -> Result<CommitPos, Error> {
self.txhashset.read().is_unspent(output_ref)
}

Expand Down
6 changes: 3 additions & 3 deletions chain/src/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::core::pow;
use crate::error::{Error, ErrorKind};
use crate::store;
use crate::txhashset;
use crate::types::{Options, OutputPos, Tip};
use crate::types::{CommitPos, Options, Tip};
use crate::util::RwLock;
use grin_store;
use std::sync::Arc;
Expand Down Expand Up @@ -431,7 +431,7 @@ fn apply_block_to_txhashset(
block: &Block,
ext: &mut txhashset::ExtensionPair<'_>,
batch: &store::Batch<'_>,
) -> Result<Vec<OutputPos>, Error> {
) -> Result<Vec<CommitPos>, Error> {
let spent = ext.extension.apply_block(block, batch)?;
ext.extension.validate_roots(&block.header)?;
ext.extension.validate_sizes(&block.header)?;
Expand All @@ -444,7 +444,7 @@ fn apply_block_to_txhashset(
fn add_block(
b: &Block,
block_sums: &BlockSums,
spent: &Vec<OutputPos>,
spent: &Vec<CommitPos>,
batch: &store::Batch<'_>,
) -> Result<(), Error> {
batch.save_block(b)?;
Expand Down
6 changes: 3 additions & 3 deletions chain/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::{Block, BlockHeader, BlockSums};
use crate::core::pow::Difficulty;
use crate::core::ser::ProtocolVersion;
use crate::types::{OutputPos, Tip};
use crate::types::{CommitPos, Tip};
use crate::util::secp::pedersen::Commitment;
use croaring::Bitmap;
use grin_store as store;
Expand Down Expand Up @@ -190,7 +190,7 @@ impl<'a> Batch<'a> {

/// We maintain a "spent" index for each full block to allow the output_pos
/// to be easily reverted during rewind.
pub fn save_spent_index(&self, h: &Hash, spent: &Vec<OutputPos>) -> Result<(), Error> {
pub fn save_spent_index(&self, h: &Hash, spent: &Vec<CommitPos>) -> Result<(), Error> {
self.db
.put_ser(&to_key(BLOCK_SPENT_PREFIX, &mut h.to_vec())[..], spent)?;
Ok(())
Expand Down Expand Up @@ -349,7 +349,7 @@ impl<'a> Batch<'a> {

/// Get the "spent index" from the db for the specified block.
/// If we need to rewind a block then we use this to "unspend" the spent outputs.
pub fn get_spent_index(&self, bh: &Hash) -> Result<Vec<OutputPos>, Error> {
pub fn get_spent_index(&self, bh: &Hash) -> Result<Vec<CommitPos>, Error> {
option_to_not_found(
self.db
.get_ser(&to_key(BLOCK_SPENT_PREFIX, &mut bh.to_vec())),
Expand Down
44 changes: 17 additions & 27 deletions chain/src/txhashset/txhashset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::error::{Error, ErrorKind};
use crate::store::{Batch, ChainStore};
use crate::txhashset::bitmap_accumulator::BitmapAccumulator;
use crate::txhashset::{RewindableKernelView, UTXOView};
use crate::types::{OutputPos, OutputRoots, Tip, TxHashSetRoots, TxHashsetWriteStatus};
use crate::types::{CommitPos, OutputRoots, Tip, TxHashSetRoots, TxHashsetWriteStatus};
use crate::util::secp::pedersen::{Commitment, RangeProof};
use crate::util::{file, secp_static, zip};
use croaring::Bitmap;
Expand Down Expand Up @@ -223,19 +223,15 @@ impl TxHashSet {
/// Check if an output is unspent.
/// We look in the index to find the output MMR pos.
/// Then we check the entry in the output MMR and confirm the hash matches.
pub fn is_unspent(&self, output_id: &OutputIdentifier) -> Result<OutputPos, Error> {
pub fn is_unspent(&self, output_id: &OutputIdentifier) -> Result<CommitPos, Error> {
let commit = output_id.commit;
match self.commit_index.get_output_pos_height(&commit) {
Ok((pos, height)) => {
let output_pmmr: ReadonlyPMMR<'_, Output, _> =
ReadonlyPMMR::at(&self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
if let Some(hash) = output_pmmr.get_hash(pos) {
if hash == output_id.hash_with_index(pos - 1) {
Ok(OutputPos {
pos,
height,
commit,
})
Ok(CommitPos { pos, height })
} else {
Err(ErrorKind::TxHashSetErr("txhashset hash mismatch".to_string()).into())
}
Expand Down Expand Up @@ -927,27 +923,28 @@ impl<'a> Extension<'a> {
}

/// Apply a new block to the current txhashet extension (output, rangeproof, kernel MMRs).
pub fn apply_block(&mut self, b: &Block, batch: &Batch<'_>) -> Result<Vec<OutputPos>, Error> {
/// Returns a vec of commit_pos representing the pos and height of the outputs spent
/// by this block.
pub fn apply_block(&mut self, b: &Block, batch: &Batch<'_>) -> Result<Vec<CommitPos>, Error> {
let mut affected_pos = vec![];
let mut spent = vec![];

// Apply the output to the output and rangeproof MMRs.
// Add pos to affected_pos to update the accumulator later on.
// Add the new output to the output_pos index.
for out in b.outputs() {
let pos = self.apply_output(out, batch)?;
affected_pos.push(pos);

// TODO - we do *not* want to actually add to batch here?
// if we are processing a fork we want this batch to rollback.
batch.save_output_pos_height(&out.commitment(), pos, b.header.height)?;
}

// Remove the output from the output and rangeproof MMRs.
// Add spent_pos to affected_pos to update the accumulator later on.
// Remove the spent output from the output_pos index.
for input in b.inputs() {
let spent_pos = self.apply_input(input, batch)?;
affected_pos.push(spent_pos.pos);

// TODO - we do *not* want to actually add to batch here?
// if processing a fork we want this batch to rollback.
batch.delete_output_pos_height(&spent_pos.commit)?;

batch.delete_output_pos_height(&input.commitment())?;
spent.push(spent_pos);
}

Expand All @@ -965,9 +962,6 @@ impl<'a> Extension<'a> {
}

fn apply_to_bitmap_accumulator(&mut self, output_pos: &[u64]) -> Result<(), Error> {
// if self.output_pmmr.is_empty() || output_pos.is_empty() {
// return Ok(());
// }
let mut output_idx: Vec<_> = output_pos
.iter()
.map(|x| pmmr::n_leaves(*x).saturating_sub(1))
Expand All @@ -983,7 +977,7 @@ impl<'a> Extension<'a> {
)
}

fn apply_input(&mut self, input: &Input, batch: &Batch<'_>) -> Result<OutputPos, Error> {
fn apply_input(&mut self, input: &Input, batch: &Batch<'_>) -> Result<CommitPos, Error> {
let commit = input.commitment();
if let Ok((pos, height)) = batch.get_output_pos_height(&commit) {
// First check this input corresponds to an existing entry in the output MMR.
Expand All @@ -1003,11 +997,7 @@ impl<'a> Extension<'a> {
self.rproof_pmmr
.prune(pos)
.map_err(ErrorKind::TxHashSetErr)?;
Ok(OutputPos {
pos,
height,
commit,
})
Ok(CommitPos { pos, height })
}
Ok(false) => Err(ErrorKind::AlreadySpent(commit).into()),
Err(e) => Err(ErrorKind::TxHashSetErr(e).into()),
Expand Down Expand Up @@ -1185,8 +1175,8 @@ impl<'a> Extension<'a> {
// reused output commitment. For example an output at pos 1, spent, reused at pos 2.
// The output_pos index should be updated to reflect the old pos 1 when unspent.
if let Ok(spent) = spent {
for x in spent {
batch.save_output_pos_height(&x.commit, x.pos, x.height)?;
for (x, y) in block.inputs().into_iter().zip(spent) {
batch.save_output_pos_height(&x.commitment(), y.pos, y.height)?;
}
}

Expand Down
23 changes: 13 additions & 10 deletions chain/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,24 +271,27 @@ pub struct OutputPos {
pub commit: Commitment,
}

impl Readable for OutputPos {
fn read(reader: &mut dyn Reader) -> Result<OutputPos, ser::Error> {
/// Minimal struct representing a known MMR position and associated block height.
#[derive(Debug)]
pub struct CommitPos {
/// MMR position
pub pos: u64,
/// Block height
pub height: u64,
}

impl Readable for CommitPos {
fn read(reader: &mut dyn Reader) -> Result<CommitPos, ser::Error> {
let pos = reader.read_u64()?;
let height = reader.read_u64()?;
let commit = Commitment::read(reader)?;
Ok(OutputPos {
pos,
height,
commit,
})
Ok(CommitPos { pos, height })
}
}

impl Writeable for OutputPos {
impl Writeable for CommitPos {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_u64(self.pos)?;
writer.write_u64(self.height)?;
self.commit.write(writer)?;
Ok(())
}
}
Expand Down

0 comments on commit 73e13fc

Please sign in to comment.