Add test for fee calculation in add_transaction_views migration.
This commit is contained in:
parent
b327bf7073
commit
7934e834d3
|
@ -14,19 +14,17 @@ use zcash_primitives::{
|
|||
|
||||
use super::super::{WalletMigration2, WalletMigrationError};
|
||||
|
||||
pub(super) struct Migration<P> {
|
||||
pub(super) params: P,
|
||||
pub(crate) fn migration_id() -> Uuid {
|
||||
Uuid::parse_str("282fad2e-8372-4ca0-8bed-71821320909f").unwrap()
|
||||
}
|
||||
|
||||
impl<P> Migration<P> {
|
||||
fn id() -> Uuid {
|
||||
Uuid::parse_str("282fad2e-8372-4ca0-8bed-71821320909f").unwrap()
|
||||
}
|
||||
pub(crate) struct Migration<P> {
|
||||
pub(super) params: P,
|
||||
}
|
||||
|
||||
impl<P> schemer::Migration for Migration<P> {
|
||||
fn id(&self) -> Uuid {
|
||||
Migration::<P>::id()
|
||||
migration_id()
|
||||
}
|
||||
|
||||
fn dependencies(&self) -> HashSet<Uuid> {
|
||||
|
@ -97,7 +95,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
|||
SUM(
|
||||
CASE
|
||||
WHEN sent_notes.memo IS NULL THEN 0
|
||||
WHEN SUBSTR(sent_notes.memo, 0, 2) = X'F6' THEN 0
|
||||
WHEN sent_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0
|
||||
ELSE 1
|
||||
END
|
||||
) AS memo_count,
|
||||
|
@ -118,7 +116,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
|||
SUM(
|
||||
CASE
|
||||
WHEN received_notes.memo IS NULL THEN 0
|
||||
WHEN SUBSTR(received_notes.memo, 0, 2) = X'F6' THEN 0
|
||||
WHEN received_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0
|
||||
ELSE 1
|
||||
END
|
||||
) AS memo_count,
|
||||
|
@ -154,7 +152,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
|||
received_notes.is_change AS is_change,
|
||||
CASE
|
||||
WHEN received_notes.memo IS NULL THEN 0
|
||||
WHEN SUBSTR(received_notes.memo, 0, 2) = X'F6' THEN 0
|
||||
WHEN received_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0
|
||||
ELSE 1
|
||||
END AS memo_present
|
||||
FROM transactions
|
||||
|
@ -171,7 +169,7 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
|||
false AS is_change,
|
||||
CASE
|
||||
WHEN sent_notes.memo IS NULL THEN 0
|
||||
WHEN SUBSTR(sent_notes.memo, 0, 2) = X'F6' THEN 0
|
||||
WHEN sent_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0
|
||||
ELSE 1
|
||||
END AS memo_present
|
||||
FROM transactions
|
||||
|
@ -192,15 +190,29 @@ impl<P: consensus::Parameters> RusqliteMigration for Migration<P> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rusqlite::{self, NO_PARAMS};
|
||||
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
use crate::{
|
||||
tests::{self},
|
||||
wallet::init::init_wallet_db,
|
||||
WalletDb,
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
use {
|
||||
crate::wallet::init::{init_wallet_db_internal, WalletMigration2},
|
||||
rusqlite::params,
|
||||
zcash_client_backend::{encoding::AddressCodec, keys::UnifiedSpendingKey},
|
||||
zcash_primitives::{
|
||||
consensus::{BlockHeight, BranchId, Network},
|
||||
legacy::{keys::IncomingViewingKey, Script},
|
||||
transaction::{
|
||||
components::{
|
||||
transparent::{self, Authorized, OutPoint},
|
||||
Amount, TxIn, TxOut,
|
||||
},
|
||||
TransactionData, TxVersion,
|
||||
},
|
||||
zip32::AccountId,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{tests, wallet::init::init_wallet_db, WalletDb};
|
||||
|
||||
#[test]
|
||||
fn transaction_views() {
|
||||
let data_file = NamedTempFile::new().unwrap();
|
||||
|
@ -217,7 +229,7 @@ mod tests {
|
|||
INSERT INTO sent_notes (tx, output_pool, output_index, from_account, address, value, memo)
|
||||
VALUES (0, 2, 1, 0, '', 3, X'61');
|
||||
INSERT INTO sent_notes (tx, output_pool, output_index, from_account, address, value, memo)
|
||||
VALUES (0, 2, 2, 0, '', 0, X'f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');
|
||||
VALUES (0, 2, 2, 0, '', 0, X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000');
|
||||
|
||||
INSERT INTO received_notes (tx, output_index, account, diversifier, value, rcm, nf, is_change, memo)
|
||||
VALUES (0, 0, 0, '', 5, '', 'a', false, X'62');
|
||||
|
@ -276,4 +288,91 @@ mod tests {
|
|||
}
|
||||
assert_eq!(row_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "transparent-inputs")]
|
||||
fn migrate_from_wm2() {
|
||||
let data_file = NamedTempFile::new().unwrap();
|
||||
let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap();
|
||||
init_wallet_db_internal(&mut db_data, None, Some(WalletMigration2::<Network>::id()))
|
||||
.unwrap();
|
||||
|
||||
// create a UTXO to spend
|
||||
let tx = TransactionData::from_parts(
|
||||
TxVersion::Sapling,
|
||||
BranchId::Canopy,
|
||||
0,
|
||||
BlockHeight::from(3),
|
||||
Some(transparent::Bundle {
|
||||
vin: vec![TxIn {
|
||||
prevout: OutPoint::new([1u8; 32], 1),
|
||||
script_sig: Script(vec![]),
|
||||
sequence: 0,
|
||||
}],
|
||||
vout: vec![TxOut {
|
||||
value: Amount::from_i64(1100000000).unwrap(),
|
||||
script_pubkey: Script(vec![]),
|
||||
}],
|
||||
authorization: Authorized,
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.freeze()
|
||||
.unwrap();
|
||||
|
||||
let mut tx_bytes = vec![];
|
||||
tx.write(&mut tx_bytes).unwrap();
|
||||
|
||||
let usk =
|
||||
UnifiedSpendingKey::from_seed(&tests::network(), &[0u8; 32][..], AccountId::from(0))
|
||||
.unwrap();
|
||||
let ufvk = usk.to_unified_full_viewing_key();
|
||||
let (ua, _) = ufvk.default_address();
|
||||
let taddr = ufvk
|
||||
.transparent()
|
||||
.and_then(|k| {
|
||||
k.derive_external_ivk()
|
||||
.ok()
|
||||
.map(|k| k.derive_address(0).unwrap())
|
||||
})
|
||||
.map(|a| a.encode(&tests::network()));
|
||||
|
||||
db_data.conn.execute(
|
||||
"INSERT INTO accounts (account, ufvk, address, transparent_address) VALUES (0, ?, ?, ?)",
|
||||
params![ufvk.encode(&tests::network()), ua.encode(&tests::network()), &taddr]
|
||||
).unwrap();
|
||||
db_data
|
||||
.conn
|
||||
.execute_batch(
|
||||
"INSERT INTO blocks (height, hash, time, sapling_tree) VALUES (0, 0, 0, '');",
|
||||
)
|
||||
.unwrap();
|
||||
db_data.conn.execute(
|
||||
"INSERT INTO utxos (address, prevout_txid, prevout_idx, script, value_zat, height)
|
||||
VALUES (?, X'0101010101010101010101010101010101010101010101010101010101010101', 1, X'', 1400000000, 1)",
|
||||
&[taddr]
|
||||
).unwrap();
|
||||
db_data
|
||||
.conn
|
||||
.execute(
|
||||
"INSERT INTO transactions (block, id_tx, txid, raw) VALUES (0, 0, '', ?)",
|
||||
params![tx_bytes],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
init_wallet_db(&mut db_data, None).unwrap();
|
||||
|
||||
let fee = db_data
|
||||
.conn
|
||||
.query_row(
|
||||
"SELECT fee FROM transactions WHERE id_tx = 0",
|
||||
NO_PARAMS,
|
||||
|row| Ok(Amount::from_i64(row.get(0)?).unwrap()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(fee, Amount::from_i64(300000000).unwrap());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,11 @@ and this library adheres to Rust's notion of
|
|||
- `Builder::new_with_rng_and_fee`
|
||||
- `zcash_primitives::transaction::TransactionData::fee_paid`
|
||||
- `zcash_primitives::transaction::components::amount::BalanceError`
|
||||
- `zcash_primitives::transaction::components::sprout::Bundle::value_balance`
|
||||
- Added in `zcash_primitives::transaction::components::sprout`
|
||||
- `Bundle::value_balance`
|
||||
- `JSDescription::net_value`
|
||||
- Added in `zcash_primitives::transaction::components::transparent`
|
||||
- `Bundle::value_balance`
|
||||
|
||||
### Changed
|
||||
- `zcash_primitives::sapling::ViewingKey` now stores `nk` as a
|
||||
|
|
|
@ -396,15 +396,13 @@ impl<A: Authorization> TransactionData<A> {
|
|||
self.tze_bundle.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the total fees paid by the transaction, given a function that can
|
||||
/// be used to retrieve the output values of previous transactions' outputs
|
||||
/// that are being spent in this transaction.
|
||||
pub fn fee_paid<E, F: FnMut(&OutPoint) -> Result<Amount, E>>(
|
||||
&self,
|
||||
get_prevout: F,
|
||||
) -> Result<Amount, E>
|
||||
/// Returns the total fees paid by the transaction, given a function that can be used to
|
||||
/// retrieve the value of previous transactions' transparent outputs that are being spent in
|
||||
/// this transaction.
|
||||
pub fn fee_paid<E, F>(&self, get_prevout: F) -> Result<Amount, E>
|
||||
where
|
||||
E: From<BalanceError>,
|
||||
F: FnMut(&OutPoint) -> Result<Amount, E>,
|
||||
{
|
||||
let value_balances = [
|
||||
self.transparent_bundle
|
||||
|
|
Loading…
Reference in New Issue