decouple outputs from output MMR (#2044)

This commit is contained in:
Antioch Peverell 2018-11-29 10:17:44 +00:00 committed by GitHub
parent 8e62130a7a
commit f05d3dd920
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 19 deletions

View file

@ -102,7 +102,7 @@ pub struct TxHashSet {
/// via a "sync_extension". /// via a "sync_extension".
sync_pmmr_h: PMMRHandle<BlockHeader>, sync_pmmr_h: PMMRHandle<BlockHeader>,
output_pmmr_h: PMMRHandle<OutputIdentifier>, output_pmmr_h: PMMRHandle<Output>,
rproof_pmmr_h: PMMRHandle<RangeProof>, rproof_pmmr_h: PMMRHandle<RangeProof>,
kernel_pmmr_h: PMMRHandle<TxKernel>, kernel_pmmr_h: PMMRHandle<TxKernel>,
@ -163,7 +163,7 @@ impl TxHashSet {
pub fn is_unspent(&mut self, output_id: &OutputIdentifier) -> Result<(Hash, u64), Error> { pub fn is_unspent(&mut self, output_id: &OutputIdentifier) -> Result<(Hash, u64), Error> {
match self.commit_index.get_output_pos(&output_id.commit) { match self.commit_index.get_output_pos(&output_id.commit) {
Ok(pos) => { Ok(pos) => {
let output_pmmr: PMMR<OutputIdentifier, _> = let output_pmmr: PMMR<Output, _> =
PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos); PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
if let Some(hash) = output_pmmr.get_hash(pos) { if let Some(hash) = output_pmmr.get_hash(pos) {
if hash == output_id.hash_with_index(pos - 1) { if hash == output_id.hash_with_index(pos - 1) {
@ -185,7 +185,7 @@ impl TxHashSet {
/// TODO: These need to return the actual data from the flat-files instead /// TODO: These need to return the actual data from the flat-files instead
/// of hashes now /// of hashes now
pub fn last_n_output(&mut self, distance: u64) -> Vec<(Hash, OutputIdentifier)> { pub fn last_n_output(&mut self, distance: u64) -> Vec<(Hash, OutputIdentifier)> {
let output_pmmr: PMMR<OutputIdentifier, _> = let output_pmmr: PMMR<Output, _> =
PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos); PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
output_pmmr.get_last_n_insertions(distance) output_pmmr.get_last_n_insertions(distance)
} }
@ -227,7 +227,7 @@ impl TxHashSet {
start_index: u64, start_index: u64,
max_count: u64, max_count: u64,
) -> (u64, Vec<OutputIdentifier>) { ) -> (u64, Vec<OutputIdentifier>) {
let output_pmmr: PMMR<OutputIdentifier, _> = let output_pmmr: PMMR<Output, _> =
PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos); PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
output_pmmr.elements_from_insertion_index(start_index, max_count) output_pmmr.elements_from_insertion_index(start_index, max_count)
} }
@ -252,7 +252,7 @@ impl TxHashSet {
pub fn roots(&mut self) -> TxHashSetRoots { pub fn roots(&mut self) -> TxHashSetRoots {
let header_pmmr: PMMR<BlockHeader, _> = let header_pmmr: PMMR<BlockHeader, _> =
PMMR::at(&mut self.header_pmmr_h.backend, self.header_pmmr_h.last_pos); PMMR::at(&mut self.header_pmmr_h.backend, self.header_pmmr_h.last_pos);
let output_pmmr: PMMR<OutputIdentifier, _> = let output_pmmr: PMMR<Output, _> =
PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos); PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
let rproof_pmmr: PMMR<RangeProof, _> = let rproof_pmmr: PMMR<RangeProof, _> =
PMMR::at(&mut self.rproof_pmmr_h.backend, self.rproof_pmmr_h.last_pos); PMMR::at(&mut self.rproof_pmmr_h.backend, self.rproof_pmmr_h.last_pos);
@ -270,7 +270,7 @@ impl TxHashSet {
/// build a new merkle proof for the given position /// build a new merkle proof for the given position
pub fn merkle_proof(&mut self, commit: Commitment) -> Result<MerkleProof, String> { pub fn merkle_proof(&mut self, commit: Commitment) -> Result<MerkleProof, String> {
let pos = self.commit_index.get_output_pos(&commit).unwrap(); let pos = self.commit_index.get_output_pos(&commit).unwrap();
let output_pmmr: PMMR<OutputIdentifier, _> = let output_pmmr: PMMR<Output, _> =
PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos); PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
output_pmmr.merkle_proof(pos) output_pmmr.merkle_proof(pos)
} }
@ -773,7 +773,7 @@ pub struct Extension<'a> {
header: BlockHeader, header: BlockHeader,
header_pmmr: PMMR<'a, BlockHeader, PMMRBackend<BlockHeader>>, header_pmmr: PMMR<'a, BlockHeader, PMMRBackend<BlockHeader>>,
output_pmmr: PMMR<'a, OutputIdentifier, PMMRBackend<OutputIdentifier>>, output_pmmr: PMMR<'a, Output, PMMRBackend<Output>>,
rproof_pmmr: PMMR<'a, RangeProof, PMMRBackend<RangeProof>>, rproof_pmmr: PMMR<'a, RangeProof, PMMRBackend<RangeProof>>,
kernel_pmmr: PMMR<'a, TxKernel, PMMRBackend<TxKernel>>, kernel_pmmr: PMMR<'a, TxKernel, PMMRBackend<TxKernel>>,
@ -967,7 +967,7 @@ impl<'a> Extension<'a> {
// push the new output to the MMR. // push the new output to the MMR.
let output_pos = self let output_pos = self
.output_pmmr .output_pmmr
.push(OutputIdentifier::from_output(out)) .push(out.clone())
.map_err(&ErrorKind::TxHashSetErr)?; .map_err(&ErrorKind::TxHashSetErr)?;
// push the rangeproof to the MMR. // push the rangeproof to the MMR.

View file

@ -15,7 +15,7 @@
//! Lightweight readonly view into output MMR for convenience. //! Lightweight readonly view into output MMR for convenience.
use core::core::pmmr::ReadonlyPMMR; use core::core::pmmr::ReadonlyPMMR;
use core::core::{Block, Input, Output, OutputIdentifier, Transaction}; use core::core::{Block, Input, Output, Transaction};
use error::{Error, ErrorKind}; use error::{Error, ErrorKind};
use grin_store::pmmr::PMMRBackend; use grin_store::pmmr::PMMRBackend;
@ -23,14 +23,14 @@ use store::Batch;
/// Readonly view of the UTXO set (based on output MMR). /// Readonly view of the UTXO set (based on output MMR).
pub struct UTXOView<'a> { pub struct UTXOView<'a> {
pmmr: ReadonlyPMMR<'a, OutputIdentifier, PMMRBackend<OutputIdentifier>>, pmmr: ReadonlyPMMR<'a, Output, PMMRBackend<Output>>,
batch: &'a Batch<'a>, batch: &'a Batch<'a>,
} }
impl<'a> UTXOView<'a> { impl<'a> UTXOView<'a> {
/// Build a new UTXO view. /// Build a new UTXO view.
pub fn new( pub fn new(
pmmr: ReadonlyPMMR<'a, OutputIdentifier, PMMRBackend<OutputIdentifier>>, pmmr: ReadonlyPMMR<'a, Output, PMMRBackend<Output>>,
batch: &'a Batch, batch: &'a Batch,
) -> UTXOView<'a> { ) -> UTXOView<'a> {
UTXOView { pmmr, batch } UTXOView { pmmr, batch }

View file

@ -1147,6 +1147,15 @@ impl Readable for Output {
} }
} }
/// We can build an Output MMR but store instances of OutputIdentifier in the MMR data file.
impl PMMRable for Output {
type E = OutputIdentifier;
fn as_elmt(self) -> Self::E {
self.into()
}
}
impl Output { impl Output {
/// Commitment for the output /// Commitment for the output
pub fn commitment(&self) -> Commitment { pub fn commitment(&self) -> Commitment {
@ -1244,14 +1253,6 @@ impl FixedLength for OutputIdentifier {
const LEN: usize = 1 + secp::constants::PEDERSEN_COMMITMENT_SIZE; const LEN: usize = 1 + secp::constants::PEDERSEN_COMMITMENT_SIZE;
} }
impl PMMRable for OutputIdentifier {
type E = Self;
fn as_elmt(self) -> Self::E {
self
}
}
impl Writeable for OutputIdentifier { impl Writeable for OutputIdentifier {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> { fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_u8(self.features.bits())?; writer.write_u8(self.features.bits())?;
@ -1271,6 +1272,15 @@ impl Readable for OutputIdentifier {
} }
} }
impl From<Output> for OutputIdentifier {
fn from(out: Output) -> Self {
OutputIdentifier {
features: out.features,
commit: out.commit,
}
}
}
/// Construct msg from tx fee and lock_height. /// Construct msg from tx fee and lock_height.
pub fn kernel_sig_msg(fee: u64, lock_height: u64) -> Result<secp::Message, Error> { pub fn kernel_sig_msg(fee: u64, lock_height: u64) -> Result<secp::Message, Error> {
let mut bytes = [0; 32]; let mut bytes = [0; 32];