WIP
This commit is contained in:
parent
74c26bf87d
commit
d53b9446d3
|
@ -2,13 +2,14 @@ use std::cmp::min;
|
|||
use zcash_address::{AddressKind, ZcashAddress};
|
||||
use zcash_address::unified::{Container, Receiver};
|
||||
use zcash_primitives::memo::MemoBytes;
|
||||
use crate::note_selection::types::{PrivacyPolicy, Fill, Execution, Order, Pool, PoolAllocation, Destination, PoolPrecedence};
|
||||
use crate::note_selection::types::{PrivacyPolicy, Fill, Execution, Order, Pool, PoolAllocation, Destination, PoolPrecedence, PoolPriority};
|
||||
|
||||
/// Decode address and return it as an order
|
||||
///
|
||||
pub fn decode(id: u32, address: &str, amount: u64, memo: MemoBytes) -> anyhow::Result<Order> {
|
||||
let address = ZcashAddress::try_from_encoded(address)?;
|
||||
let mut order = Order::default();
|
||||
let mut precedence = order.priority.to_pool_precedence().clone();
|
||||
order.id = id;
|
||||
match address.kind {
|
||||
AddressKind::Sprout(_) => {}
|
||||
|
@ -17,7 +18,7 @@ pub fn decode(id: u32, address: &str, amount: u64, memo: MemoBytes) -> anyhow::R
|
|||
order.destinations[Pool::Sapling as usize] = Some(destination);
|
||||
}
|
||||
AddressKind::Unified(unified_address) => {
|
||||
for address in unified_address.items() {
|
||||
for (i, address) in unified_address.items().into_iter().enumerate() {
|
||||
match address {
|
||||
Receiver::Orchard(data) => {
|
||||
let destination = Destination::Orchard(data);
|
||||
|
@ -54,11 +55,12 @@ pub fn execute_orders(orders: &mut [Order], initial_pool: &PoolAllocation, use_t
|
|||
let mut fills = vec![];
|
||||
|
||||
for order in orders.iter_mut() {
|
||||
let order_precedence = order.priority.to_pool_precedence();
|
||||
// log::info!("Order {:?}", order);
|
||||
// Direct Shielded Fill - s2s, o2o
|
||||
// t2t only for fees
|
||||
if use_shielded {
|
||||
for &pool in precedence {
|
||||
for &pool in order_precedence {
|
||||
if pool == Pool::Transparent && !order.is_fee { continue }
|
||||
if order.destinations[pool as usize].is_some() {
|
||||
fill_order(pool, pool, order, initial_pool, &mut allocation, &mut fills);
|
||||
|
@ -68,7 +70,7 @@ pub fn execute_orders(orders: &mut [Order], initial_pool: &PoolAllocation, use_t
|
|||
|
||||
if privacy_policy != PrivacyPolicy::SamePoolOnly {
|
||||
// Indirect Shielded - z2z: s2o, o2s
|
||||
for &pool in precedence {
|
||||
for &pool in order_precedence {
|
||||
if order.destinations[pool as usize].is_none() { continue }
|
||||
if !use_shielded { continue }
|
||||
if let Some(from_pool) = pool.other_shielded() {
|
||||
|
@ -78,7 +80,7 @@ pub fn execute_orders(orders: &mut [Order], initial_pool: &PoolAllocation, use_t
|
|||
|
||||
if privacy_policy == PrivacyPolicy::AnyPool {
|
||||
// Other - s2t, o2t, t2s, t2o
|
||||
for &pool in precedence {
|
||||
for &pool in order_precedence {
|
||||
if order.destinations[pool as usize].is_none() { continue }
|
||||
match pool {
|
||||
Pool::Transparent if use_shielded => {
|
||||
|
@ -94,12 +96,12 @@ pub fn execute_orders(orders: &mut [Order], initial_pool: &PoolAllocation, use_t
|
|||
_ => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// t2t
|
||||
if use_transparent && order.destinations[Pool::Transparent as usize].is_some() {
|
||||
fill_order(Pool::Transparent, Pool::Transparent, order, initial_pool, &mut allocation, &mut fills);
|
||||
// t2t
|
||||
if use_transparent && order.destinations[Pool::Transparent as usize].is_some() {
|
||||
fill_order(Pool::Transparent, Pool::Transparent, order, initial_pool, &mut allocation, &mut fills);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use zcash_primitives::memo::MemoBytes;
|
|||
use crate::note_selection::decode;
|
||||
use crate::note_selection::fee::FeeCalculator;
|
||||
use crate::note_selection::fill::execute_orders;
|
||||
use crate::note_selection::types::{NoteSelectConfig, Order, PoolAllocation, UTXO, Destination, TransactionPlan, Fill, PoolPrecedence};
|
||||
use crate::note_selection::types::{NoteSelectConfig, Order, PoolAllocation, UTXO, Destination, TransactionPlan, Fill, PoolPrecedence, PoolPriority};
|
||||
|
||||
pub fn select_notes(allocation: &PoolAllocation, utxos: &[UTXO]) -> anyhow::Result<Vec<UTXO>> {
|
||||
let mut allocation = allocation.clone();
|
||||
|
@ -82,14 +82,6 @@ pub fn note_select_with_fee<F: FeeCalculator>(utxos: &[UTXO], orders: &mut [Orde
|
|||
fee = F::calculate_fee(¬es, &executor.fills);
|
||||
log::debug!("base fee: {}", fee);
|
||||
}
|
||||
let mut fee_order = Order {
|
||||
id: u32::MAX,
|
||||
destinations: ANY_DESTINATION,
|
||||
amount: fee,
|
||||
memo: MemoBytes::empty(),
|
||||
is_fee: true, // do not include in fee calculation
|
||||
filled: 0,
|
||||
};
|
||||
|
||||
// Favor the pools that are already used, because it may cause lower fees
|
||||
let pool_needed = executor.pool_used;
|
||||
|
@ -97,6 +89,15 @@ pub fn note_select_with_fee<F: FeeCalculator>(utxos: &[UTXO], orders: &mut [Orde
|
|||
let prec_2 = config.precedence.iter().filter(|&&p| pool_needed.0[p as usize] == 0);
|
||||
let fee_precedence: PoolPrecedence = prec_1.chain(prec_2).cloned().collect::<Vec<_>>().try_into().unwrap();
|
||||
log::debug!("Fee precedence: {:?}", fee_precedence);
|
||||
let mut fee_order = Order {
|
||||
id: u32::MAX,
|
||||
destinations: ANY_DESTINATION,
|
||||
priority: fee_precedence.try_into().unwrap(),
|
||||
amount: fee,
|
||||
memo: MemoBytes::empty(),
|
||||
is_fee: true, // do not include in fee calculation
|
||||
filled: 0,
|
||||
};
|
||||
|
||||
if !executor.execute(slice::from_mut(&mut fee_order), &fee_precedence)? {
|
||||
anyhow::bail!("Unsufficient Funds [fees]")
|
||||
|
|
|
@ -75,6 +75,7 @@ macro_rules! order {
|
|||
id: $id,
|
||||
amount: $q * 1000,
|
||||
destinations: $destinations,
|
||||
priority: PoolPriority::OST,
|
||||
filled: 0,
|
||||
is_fee: false,
|
||||
memo: MemoBytes::empty(),
|
||||
|
@ -176,7 +177,7 @@ fn test_example1() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":5000},{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":2}},"amount":7000},{"source":{"Sapling":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":12000},{"source":{"Orchard":{"id_note":4,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":10000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":4000}],"fee":20000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":5000},{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":2}},"amount":7000},{"source":{"Sapling":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":12000},{"source":{"Orchard":{"id_note":4,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":10000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":4000,"memo":[246]}],"fee":20000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -193,7 +194,7 @@ fn test_example2() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":5000},{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":2}},"amount":7000},{"source":{"Sapling":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":12000},{"source":{"Orchard":{"id_note":4,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":10000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":4000}],"fee":20000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":5000},{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":2}},"amount":7000},{"source":{"Sapling":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":12000},{"source":{"Orchard":{"id_note":4,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":10000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":4000,"memo":[246]}],"fee":20000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,7 @@ fn test_example3() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":100000},{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":160000},{"source":{"Orchard":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":70000},{"source":{"Orchard":{"id_note":4,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000},{"id_order":2,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":20000},{"id_order":3,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":30000},{"id_order":4,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":40000},{"id_order":5,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":50000},{"id_order":6,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":60000},{"id_order":7,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":30000},{"id_order":7,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":40000},{"id_order":4294967295,"destination":{"Transparent":"c7b7b3d299bd173ea278d792b1bd5fbdd11afe34"},"amount":55000}],"fee":45000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":100000},{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":160000},{"source":{"Orchard":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":70000},{"source":{"Orchard":{"id_note":4,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":2,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":20000,"memo":[246]},{"id_order":3,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":30000,"memo":[246]},{"id_order":4,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":40000,"memo":[246]},{"id_order":5,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":50000,"memo":[246]},{"id_order":6,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":40000,"memo":[246]},{"id_order":6,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":20000,"memo":[246]},{"id_order":7,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":70000,"memo":[246]},{"id_order":4294967295,"destination":{"Transparent":"c7b7b3d299bd173ea278d792b1bd5fbdd11afe34"},"amount":55000,"memo":[246]}],"fee":45000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -223,6 +224,8 @@ fn test_example4() {
|
|||
let _ = env_logger::try_init();
|
||||
let mut config = NoteSelectConfig::new(CHANGE_ADDRESS);
|
||||
config.use_transparent = true;
|
||||
config.use_shielded = false;
|
||||
config.privacy_policy = PrivacyPolicy::AnyPool;
|
||||
|
||||
let utxos = [utxo!(1, 50), sapling!(2, 50), orchard!(3, 50)];
|
||||
let mut orders = [t!(1, 10)];
|
||||
|
@ -231,7 +234,7 @@ fn test_example4() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Transparent":"c7b7b3d299bd173ea278d792b1bd5fbdd11afe34"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Transparent":"c7b7b3d299bd173ea278d792b1bd5fbdd11afe34"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -250,7 +253,7 @@ fn test_example5() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Sapling":"9fae6f28c245e095abf8c6730098e110bb67ae3e73302406b2b9c6d6b672ca9e64e14ef0560062a91dd429"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Sapling":"9fae6f28c245e095abf8c6730098e110bb67ae3e73302406b2b9c6d6b672ca9e64e14ef0560062a91dd429"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -269,7 +272,7 @@ fn test_example5b() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Orchard":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Orchard":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
/// A simple z2t sapling
|
||||
|
@ -288,7 +291,7 @@ fn test_example6() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Sapling":"9fae6f28c245e095abf8c6730098e110bb67ae3e73302406b2b9c6d6b672ca9e64e14ef0560062a91dd429"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Sapling":"9fae6f28c245e095abf8c6730098e110bb67ae3e73302406b2b9c6d6b672ca9e64e14ef0560062a91dd429"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -309,7 +312,7 @@ fn test_example7() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Orchard":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Orchard":{"id_note":3,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","rho":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Transparent":"0000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Orchard":"2b6dca785c846b3752d13150e1c8f197ba9c8ead0a8bee1b3a52df0ad866362941e32d1b69d438b257cf82"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -330,7 +333,7 @@ fn test_example8() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Transparent":"c7b7b3d299bd173ea278d792b1bd5fbdd11afe34"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Transparent":{"txid":"0000000000000000000000000000000000000000000000000000000000000000","index":1}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Sapling":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Transparent":"c7b7b3d299bd173ea278d792b1bd5fbdd11afe34"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
||||
|
@ -348,6 +351,6 @@ fn test_example9() {
|
|||
println!("{}", serde_json::to_string(&tx_plan).unwrap());
|
||||
|
||||
let tx_plan_json = serde_json::to_value(&tx_plan).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000},{"id_order":4294967295,"destination":{"Sapling":"9fae6f28c245e095abf8c6730098e110bb67ae3e73302406b2b9c6d6b672ca9e64e14ef0560062a91dd429"},"amount":30000}],"fee":10000}"#).unwrap();
|
||||
let expected: Value = serde_json::from_str(r#"{"spends":[{"source":{"Sapling":{"id_note":2,"diversifier":"0000000000000000000000","rseed":"0000000000000000000000000000000000000000000000000000000000000000","witness":""}},"amount":50000}],"outputs":[{"id_order":1,"destination":{"Orchard":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"amount":10000,"memo":[246]},{"id_order":4294967295,"destination":{"Sapling":"9fae6f28c245e095abf8c6730098e110bb67ae3e73302406b2b9c6d6b672ca9e64e14ef0560062a91dd429"},"amount":30000,"memo":[246]}],"fee":10000}"#).unwrap();
|
||||
assert_eq!(tx_plan_json, expected);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::ops::{Add, Sub};
|
||||
use anyhow::anyhow;
|
||||
use zcash_primitives::memo::MemoBytes;
|
||||
use serde::Serialize;
|
||||
use serde_with::serde_as;
|
||||
|
@ -52,6 +53,7 @@ pub enum Pool {
|
|||
pub struct Order {
|
||||
pub id: u32,
|
||||
pub destinations: [Option<Destination>; 3],
|
||||
pub priority: PoolPriority,
|
||||
pub amount: u64,
|
||||
#[serde(with = "MemoBytesProxy")] pub memo: MemoBytes,
|
||||
pub is_fee: bool,
|
||||
|
@ -83,6 +85,7 @@ impl Default for Order {
|
|||
Order {
|
||||
id: 0,
|
||||
destinations: [None; 3],
|
||||
priority: PoolPriority::OST,
|
||||
amount: 0,
|
||||
memo: MemoBytes::empty(),
|
||||
is_fee: false,
|
||||
|
@ -206,3 +209,41 @@ impl Destination {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Debug)]
|
||||
pub enum PoolPriority {
|
||||
TSO = 1,
|
||||
OST = 2,
|
||||
TOS = 3,
|
||||
SOT = 4,
|
||||
OTS = 5,
|
||||
STO = 6,
|
||||
}
|
||||
|
||||
impl PoolPriority {
|
||||
const VALUES: [PoolPriority; 6] = [ PoolPriority::TSO, PoolPriority::OST, PoolPriority::TOS, PoolPriority::SOT, PoolPriority::OTS, PoolPriority::STO];
|
||||
pub fn to_pool_precedence(&self) -> &'static PoolPrecedence {
|
||||
match self {
|
||||
PoolPriority::TSO => &[ Pool:: Transparent, Pool::Sapling, Pool::Orchard ],
|
||||
PoolPriority::OST => &[ Pool::Orchard, Pool::Sapling, Pool:: Transparent ],
|
||||
PoolPriority::TOS => &[ Pool:: Transparent, Pool::Orchard, Pool::Sapling ],
|
||||
PoolPriority::SOT => &[ Pool::Sapling, Pool::Orchard, Pool:: Transparent ],
|
||||
PoolPriority::OTS => &[ Pool::Orchard, Pool:: Transparent, Pool::Sapling ],
|
||||
PoolPriority::STO => &[ Pool::Sapling, Pool:: Transparent, Pool::Orchard ],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<PoolPrecedence> for PoolPriority {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: PoolPrecedence) -> Result<Self, Self::Error> {
|
||||
let p: [Pool; 3] = value.try_into().unwrap();
|
||||
for pp in PoolPriority::VALUES {
|
||||
if p == *pp.to_pool_precedence() {
|
||||
return Ok(pp)
|
||||
}
|
||||
}
|
||||
Err(anyhow!("Pool preference invalid"))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue