mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
Save outputs under their own keys
Save outputs in every new block under their own hash. Done in the same batch as the block. Allows for direct output lookups by hash required by the p2p layer. Also store an index of output commitment to output hash for wallet and input lookups.
This commit is contained in:
parent
ca496ee101
commit
4e36c63cbb
2 changed files with 34 additions and 5 deletions
|
@ -14,9 +14,11 @@
|
|||
|
||||
//! Implements storage primitives required by the chain
|
||||
|
||||
use secp::pedersen::Commitment;
|
||||
|
||||
use types::*;
|
||||
use core::core::hash::{Hash, Hashed};
|
||||
use core::core::{Block, BlockHeader};
|
||||
use core::core::{Block, BlockHeader, Output};
|
||||
use grin_store::{self, Error, to_key, u64_to_key, option_to_not_found};
|
||||
|
||||
const STORE_SUBPATH: &'static str = "chain";
|
||||
|
@ -26,6 +28,8 @@ const BLOCK_PREFIX: u8 = 'b' as u8;
|
|||
const HEAD_PREFIX: u8 = 'H' as u8;
|
||||
const HEADER_HEAD_PREFIX: u8 = 'I' as u8;
|
||||
const HEADER_HEIGHT_PREFIX: u8 = '8' as u8;
|
||||
const OUTPUT_PREFIX: u8 = 'O' as u8;
|
||||
const OUTPUT_COMMIT_PREFIX: u8 = 'o' as u8;
|
||||
|
||||
/// An implementation of the ChainStore trait backed by a simple key-value
|
||||
/// store.
|
||||
|
@ -75,12 +79,20 @@ impl ChainStore for ChainKVStore {
|
|||
}
|
||||
|
||||
fn save_block(&self, b: &Block) -> Result<(), Error> {
|
||||
self.db
|
||||
// saving the block and its header
|
||||
let mut batch = self.db
|
||||
.batch()
|
||||
.put_ser(&to_key(BLOCK_PREFIX, &mut b.hash().to_vec())[..], b)?
|
||||
.put_ser(&to_key(BLOCK_HEADER_PREFIX, &mut b.hash().to_vec())[..],
|
||||
&b.header)?
|
||||
.write()
|
||||
&b.header)?;
|
||||
|
||||
// saving the full output under its hash, as well as a commitment to hash index
|
||||
for out in &b.outputs {
|
||||
batch = batch.put_ser(&to_key(OUTPUT_PREFIX, &mut out.hash().to_vec())[..], out)?
|
||||
.put_ser(&to_key(OUTPUT_COMMIT_PREFIX, &mut out.commit.as_ref().to_vec())[..],
|
||||
&out.hash())?;
|
||||
}
|
||||
batch.write()
|
||||
}
|
||||
|
||||
fn save_block_header(&self, bh: &BlockHeader) -> Result<(), Error> {
|
||||
|
@ -92,6 +104,15 @@ impl ChainStore for ChainKVStore {
|
|||
option_to_not_found(self.db.get_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, height)))
|
||||
}
|
||||
|
||||
fn get_output(&self, h: &Hash) -> Result<Output, Error> {
|
||||
option_to_not_found(self.db.get_ser(&to_key(OUTPUT_PREFIX, &mut h.to_vec())))
|
||||
}
|
||||
|
||||
fn has_output_commit(&self, commit: &Commitment) -> Result<Hash, Error> {
|
||||
option_to_not_found(self.db
|
||||
.get_ser(&to_key(OUTPUT_COMMIT_PREFIX, &mut commit.as_ref().to_vec())))
|
||||
}
|
||||
|
||||
fn setup_height(&self, bh: &BlockHeader) -> Result<(), Error> {
|
||||
self.db.put_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, bh.height), bh)?;
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
|
||||
//! Base types that the block chain pipeline requires.
|
||||
|
||||
use secp::pedersen::Commitment;
|
||||
|
||||
use grin_store::Error;
|
||||
use core::core::{Block, BlockHeader};
|
||||
use core::core::{Block, BlockHeader, Output};
|
||||
use core::core::hash::{Hash, Hashed};
|
||||
use core::core::target::Difficulty;
|
||||
use core::ser;
|
||||
|
@ -116,6 +118,12 @@ pub trait ChainStore: Send + Sync {
|
|||
/// Gets the block header at the provided height
|
||||
fn get_header_by_height(&self, height: u64) -> Result<BlockHeader, Error>;
|
||||
|
||||
/// Gets an output by its hash
|
||||
fn get_output(&self, h: &Hash) -> Result<Output, Error>;
|
||||
|
||||
/// Checks whether an output commitment exists and returns the output hash
|
||||
fn has_output_commit(&self, commit: &Commitment) -> Result<Hash, Error>;
|
||||
|
||||
/// Saves the provided block header at the corresponding height. Also check
|
||||
/// the consistency of the height chain in store by assuring previous
|
||||
/// headers
|
||||
|
|
Loading…
Reference in a new issue