mirror of
https://github.com/Qortal/piratewallet-light-cli.git
synced 2025-07-30 03:41:28 +00:00
Read UTXOs from walletTx
This commit is contained in:
@@ -273,7 +273,7 @@ impl LightClient {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Collect UTXOs
|
// Collect UTXOs
|
||||||
let utxos = self.wallet.utxos.read().unwrap().iter()
|
let utxos = self.wallet.get_utxos().iter()
|
||||||
.map(|utxo| {
|
.map(|utxo| {
|
||||||
object!{
|
object!{
|
||||||
"created_in_block" => utxo.height,
|
"created_in_block" => utxo.height,
|
||||||
@@ -457,6 +457,11 @@ impl LightClient {
|
|||||||
// Get the end height to scan to.
|
// Get the end height to scan to.
|
||||||
let mut end_height = std::cmp::min(last_scanned_height + 1000, last_block);
|
let mut end_height = std::cmp::min(last_scanned_height + 1000, last_block);
|
||||||
|
|
||||||
|
// If there's nothing to scan, just return
|
||||||
|
if last_scanned_height == last_block {
|
||||||
|
return "".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
// Count how many bytes we've downloaded
|
// Count how many bytes we've downloaded
|
||||||
let bytes_downloaded = Arc::new(AtomicUsize::new(0));
|
let bytes_downloaded = Arc::new(AtomicUsize::new(0));
|
||||||
|
|
||||||
@@ -553,20 +558,6 @@ impl LightClient {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Finally, fetch the UTXOs
|
|
||||||
|
|
||||||
// Get all the UTXOs for our transparent addresses, clearing out the current list
|
|
||||||
self.wallet.clear_utxos();
|
|
||||||
// Fetch UTXOs
|
|
||||||
self.wallet.tkeys.iter()
|
|
||||||
.map( |sk| LightWallet::address_from_sk(&sk))
|
|
||||||
.for_each( |taddr| {
|
|
||||||
let wallet = self.wallet.clone();
|
|
||||||
self.fetch_utxos(taddr, move |utxo| {
|
|
||||||
wallet.add_utxo(&utxo);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
responses.join("\n")
|
responses.join("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,66 +628,6 @@ impl LightClient {
|
|||||||
tokio::runtime::current_thread::Runtime::new().unwrap().block_on(say_hello).unwrap();
|
tokio::runtime::current_thread::Runtime::new().unwrap().block_on(say_hello).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_utxos<F : 'static + std::marker::Send>(&self, address: String, c: F)
|
|
||||||
where F : Fn(crate::lightwallet::Utxo) {
|
|
||||||
let uri: http::Uri = self.server.parse().unwrap();
|
|
||||||
|
|
||||||
let dst = Destination::try_from_uri(uri.clone()).unwrap();
|
|
||||||
let connector = util::Connector::new(HttpConnector::new(4));
|
|
||||||
let settings = client::Builder::new().http2_only(true).clone();
|
|
||||||
let mut make_client = client::Connect::with_builder(connector, settings);
|
|
||||||
|
|
||||||
let say_hello = make_client
|
|
||||||
.make_service(dst)
|
|
||||||
.map_err(|e| panic!("connect error: {:?}", e))
|
|
||||||
.and_then(move |conn| {
|
|
||||||
|
|
||||||
let conn = tower_request_modifier::Builder::new()
|
|
||||||
.set_origin(uri)
|
|
||||||
.build(conn)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Wait until the client is ready...
|
|
||||||
CompactTxStreamer::new(conn)
|
|
||||||
.ready()
|
|
||||||
.map_err(|e| eprintln!("streaming error {:?}", e))
|
|
||||||
})
|
|
||||||
.and_then(move |mut client| {
|
|
||||||
|
|
||||||
let br = Request::new(TransparentAddress{ address });
|
|
||||||
client
|
|
||||||
.get_utxos(br)
|
|
||||||
.map_err(|e| {
|
|
||||||
eprintln!("RouteChat request failed; err={:?}", e);
|
|
||||||
})
|
|
||||||
.and_then(move |response| {
|
|
||||||
let inbound = response.into_inner();
|
|
||||||
inbound.for_each(move |b| {
|
|
||||||
let mut txid_bytes = [0u8; 32];
|
|
||||||
txid_bytes.copy_from_slice(&b.txid);
|
|
||||||
|
|
||||||
let u = crate::lightwallet::Utxo {
|
|
||||||
address: b.address.unwrap().address,
|
|
||||||
txid: TxId {0: txid_bytes},
|
|
||||||
output_index: b.output_index,
|
|
||||||
script: b.script.to_vec(),
|
|
||||||
height: b.height as i32,
|
|
||||||
value: b.value,
|
|
||||||
spent: None,
|
|
||||||
unconfirmed_spent: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
c(u);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
.map_err(|e| eprintln!("gRPC inbound stream error: {:?}", e))
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
tokio::runtime::current_thread::Runtime::new().unwrap().block_on(say_hello).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fetch_transparent_txids<F : 'static + std::marker::Send>(&self, address: String,
|
pub fn fetch_transparent_txids<F : 'static + std::marker::Send>(&self, address: String,
|
||||||
start_height: u64, end_height: u64,c: F)
|
start_height: u64, end_height: u64,c: F)
|
||||||
where F : Fn(&[u8], u64) {
|
where F : Fn(&[u8], u64) {
|
||||||
|
@@ -469,6 +469,7 @@ impl WalletTx {
|
|||||||
let txid = TxId{0: txid_bytes};
|
let txid = TxId{0: txid_bytes};
|
||||||
|
|
||||||
let notes = Vector::read(&mut reader, |r| SaplingNoteData::read(r))?;
|
let notes = Vector::read(&mut reader, |r| SaplingNoteData::read(r))?;
|
||||||
|
let utxos = Vector::read(&mut reader, |r| Utxo::read(r))?;
|
||||||
|
|
||||||
let total_shielded_value_spent = reader.read_u64::<LittleEndian>()?;
|
let total_shielded_value_spent = reader.read_u64::<LittleEndian>()?;
|
||||||
let total_transparent_value_spent = reader.read_u64::<LittleEndian>()?;
|
let total_transparent_value_spent = reader.read_u64::<LittleEndian>()?;
|
||||||
@@ -477,7 +478,7 @@ impl WalletTx {
|
|||||||
block,
|
block,
|
||||||
txid,
|
txid,
|
||||||
notes,
|
notes,
|
||||||
utxos: vec![],
|
utxos,
|
||||||
total_shielded_value_spent,
|
total_shielded_value_spent,
|
||||||
total_transparent_value_spent
|
total_transparent_value_spent
|
||||||
})
|
})
|
||||||
@@ -491,6 +492,7 @@ impl WalletTx {
|
|||||||
writer.write_all(&self.txid.0)?;
|
writer.write_all(&self.txid.0)?;
|
||||||
|
|
||||||
Vector::write(&mut writer, &self.notes, |w, nd| nd.write(w))?;
|
Vector::write(&mut writer, &self.notes, |w, nd| nd.write(w))?;
|
||||||
|
Vector::write(&mut writer, &self.utxos, |w, u| u.write(w))?;
|
||||||
|
|
||||||
writer.write_u64::<LittleEndian>(self.total_shielded_value_spent)?;
|
writer.write_u64::<LittleEndian>(self.total_shielded_value_spent)?;
|
||||||
writer.write_u64::<LittleEndian>(self.total_transparent_value_spent)?;
|
writer.write_u64::<LittleEndian>(self.total_transparent_value_spent)?;
|
||||||
@@ -539,10 +541,6 @@ pub struct LightWallet {
|
|||||||
// Transparent keys. TODO: Make it not pubic
|
// Transparent keys. TODO: Make it not pubic
|
||||||
pub tkeys: Vec<secp256k1::SecretKey>,
|
pub tkeys: Vec<secp256k1::SecretKey>,
|
||||||
|
|
||||||
// Current UTXOs that can be spent.
|
|
||||||
// TODO: Remove this, and read from txs.values().utxos
|
|
||||||
pub utxos: Arc<RwLock<Vec<Utxo>>>,
|
|
||||||
|
|
||||||
blocks: Arc<RwLock<Vec<BlockData>>>,
|
blocks: Arc<RwLock<Vec<BlockData>>>,
|
||||||
pub txs: Arc<RwLock<HashMap<TxId, WalletTx>>>,
|
pub txs: Arc<RwLock<HashMap<TxId, WalletTx>>>,
|
||||||
}
|
}
|
||||||
@@ -597,7 +595,6 @@ impl LightWallet {
|
|||||||
extfvks: vec![extfvk],
|
extfvks: vec![extfvk],
|
||||||
address: vec![address],
|
address: vec![address],
|
||||||
tkeys: vec![tpk],
|
tkeys: vec![tpk],
|
||||||
utxos: Arc::new(RwLock::new(vec![])),
|
|
||||||
blocks: Arc::new(RwLock::new(vec![])),
|
blocks: Arc::new(RwLock::new(vec![])),
|
||||||
txs: Arc::new(RwLock::new(HashMap::new())),
|
txs: Arc::new(RwLock::new(HashMap::new())),
|
||||||
})
|
})
|
||||||
@@ -627,8 +624,6 @@ impl LightWallet {
|
|||||||
reader.read_exact(&mut tpk_bytes)?;
|
reader.read_exact(&mut tpk_bytes)?;
|
||||||
let tpk = secp256k1::SecretKey::from_slice(&tpk_bytes).unwrap();
|
let tpk = secp256k1::SecretKey::from_slice(&tpk_bytes).unwrap();
|
||||||
|
|
||||||
let utxos = Vector::read(&mut reader, |r| Utxo::read(r))?;
|
|
||||||
|
|
||||||
let blocks = Vector::read(&mut reader, |r| BlockData::read(r))?;
|
let blocks = Vector::read(&mut reader, |r| BlockData::read(r))?;
|
||||||
|
|
||||||
let txs_tuples = Vector::read(&mut reader, |r| {
|
let txs_tuples = Vector::read(&mut reader, |r| {
|
||||||
@@ -645,7 +640,6 @@ impl LightWallet {
|
|||||||
extfvks: extfvks,
|
extfvks: extfvks,
|
||||||
address: addresses,
|
address: addresses,
|
||||||
tkeys: vec![tpk],
|
tkeys: vec![tpk],
|
||||||
utxos: Arc::new(RwLock::new(utxos)),
|
|
||||||
blocks: Arc::new(RwLock::new(blocks)),
|
blocks: Arc::new(RwLock::new(blocks)),
|
||||||
txs: Arc::new(RwLock::new(txs))
|
txs: Arc::new(RwLock::new(txs))
|
||||||
})
|
})
|
||||||
@@ -667,8 +661,6 @@ impl LightWallet {
|
|||||||
// TODO: This only writes the first key for now
|
// TODO: This only writes the first key for now
|
||||||
writer.write_all(&self.tkeys[0][..])?;
|
writer.write_all(&self.tkeys[0][..])?;
|
||||||
|
|
||||||
Vector::write(&mut writer, &self.utxos.read().unwrap(), |w, u| u.write(w))?;
|
|
||||||
|
|
||||||
Vector::write(&mut writer, &self.blocks.read().unwrap(), |w, b| b.write(w))?;
|
Vector::write(&mut writer, &self.blocks.read().unwrap(), |w, b| b.write(w))?;
|
||||||
|
|
||||||
// The hashmap, write as a set of tuples
|
// The hashmap, write as a set of tuples
|
||||||
@@ -829,8 +821,20 @@ impl LightWallet {
|
|||||||
.sum::<u64>()
|
.sum::<u64>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all (unspent) utxos. Unconfirmed spent utxos are included
|
||||||
|
pub fn get_utxos(&self) -> Vec<Utxo> {
|
||||||
|
let txs = self.txs.read().unwrap();
|
||||||
|
|
||||||
|
txs.values()
|
||||||
|
.flat_map(|tx| {
|
||||||
|
tx.utxos.iter().filter(|utxo| utxo.spent.is_none())
|
||||||
|
})
|
||||||
|
.map(|utxo| utxo.clone())
|
||||||
|
.collect::<Vec<Utxo>>()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tbalance(&self, addr: Option<String>) -> u64 {
|
pub fn tbalance(&self, addr: Option<String>) -> u64 {
|
||||||
self.utxos.read().unwrap().iter()
|
self.get_utxos().iter()
|
||||||
.filter(|utxo| {
|
.filter(|utxo| {
|
||||||
match addr.clone() {
|
match addr.clone() {
|
||||||
Some(a) => utxo.address == a,
|
Some(a) => utxo.address == a,
|
||||||
@@ -1006,16 +1010,6 @@ impl LightWallet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_utxos(&self) {
|
|
||||||
let mut utxos = self.utxos.write().unwrap();
|
|
||||||
utxos.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_utxo(&self, utxo: &Utxo) {
|
|
||||||
let mut utxos = self.utxos.write().unwrap();
|
|
||||||
utxos.push(utxo.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scan_block(&self, block: &[u8]) -> bool {
|
pub fn scan_block(&self, block: &[u8]) -> bool {
|
||||||
let block: CompactBlock = match parse_from_bytes(block) {
|
let block: CompactBlock = match parse_from_bytes(block) {
|
||||||
Ok(block) => block,
|
Ok(block) => block,
|
||||||
@@ -1240,7 +1234,7 @@ impl LightWallet {
|
|||||||
// Specifically, if you send an outgoing transaction that is sent to a shielded address,
|
// Specifically, if you send an outgoing transaction that is sent to a shielded address,
|
||||||
// ZecWallet will add all your t-address funds into that transaction, and send them to your shielded
|
// ZecWallet will add all your t-address funds into that transaction, and send them to your shielded
|
||||||
// address as change.
|
// address as change.
|
||||||
let tinputs = self.utxos.read().unwrap().iter()
|
let tinputs = self.get_utxos().iter()
|
||||||
.map(|utxo| {
|
.map(|utxo| {
|
||||||
let outpoint: OutPoint = utxo.to_outpoint();
|
let outpoint: OutPoint = utxo.to_outpoint();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user