Wallet now supports coinbase maturity (#130)

This commit is contained in:
AntiochP
2017-09-22 12:44:12 -04:00
committed by Ignotus Peverell
parent 139af79509
commit dbc4e10cec
8 changed files with 182 additions and 69 deletions
+24 -30
View File
@@ -12,23 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// pub struct HashID(pub [u8; 32]);
//
// impl FromStr for HashId {
// type Err = ;
//
// fn from_str(s: &str) -> Result<HashId, > {
// }
// }
use std::sync::{Arc, RwLock};
use std::thread;
use core::core::{Transaction, Output};
use chain;
use core::core::Transaction;
use core::ser;
use chain::{self, Tip};
use pool;
use rest::*;
use types::*;
use secp::pedersen::Commitment;
use util;
@@ -51,7 +44,10 @@ impl ApiEndpoint for ChainApi {
}
fn get(&self, _: String) -> ApiResult<Tip> {
self.chain.head().map_err(|e| Error::Internal(format!("{:?}", e)))
match self.chain.head() {
Ok(tip) => Ok(Tip::from_tip(tip)),
Err(e) => Err(Error::Internal(format!("{:?}", e)))
}
}
}
@@ -75,12 +71,14 @@ impl ApiEndpoint for OutputApi {
fn get(&self, id: String) -> ApiResult<Output> {
debug!("GET output {}", id);
let c = util::from_hex(id.clone()).map_err(|_| Error::Argument(format!("Not a valid commitment: {}", id)))?;
let commit = Commitment::from_vec(c);
// TODO - can probably clean up the error mapping here
match self.chain.get_unspent(&Commitment::from_vec(c)) {
Ok(utxo) => Ok(utxo),
Err(_) => Err(Error::NotFound),
}
let out = self.chain.get_unspent(&commit)
.map_err(|_| Error::NotFound)?;
let header = self.chain.get_block_header_by_output_commit(&commit)
.map_err(|_| Error::NotFound)?;
Ok(Output::from_output(&out, &header))
}
}
@@ -91,13 +89,6 @@ pub struct PoolApi<T> {
tx_pool: Arc<RwLock<pool::TransactionPool<T>>>,
}
#[derive(Serialize, Deserialize)]
pub struct PoolInfo {
pool_size: usize,
orphans_size: usize,
total_size: usize,
}
impl<T> ApiEndpoint for PoolApi<T>
where T: pool::BlockChain + Clone + Send + Sync + 'static
{
@@ -120,20 +111,23 @@ impl<T> ApiEndpoint for PoolApi<T>
}
fn operation(&self, _: String, input: TxWrapper) -> ApiResult<()> {
let tx_bin = util::from_hex(input.tx_hex)
.map_err(|_| Error::Argument(format!("Invalid hex in transaction wrapper.")))?;
let tx_bin = util::from_hex(input.tx_hex).map_err(|_| {
Error::Argument(format!("Invalid hex in transaction wrapper."))
})?;
let tx: Transaction = ser::deserialize(&mut &tx_bin[..]).map_err(|_| {
Error::Argument("Could not deserialize transaction, invalid format.".to_string())
})?;
Error::Argument("Could not deserialize transaction, invalid format.".to_string())
})?;
let source = pool::TxSource {
debug_name: "push-api".to_string(),
identifier: "?.?.?.?".to_string(),
};
debug!("Pushing transaction with {} inputs and {} outputs to pool.",
tx.inputs.len(),
tx.outputs.len());
info!(
"Pushing transaction with {} inputs and {} outputs to pool.",
tx.inputs.len(),
tx.outputs.len()
);
self.tx_pool
.write()
.unwrap()
+2
View File
@@ -32,6 +32,8 @@ extern crate serde_json;
pub mod client;
mod endpoints;
mod rest;
mod types;
pub use endpoints::start_rest_apis;
pub use types::*;
pub use rest::*;
+85
View File
@@ -0,0 +1,85 @@
// Copyright 2016 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use core::{core, consensus};
use chain;
use secp::pedersen;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Tip {
/// Height of the tip (max height of the fork)
pub height: u64,
// Last block pushed to the fork
// pub last_block_h: Hash,
// Block previous to last
// pub prev_block_h: Hash,
// Total difficulty accumulated on that fork
// pub total_difficulty: Difficulty,
}
impl Tip {
pub fn from_tip(tip: chain::Tip) -> Tip {
Tip {
height: tip.height,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub enum OutputType {
Coinbase,
Transaction,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Output {
/// The type of output Coinbase|Transaction
pub output_type: OutputType,
/// The homomorphic commitment representing the output's amount
pub commit: pedersen::Commitment,
/// A proof that the commitment is in the right range
pub proof: pedersen::RangeProof,
/// The height of the block creating this output
pub height: u64,
/// The lock height (spendable after block)
pub lock_height: u64,
}
impl Output {
pub fn from_output(output: &core::Output, block_header: &core::BlockHeader) -> Output {
let (output_type, maturity) = match output.features {
x if x.contains(core::transaction::COINBASE_OUTPUT) => {
(OutputType::Coinbase, consensus::COINBASE_MATURITY)
},
_ => (OutputType::Transaction, 0),
};
Output {
output_type: output_type,
commit: output.commit,
proof: output.proof,
height: block_header.height,
lock_height: block_header.height + maturity,
}
}
}
#[derive(Serialize, Deserialize)]
pub struct PoolInfo {
/// Size of the pool
pub pool_size: usize,
/// Size of orphans
pub orphans_size: usize,
/// Total size of pool + orphans
pub total_size: usize,
}