Pool transfer
This commit is contained in:
parent
7e4102b5ae
commit
39eeec8583
|
@ -120,7 +120,7 @@ apple_metal = ["metal", "objc", "block"]
|
||||||
|
|
||||||
[dependencies.zcash_params]
|
[dependencies.zcash_params]
|
||||||
git = "https://github.com/hhanh00/zcash-params.git"
|
git = "https://github.com/hhanh00/zcash-params.git"
|
||||||
rev = "86bb1d12e0230c0bf40758fd7d57f3e4c104e36e"
|
rev = "9fabe6aa8b3ca7099dc39db16fe126129c7755b8"
|
||||||
|
|
||||||
[dependencies.zcash_client_backend]
|
[dependencies.zcash_client_backend]
|
||||||
git = "https://github.com/hhanh00/librustzcash.git"
|
git = "https://github.com/hhanh00/librustzcash.git"
|
||||||
|
|
|
@ -105,6 +105,13 @@ void rescan_from(uint32_t height);
|
||||||
|
|
||||||
struct CResult_u64 get_taddr_balance(uint8_t coin, uint32_t id_account);
|
struct CResult_u64 get_taddr_balance(uint8_t coin, uint32_t id_account);
|
||||||
|
|
||||||
|
struct CResult_____c_char transfer_pools(uint8_t coin,
|
||||||
|
uint32_t account,
|
||||||
|
uint8_t from_pool,
|
||||||
|
uint8_t to_pool,
|
||||||
|
uint64_t amount,
|
||||||
|
uint32_t confirmations);
|
||||||
|
|
||||||
struct CResult_____c_char shield_taddr(uint8_t coin, uint32_t account, uint32_t confirmations);
|
struct CResult_____c_char shield_taddr(uint8_t coin, uint32_t account, uint32_t confirmations);
|
||||||
|
|
||||||
void scan_transparent_accounts(uint32_t gap_limit);
|
void scan_transparent_accounts(uint32_t gap_limit);
|
||||||
|
@ -116,7 +123,7 @@ struct CResult_____c_char prepare_multi_payment(uint8_t coin,
|
||||||
|
|
||||||
struct CResult_____c_char transaction_report(uint8_t coin, char *plan);
|
struct CResult_____c_char transaction_report(uint8_t coin, char *plan);
|
||||||
|
|
||||||
struct CResult_____c_char sign(uint8_t coin, uint32_t account, char *tx, int64_t _port);
|
struct CResult_____c_char sign(uint8_t coin, uint32_t account, char *tx_plan, int64_t _port);
|
||||||
|
|
||||||
struct CResult_____c_char sign_and_broadcast(uint8_t coin, uint32_t account, char *tx_plan);
|
struct CResult_____c_char sign_and_broadcast(uint8_t coin, uint32_t account, char *tx_plan);
|
||||||
|
|
||||||
|
|
|
@ -365,16 +365,14 @@ pub fn derive_keys(
|
||||||
pub fn get_unified_address(
|
pub fn get_unified_address(
|
||||||
coin: u8,
|
coin: u8,
|
||||||
id_account: u32,
|
id_account: u32,
|
||||||
t: bool,
|
address_type: u8,
|
||||||
s: bool,
|
|
||||||
o: bool,
|
|
||||||
) -> anyhow::Result<String> {
|
) -> anyhow::Result<String> {
|
||||||
let c = CoinConfig::get(coin);
|
let c = CoinConfig::get(coin);
|
||||||
let db = c.db()?;
|
let db = c.db()?;
|
||||||
let tpe = UnifiedAddressType {
|
let tpe = UnifiedAddressType {
|
||||||
transparent: t,
|
transparent: address_type & 1 != 0,
|
||||||
sapling: s,
|
sapling: address_type & 2 != 0,
|
||||||
orchard: o,
|
orchard: address_type & 4 != 0,
|
||||||
};
|
};
|
||||||
let address = crate::get_unified_address(c.chain.network(), &db, id_account, Some(tpe))?; // use ua settings
|
let address = crate::get_unified_address(c.chain.network(), &db, id_account, Some(tpe))?; // use ua settings
|
||||||
Ok(address)
|
Ok(address)
|
||||||
|
@ -390,11 +388,7 @@ fn get_sapling_address(coin: u8, id_account: u32) -> anyhow::Result<String> {
|
||||||
pub fn get_address(coin: u8, id_account: u32, address_type: u8) -> anyhow::Result<String> {
|
pub fn get_address(coin: u8, id_account: u32, address_type: u8) -> anyhow::Result<String> {
|
||||||
let c = CoinConfig::get(coin);
|
let c = CoinConfig::get(coin);
|
||||||
let address = if c.chain.has_unified() {
|
let address = if c.chain.has_unified() {
|
||||||
let t = address_type & 1 != 0;
|
get_unified_address(coin, id_account, address_type)?
|
||||||
let s = address_type & 2 != 0;
|
|
||||||
let o = address_type & 4 != 0;
|
|
||||||
|
|
||||||
get_unified_address(coin, id_account, t, s, o)?
|
|
||||||
} else {
|
} else {
|
||||||
get_sapling_address(coin, id_account)?
|
get_sapling_address(coin, id_account)?
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@ use std::path::Path;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use tokio::sync::Semaphore;
|
use tokio::sync::Semaphore;
|
||||||
use zcash_primitives::transaction::builder::Progress;
|
use zcash_primitives::transaction::builder::Progress;
|
||||||
|
use crate::api::payment_v2::AmountOrMax;
|
||||||
|
|
||||||
static mut POST_COBJ: Option<ffi::DartPostCObjectFnType> = None;
|
static mut POST_COBJ: Option<ffi::DartPostCObjectFnType> = None;
|
||||||
|
|
||||||
|
@ -416,6 +417,24 @@ pub async unsafe extern "C" fn get_taddr_balance(coin: u8, id_account: u32) -> C
|
||||||
to_cresult(res)
|
to_cresult(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
#[no_mangle]
|
||||||
|
pub async unsafe extern "C" fn transfer_pools(
|
||||||
|
coin: u8,
|
||||||
|
account: u32,
|
||||||
|
from_pool: u8, to_pool: u8,
|
||||||
|
amount: u64,
|
||||||
|
confirmations: u32,
|
||||||
|
) -> CResult<*mut c_char> {
|
||||||
|
let res = async move {
|
||||||
|
let tx_plan = crate::api::payment_v2::transfer_pools(coin, account, from_pool, to_pool,
|
||||||
|
AmountOrMax::Amount(amount), confirmations).await?;
|
||||||
|
let tx_plan = serde_json::to_string(&tx_plan)?;
|
||||||
|
Ok::<_, anyhow::Error>(tx_plan)
|
||||||
|
};
|
||||||
|
to_cresult_str(res.await)
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub async unsafe extern "C" fn shield_taddr(
|
pub async unsafe extern "C" fn shield_taddr(
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub async fn build_tx_plan(
|
||||||
let checkpoint_height = get_checkpoint_height(&db, last_height, confirmations)?;
|
let checkpoint_height = get_checkpoint_height(&db, last_height, confirmations)?;
|
||||||
(fvk, checkpoint_height)
|
(fvk, checkpoint_height)
|
||||||
};
|
};
|
||||||
let change_address = get_unified_address(coin, account, true, true, true)?;
|
let change_address = get_unified_address(coin, account, 7)?;
|
||||||
let context = TxBuilderContext::from_height(coin, checkpoint_height)?;
|
let context = TxBuilderContext::from_height(coin, checkpoint_height)?;
|
||||||
|
|
||||||
let mut orders = vec![];
|
let mut orders = vec![];
|
||||||
|
@ -144,17 +144,36 @@ pub async fn build_max_tx(
|
||||||
Err(TransactionBuilderError::TxTooComplex)
|
Err(TransactionBuilderError::TxTooComplex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a transaction that shields the transparent balance
|
pub enum AmountOrMax {
|
||||||
pub async fn shield_taddr(coin: u8, account: u32, confirmations: u32) -> anyhow::Result<String> {
|
Amount(u64),
|
||||||
let address = get_unified_address(coin, account, false, true, true)?; // get our own unified address
|
Max
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn transfer_pools(coin: u8, account: u32, from_pool: u8, to_pool: u8, amount: AmountOrMax,
|
||||||
|
confirmations: u32) -> anyhow::Result<TransactionPlan> {
|
||||||
|
let address = get_unified_address(coin, account, to_pool)?; // get our own unified address
|
||||||
|
let a = match amount {
|
||||||
|
AmountOrMax::Amount(a) => a,
|
||||||
|
AmountOrMax::Max => 0,
|
||||||
|
};
|
||||||
let recipient = RecipientMemo {
|
let recipient = RecipientMemo {
|
||||||
address,
|
address,
|
||||||
amount: 0,
|
amount: a,
|
||||||
memo: Memo::from_str("Shield Transparent Balance")?,
|
memo: Memo::from_str("Shield Transparent Balance")?,
|
||||||
max_amount_per_note: 0,
|
max_amount_per_note: 0,
|
||||||
};
|
};
|
||||||
let last_height = get_latest_height().await?;
|
let last_height = get_latest_height().await?;
|
||||||
let tx_plan = build_max_tx(coin, account, last_height, &recipient, 2, confirmations).await?;
|
let tx_plan = match amount {
|
||||||
|
AmountOrMax::Amount(_) => build_tx_plan(coin, account, last_height, slice::from_ref(&recipient),
|
||||||
|
!from_pool, confirmations).await?,
|
||||||
|
AmountOrMax::Max => build_max_tx(coin, account, last_height, &recipient, !from_pool, confirmations).await?,
|
||||||
|
};
|
||||||
|
Ok(tx_plan)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Make a transaction that shields the transparent balance
|
||||||
|
pub async fn shield_taddr(coin: u8, account: u32, confirmations: u32) -> anyhow::Result<String> {
|
||||||
|
let tx_plan = transfer_pools(coin, account, 1, 6, AmountOrMax::Max, confirmations).await?;
|
||||||
let tx_id = sign_and_broadcast(coin, account, &tx_plan).await?;
|
let tx_id = sign_and_broadcast(coin, account, &tx_plan).await?;
|
||||||
log::info!("TXID: {}", tx_id);
|
log::info!("TXID: {}", tx_id);
|
||||||
Ok(tx_id)
|
Ok(tx_id)
|
||||||
|
|
|
@ -633,14 +633,15 @@ impl DbAdapter {
|
||||||
&self,
|
&self,
|
||||||
account: u32,
|
account: u32,
|
||||||
checkpoint_height: u32,
|
checkpoint_height: u32,
|
||||||
|
orchard: bool,
|
||||||
) -> anyhow::Result<Vec<UTXO>> {
|
) -> anyhow::Result<Vec<UTXO>> {
|
||||||
let mut notes = vec![];
|
let mut notes = vec![];
|
||||||
|
|
||||||
let mut statement = self.connection.prepare(
|
let mut statement = self.connection.prepare(
|
||||||
"SELECT id_note, diversifier, value, rcm, witness FROM received_notes r, sapling_witnesses w WHERE spent IS NULL AND account = ?2 AND rho IS NULL
|
"SELECT id_note, diversifier, value, rcm, witness FROM received_notes r, sapling_witnesses w WHERE spent IS NULL AND account = ?2 AND rho IS NULL
|
||||||
AND (r.excluded IS NULL OR NOT r.excluded) AND w.height = ?1
|
AND (r.excluded IS NULL OR NOT r.excluded) AND w.height = ?1 AND r.orchard = ?3
|
||||||
AND r.id_note = w.note")?;
|
AND r.id_note = w.note")?;
|
||||||
let rows = statement.query_map(params![checkpoint_height, account], |row| {
|
let rows = statement.query_map(params![checkpoint_height, account, orchard], |row| {
|
||||||
let id_note: u32 = row.get(0)?;
|
let id_note: u32 = row.get(0)?;
|
||||||
let diversifier: Vec<u8> = row.get(1)?;
|
let diversifier: Vec<u8> = row.get(1)?;
|
||||||
let amount: i64 = row.get(2)?;
|
let amount: i64 = row.get(2)?;
|
||||||
|
|
|
@ -728,7 +728,7 @@ fn test_tx_plan() {
|
||||||
&Network::MainNetwork,
|
&Network::MainNetwork,
|
||||||
"",
|
"",
|
||||||
0,
|
0,
|
||||||
&Hash::default(),
|
None,
|
||||||
&utxos,
|
&utxos,
|
||||||
&orders,
|
&orders,
|
||||||
&TransactionBuilderConfig {
|
&TransactionBuilderConfig {
|
||||||
|
|
|
@ -16,7 +16,10 @@ pub async fn fetch_utxos(
|
||||||
let db = coin.db.as_ref().unwrap();
|
let db = coin.db.as_ref().unwrap();
|
||||||
let db = db.lock().unwrap();
|
let db = db.lock().unwrap();
|
||||||
if excluded_flags & 2 == 0 {
|
if excluded_flags & 2 == 0 {
|
||||||
utxos.extend(db.get_unspent_received_notes(account, checkpoint_height)?);
|
utxos.extend(db.get_unspent_received_notes(account, checkpoint_height, false)?);
|
||||||
|
}
|
||||||
|
if excluded_flags & 4 == 0 {
|
||||||
|
utxos.extend(db.get_unspent_received_notes(account, checkpoint_height, true)?);
|
||||||
}
|
}
|
||||||
Ok(utxos)
|
Ok(utxos)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue