mirror of
https://github.com/mimblewimble/grin.git
synced 2025-05-07 17:51:14 +03:00
utxo_view hash compare (#2082)
* utxo_view validate_input now checks the data in the output MMR * cleanup apply_input and validate_input
This commit is contained in:
parent
54a034c40a
commit
02b3bf4b59
2 changed files with 19 additions and 23 deletions
chain/src/txhashset
|
@ -910,16 +910,9 @@ impl<'a> Extension<'a> {
|
|||
let commit = input.commitment();
|
||||
let pos_res = self.batch.get_output_pos(&commit);
|
||||
if let Ok(pos) = pos_res {
|
||||
let output_id_hash = OutputIdentifier::from_input(input).hash_with_index(pos - 1);
|
||||
if let Some(read_hash) = self.output_pmmr.get_hash(pos) {
|
||||
// check hash from pmmr matches hash from input (or corresponding output)
|
||||
// if not then the input is not being honest about
|
||||
// what it is attempting to spend...
|
||||
let read_elem = self.output_pmmr.get_data(pos);
|
||||
let read_elem_hash = read_elem
|
||||
.expect("no output at pos")
|
||||
.hash_with_index(pos - 1);
|
||||
if output_id_hash != read_hash || output_id_hash != read_elem_hash {
|
||||
// First check this input corresponds to an existing entry in the output MMR.
|
||||
if let Some(hash) = self.output_pmmr.get_hash(pos) {
|
||||
if hash != input.hash_with_index(pos - 1) {
|
||||
return Err(
|
||||
ErrorKind::TxHashSetErr(format!("output pmmr hash mismatch")).into(),
|
||||
);
|
||||
|
@ -933,10 +926,10 @@ impl<'a> Extension<'a> {
|
|||
Ok(true) => {
|
||||
self.rproof_pmmr
|
||||
.prune(pos)
|
||||
.map_err(|s| ErrorKind::TxHashSetErr(s))?;
|
||||
.map_err(|e| ErrorKind::TxHashSetErr(e))?;
|
||||
}
|
||||
Ok(false) => return Err(ErrorKind::AlreadySpent(commit).into()),
|
||||
Err(s) => return Err(ErrorKind::TxHashSetErr(s).into()),
|
||||
Err(e) => return Err(ErrorKind::TxHashSetErr(e).into()),
|
||||
}
|
||||
} else {
|
||||
return Err(ErrorKind::AlreadySpent(commit).into());
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
use core::core::pmmr::ReadonlyPMMR;
|
||||
use core::core::{Block, Input, Output, Transaction};
|
||||
|
||||
use core::ser::PMMRIndexHashable;
|
||||
use error::{Error, ErrorKind};
|
||||
use grin_store::pmmr::PMMRBackend;
|
||||
use store::Batch;
|
||||
|
@ -64,23 +64,26 @@ impl<'a> UTXOView<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Input is valid if it is spending an (unspent) output
|
||||
// that currently exists in the output MMR.
|
||||
// Compare the hash in the output MMR at the expected pos.
|
||||
fn validate_input(&self, input: &Input) -> Result<(), Error> {
|
||||
let commit = input.commitment();
|
||||
let pos_res = self.batch.get_output_pos(&commit);
|
||||
if let Ok(pos) = pos_res {
|
||||
if let Some(_) = self.pmmr.get_data(pos) {
|
||||
return Ok(());
|
||||
if let Ok(pos) = self.batch.get_output_pos(&input.commitment()) {
|
||||
if let Some(hash) = self.pmmr.get_hash(pos) {
|
||||
if hash == input.hash_with_index(pos - 1) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(ErrorKind::AlreadySpent(commit).into())
|
||||
Err(ErrorKind::AlreadySpent(input.commitment()).into())
|
||||
}
|
||||
|
||||
// Output is valid if it would not result in a duplicate commitment in the output MMR.
|
||||
fn validate_output(&self, output: &Output) -> Result<(), Error> {
|
||||
let commit = output.commitment();
|
||||
if let Ok(pos) = self.batch.get_output_pos(&commit) {
|
||||
if let Ok(pos) = self.batch.get_output_pos(&output.commitment()) {
|
||||
if let Some(out_mmr) = self.pmmr.get_data(pos) {
|
||||
if out_mmr.commitment() == commit {
|
||||
return Err(ErrorKind::DuplicateCommitment(commit).into());
|
||||
if out_mmr.commitment() == output.commitment() {
|
||||
return Err(ErrorKind::DuplicateCommitment(output.commitment()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue