mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21: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,
|
||||
}
|
||||
|
||||
#[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>(
|
||||
wallet: &mut T,
|
||||
outputs: Vec<(pedersen::Commitment, pedersen::RangeProof, bool, u64, u64)>,
|
||||
|
@ -136,6 +148,7 @@ fn restore_missing_output<T, C, K>(
|
|||
wallet: &mut T,
|
||||
output: OutputResult,
|
||||
found_parents: &mut HashMap<Identifier, u32>,
|
||||
tx_stats: &mut Option<&mut HashMap<Identifier, RestoredTxStats>>,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
T: WalletBackend<C, K>,
|
||||
|
@ -148,21 +161,48 @@ where
|
|||
let parent_key_id = output.key_id.parent_path();
|
||||
if !found_parents.contains_key(&parent_key_id) {
|
||||
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 = batch.next_tx_log_id(&parent_key_id)?;
|
||||
let entry_type = match output.is_coinbase {
|
||||
true => TxLogEntryType::ConfirmedCoinbase,
|
||||
false => TxLogEntryType::TxReceived,
|
||||
let log_id = if tx_stats.is_none() || output.is_coinbase {
|
||||
let log_id = batch.next_tx_log_id(&parent_key_id)?;
|
||||
let entry_type = match output.is_coinbase {
|
||||
true => TxLogEntryType::ConfirmedCoinbase,
|
||||
false => TxLogEntryType::TxReceived,
|
||||
};
|
||||
let mut t = TxLogEntry::new(parent_key_id.clone(), entry_type, log_id);
|
||||
t.confirmed = true;
|
||||
t.amount_credited = output.value;
|
||||
t.num_outputs = 1;
|
||||
t.update_confirmation_ts();
|
||||
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 mut t = TxLogEntry::new(parent_key_id.clone(), entry_type, log_id);
|
||||
t.confirmed = true;
|
||||
t.amount_credited = output.value;
|
||||
t.num_outputs = 1;
|
||||
t.update_confirmation_ts();
|
||||
batch.save_tx_log_entry(t, &parent_key_id)?;
|
||||
|
||||
let _ = batch.save(OutputData {
|
||||
root_key_id: parent_key_id.clone(),
|
||||
key_id: output.key_id,
|
||||
|
@ -292,7 +332,7 @@ where
|
|||
Restoring.",
|
||||
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
|
||||
|
@ -330,24 +370,19 @@ where
|
|||
|
||||
// restore labels, account paths and child derivation indices
|
||||
let label_base = "account";
|
||||
let mut index = 1;
|
||||
let mut acct_index = 1;
|
||||
for (path, max_child_index) in found_parents.iter() {
|
||||
if *path == ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
||||
//default path already exists
|
||||
continue;
|
||||
}
|
||||
let res = wallet.acct_path_iter().find(|e| e.path == *path);
|
||||
if let None = res {
|
||||
let label = format!("{}_{}", label_base, index);
|
||||
// default path already exists
|
||||
if *path != ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
||||
let label = format!("{}_{}", label_base, acct_index);
|
||||
keys::set_acct_path(wallet, &label, path)?;
|
||||
index = index + 1;
|
||||
}
|
||||
{
|
||||
let mut batch = wallet.batch()?;
|
||||
batch.save_child_index(path, max_child_index + 1)?;
|
||||
acct_index += 1;
|
||||
}
|
||||
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.commit()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -375,27 +410,43 @@ where
|
|||
);
|
||||
|
||||
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 {
|
||||
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
|
||||
let label_base = "account";
|
||||
let mut index = 1;
|
||||
let mut acct_index = 1;
|
||||
for (path, max_child_index) in found_parents.iter() {
|
||||
if *path == ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
||||
//default path already exists
|
||||
continue;
|
||||
// default path already exists
|
||||
if *path != ExtKeychain::derive_key_id(2, 0, 0, 0, 0) {
|
||||
let label = format!("{}_{}", label_base, acct_index);
|
||||
keys::set_acct_path(wallet, &label, path)?;
|
||||
acct_index += 1;
|
||||
}
|
||||
let label = format!("{}_{}", label_base, index);
|
||||
keys::set_acct_path(wallet, &label, path)?;
|
||||
index = index + 1;
|
||||
{
|
||||
// restore tx log entry for non-coinbase outputs
|
||||
if let Some(s) = restore_stats.get(path) {
|
||||
let mut batch = wallet.batch()?;
|
||||
batch.save_child_index(path, max_child_index + 1)?;
|
||||
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()?;
|
||||
batch.save_child_index(path, max_child_index + 1)?;
|
||||
debug!("Next child for account {} is {}", path, max_child_index + 1);
|
||||
batch.commit()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue