diff --git a/chain/src/store.rs b/chain/src/store.rs
index 69f49db8b..fed82349c 100644
--- a/chain/src/store.rs
+++ b/chain/src/store.rs
@@ -39,8 +39,6 @@ const HEADER_HEAD_PREFIX: u8 = 'I' as u8;
const SYNC_HEAD_PREFIX: u8 = 's' as u8;
const HEADER_HEIGHT_PREFIX: u8 = '8' as u8;
const COMMIT_POS_PREFIX: u8 = 'c' as u8;
-const BLOCK_MARKER_PREFIX: u8 = 'm' as u8;
-const BLOCK_SUMS_PREFIX: u8 = 'M' as u8;
const BLOCK_INPUT_BITMAP_PREFIX: u8 = 'B' as u8;
/// All chain-related database operations
diff --git a/chain/src/txhashset.rs b/chain/src/txhashset.rs
index 8c04b901c..4b469df9c 100644
--- a/chain/src/txhashset.rs
+++ b/chain/src/txhashset.rs
@@ -564,36 +564,39 @@ impl<'a> Extension<'a> {
inputs: &Vec,
height: u64,
) -> Result<(), Error> {
- for input in inputs {
- if input.features.contains(OutputFeatures::COINBASE_OUTPUT) {
- self.verify_maturity_via_merkle_proof(input, height)?;
+ // Find the greatest output pos of any coinbase
+ // outputs we are attempting to spend.
+ let pos = inputs
+ .iter()
+ .filter(|x| x.features.contains(OutputFeatures::COINBASE_OUTPUT))
+ .filter_map(|x| self.commit_index.get_output_pos(&x.commitment()).ok())
+ .max()
+ .unwrap_or(0);
+
+ if pos > 0 {
+ // If we have not yet reached 1,000 blocks then
+ // we can fail immediately as coinbase cannot be mature.
+ if height < global::coinbase_maturity() {
+ return Err(Error::ImmatureCoinbase);
+ }
+
+ // Find the "cutoff" pos in the output MMR based on the
+ // header from 1,000 blocks ago.
+ let cutoff_height = height.checked_sub(global::coinbase_maturity()).unwrap_or(0);
+ let cutoff_header = self.commit_index.get_header_by_height(cutoff_height)?;
+ let cutoff_pos = cutoff_header.output_mmr_size;
+
+
+ // If any output pos exceeed the cutoff_pos
+ // we know they have not yet sufficiently matured.
+ if pos > cutoff_pos {
+ return Err(Error::ImmatureCoinbase);
}
}
+
Ok(())
}
- fn verify_maturity_via_merkle_proof(&self, input: &Input, height: u64) -> Result<(), Error> {
- let header = self.commit_index.get_block_header(&input.block_hash())?;
-
- // Check that the height indicates it has matured sufficiently
- // we will check the Merkle proof below to ensure we are being
- // honest about the height
- if header.height + global::coinbase_maturity() >= height {
- return Err(Error::ImmatureCoinbase);
- }
-
- // We need the MMR pos to verify the Merkle proof
- let pos = self.get_output_pos(&input.commitment())?;
-
- let out_id = OutputIdentifier::from_input(input);
- let res = input
- .merkle_proof()
- .verify(header.output_root, &out_id, pos)
- .map_err(|_| Error::MerkleProof)?;
-
- Ok(res)
- }
-
/// Apply a new set of blocks on top the existing sum trees. Blocks are
/// applied in order of the provided Vec. If pruning is enabled, inputs also
/// prune MMR data.
diff --git a/chain/src/types.rs b/chain/src/types.rs
index 3b0f4c4cf..0c3a61a93 100644
--- a/chain/src/types.rs
+++ b/chain/src/types.rs
@@ -18,13 +18,12 @@ use std::{error, fmt, io};
use util::secp;
use util::secp::pedersen::Commitment;
-use util::secp_static;
use core::core::committed;
use core::core::hash::{Hash, Hashed};
use core::core::target::Difficulty;
use core::core::{block, transaction, Block, BlockHeader};
-use core::ser::{self, Readable, Reader, Writeable, Writer};
+use core::ser;
use grin_store as store;
use keychain;
diff --git a/chain/tests/mine_simple_chain.rs b/chain/tests/mine_simple_chain.rs
index 13c49a84d..ffe0e10ef 100644
--- a/chain/tests/mine_simple_chain.rs
+++ b/chain/tests/mine_simple_chain.rs
@@ -263,8 +263,6 @@ fn spend_in_fork_and_compact() {
vec![
build::coinbase_input(
consensus::REWARD,
- block_hash,
- merkle_proof,
kc.derive_key_id(2).unwrap(),
),
build::output(consensus::REWARD - 20000, kc.derive_key_id(30).unwrap()),
diff --git a/chain/tests/test_coinbase_maturity.rs b/chain/tests/test_coinbase_maturity.rs
index 162b8eef4..fb035ff22 100644
--- a/chain/tests/test_coinbase_maturity.rs
+++ b/chain/tests/test_coinbase_maturity.rs
@@ -106,7 +106,7 @@ fn test_coinbase_maturity() {
// this is not a valid tx as the coinbase output cannot be spent yet
let coinbase_txn = build::transaction(
vec![
- build::coinbase_input(amount, block_hash, merkle_proof.clone(), key_id1.clone()),
+ build::coinbase_input(amount, key_id1.clone()),
build::output(amount - 2, key_id2.clone()),
build::with_fee(2),
],
diff --git a/chain/tests/test_txhashset_raw_txs.rs b/chain/tests/test_txhashset_raw_txs.rs
index 7dbd6caa6..f96306dfa 100644
--- a/chain/tests/test_txhashset_raw_txs.rs
+++ b/chain/tests/test_txhashset_raw_txs.rs
@@ -81,8 +81,6 @@ fn test_some_raw_txs() {
vec![
build::coinbase_input(
coinbase_reward,
- block.hash(),
- MerkleProof::default(),
key_id1.clone(),
),
build::output(100, key_id2.clone()),
@@ -97,8 +95,6 @@ fn test_some_raw_txs() {
vec![
build::coinbase_input(
coinbase_reward,
- block.hash(),
- MerkleProof::default(),
key_id1.clone(),
),
build::output(100, key_id4.clone()),
diff --git a/core/src/core/transaction.rs b/core/src/core/transaction.rs
index bb06a8093..bddbe8550 100644
--- a/core/src/core/transaction.rs
+++ b/core/src/core/transaction.rs
@@ -17,19 +17,17 @@
use std::cmp::Ordering;
use std::cmp::max;
use std::collections::HashSet;
-use std::io::Cursor;
use std::{error, fmt};
-use util::secp::pedersen::{Commitment, ProofMessage, RangeProof};
+use util::secp::pedersen::{Commitment, RangeProof};
use util::secp::{self, Message, Signature};
use util::{kernel_sig_msg, static_secp_instance};
use consensus::{self, VerifySortOrder};
-use core::hash::{Hash, Hashed, ZERO_HASH};
-use core::merkle_proof::MerkleProof;
+use core::hash::Hashed;
use core::{committed, Committed};
use keychain::{self, BlindingFactor};
-use ser::{self, read_and_verify_sorted, ser_vec, PMMRable, Readable, Reader, Writeable,
+use ser::{self, read_and_verify_sorted, PMMRable, Readable, Reader, Writeable,
WriteableSorted, Writer};
use util;
@@ -441,22 +439,13 @@ impl Transaction {
Transaction::weight(
self.inputs.len(),
self.outputs.len(),
- self.input_proofs_count(),
)
}
- /// Collect input's Merkle proofs
- pub fn input_proofs_count(&self) -> usize {
- self.inputs
- .iter()
- .filter(|i| i.merkle_proof.is_some())
- .count()
- }
-
/// Calculate transaction weight from transaction details
- pub fn weight(input_len: usize, output_len: usize, proof_len: usize) -> u32 {
+ pub fn weight(input_len: usize, output_len: usize) -> u32 {
let mut tx_weight =
- -1 * (input_len as i32) + (4 * output_len as i32) + (proof_len as i32) + 1;
+ -1 * (input_len as i32) + (4 * output_len as i32) + 1;
if tx_weight < 1 {
tx_weight = 1;
}
@@ -636,13 +625,6 @@ pub struct Input {
pub features: OutputFeatures,
/// The commit referencing the output being spent.
pub commit: Commitment,
- /// The hash of the block the output originated from.
- /// Currently we only care about this for coinbase outputs.
- pub block_hash: Option,
- /// The Merkle Proof that shows the output being spent by this input
- /// existed and was unspent at the time of this block (proof of inclusion
- /// in output_root)
- pub merkle_proof: Option,
}
hashable_ord!(Input);
@@ -663,17 +645,6 @@ impl Writeable for Input {
fn write(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_u8(self.features.bits())?;
self.commit.write(writer)?;
-
- if writer.serialization_mode() != ser::SerializationMode::Hash {
- if self.features.contains(OutputFeatures::COINBASE_OUTPUT) {
- let block_hash = &self.block_hash.unwrap_or(ZERO_HASH);
- let merkle_proof = self.merkle_proof();
-
- writer.write_fixed_bytes(block_hash)?;
- merkle_proof.write(writer)?;
- }
- }
-
Ok(())
}
}
@@ -687,13 +658,7 @@ impl Readable for Input {
let commit = Commitment::read(reader)?;
- if features.contains(OutputFeatures::COINBASE_OUTPUT) {
- let block_hash = Some(Hash::read(reader)?);
- let merkle_proof = Some(MerkleProof::read(reader)?);
- Ok(Input::new(features, commit, block_hash, merkle_proof))
- } else {
- Ok(Input::new(features, commit, None, None))
- }
+ Ok(Input::new(features, commit))
}
}
@@ -707,14 +672,10 @@ impl Input {
pub fn new(
features: OutputFeatures,
commit: Commitment,
- block_hash: Option,
- merkle_proof: Option,
) -> Input {
Input {
features,
commit,
- block_hash,
- merkle_proof,
}
}
@@ -725,21 +686,6 @@ impl Input {
pub fn commitment(&self) -> Commitment {
self.commit
}
-
- /// Convenience function to return the (optional) block_hash for this input.
- /// Will return the default hash if we do not have one.
- pub fn block_hash(&self) -> Hash {
- self.block_hash.unwrap_or_else(Hash::default)
- }
-
- /// Convenience function to return the (optional) merkle_proof for this
- /// input. Will return the "empty" Merkle proof if we do not have one.
- /// We currently only care about the Merkle proof for inputs spending
- /// coinbase outputs.
- pub fn merkle_proof(&self) -> MerkleProof {
- let merkle_proof = self.merkle_proof.clone();
- merkle_proof.unwrap_or_else(MerkleProof::empty)
- }
}
bitflags! {
@@ -920,6 +866,7 @@ impl Readable for OutputIdentifier {
#[cfg(test)]
mod test {
use super::*;
+ use core::hash::Hash;
use core::id::{ShortId, ShortIdentifiable};
use keychain::{ExtKeychain, Keychain};
use util::secp;
@@ -991,8 +938,6 @@ mod test {
let input = Input {
features: OutputFeatures::DEFAULT_OUTPUT,
commit: commit,
- block_hash: None,
- merkle_proof: None,
};
let block_hash = Hash::from_hex(
@@ -1009,8 +954,6 @@ mod test {
let input = Input {
features: OutputFeatures::COINBASE_OUTPUT,
commit: commit,
- block_hash: None,
- merkle_proof: None,
};
let short_id = input.short_id(&block_hash, nonce);
diff --git a/pool/tests/common/mod.rs b/pool/tests/common/mod.rs
index 4d06ebf60..c65fe5d12 100644
--- a/pool/tests/common/mod.rs
+++ b/pool/tests/common/mod.rs
@@ -126,8 +126,6 @@ where
let key_id = keychain.derive_key_id(header.height as u32).unwrap();
tx_elements.push(libtx::build::coinbase_input(
coinbase_reward,
- header.hash(),
- MerkleProof::default(),
key_id,
));
}
diff --git a/wallet/src/client.rs b/wallet/src/client.rs
index 782882c43..152b27fa1 100644
--- a/wallet/src/client.rs
+++ b/wallet/src/client.rs
@@ -207,76 +207,3 @@ pub fn get_outputs_by_pmmr_index(
}
}
}
-
-/// Get any missing block hashes from node
-pub fn get_missing_block_hashes_from_node(
- addr: &str,
- height: u64,
- wallet_outputs: Vec,
-) -> Result<
- (
- HashMap,
- HashMap,
- ),
- Error,
-> {
- let id_params: Vec = wallet_outputs
- .iter()
- .map(|commit| format!("id={}", util::to_hex(commit.as_ref().to_vec())))
- .collect();
-
- let height_params = [format!("start_height={}&end_height={}", 0, height)];
- let mut api_blocks: HashMap = HashMap::new();
- let mut api_merkle_proofs: HashMap = HashMap::new();
-
- // Split up into separate requests, to avoid hitting http limits
- for mut query_chunk in id_params.chunks(1000) {
- let url = format!(
- "{}/v1/chain/outputs/byheight?{}",
- addr,
- [&height_params, query_chunk].concat().join("&"),
- );
-
- match api::client::get::>(url.as_str()) {
- Ok(blocks) => for block in blocks {
- for out in block.outputs {
- api_blocks.insert(
- out.commit,
- (
- block.header.height,
- BlockIdentifier::from_hex(&block.header.hash).unwrap(),
- ),
- );
- if let Some(merkle_proof) = out.merkle_proof {
- let wrapper = MerkleProofWrapper(merkle_proof);
- api_merkle_proofs.insert(out.commit, wrapper);
- }
- }
- },
- Err(e) => {
- // if we got anything other than 200 back from server, bye
- return Err(e)?;
- }
- }
- }
- Ok((api_blocks, api_merkle_proofs))
-}
-
-/// Create a merkle proof at the given height for the given commit
-pub fn create_merkle_proof(addr: &str, commit: &str) -> Result {
- let url = format!("{}/v1/txhashset/merkleproof?id={}", addr, commit);
-
- match api::client::get::(url.as_str()) {
- Ok(output) => Ok(MerkleProofWrapper(output.merkle_proof.unwrap())),
- Err(e) => {
- // if we got anything other than 200 back from server, bye
- error!(
- LOGGER,
- "get_merkle_proof_for_pos: Restore failed... unable to create merkle proof for commit {}. Error: {}",
- commit,
- e
- );
- Err(e)?
- }
- }
-}
diff --git a/wallet/src/file_wallet.rs b/wallet/src/file_wallet.rs
index b439f8838..671585a52 100644
--- a/wallet/src/file_wallet.rs
+++ b/wallet/src/file_wallet.rs
@@ -34,7 +34,7 @@ use client;
use libtx::slate::Slate;
use libwallet;
use libwallet::types::{
- BlockFees, BlockIdentifier, CbData, MerkleProofWrapper, OutputData, TxWrapper, WalletBackend,
+ BlockFees, BlockIdentifier, CbData, OutputData, TxWrapper, WalletBackend,
WalletClient, WalletDetails, WalletOutputBatch,
};
use types::{WalletConfig, WalletSeed};
@@ -400,31 +400,6 @@ impl WalletClient for FileWallet {
.context(libwallet::ErrorKind::Node)?;
Ok(res)
}
-
- /// Get any missing block hashes from node
- fn get_missing_block_hashes_from_node(
- &self,
- height: u64,
- wallet_outputs: Vec,
- ) -> Result<
- (
- HashMap,
- HashMap,
- ),
- libwallet::Error,
- > {
- let res =
- client::get_missing_block_hashes_from_node(self.node_url(), height, wallet_outputs)
- .context(libwallet::ErrorKind::Node)?;
- Ok(res)
- }
-
- /// retrieve merkle proof for a commit from a node
- fn create_merkle_proof(&self, commit: &str) -> Result {
- let res = client::create_merkle_proof(self.node_url(), commit)
- .context(libwallet::ErrorKind::Node)?;
- Ok(res)
- }
}
impl FileWallet
diff --git a/wallet/src/libtx/build.rs b/wallet/src/libtx/build.rs
index b1ed5ece6..1cdd74a9c 100644
--- a/wallet/src/libtx/build.rs
+++ b/wallet/src/libtx/build.rs
@@ -28,7 +28,6 @@
use util::{kernel_sig_msg, secp};
use core::core::hash::Hash;
-use core::core::merkle_proof::MerkleProof;
use core::core::{Input, Output, OutputFeatures, Transaction, TxKernel};
use keychain::{self, BlindSum, BlindingFactor, Identifier, Keychain};
use libtx::{aggsig, proof};
@@ -52,8 +51,6 @@ pub type Append = for<'a> Fn(&'a mut Context, (Transaction, TxKe
fn build_input(
value: u64,
features: OutputFeatures,
- block_hash: Option,
- merkle_proof: Option,
key_id: Identifier,
) -> Box>
where
@@ -62,7 +59,7 @@ where
Box::new(
move |build, (tx, kern, sum)| -> (Transaction, TxKernel, BlindSum) {
let commit = build.keychain.commit(value, &key_id).unwrap();
- let input = Input::new(features, commit, block_hash.clone(), merkle_proof.clone());
+ let input = Input::new(features, commit);
(tx.with_input(input), kern, sum.sub_key_id(key_id.clone()))
},
)
@@ -78,15 +75,12 @@ where
LOGGER,
"Building input (spending regular output): {}, {}", value, key_id
);
- build_input(value, OutputFeatures::DEFAULT_OUTPUT, None, None, key_id)
+ build_input(value, OutputFeatures::DEFAULT_OUTPUT, key_id)
}
/// Adds a coinbase input spending a coinbase output.
-/// We will use the block hash to verify coinbase maturity.
pub fn coinbase_input(
value: u64,
- block_hash: Hash,
- merkle_proof: MerkleProof,
key_id: Identifier,
) -> Box>
where
@@ -96,13 +90,7 @@ where
LOGGER,
"Building input (spending coinbase): {}, {}", value, key_id
);
- build_input(
- value,
- OutputFeatures::COINBASE_OUTPUT,
- Some(block_hash),
- Some(merkle_proof),
- key_id,
- )
+ build_input(value, OutputFeatures::COINBASE_OUTPUT, key_id)
}
/// Adds an output with the provided value and key identifier from the
diff --git a/wallet/src/libtx/mod.rs b/wallet/src/libtx/mod.rs
index b1378058d..f29363b5a 100644
--- a/wallet/src/libtx/mod.rs
+++ b/wallet/src/libtx/mod.rs
@@ -36,11 +36,11 @@ pub use libtx::error::{Error, ErrorKind};
const DEFAULT_BASE_FEE: u64 = consensus::MILLI_GRIN;
/// Transaction fee calculation
-pub fn tx_fee(input_len: usize, output_len: usize, proof_len: usize, base_fee: Option) -> u64 {
+pub fn tx_fee(input_len: usize, output_len: usize, base_fee: Option) -> u64 {
let use_base_fee = match base_fee {
Some(bf) => bf,
None => DEFAULT_BASE_FEE,
};
- (Transaction::weight(input_len, output_len, proof_len) as u64) * use_base_fee
+ (Transaction::weight(input_len, output_len) as u64) * use_base_fee
}
diff --git a/wallet/src/libtx/slate.rs b/wallet/src/libtx/slate.rs
index d9c65f6a4..5ffd62d93 100644
--- a/wallet/src/libtx/slate.rs
+++ b/wallet/src/libtx/slate.rs
@@ -264,7 +264,6 @@ impl Slate {
let fee = tx_fee(
self.tx.inputs.len(),
self.tx.outputs.len(),
- self.tx.input_proofs_count(),
None,
);
if fee > self.tx.fee() {
diff --git a/wallet/src/libwallet/api.rs b/wallet/src/libwallet/api.rs
index c7809f6c6..052c01989 100644
--- a/wallet/src/libwallet/api.rs
+++ b/wallet/src/libwallet/api.rs
@@ -108,7 +108,8 @@ where
Err(e) => {
error!(
LOGGER,
- "Communication with receiver failed on SenderInitiation send. Aborting transaction"
+ "Communication with receiver failed on SenderInitiation send. Aborting transaction {:?}",
+ e,
);
return Err(e)?;
}
diff --git a/wallet/src/libwallet/internal/restore.rs b/wallet/src/libwallet/internal/restore.rs
index 611cd463b..98e079212 100644
--- a/wallet/src/libwallet/internal/restore.rs
+++ b/wallet/src/libwallet/internal/restore.rs
@@ -38,8 +38,6 @@ struct OutputResult {
///
pub is_coinbase: bool,
///
- pub merkle_proof: Option,
- ///
pub blinding: SecretKey,
}
@@ -75,13 +73,8 @@ where
"Output found: {:?}, amount: {:?}", commit, info.value
);
- let mut merkle_proof = None;
let commit_str = util::to_hex(commit.as_ref().to_vec());
- if *is_coinbase {
- merkle_proof = Some(wallet.create_merkle_proof(&commit_str)?);
- }
-
let height = current_chain_height;
let lock_height = if *is_coinbase {
height + global::coinbase_maturity()
@@ -97,7 +90,6 @@ where
height: height,
lock_height: lock_height,
is_coinbase: *is_coinbase,
- merkle_proof: merkle_proof,
blinding: info.blinding,
});
}
@@ -219,8 +211,6 @@ where
height: output.height,
lock_height: output.lock_height,
is_coinbase: output.is_coinbase,
- block: None,
- merkle_proof: output.merkle_proof,
});
} else {
warn!(
diff --git a/wallet/src/libwallet/internal/selection.rs b/wallet/src/libwallet/internal/selection.rs
index 30de86a51..89d4a4612 100644
--- a/wallet/src/libwallet/internal/selection.rs
+++ b/wallet/src/libwallet/internal/selection.rs
@@ -109,8 +109,6 @@ where
height: current_height,
lock_height: 0,
is_coinbase: false,
- block: None,
- merkle_proof: None,
});
}
batch.commit()?;
@@ -174,8 +172,6 @@ where
height: height,
lock_height: 0,
is_coinbase: false,
- block: None,
- merkle_proof: None,
});
batch.commit()?;
Ok(())
@@ -238,7 +234,7 @@ where
// sender
let mut fee;
// First attempt to spend without change
- fee = tx_fee(coins.len(), 1, coins_proof_count(&coins), None);
+ fee = tx_fee(coins.len(), 1, None);
let mut total: u64 = coins.iter().map(|c| c.value).sum();
let mut amount_with_fee = amount + fee;
@@ -251,7 +247,7 @@ where
// Check if we need to use a change address
if total > amount_with_fee {
- fee = tx_fee(coins.len(), 2, coins_proof_count(&coins), None);
+ fee = tx_fee(coins.len(), 2, None);
amount_with_fee = amount + fee;
// Here check if we have enough outputs for the amount including fee otherwise
@@ -274,7 +270,7 @@ where
max_outputs,
selection_strategy_is_use_all,
);
- fee = tx_fee(coins.len(), 2, coins_proof_count(&coins), None);
+ fee = tx_fee(coins.len(), 2, None);
total = coins.iter().map(|c| c.value).sum();
amount_with_fee = amount + fee;
}
@@ -290,11 +286,6 @@ where
Ok((parts, coins, change, change_derivation, amount, fee))
}
-/// coins proof count
-pub fn coins_proof_count(coins: &Vec) -> usize {
- coins.iter().filter(|c| c.merkle_proof.is_some()).count()
-}
-
/// Selects inputs and change for a transaction
pub fn inputs_and_change(
coins: &Vec,
@@ -322,14 +313,8 @@ where
for coin in coins {
let key_id = wallet.keychain().derive_key_id(coin.n_child)?;
if coin.is_coinbase {
- let block = coin.block.clone();
- let merkle_proof = coin.merkle_proof.clone();
- let merkle_proof = merkle_proof.unwrap().merkle_proof();
-
parts.push(build::coinbase_input(
coin.value,
- block.unwrap().hash(),
- merkle_proof,
key_id,
));
} else {
diff --git a/wallet/src/libwallet/internal/tx.rs b/wallet/src/libwallet/internal/tx.rs
index 6893341d8..cfca90fbc 100644
--- a/wallet/src/libwallet/internal/tx.rs
+++ b/wallet/src/libwallet/internal/tx.rs
@@ -162,7 +162,7 @@ where
debug!(LOGGER, "selected some coins - {}", coins.len());
- let fee = tx_fee(coins.len(), 2, selection::coins_proof_count(&coins), None);
+ let fee = tx_fee(coins.len(), 2, None);
let (mut parts, _, _) = selection::inputs_and_change(&coins, wallet, amount, fee)?;
//TODO: If we end up using this, create change output here
diff --git a/wallet/src/libwallet/internal/updater.rs b/wallet/src/libwallet/internal/updater.rs
index 5b355721b..19efc6b22 100644
--- a/wallet/src/libwallet/internal/updater.rs
+++ b/wallet/src/libwallet/internal/updater.rs
@@ -65,55 +65,6 @@ where
{
let height = wallet.get_chain_height()?;
refresh_output_state(wallet, height)?;
- refresh_missing_block_hashes(wallet, height)?;
- Ok(())
-}
-
-// TODO - this might be slow if we have really old outputs that have never been
-// refreshed
-fn refresh_missing_block_hashes(wallet: &mut T, height: u64) -> Result<(), Error>
-where
- T: WalletBackend + WalletClient,
- K: Keychain,
-{
- // build a local map of wallet outputs keyed by commit
- // and a list of outputs we want to query the node for
- let wallet_outputs = map_wallet_outputs_missing_block(wallet)?;
-
- let wallet_output_keys = wallet_outputs.keys().map(|commit| commit.clone()).collect();
-
- // nothing to do so return (otherwise we hit the api with a monster query...)
- if wallet_outputs.is_empty() {
- return Ok(());
- }
-
- debug!(
- LOGGER,
- "Refreshing missing block hashes (and heights) for {} outputs",
- wallet_outputs.len(),
- );
-
- let (api_blocks, api_merkle_proofs) =
- wallet.get_missing_block_hashes_from_node(height, wallet_output_keys)?;
-
- // now for each commit, find the output in the wallet and
- // the corresponding api output (if it exists)
- // and refresh it in-place in the wallet.
- // Note: minimizing the time we spend holding the wallet lock.
- let mut batch = wallet.batch()?;
- for (commit, id) in wallet_outputs.iter() {
- if let Some((height, bid)) = api_blocks.get(&commit) {
- if let Ok(mut output) = batch.get(id) {
- output.height = *height;
- output.block = Some(bid.clone());
- if let Some(merkle_proof) = api_merkle_proofs.get(&commit) {
- output.merkle_proof = Some(merkle_proof.clone());
- }
- batch.save(output);
- }
- }
- }
- batch.commit()?;
Ok(())
}
@@ -139,29 +90,6 @@ where
Ok(wallet_outputs)
}
-/// As above, but only return unspent outputs with missing block hashes
-/// and a list of outputs we want to query the node for
-pub fn map_wallet_outputs_missing_block(
- wallet: &mut T,
-) -> Result, Error>
-where
- T: WalletBackend,
- K: Keychain,
-{
- let mut wallet_outputs: HashMap = HashMap::new();
- let keychain = wallet.keychain().clone();
- let unspents = wallet.iter().filter(|x| {
- x.root_key_id == keychain.root_key_id()
- && x.block.is_none()
- && x.status == OutputStatus::Unspent
- });
- for out in unspents {
- let commit = keychain.commit_with_key_index(out.value, out.n_child)?;
- wallet_outputs.insert(commit, out.key_id.clone());
- }
- Ok(wallet_outputs)
-}
-
/// Apply refreshed API output data to the wallet
pub fn apply_api_outputs(
wallet: &mut T,
@@ -329,20 +257,16 @@ where
{
// Now acquire the wallet lock and write the new output.
let mut batch = wallet.batch()?;
- {
- batch.save(OutputData {
- root_key_id: root_key_id.clone(),
- key_id: key_id.clone(),
- n_child: derivation,
- value: reward(block_fees.fees),
- status: OutputStatus::Unconfirmed,
- height: height,
- lock_height: lock_height,
- is_coinbase: true,
- block: None,
- merkle_proof: None,
- })?;
- }
+ batch.save(OutputData {
+ root_key_id: root_key_id.clone(),
+ key_id: key_id.clone(),
+ n_child: derivation,
+ value: reward(block_fees.fees),
+ status: OutputStatus::Unconfirmed,
+ height: height,
+ lock_height: lock_height,
+ is_coinbase: true,
+ });
batch.commit()?;
}
diff --git a/wallet/src/libwallet/types.rs b/wallet/src/libwallet/types.rs
index 1bdaac243..2197bfe19 100644
--- a/wallet/src/libwallet/types.rs
+++ b/wallet/src/libwallet/types.rs
@@ -24,7 +24,6 @@ use serde_json;
use failure::ResultExt;
use core::core::hash::Hash;
-use core::core::merkle_proof::MerkleProof;
use core::ser;
use keychain::{Identifier, Keychain};
@@ -150,22 +149,6 @@ pub trait WalletClient {
),
Error,
>;
-
- /// Get any missing block hashes from node
- fn get_missing_block_hashes_from_node(
- &self,
- height: u64,
- wallet_outputs: Vec,
- ) -> Result<
- (
- HashMap,
- HashMap,
- ),
- Error,
- >;
-
- /// create merkle proof for a commit from a node at the current height
- fn create_merkle_proof(&self, commit: &str) -> Result;
}
/// Information about an output that's being tracked by the wallet. Must be
@@ -190,10 +173,6 @@ pub struct OutputData {
pub lock_height: u64,
/// Is this a coinbase output? Is it subject to coinbase locktime?
pub is_coinbase: bool,
- /// Hash of the block this output originated from.
- pub block: Option,
- /// Merkle proof
- pub merkle_proof: Option,
}
impl ser::Writeable for OutputData {
@@ -239,14 +218,6 @@ impl OutputData {
return false;
} else if self.status == OutputStatus::Unconfirmed && self.is_coinbase {
return false;
- } else if self.is_coinbase && self.block.is_none() {
- // if we do not have a block hash for coinbase output we cannot spent it
- // block index got compacted before we refreshed our wallet?
- return false;
- } else if self.is_coinbase && self.merkle_proof.is_none() {
- // if we do not have a Merkle proof for coinbase output we cannot spent it
- // block index got compacted before we refreshed our wallet?
- return false;
} else if self.lock_height > current_height {
return false;
} else if self.status == OutputStatus::Unspent
@@ -304,53 +275,6 @@ impl fmt::Display for OutputStatus {
}
}
-/// Wrapper for a merkle proof
-#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
-pub struct MerkleProofWrapper(pub MerkleProof);
-
-impl MerkleProofWrapper {
- /// Create
- pub fn merkle_proof(&self) -> MerkleProof {
- self.0.clone()
- }
-}
-
-impl serde::ser::Serialize for MerkleProofWrapper {
- fn serialize(&self, serializer: S) -> Result
- where
- S: serde::ser::Serializer,
- {
- serializer.serialize_str(&self.0.to_hex())
- }
-}
-
-impl<'de> serde::de::Deserialize<'de> for MerkleProofWrapper {
- fn deserialize(deserializer: D) -> Result
- where
- D: serde::de::Deserializer<'de>,
- {
- deserializer.deserialize_str(MerkleProofWrapperVisitor)
- }
-}
-
-struct MerkleProofWrapperVisitor;
-
-impl<'de> serde::de::Visitor<'de> for MerkleProofWrapperVisitor {
- type Value = MerkleProofWrapper;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("a merkle proof")
- }
-
- fn visit_str(self, s: &str) -> Result
- where
- E: serde::de::Error,
- {
- let merkle_proof = MerkleProof::from_hex(s).unwrap();
- Ok(MerkleProofWrapper(merkle_proof))
- }
-}
-
/// Block Identifier
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct BlockIdentifier(pub Hash);
diff --git a/wallet/src/lmdb_wallet.rs b/wallet/src/lmdb_wallet.rs
index b24d12f12..0547bccf4 100644
--- a/wallet/src/lmdb_wallet.rs
+++ b/wallet/src/lmdb_wallet.rs
@@ -251,28 +251,4 @@ impl WalletClient for LMDBBackend {
.context(ErrorKind::Node)?;
Ok(res)
}
-
- /// Get any missing block hashes from node
- fn get_missing_block_hashes_from_node(
- &self,
- height: u64,
- wallet_outputs: Vec,
- ) -> Result<
- (
- HashMap,
- HashMap,
- ),
- Error,
- > {
- let res =
- client::get_missing_block_hashes_from_node(self.node_url(), height, wallet_outputs)
- .context(ErrorKind::Node)?;
- Ok(res)
- }
-
- /// retrieve merkle proof for a commit from a node
- fn create_merkle_proof(&self, commit: &str) -> Result {
- let res = client::create_merkle_proof(self.node_url(), commit).context(ErrorKind::Node)?;
- Ok(res)
- }
}
diff --git a/wallet/tests/common/mod.rs b/wallet/tests/common/mod.rs
index 325c4347b..d9c8bb144 100644
--- a/wallet/tests/common/mod.rs
+++ b/wallet/tests/common/mod.rs
@@ -31,7 +31,7 @@ use keychain::ExtKeychain;
use wallet::WalletConfig;
use wallet::file_wallet::FileWallet;
use wallet::libwallet::internal::updater;
-use wallet::libwallet::types::{BlockFees, BlockIdentifier, MerkleProofWrapper, OutputStatus,
+use wallet::libwallet::types::{BlockFees, BlockIdentifier, OutputStatus,
WalletBackend};
use wallet::libwallet::{Error, ErrorKind};
@@ -176,13 +176,7 @@ where
}
};
add_block_with_reward(chain, txs, coinbase_tx.clone());
- // build merkle proof and block identifier and save in wallet
- let output_id = OutputIdentifier::from_output(&coinbase_tx.0.clone());
- let m_proof = chain.get_merkle_proof(&output_id, &chain.head_header().unwrap());
- let block_id = Some(BlockIdentifier(chain.head_header().unwrap().hash()));
- let mut output = wallet.get(&fees.key_id.unwrap()).unwrap();
- output.block = block_id;
- output.merkle_proof = Some(MerkleProofWrapper(m_proof.unwrap()));
+ let output = wallet.get(&fees.key_id.unwrap()).unwrap();
let mut batch = wallet.batch().unwrap();
batch.save(output).unwrap();
batch.commit().unwrap();