Cleanup HTTP APIs, update ports to avoid gap, rustfmt
Moved the HTTP APIs away from the REST endpoint abstraction and to simpler Hyper handlers. Re-established all routes as v1. Changed wallet receiver port to 13415 to avoid a gap in port numbers. Finally, rustfmt seems to have ignored specific files arguments, running on everything.
This commit is contained in:
+43
-30
@@ -20,8 +20,8 @@ use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
use util::secp::pedersen::{Commitment, RangeProof};
|
||||
|
||||
use core::core::{SumCommit};
|
||||
use core::core::pmmr::{NoSum, HashSum};
|
||||
use core::core::SumCommit;
|
||||
use core::core::pmmr::{HashSum, NoSum};
|
||||
|
||||
use core::core::{Block, BlockHeader, Output, TxKernel};
|
||||
use core::core::target::Difficulty;
|
||||
@@ -119,8 +119,10 @@ impl Chain {
|
||||
/// has been added to the longest chain, None if it's added to an (as of
|
||||
/// now) orphan chain.
|
||||
pub fn process_block(&self, b: Block, opts: Options) -> Result<Option<Tip>, Error> {
|
||||
let head = self.store.head().map_err(|e| Error::StoreErr(e, "chain load head".to_owned()))?;
|
||||
let height = head.height;
|
||||
let head = self.store
|
||||
.head()
|
||||
.map_err(|e| Error::StoreErr(e, "chain load head".to_owned()))?;
|
||||
let height = head.height;
|
||||
let ctx = self.ctx_from_head(head, opts);
|
||||
|
||||
let res = pipe::process_block(&b, ctx);
|
||||
@@ -143,13 +145,11 @@ impl Chain {
|
||||
self.check_orphans();
|
||||
}
|
||||
Ok(None) => {}
|
||||
Err(Error::Orphan) => {
|
||||
if b.header.height < height + (MAX_ORPHANS as u64) {
|
||||
let mut orphans = self.orphans.lock().unwrap();
|
||||
orphans.push_front((opts, b));
|
||||
orphans.truncate(MAX_ORPHANS);
|
||||
}
|
||||
}
|
||||
Err(Error::Orphan) => if b.header.height < height + (MAX_ORPHANS as u64) {
|
||||
let mut orphans = self.orphans.lock().unwrap();
|
||||
orphans.push_front((opts, b));
|
||||
orphans.truncate(MAX_ORPHANS);
|
||||
},
|
||||
Err(ref e) => {
|
||||
info!(
|
||||
LOGGER,
|
||||
@@ -171,8 +171,9 @@ impl Chain {
|
||||
bh: &BlockHeader,
|
||||
opts: Options,
|
||||
) -> Result<Option<Tip>, Error> {
|
||||
|
||||
let head = self.store.get_header_head().map_err(|e| Error::StoreErr(e, "chain header head".to_owned()))?;
|
||||
let head = self.store
|
||||
.get_header_head()
|
||||
.map_err(|e| Error::StoreErr(e, "chain header head".to_owned()))?;
|
||||
let ctx = self.ctx_from_head(head, opts);
|
||||
|
||||
pipe::process_block_header(bh, ctx)
|
||||
@@ -199,7 +200,7 @@ impl Chain {
|
||||
/// Pop orphans out of the queue and check if we can now accept them.
|
||||
fn check_orphans(&self) {
|
||||
// first check how many we have to retry, unfort. we can't extend the lock
|
||||
// in the loop as it needs to be freed before going in process_block
|
||||
// in the loop as it needs to be freed before going in process_block
|
||||
let orphan_count;
|
||||
{
|
||||
let orphans = self.orphans.lock().unwrap();
|
||||
@@ -227,9 +228,9 @@ impl Chain {
|
||||
let sumtrees = self.sumtrees.read().unwrap();
|
||||
let is_unspent = sumtrees.is_unspent(output_ref)?;
|
||||
if is_unspent {
|
||||
self.store.get_output_by_commit(output_ref).map_err(|e|
|
||||
Error::StoreErr(e, "chain get unspent".to_owned())
|
||||
)
|
||||
self.store
|
||||
.get_output_by_commit(output_ref)
|
||||
.map_err(|e| Error::StoreErr(e, "chain get unspent".to_owned()))
|
||||
} else {
|
||||
Err(Error::OutputNotFound)
|
||||
}
|
||||
@@ -254,9 +255,13 @@ impl Chain {
|
||||
}
|
||||
|
||||
/// returs sumtree roots
|
||||
pub fn get_sumtree_roots(&self) -> (HashSum<SumCommit>,
|
||||
pub fn get_sumtree_roots(
|
||||
&self,
|
||||
) -> (
|
||||
HashSum<SumCommit>,
|
||||
HashSum<NoSum<RangeProof>>,
|
||||
HashSum<NoSum<TxKernel>>) {
|
||||
HashSum<NoSum<TxKernel>>,
|
||||
) {
|
||||
let mut sumtrees = self.sumtrees.write().unwrap();
|
||||
sumtrees.roots()
|
||||
}
|
||||
@@ -264,10 +269,10 @@ impl Chain {
|
||||
/// returns the last n nodes inserted into the utxo sum tree
|
||||
/// returns sum tree hash plus output itself (as the sum is contained
|
||||
/// in the output anyhow)
|
||||
pub fn get_last_n_utxo(&self, distance: u64) -> Vec<(Hash, Output)>{
|
||||
pub fn get_last_n_utxo(&self, distance: u64) -> Vec<(Hash, Output)> {
|
||||
let mut sumtrees = self.sumtrees.write().unwrap();
|
||||
let mut return_vec = Vec::new();
|
||||
let sum_nodes=sumtrees.last_n_utxo(distance);
|
||||
let sum_nodes = sumtrees.last_n_utxo(distance);
|
||||
for sum_commit in sum_nodes {
|
||||
let output = self.store.get_output_by_commit(&sum_commit.sum.commit);
|
||||
return_vec.push((sum_commit.hash, output.unwrap()));
|
||||
@@ -276,13 +281,13 @@ impl Chain {
|
||||
}
|
||||
|
||||
/// as above, for rangeproofs
|
||||
pub fn get_last_n_rangeproof(&self, distance: u64) -> Vec<HashSum<NoSum<RangeProof>>>{
|
||||
pub fn get_last_n_rangeproof(&self, distance: u64) -> Vec<HashSum<NoSum<RangeProof>>> {
|
||||
let mut sumtrees = self.sumtrees.write().unwrap();
|
||||
sumtrees.last_n_rangeproof(distance)
|
||||
}
|
||||
|
||||
/// as above, for kernels
|
||||
pub fn get_last_n_kernel(&self, distance: u64) -> Vec<HashSum<NoSum<TxKernel>>>{
|
||||
pub fn get_last_n_kernel(&self, distance: u64) -> Vec<HashSum<NoSum<TxKernel>>> {
|
||||
let mut sumtrees = self.sumtrees.write().unwrap();
|
||||
sumtrees.last_n_kernel(distance)
|
||||
}
|
||||
@@ -299,24 +304,30 @@ impl Chain {
|
||||
|
||||
/// Block header for the chain head
|
||||
pub fn head_header(&self) -> Result<BlockHeader, Error> {
|
||||
self.store.head_header().map_err(|e| Error::StoreErr(e, "chain head header".to_owned()))
|
||||
self.store
|
||||
.head_header()
|
||||
.map_err(|e| Error::StoreErr(e, "chain head header".to_owned()))
|
||||
}
|
||||
|
||||
/// Gets a block header by hash
|
||||
pub fn get_block(&self, h: &Hash) -> Result<Block, Error> {
|
||||
self.store.get_block(h).map_err(|e| Error::StoreErr(e, "chain get block".to_owned()))
|
||||
self.store
|
||||
.get_block(h)
|
||||
.map_err(|e| Error::StoreErr(e, "chain get block".to_owned()))
|
||||
}
|
||||
|
||||
/// Gets a block header by hash
|
||||
pub fn get_block_header(&self, h: &Hash) -> Result<BlockHeader, Error> {
|
||||
self.store.get_block_header(h).map_err(|e| Error::StoreErr(e, "chain get header".to_owned()))
|
||||
self.store
|
||||
.get_block_header(h)
|
||||
.map_err(|e| Error::StoreErr(e, "chain get header".to_owned()))
|
||||
}
|
||||
|
||||
/// Gets the block header at the provided height
|
||||
pub fn get_header_by_height(&self, height: u64) -> Result<BlockHeader, Error> {
|
||||
self.store.get_header_by_height(height).map_err(|e|
|
||||
Error::StoreErr(e, "chain get header by height".to_owned()),
|
||||
)
|
||||
self.store.get_header_by_height(height).map_err(|e| {
|
||||
Error::StoreErr(e, "chain get header by height".to_owned())
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets the block header by the provided output commitment
|
||||
@@ -331,7 +342,9 @@ impl Chain {
|
||||
|
||||
/// Get the tip of the header chain
|
||||
pub fn get_header_head(&self) -> Result<Tip, Error> {
|
||||
self.store.get_header_head().map_err(|e |Error::StoreErr(e, "chain get header head".to_owned()))
|
||||
self.store
|
||||
.get_header_head()
|
||||
.map_err(|e| Error::StoreErr(e, "chain get header head".to_owned()))
|
||||
}
|
||||
|
||||
/// Builds an iterator on blocks starting from the current chain head and
|
||||
|
||||
+4
-4
@@ -23,16 +23,16 @@
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
extern crate byteorder;
|
||||
#[macro_use]
|
||||
extern crate slog;
|
||||
extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate slog;
|
||||
extern crate time;
|
||||
|
||||
extern crate grin_core as core;
|
||||
extern crate grin_util as util;
|
||||
extern crate grin_store;
|
||||
extern crate grin_util as util;
|
||||
|
||||
mod chain;
|
||||
pub mod pipe;
|
||||
@@ -43,4 +43,4 @@ pub mod types;
|
||||
// Re-export the base interface
|
||||
|
||||
pub use chain::Chain;
|
||||
pub use types::{ChainStore, Tip, ChainAdapter, SYNC, NONE, SKIP_POW, EASY_POW, Options, Error};
|
||||
pub use types::{ChainAdapter, ChainStore, Error, Options, Tip, EASY_POW, NONE, SKIP_POW, SYNC};
|
||||
|
||||
+56
-51
@@ -21,7 +21,7 @@ use time;
|
||||
|
||||
use core::consensus;
|
||||
use core::core::hash::{Hash, Hashed};
|
||||
use core::core::{BlockHeader, Block};
|
||||
use core::core::{Block, BlockHeader};
|
||||
use core::core::transaction;
|
||||
use types::*;
|
||||
use store;
|
||||
@@ -49,7 +49,7 @@ pub struct BlockContext {
|
||||
/// chain head if updated.
|
||||
pub fn process_block(b: &Block, mut ctx: BlockContext) -> Result<Option<Tip>, Error> {
|
||||
// TODO should just take a promise for a block with a full header so we don't
|
||||
// spend resources reading the full block when its header is invalid
|
||||
// spend resources reading the full block when its header is invalid
|
||||
|
||||
info!(
|
||||
LOGGER,
|
||||
@@ -68,13 +68,13 @@ pub fn process_block(b: &Block, mut ctx: BlockContext) -> Result<Option<Tip>, Er
|
||||
let mut sumtrees = local_sumtrees.write().unwrap();
|
||||
|
||||
// update head now that we're in the lock
|
||||
ctx.head = ctx.store.head().
|
||||
map_err(|e| Error::StoreErr(e, "pipe reload head".to_owned()))?;
|
||||
ctx.head = ctx.store
|
||||
.head()
|
||||
.map_err(|e| Error::StoreErr(e, "pipe reload head".to_owned()))?;
|
||||
|
||||
// start a chain extension unit of work dependent on the success of the
|
||||
// internal validation and saving operations
|
||||
// internal validation and saving operations
|
||||
sumtree::extending(&mut sumtrees, |mut extension| {
|
||||
|
||||
validate_block(b, &mut ctx, &mut extension)?;
|
||||
debug!(
|
||||
LOGGER,
|
||||
@@ -94,7 +94,6 @@ pub fn process_block(b: &Block, mut ctx: BlockContext) -> Result<Option<Tip>, Er
|
||||
|
||||
/// Process the block header
|
||||
pub fn process_block_header(bh: &BlockHeader, mut ctx: BlockContext) -> Result<Option<Tip>, Error> {
|
||||
|
||||
info!(
|
||||
LOGGER,
|
||||
"Starting validation pipeline for block header {} at {}.",
|
||||
@@ -120,7 +119,7 @@ fn check_known(bh: Hash, ctx: &mut BlockContext) -> Result<(), Error> {
|
||||
}
|
||||
if let Ok(b) = ctx.store.get_block(&bh) {
|
||||
// there is a window where a block can be saved but the chain head not
|
||||
// updated yet, we plug that window here by re-accepting the block
|
||||
// updated yet, we plug that window here by re-accepting the block
|
||||
if b.header.total_difficulty <= ctx.head.total_difficulty {
|
||||
return Err(Error::Unfit("already in store".to_string()));
|
||||
}
|
||||
@@ -147,11 +146,11 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
|
||||
return Err(Error::InvalidBlockVersion(header.version));
|
||||
}
|
||||
|
||||
if header.timestamp >
|
||||
time::now_utc() + time::Duration::seconds(12 * (consensus::BLOCK_TIME_SEC as i64))
|
||||
if header.timestamp
|
||||
> time::now_utc() + time::Duration::seconds(12 * (consensus::BLOCK_TIME_SEC as i64))
|
||||
{
|
||||
// refuse blocks more than 12 blocks intervals in future (as in bitcoin)
|
||||
// TODO add warning in p2p code if local time is too different from peers
|
||||
// TODO add warning in p2p code if local time is too different from peers
|
||||
return Err(Error::InvalidBlockTime);
|
||||
}
|
||||
|
||||
@@ -168,16 +167,16 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
|
||||
}
|
||||
|
||||
// first I/O cost, better as late as possible
|
||||
let prev = try!(ctx.store.get_block_header(&header.previous).map_err(|e|
|
||||
Error::StoreErr(e, format!("previous block header {}", header.previous)),
|
||||
));
|
||||
let prev = try!(ctx.store.get_block_header(&header.previous,).map_err(|e| {
|
||||
Error::StoreErr(e, format!("previous block header {}", header.previous))
|
||||
},));
|
||||
|
||||
if header.height != prev.height + 1 {
|
||||
return Err(Error::InvalidBlockHeight);
|
||||
}
|
||||
if header.timestamp <= prev.timestamp && !global::is_automated_testing_mode() {
|
||||
// prevent time warp attacks and some timestamp manipulations by forcing strict
|
||||
// time progression (but not in CI mode)
|
||||
// time progression (but not in CI mode)
|
||||
return Err(Error::InvalidBlockTime);
|
||||
}
|
||||
|
||||
@@ -189,9 +188,8 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
|
||||
}
|
||||
|
||||
let diff_iter = store::DifficultyIter::from(header.previous, ctx.store.clone());
|
||||
let difficulty = consensus::next_difficulty(diff_iter).map_err(|e| {
|
||||
Error::Other(e.to_string())
|
||||
})?;
|
||||
let difficulty =
|
||||
consensus::next_difficulty(diff_iter).map_err(|e| Error::Other(e.to_string()))?;
|
||||
if header.difficulty < difficulty {
|
||||
return Err(Error::DifficultyTooLow);
|
||||
}
|
||||
@@ -219,9 +217,8 @@ fn validate_block(
|
||||
// standard head extension
|
||||
ext.apply_block(b)?;
|
||||
} else {
|
||||
|
||||
// extending a fork, first identify the block where forking occurred
|
||||
// keeping the hashes of blocks along the fork
|
||||
// keeping the hashes of blocks along the fork
|
||||
let mut current = b.header.previous;
|
||||
let mut hashes = vec![];
|
||||
loop {
|
||||
@@ -236,16 +233,12 @@ fn validate_block(
|
||||
}
|
||||
|
||||
// rewind the sum trees up the forking block, providing the height of the
|
||||
// forked block and the last commitment we want to rewind to
|
||||
// forked block and the last commitment we want to rewind to
|
||||
let forked_block = ctx.store.get_block(¤t)?;
|
||||
if forked_block.header.height > 0 {
|
||||
let last_output = &forked_block.outputs[forked_block.outputs.len() - 1];
|
||||
let last_kernel = &forked_block.kernels[forked_block.kernels.len() - 1];
|
||||
ext.rewind(
|
||||
forked_block.header.height,
|
||||
last_output,
|
||||
last_kernel,
|
||||
)?;
|
||||
ext.rewind(forked_block.header.height, last_output, last_kernel)?;
|
||||
}
|
||||
|
||||
// apply all forked blocks, including this new one
|
||||
@@ -257,10 +250,9 @@ fn validate_block(
|
||||
}
|
||||
|
||||
let (utxo_root, rproof_root, kernel_root) = ext.roots();
|
||||
if utxo_root.hash != b.header.utxo_root || rproof_root.hash != b.header.range_proof_root ||
|
||||
kernel_root.hash != b.header.kernel_root
|
||||
if utxo_root.hash != b.header.utxo_root || rproof_root.hash != b.header.range_proof_root
|
||||
|| kernel_root.hash != b.header.kernel_root
|
||||
{
|
||||
|
||||
ext.dump(false);
|
||||
return Err(Error::InvalidRoot);
|
||||
}
|
||||
@@ -269,14 +261,11 @@ fn validate_block(
|
||||
for input in &b.inputs {
|
||||
if let Ok(output) = ctx.store.get_output_by_commit(&input.commitment()) {
|
||||
if output.features.contains(transaction::COINBASE_OUTPUT) {
|
||||
if let Ok(output_header) =
|
||||
ctx.store.get_block_header_by_output_commit(
|
||||
&input.commitment(),
|
||||
)
|
||||
if let Ok(output_header) = ctx.store
|
||||
.get_block_header_by_output_commit(&input.commitment())
|
||||
{
|
||||
|
||||
// TODO - make sure we are not off-by-1 here vs. the equivalent tansaction
|
||||
// validation rule
|
||||
// validation rule
|
||||
if b.header.height <= output_header.height + global::coinbase_maturity() {
|
||||
return Err(Error::ImmatureCoinbase);
|
||||
}
|
||||
@@ -290,12 +279,16 @@ fn validate_block(
|
||||
|
||||
/// Officially adds the block to our chain.
|
||||
fn add_block(b: &Block, ctx: &mut BlockContext) -> Result<(), Error> {
|
||||
ctx.store.save_block(b).map_err(|e| Error::StoreErr(e, "pipe save block".to_owned()))
|
||||
ctx.store
|
||||
.save_block(b)
|
||||
.map_err(|e| Error::StoreErr(e, "pipe save block".to_owned()))
|
||||
}
|
||||
|
||||
/// Officially adds the block header to our header chain.
|
||||
fn add_block_header(bh: &BlockHeader, ctx: &mut BlockContext) -> Result<(), Error> {
|
||||
ctx.store.save_block_header(bh).map_err(|e| Error::StoreErr(e, "pipe save header".to_owned()))
|
||||
ctx.store
|
||||
.save_block_header(bh)
|
||||
.map_err(|e| Error::StoreErr(e, "pipe save header".to_owned()))
|
||||
}
|
||||
|
||||
/// Directly updates the head if we've just appended a new block to it or handle
|
||||
@@ -303,23 +296,33 @@ fn add_block_header(bh: &BlockHeader, ctx: &mut BlockContext) -> Result<(), Erro
|
||||
/// work than the head.
|
||||
fn update_head(b: &Block, ctx: &mut BlockContext) -> Result<Option<Tip>, Error> {
|
||||
// if we made a fork with more work than the head (which should also be true
|
||||
// when extending the head), update it
|
||||
// when extending the head), update it
|
||||
let tip = Tip::from_block(&b.header);
|
||||
if tip.total_difficulty > ctx.head.total_difficulty {
|
||||
|
||||
// update the block height index
|
||||
ctx.store.setup_height(&b.header).map_err(|e| Error::StoreErr(e, "pipe setup height".to_owned()))?;
|
||||
ctx.store
|
||||
.setup_height(&b.header)
|
||||
.map_err(|e| Error::StoreErr(e, "pipe setup height".to_owned()))?;
|
||||
|
||||
// in sync mode, only update the "body chain", otherwise update both the
|
||||
// "header chain" and "body chain", updating the header chain in sync resets
|
||||
// all additional "future" headers we've received
|
||||
if ctx.opts.intersects(SYNC) {
|
||||
ctx.store.save_body_head(&tip).map_err(|e| Error::StoreErr(e, "pipe save body".to_owned()))?;
|
||||
} else {
|
||||
ctx.store.save_head(&tip).map_err(|e| Error::StoreErr(e, "pipe save head".to_owned()))?;
|
||||
}
|
||||
// in sync mode, only update the "body chain", otherwise update both the
|
||||
// "header chain" and "body chain", updating the header chain in sync resets
|
||||
// all additional "future" headers we've received
|
||||
if ctx.opts.intersects(SYNC) {
|
||||
ctx.store
|
||||
.save_body_head(&tip)
|
||||
.map_err(|e| Error::StoreErr(e, "pipe save body".to_owned()))?;
|
||||
} else {
|
||||
ctx.store
|
||||
.save_head(&tip)
|
||||
.map_err(|e| Error::StoreErr(e, "pipe save head".to_owned()))?;
|
||||
}
|
||||
ctx.head = tip.clone();
|
||||
info!(LOGGER, "Updated head to {} at {}.", b.hash(), b.header.height);
|
||||
info!(
|
||||
LOGGER,
|
||||
"Updated head to {} at {}.",
|
||||
b.hash(),
|
||||
b.header.height
|
||||
);
|
||||
Ok(Some(tip))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -331,10 +334,12 @@ fn update_head(b: &Block, ctx: &mut BlockContext) -> Result<Option<Tip>, Error>
|
||||
/// work than the head.
|
||||
fn update_header_head(bh: &BlockHeader, ctx: &mut BlockContext) -> Result<Option<Tip>, Error> {
|
||||
// if we made a fork with more work than the head (which should also be true
|
||||
// when extending the head), update it
|
||||
// when extending the head), update it
|
||||
let tip = Tip::from_block(bh);
|
||||
if tip.total_difficulty > ctx.head.total_difficulty {
|
||||
ctx.store.save_header_head(&tip).map_err(|e| Error::StoreErr(e, "pipe save header head".to_owned()))?;
|
||||
ctx.store
|
||||
.save_header_head(&tip)
|
||||
.map_err(|e| Error::StoreErr(e, "pipe save header head".to_owned()))?;
|
||||
|
||||
ctx.head = tip.clone();
|
||||
info!(
|
||||
|
||||
+33
-36
@@ -23,7 +23,7 @@ use core::core::hash::{Hash, Hashed};
|
||||
use core::core::{Block, BlockHeader, Output};
|
||||
use core::consensus::TargetError;
|
||||
use core::core::target::Difficulty;
|
||||
use grin_store::{self, Error, to_key, u64_to_key, option_to_not_found};
|
||||
use grin_store::{self, option_to_not_found, to_key, Error, u64_to_key};
|
||||
|
||||
const STORE_SUBPATH: &'static str = "chain";
|
||||
|
||||
@@ -85,9 +85,10 @@ impl ChainStore for ChainKVStore {
|
||||
}
|
||||
|
||||
fn get_block_header(&self, h: &Hash) -> Result<BlockHeader, Error> {
|
||||
option_to_not_found(self.db.get_ser(
|
||||
&to_key(BLOCK_HEADER_PREFIX, &mut h.to_vec()),
|
||||
))
|
||||
option_to_not_found(
|
||||
self.db
|
||||
.get_ser(&to_key(BLOCK_HEADER_PREFIX, &mut h.to_vec())),
|
||||
)
|
||||
}
|
||||
|
||||
fn check_block_exists(&self, h: &Hash) -> Result<bool, Error> {
|
||||
@@ -111,16 +112,14 @@ impl ChainStore for ChainKVStore {
|
||||
&to_key(
|
||||
OUTPUT_COMMIT_PREFIX,
|
||||
&mut out.commitment().as_ref().to_vec(),
|
||||
)
|
||||
[..],
|
||||
)[..],
|
||||
out,
|
||||
)?
|
||||
.put_ser(
|
||||
&to_key(
|
||||
HEADER_BY_OUTPUT_PREFIX,
|
||||
&mut out.commitment().as_ref().to_vec(),
|
||||
)
|
||||
[..],
|
||||
)[..],
|
||||
&b.hash(),
|
||||
)?;
|
||||
}
|
||||
@@ -128,18 +127,18 @@ impl ChainStore for ChainKVStore {
|
||||
}
|
||||
|
||||
// lookup the block header hash by output commitment
|
||||
// lookup the block header based on this hash
|
||||
// to check the chain is correct compare this block header to
|
||||
// the block header currently indexed at the relevant block height (tbd if
|
||||
// actually necessary)
|
||||
//
|
||||
// NOTE: This index is not exhaustive.
|
||||
// This node may not have seen this full block, so may not have populated the
|
||||
// index.
|
||||
// Block headers older than some threshold (2 months?) will not necessarily be
|
||||
// included
|
||||
// in this index.
|
||||
//
|
||||
// lookup the block header based on this hash
|
||||
// to check the chain is correct compare this block header to
|
||||
// the block header currently indexed at the relevant block height (tbd if
|
||||
// actually necessary)
|
||||
//
|
||||
// NOTE: This index is not exhaustive.
|
||||
// This node may not have seen this full block, so may not have populated the
|
||||
// index.
|
||||
// Block headers older than some threshold (2 months?) will not necessarily be
|
||||
// included
|
||||
// in this index.
|
||||
//
|
||||
fn get_block_header_by_output_commit(&self, commit: &Commitment) -> Result<BlockHeader, Error> {
|
||||
let block_hash = self.db.get_ser(&to_key(
|
||||
HEADER_BY_OUTPUT_PREFIX,
|
||||
@@ -172,10 +171,10 @@ impl ChainStore for ChainKVStore {
|
||||
}
|
||||
|
||||
fn get_output_by_commit(&self, commit: &Commitment) -> Result<Output, Error> {
|
||||
option_to_not_found(self.db.get_ser(&to_key(
|
||||
OUTPUT_COMMIT_PREFIX,
|
||||
&mut commit.as_ref().to_vec(),
|
||||
)))
|
||||
option_to_not_found(
|
||||
self.db
|
||||
.get_ser(&to_key(OUTPUT_COMMIT_PREFIX, &mut commit.as_ref().to_vec())),
|
||||
)
|
||||
}
|
||||
|
||||
fn save_output_pos(&self, commit: &Commitment, pos: u64) -> Result<(), Error> {
|
||||
@@ -186,10 +185,10 @@ impl ChainStore for ChainKVStore {
|
||||
}
|
||||
|
||||
fn get_output_pos(&self, commit: &Commitment) -> Result<u64, Error> {
|
||||
option_to_not_found(self.db.get_ser(&to_key(
|
||||
COMMIT_POS_PREFIX,
|
||||
&mut commit.as_ref().to_vec(),
|
||||
)))
|
||||
option_to_not_found(
|
||||
self.db
|
||||
.get_ser(&to_key(COMMIT_POS_PREFIX, &mut commit.as_ref().to_vec())),
|
||||
)
|
||||
}
|
||||
|
||||
fn save_kernel_pos(&self, excess: &Commitment, pos: u64) -> Result<(), Error> {
|
||||
@@ -200,10 +199,10 @@ impl ChainStore for ChainKVStore {
|
||||
}
|
||||
|
||||
fn get_kernel_pos(&self, excess: &Commitment) -> Result<u64, Error> {
|
||||
option_to_not_found(self.db.get_ser(&to_key(
|
||||
KERNEL_POS_PREFIX,
|
||||
&mut excess.as_ref().to_vec(),
|
||||
)))
|
||||
option_to_not_found(
|
||||
self.db
|
||||
.get_ser(&to_key(KERNEL_POS_PREFIX, &mut excess.as_ref().to_vec())),
|
||||
)
|
||||
}
|
||||
|
||||
/// Maintain consistency of the "header_by_height" index by traversing back
|
||||
@@ -213,10 +212,8 @@ impl ChainStore for ChainKVStore {
|
||||
/// that is consistent with its height (everything prior to this will be
|
||||
/// consistent)
|
||||
fn setup_height(&self, bh: &BlockHeader) -> Result<(), Error> {
|
||||
self.db.put_ser(
|
||||
&u64_to_key(HEADER_HEIGHT_PREFIX, bh.height),
|
||||
bh,
|
||||
)?;
|
||||
self.db
|
||||
.put_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, bh.height), bh)?;
|
||||
if bh.height == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
+12
-5
@@ -24,7 +24,7 @@ use util::secp;
|
||||
use util::secp::pedersen::{RangeProof, Commitment};
|
||||
|
||||
use core::core::{Block, Output, SumCommit, TxKernel};
|
||||
use core::core::pmmr::{Summable, NoSum, PMMR, HashSum, Backend};
|
||||
use core::core::pmmr::{Backend, HashSum, NoSum, Summable, PMMR};
|
||||
use grin_store;
|
||||
use grin_store::sumtree::PMMRBackend;
|
||||
use types::ChainStore;
|
||||
@@ -121,7 +121,11 @@ impl SumTrees {
|
||||
/// Get sum tree roots
|
||||
pub fn roots(
|
||||
&mut self,
|
||||
) -> (HashSum<SumCommit>, HashSum<NoSum<RangeProof>>, HashSum<NoSum<TxKernel>>) {
|
||||
) -> (
|
||||
HashSum<SumCommit>,
|
||||
HashSum<NoSum<RangeProof>>,
|
||||
HashSum<NoSum<TxKernel>>,
|
||||
) {
|
||||
let output_pmmr = PMMR::at(&mut self.output_pmmr_h.backend, self.output_pmmr_h.last_pos);
|
||||
let rproof_pmmr = PMMR::at(&mut self.rproof_pmmr_h.backend, self.rproof_pmmr_h.last_pos);
|
||||
let kernel_pmmr = PMMR::at(&mut self.kernel_pmmr_h.backend, self.kernel_pmmr_h.last_pos);
|
||||
@@ -140,7 +144,6 @@ pub fn extending<'a, F, T>(trees: &'a mut SumTrees, inner: F) -> Result<T, Error
|
||||
where
|
||||
F: FnOnce(&mut Extension) -> Result<T, Error>,
|
||||
{
|
||||
|
||||
let sizes: (u64, u64, u64);
|
||||
let res: Result<T, Error>;
|
||||
let rollback: bool;
|
||||
@@ -229,7 +232,7 @@ impl<'a> Extension<'a> {
|
||||
let secp = secp::Secp256k1::with_caps(secp::ContextFlag::Commit);
|
||||
|
||||
// doing inputs first guarantees an input can't spend an output in the
|
||||
// same block, enforcing block cut-through
|
||||
// same block, enforcing block cut-through
|
||||
for input in &b.inputs {
|
||||
let pos_res = self.commit_index.get_output_pos(&input.commitment());
|
||||
if let Ok(pos) = pos_res {
|
||||
@@ -319,7 +322,11 @@ impl<'a> Extension<'a> {
|
||||
/// and kernel sum trees.
|
||||
pub fn roots(
|
||||
&self,
|
||||
) -> (HashSum<SumCommit>, HashSum<NoSum<RangeProof>>, HashSum<NoSum<TxKernel>>) {
|
||||
) -> (
|
||||
HashSum<SumCommit>,
|
||||
HashSum<NoSum<RangeProof>>,
|
||||
HashSum<NoSum<TxKernel>>,
|
||||
) {
|
||||
(
|
||||
self.output_pmmr.root(),
|
||||
self.rproof_pmmr.root(),
|
||||
|
||||
+5
-4
@@ -19,7 +19,7 @@ use std::io;
|
||||
use util::secp::pedersen::Commitment;
|
||||
|
||||
use grin_store as store;
|
||||
use core::core::{Block, BlockHeader, block, Output};
|
||||
use core::core::{block, Block, BlockHeader, Output};
|
||||
use core::core::hash::{Hash, Hashed};
|
||||
use core::core::target::Difficulty;
|
||||
use core::ser;
|
||||
@@ -209,9 +209,10 @@ pub trait ChainStore: Send + Sync {
|
||||
fn get_output_by_commit(&self, commit: &Commitment) -> Result<Output, store::Error>;
|
||||
|
||||
/// Gets a block_header for the given input commit
|
||||
fn get_block_header_by_output_commit(&self,
|
||||
commit: &Commitment)
|
||||
-> Result<BlockHeader, store::Error>;
|
||||
fn get_block_header_by_output_commit(
|
||||
&self,
|
||||
commit: &Commitment,
|
||||
) -> Result<BlockHeader, store::Error>;
|
||||
|
||||
/// Saves the position of an output, represented by its commitment, in the
|
||||
/// UTXO MMR. Used as an index for spending and pruning.
|
||||
|
||||
Reference in New Issue
Block a user