Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] coinbase outputs with lock_height in switch commitments #215

Closed
wants to merge 38 commits into from
Closed
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9a193fd
experiment with lock_heights on outputs
antiochp Oct 27, 2017
1e21029
playing around with lock_height as part of the switch commitment hash
antiochp Oct 30, 2017
1bb9ed7
cleanup
antiochp Nov 2, 2017
d13b39b
include features in the switch commit hash key
antiochp Nov 2, 2017
ba22ed5
commit
antiochp Nov 3, 2017
1267fd5
rebase off master
antiochp Nov 13, 2017
13acb42
commit
antiochp Nov 13, 2017
8de1189
cleanup
antiochp Nov 13, 2017
27ca435
missing docs
antiochp Nov 13, 2017
70a99f4
rework coinbase maturity test to build valid tx
antiochp Nov 13, 2017
3bab309
pool and chain tests passing (inputs have switch commitments)
antiochp Nov 13, 2017
60f8c0b
commit
antiochp Nov 13, 2017
f8e5d35
cleanup
antiochp Nov 13, 2017
1c46b86
check inputs spending coinbase outputs have valid lock_heights
antiochp Nov 13, 2017
ab41029
wip - got it building (tests still failing)
antiochp Jan 3, 2018
6abdc25
use zero key for non coinbase switch commit hash
antiochp Jan 3, 2018
6861862
fees and height wrong order...
antiochp Jan 3, 2018
2db64ff
send output lock_height over to wallet via api
antiochp Jan 3, 2018
22a04d5
no more header by height index
antiochp Jan 3, 2018
47e4719
refresh heights for unspent wallet outputs where missing
antiochp Jan 4, 2018
4d3b48c
TODO - might be slow?
antiochp Jan 4, 2018
ced54ec
simplify - do not pass around lock_height for non coinbase outputs
antiochp Jan 4, 2018
1d2cb4e
commit
antiochp Jan 4, 2018
ca22c40
Merge branch 'master' into lockheight_outputs
antiochp Jan 7, 2018
94f70f5
fix tests after merge
antiochp Jan 7, 2018
057d581
build input vs coinbase_input
antiochp Jan 7, 2018
5c5fe39
is_unspent and get_unspent cleanup - we have no outputs, only switch_…
antiochp Jan 7, 2018
6598d45
separate concept of utxo vs output in the api
antiochp Jan 7, 2018
7b3b5d6
cleanup
antiochp Jan 7, 2018
90ad055
better api support for block outputs with range proofs
antiochp Jan 8, 2018
1a8dfde
basic wallet operations appear to work
antiochp Jan 8, 2018
eb62f2f
wallet refresh and wallet restore appear to be working now
antiochp Jan 8, 2018
f49a0ec
Merge branch 'master' into lockheight_outputs
antiochp Jan 8, 2018
8c531b2
fix core tests
antiochp Jan 8, 2018
fea627d
fix some mine_simple_chain tests
antiochp Jan 9, 2018
3b5387e
fixup chain tests
antiochp Jan 9, 2018
289ed54
rework so pool tests pass
antiochp Jan 9, 2018
a988f95
wallet restore now safely habndles duplicate commitments (reused wall…
antiochp Jan 9, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 61 additions & 40 deletions api/src/handlers.rs
Original file line number Diff line number Diff line change
@@ -54,38 +54,26 @@ impl Handler for IndexHandler {
// Supports retrieval of multiple outputs in a single request -
// GET /v1/chain/utxos/byids?id=xxx,yyy,zzz
// GET /v1/chain/utxos/byids?id=xxx&id=yyy&id=zzz
// GET /v1/chain/utxos/byheight?height=n
// GET /v1/chain/utxos/byheight?start_height=101&end_height=200
struct UtxoHandler {
chain: Arc<chain::Chain>,
}

impl UtxoHandler {
fn get_utxo(&self, id: &str, include_rp: bool, include_switch: bool) -> Result<Output, Error> {
debug!(LOGGER, "getting utxo: {}", id);
fn get_utxo(&self, id: &str) -> Result<Utxo, Error> {
let c = util::from_hex(String::from(id))
.map_err(|_| Error::Argument(format!("Not a valid commitment: {}", id)))?;
let commit = Commitment::from_vec(c);

let out = self.chain
let switch_commit_hash = 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,
include_rp,
include_switch,
))
Ok(Utxo::new(&commit, &switch_commit_hash))
}

fn utxos_by_ids(&self, req: &mut Request) -> Vec<Output> {
fn utxos_by_ids(&self, req: &mut Request) -> Vec<Utxo> {
let mut commitments: Vec<&str> = vec![];
let mut rp = false;
let mut switch = false;
if let Ok(params) = req.get_ref::<UrlEncodedQuery>() {
if let Some(ids) = params.get("id") {
for id in ids {
@@ -94,23 +82,25 @@ impl UtxoHandler {
}
}
}
if let Some(_) = params.get("include_rp") {
rp = true;
}
if let Some(_) = params.get("include_switch") {
switch = true;
}
}
let mut utxos: Vec<Output> = vec![];
for commit in commitments {
if let Ok(out) = self.get_utxo(commit, rp, switch) {
utxos.push(out);

debug!(LOGGER, "utxos_by_ids: {:?}", commitments);

let mut utxos: Vec<Utxo> = vec![];
for x in commitments {
if let Ok(utxo) = self.get_utxo(x) {
utxos.push(utxo);
}
}
utxos
}

fn utxos_at_height(&self, block_height: u64) -> BlockOutputs {
fn outputs_at_height(
&self,
block_height: u64,
commitments: Vec<Commitment>,
include_proof: bool,
) -> BlockOutputs {
let header = self.chain
.clone()
.get_header_by_height(block_height)
@@ -119,20 +109,37 @@ impl UtxoHandler {
let outputs = block
.outputs
.iter()
.filter(|c| self.chain.is_unspent(&c.commit).unwrap())
.map(|k| OutputSwitch::from_output(k, &header))
.filter(|c| {
(commitments.is_empty() || commitments.contains(&c.commit)) &&
self.chain.get_unspent(&c.commit).is_ok()
})
.map(|k| {
OutputPrintable::from_output(k, self.chain.clone(), include_proof)
})
.collect();
BlockOutputs {
header: BlockHeaderInfo::from_header(&header),
outputs: outputs,
}
}

// returns utxos for a specified range of blocks
fn utxo_block_batch(&self, req: &mut Request) -> Vec<BlockOutputs> {
// returns outputs for a specified range of blocks
fn outputs_block_batch(&self, req: &mut Request) -> Vec<BlockOutputs> {
let mut commitments: Vec<Commitment> = vec![];
let mut start_height = 1;
let mut end_height = 1;
let mut include_rp = false;

if let Ok(params) = req.get_ref::<UrlEncodedQuery>() {
if let Some(ids) = params.get("id") {
for id in ids {
for id in id.split(",") {
if let Ok(x) = util::from_hex(String::from(id)) {
commitments.push(Commitment::from_vec(x));
}
}
}
}
if let Some(heights) = params.get("start_height") {
for height in heights {
start_height = height.parse().unwrap();
@@ -143,11 +150,28 @@ impl UtxoHandler {
end_height = height.parse().unwrap();
}
}
if let Some(_) = params.get("include_rp") {
include_rp = true;
}
}

debug!(
LOGGER,
"outputs_block_batch: {}-{}, {:?}, {:?}",
start_height,
end_height,
commitments,
include_rp,
);

let mut return_vec = vec![];
for i in start_height..end_height + 1 {
return_vec.push(self.utxos_at_height(i));
let res = self.outputs_at_height(i, commitments.clone(), include_rp);
if res.outputs.len() > 0 {
return_vec.push(res);
}
}

return_vec
}
}
@@ -161,7 +185,7 @@ impl Handler for UtxoHandler {
}
match *path_elems.last().unwrap() {
"byids" => json_response(&self.utxos_by_ids(req)),
"byheight" => json_response(&self.utxo_block_batch(req)),
"byheight" => json_response(&self.outputs_block_batch(req)),
_ => Ok(Response::with((status::BadRequest, ""))),
}
}
@@ -344,11 +368,8 @@ pub struct BlockHandler {

impl BlockHandler {
fn get_block(&self, h: &Hash) -> Result<BlockPrintable, Error> {
let block = self.chain
.clone()
.get_block(h)
.map_err(|_| Error::NotFound)?;
Ok(BlockPrintable::from_block(&block))
let block = self.chain.clone().get_block(h).map_err(|_| Error::NotFound)?;
Ok(BlockPrintable::from_block(&block, self.chain.clone(), false))
}

// Try to decode the string as a height or a hash.
@@ -440,7 +461,7 @@ where
tx.inputs.len(),
tx.outputs.len()
);

let res = self.tx_pool
.write()
.unwrap()
Loading