Fix AlreadySpent when UTXO created and spent on fork

When applying a fork, everything is done in memory to be able to
rewind if it's either invalid or doesn't have more work. But
checking for the UTXO index was done only against the store. Now
checking the memory as well to find UTXOs that haven't been
stored yet.
This commit is contained in:
Ignotus Peverell 2017-12-25 00:27:13 +00:00
parent 707a2073a5
commit da4b349d49
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211

View file

@ -248,14 +248,7 @@ impl<'a> Extension<'a> {
// same block, enforcing block cut-through
for input in &b.inputs {
let commit = input.commitment();
let pos_res = self.commit_index.get_output_pos(&commit);
// TODO - Assume this hash specific debug can be cleaned up?
if b.hash().to_string() == "f697a877" {
debug!(LOGGER, "input pos: {:?}, commit: {} {:?}",
pos_res, input.commitment().hash(), commit);
}
let pos_res = self.get_output_pos(&commit);
if let Ok(pos) = pos_res {
match self.output_pmmr.prune(pos, b.header.height as u32) {
Ok(true) => {
@ -273,7 +266,7 @@ impl<'a> Extension<'a> {
for out in &b.outputs {
let commit = out.commitment();
if let Ok(pos) = self.commit_index.get_output_pos(&commit) {
if let Ok(pos) = self.get_output_pos(&commit) {
// we need to check whether the commitment is in the current MMR view
// as well as the index doesn't support rewind and is non-authoritative
// (non-historical node will have a much smaller one)
@ -309,7 +302,7 @@ impl<'a> Extension<'a> {
}
for kernel in &b.kernels {
if let Ok(pos) = self.commit_index.get_kernel_pos(&kernel.excess) {
if let Ok(pos) = self.get_kernel_pos(&kernel.excess) {
// same as outputs
if let Some(k) = self.kernel_pmmr.get(pos) {
let hashsum = HashSum::from_summable(
@ -365,7 +358,7 @@ impl<'a> Extension<'a> {
);
let out_pos_rew = match block.outputs.last() {
Some(output) => self.commit_index.get_output_pos(&output.commitment())
Some(output) => self.get_output_pos(&output.commitment())
.map_err(|e| {
Error::StoreErr(e, format!("missing output pos for known block"))
})?,
@ -373,7 +366,7 @@ impl<'a> Extension<'a> {
};
let kern_pos_rew = match block.kernels.last() {
Some(kernel) => self.commit_index.get_kernel_pos(&kernel.excess)
Some(kernel) => self.get_kernel_pos(&kernel.excess)
.map_err(|e| {
Error::StoreErr(e, format!("missing kernel pos for known block"))
})?,
@ -403,6 +396,22 @@ impl<'a> Extension<'a> {
Ok(())
}
fn get_output_pos(&self, commit: &Commitment) -> Result<u64, grin_store::Error> {
if let Some(pos) = self.new_output_commits.get(commit) {
Ok(*pos)
} else {
self.commit_index.get_output_pos(commit)
}
}
fn get_kernel_pos(&self, excess: &Commitment) -> Result<u64, grin_store::Error> {
if let Some(pos) = self.new_kernel_excesses.get(excess) {
Ok(*pos)
} else {
self.commit_index.get_kernel_pos(excess)
}
}
/// Current root hashes and sums (if applicable) for the UTXO, range proof
/// and kernel sum trees.
pub fn roots(