Update migration to handle the raw-tx-absent case.
The raw serialized transaction data for a transaction is not always guaranteed to be present, and we cannot correctly calculate the fee paid by a transaction if we don't have the raw data. For such rows that contain only transaction metadata, the fee information will be added at the same time the raw transaction data is added.
This commit is contained in:
parent
7934e834d3
commit
167bcd86ce
|
@ -1,5 +1,5 @@
|
||||||
//! Functions for initializing the various databases.
|
//! Functions for initializing the various databases.
|
||||||
use rusqlite::{self, types::ToSql, NO_PARAMS};
|
use rusqlite::{self, types::ToSql, OptionalExtension, NO_PARAMS};
|
||||||
use schemer::{self};
|
use schemer::{self};
|
||||||
use schemer_rusqlite::RusqliteMigration;
|
use schemer_rusqlite::RusqliteMigration;
|
||||||
|
|
||||||
|
@ -56,30 +56,50 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
||||||
let mut tx_rows = stmt_list_txs.query(NO_PARAMS)?;
|
let mut tx_rows = stmt_list_txs.query(NO_PARAMS)?;
|
||||||
while let Some(row) = tx_rows.next()? {
|
while let Some(row) = tx_rows.next()? {
|
||||||
let id_tx: i64 = row.get(0)?;
|
let id_tx: i64 = row.get(0)?;
|
||||||
let tx_bytes: Vec<u8> = row.get(1)?;
|
let tx_bytes: Option<Vec<u8>> = row.get(1)?;
|
||||||
let h: u32 = row.get(2)?;
|
let h: u32 = row.get(2)?;
|
||||||
let block_height = BlockHeight::from(h);
|
let block_height = BlockHeight::from(h);
|
||||||
|
|
||||||
let tx = Transaction::read(
|
// If only transaction metadata has been stored, and not transaction data, the fee
|
||||||
&tx_bytes[..],
|
// information will eventually be set when the full transaction data is inserted.
|
||||||
BranchId::for_height(&self.params, block_height),
|
if let Some(b) = tx_bytes {
|
||||||
)
|
let tx =
|
||||||
.map_err(|e| {
|
Transaction::read(&b[..], BranchId::for_height(&self.params, block_height))
|
||||||
WalletMigrationError::CorruptedData(format!(
|
.map_err(|e| {
|
||||||
"Parsing failed for transaction {:?}: {:?}",
|
WalletMigrationError::CorruptedData(format!(
|
||||||
id_tx, e
|
"Parsing failed for transaction {:?}: {:?}",
|
||||||
))
|
id_tx, e
|
||||||
})?;
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
let fee_paid = tx.fee_paid(|op| {
|
let fee_paid = tx.fee_paid(|op| {
|
||||||
stmt_find_utxo_value
|
let op_amount = stmt_find_utxo_value
|
||||||
.query_row(&[op.hash().to_sql()?, op.n().to_sql()?], |row| {
|
.query_row(&[op.hash().to_sql()?, op.n().to_sql()?], |row| {
|
||||||
row.get(0).map(|i| Amount::from_i64(i).unwrap())
|
row.get::<_, i64>(0)
|
||||||
})
|
})
|
||||||
.map_err(WalletMigrationError::DbError)
|
.optional()
|
||||||
})?;
|
.map_err(WalletMigrationError::DbError)?;
|
||||||
|
|
||||||
stmt_set_fee.execute(&[i64::from(fee_paid), id_tx])?;
|
op_amount.map_or_else(
|
||||||
|
|| {
|
||||||
|
Err(WalletMigrationError::CorruptedData(format!(
|
||||||
|
"Unable to find UTXO corresponding to outpoint {:?}",
|
||||||
|
op
|
||||||
|
)))
|
||||||
|
},
|
||||||
|
|i| {
|
||||||
|
Amount::from_i64(i).map_err(|_| {
|
||||||
|
WalletMigrationError::CorruptedData(format!(
|
||||||
|
"UTXO amount out of range in outpoint {:?}",
|
||||||
|
op
|
||||||
|
))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
stmt_set_fee.execute(&[i64::from(fee_paid), id_tx])?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.execute_batch(
|
transaction.execute_batch(
|
||||||
|
|
Loading…
Reference in New Issue