mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 11:31:08 +03:00
Only create 1 received tx log entry on restore (#2378)
* restore only creates 1 received tx * restore child index sanity output
This commit is contained in:
parent
9a497f1439
commit
5d257283bd
1 changed files with 88 additions and 37 deletions
|
@ -45,6 +45,18 @@ struct OutputResult {
|
||||||
pub blinding: SecretKey,
|
pub blinding: SecretKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
/// Collect stats in case we want to just output a single tx log entry
|
||||||
|
/// for restored non-coinbase outputs
|
||||||
|
struct RestoredTxStats {
|
||||||
|
///
|
||||||
|
pub log_id: u32,
|
||||||
|
///
|
||||||
|
pub amount_credited: u64,
|
||||||
|
///
|
||||||
|
pub num_outputs: usize,
|
||||||
|
}
|
||||||
|
|
||||||
fn identify_utxo_outputs<T, C, K>(
|
fn identify_utxo_outputs<T, C, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64, u64)>,
|
outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64, u64)>,
|
||||||
|
@ -136,6 +148,7 @@ fn restore_missing_output<T, C, K>(
|
||||||
wallet: &mut T,
|
wallet: &mut T,
|
||||||
output: OutputResult,
|
output: OutputResult,
|
||||||
found_parents: &mut HashMap<Identifier, u32>,
|
found_parents: &mut HashMap<Identifier, u32>,
|
||||||
|
tx_stats: &mut Option<&mut HashMap<Identifier, RestoredTxStats>>,
|
||||||
) -> Result<(), Error>
|
) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: WalletBackend<C, K>,
|
T: WalletBackend<C, K>,
|
||||||
|
@ -148,20 +161,47 @@ where
|
||||||
let parent_key_id = output.key_id.parent_path();
|
let parent_key_id = output.key_id.parent_path();
|
||||||
if !found_parents.contains_key(&parent_key_id) {
|
if !found_parents.contains_key(&parent_key_id) {
|
||||||
found_parents.insert(parent_key_id.clone(), 0);
|
found_parents.insert(parent_key_id.clone(), 0);
|
||||||
|
if let Some(ref mut s) = tx_stats {
|
||||||
|
s.insert(
|
||||||
|
parent_key_id.clone(),
|
||||||
|
RestoredTxStats {
|
||||||
|
log_id: batch.next_tx_log_id(&parent_key_id)?,
|
||||||
|
amount_credited: 0,
|
||||||
|
num_outputs: 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let log_id = if tx_stats.is_none() || output.is_coinbase {
|
||||||
let log_id = batch.next_tx_log_id(&parent_key_id)?;
|
let log_id = batch.next_tx_log_id(&parent_key_id)?;
|
||||||
let entry_type = match output.is_coinbase {
|
let entry_type = match output.is_coinbase {
|
||||||
true => TxLogEntryType::ConfirmedCoinbase,
|
true => TxLogEntryType::ConfirmedCoinbase,
|
||||||
false => TxLogEntryType::TxReceived,
|
false => TxLogEntryType::TxReceived,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut t = TxLogEntry::new(parent_key_id.clone(), entry_type, log_id);
|
let mut t = TxLogEntry::new(parent_key_id.clone(), entry_type, log_id);
|
||||||
t.confirmed = true;
|
t.confirmed = true;
|
||||||
t.amount_credited = output.value;
|
t.amount_credited = output.value;
|
||||||
t.num_outputs = 1;
|
t.num_outputs = 1;
|
||||||
t.update_confirmation_ts();
|
t.update_confirmation_ts();
|
||||||
batch.save_tx_log_entry(t, &parent_key_id)?;
|
batch.save_tx_log_entry(t, &parent_key_id)?;
|
||||||
|
log_id
|
||||||
|
} else {
|
||||||
|
if let Some(ref mut s) = tx_stats {
|
||||||
|
let ts = s.get(&parent_key_id).unwrap().clone();
|
||||||
|
s.insert(
|
||||||
|
parent_key_id.clone(),
|
||||||
|
RestoredTxStats {
|
||||||
|
log_id: ts.log_id,
|
||||||
|
amount_credited: ts.amount_credited + output.value,
|
||||||
|
num_outputs: ts.num_outputs + 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
ts.log_id
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let _ = batch.save(OutputData {
|
let _ = batch.save(OutputData {
|
||||||
root_key_id: parent_key_id.clone(),
|
root_key_id: parent_key_id.clone(),
|
||||||
|
@ -292,7 +332,7 @@ where
|
||||||
Restoring.",
|
Restoring.",
|
||||||
m.value, m.key_id, m.commit,
|
m.value, m.key_id, m.commit,
|
||||||
);
|
);
|
||||||
restore_missing_output(wallet, m, &mut found_parents)?;
|
restore_missing_output(wallet, m, &mut found_parents, &mut None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlock locked outputs
|
// Unlock locked outputs
|
||||||
|
@ -330,24 +370,19 @@ where
|
||||||
|
|
||||||
// restore labels, account paths and child derivation indices
|
// restore labels, account paths and child derivation indices
|
||||||
let label_base = "account";
|
let label_base = "account";
|
||||||
let mut index = 1;
|
let mut acct_index = 1;
|
||||||
for (path, max_child_index) in found_parents.iter() {
|
for (path, max_child_index) in found_parents.iter() {
|
||||||
if *path == ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
|
||||||
// default path already exists
|
// default path already exists
|
||||||
continue;
|
if *path != ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
||||||
}
|
let label = format!("{}_{}", label_base, acct_index);
|
||||||
let res = wallet.acct_path_iter().find(|e| e.path == *path);
|
|
||||||
if let None = res {
|
|
||||||
let label = format!("{}_{}", label_base, index);
|
|
||||||
keys::set_acct_path(wallet, &label, path)?;
|
keys::set_acct_path(wallet, &label, path)?;
|
||||||
index = index + 1;
|
acct_index += 1;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
let mut batch = wallet.batch()?;
|
let mut batch = wallet.batch()?;
|
||||||
|
debug!("Next child for account {} is {}", path, max_child_index + 1);
|
||||||
batch.save_child_index(path, max_child_index + 1)?;
|
batch.save_child_index(path, max_child_index + 1)?;
|
||||||
|
batch.commit()?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,27 +410,43 @@ where
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut found_parents: HashMap<Identifier, u32> = HashMap::new();
|
let mut found_parents: HashMap<Identifier, u32> = HashMap::new();
|
||||||
// Now save what we have
|
let mut restore_stats = HashMap::new();
|
||||||
|
|
||||||
|
// Now save what we have
|
||||||
for output in result_vec {
|
for output in result_vec {
|
||||||
restore_missing_output(wallet, output, &mut found_parents)?;
|
restore_missing_output(
|
||||||
|
wallet,
|
||||||
|
output,
|
||||||
|
&mut found_parents,
|
||||||
|
&mut Some(&mut restore_stats),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore labels, account paths and child derivation indices
|
// restore labels, account paths and child derivation indices
|
||||||
let label_base = "account";
|
let label_base = "account";
|
||||||
let mut index = 1;
|
let mut acct_index = 1;
|
||||||
for (path, max_child_index) in found_parents.iter() {
|
for (path, max_child_index) in found_parents.iter() {
|
||||||
if *path == ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
|
||||||
// default path already exists
|
// default path already exists
|
||||||
continue;
|
if *path != ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
||||||
}
|
let label = format!("{}_{}", label_base, acct_index);
|
||||||
let label = format!("{}_{}", label_base, index);
|
|
||||||
keys::set_acct_path(wallet, &label, path)?;
|
keys::set_acct_path(wallet, &label, path)?;
|
||||||
index = index + 1;
|
acct_index += 1;
|
||||||
{
|
}
|
||||||
|
// restore tx log entry for non-coinbase outputs
|
||||||
|
if let Some(s) = restore_stats.get(path) {
|
||||||
|
let mut batch = wallet.batch()?;
|
||||||
|
let mut t = TxLogEntry::new(path.clone(), TxLogEntryType::TxReceived, s.log_id);
|
||||||
|
t.confirmed = true;
|
||||||
|
t.amount_credited = s.amount_credited;
|
||||||
|
t.num_outputs = s.num_outputs;
|
||||||
|
t.update_confirmation_ts();
|
||||||
|
batch.save_tx_log_entry(t, &path)?;
|
||||||
|
batch.commit()?;
|
||||||
|
}
|
||||||
let mut batch = wallet.batch()?;
|
let mut batch = wallet.batch()?;
|
||||||
batch.save_child_index(path, max_child_index + 1)?;
|
batch.save_child_index(path, max_child_index + 1)?;
|
||||||
}
|
debug!("Next child for account {} is {}", path, max_child_index + 1);
|
||||||
|
batch.commit()?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue