This commit is contained in:
Hanh 2022-12-30 23:29:59 +08:00
parent 74d8a5f04c
commit d43c4884b8
8 changed files with 372 additions and 33 deletions

View File

@ -43,6 +43,7 @@ serde_json = "1.0.64"
serde_with = { version = "2", features = ["hex"] }
serde-hex = "0.1.0"
bincode = "1.3.3"
flatbuffers = "22"
tokio = { version = "^1.6", features = ["macros", "rt-multi-thread", "time"] }
tokio-stream = "0.1.7"
protobuf = "3.0.2"

View File

@ -132,6 +132,8 @@ typedef struct CResult______u8 {
#define Spending_VT_RECIPIENT 4
#define AddressBalance_VT_INDEX 4
void dummy_export(void);
void dart_post_cobject(DartPostCObjectFnType ptr);
@ -213,7 +215,7 @@ struct CResult_____c_char shield_taddr(uint8_t coin,
uint64_t amount,
uint32_t confirmations);
void scan_transparent_accounts(uint32_t gap_limit);
struct CResult______u8 scan_transparent_accounts(uint32_t gap_limit);
struct CResult_____c_char prepare_multi_payment(uint8_t coin,
uint32_t account,
@ -310,13 +312,14 @@ struct CResult______u8 get_contacts(uint8_t coin);
struct CResult______u8 get_pnl_txs(uint8_t coin, uint32_t id, uint32_t timestamp);
struct CResult______u8 get_historical_prices(uint8_t coin,
uint32_t id,
uint32_t timestamp,
char *currency);
struct CResult______u8 get_historical_prices(uint8_t coin, uint32_t timestamp, char *currency);
struct CResult______u8 get_spendings(uint8_t coin, uint32_t id, uint32_t timestamp);
struct CResult_u8 update_excluded(uint8_t coin, uint32_t id, bool excluded);
struct CResult_u8 invert_excluded(uint8_t coin, uint32_t id);
bool has_cuda(void);
bool has_metal(void);

View File

@ -21,6 +21,7 @@ use zcash_address::{ToAddress, ZcashAddress};
use zcash_client_backend::encoding::{decode_extended_full_viewing_key, encode_payment_address};
use zcash_client_backend::keys::UnifiedFullViewingKey;
use zcash_primitives::consensus::Parameters;
use crate::db::data_generated::fb::{AddressBalance, AddressBalanceArgs, AddressBalanceVec, AddressBalanceVecArgs};
/// Create a new account
/// # Arguments
@ -260,11 +261,28 @@ pub async fn get_taddr_balance(coin: u8, id_account: u32) -> anyhow::Result<u64>
/// is exceeded and no balance was found
/// # Arguments
/// * `gap_limit`: number of accounts with 0 balance before the scan stops
pub async fn scan_transparent_accounts(gap_limit: usize) -> anyhow::Result<()> {
pub async fn scan_transparent_accounts(gap_limit: usize) -> anyhow::Result<Vec<u8>> {
let c = CoinConfig::get_active();
let mut client = c.connect_lwd().await?;
crate::taddr::scan_transparent_accounts(c.chain.network(), &mut client, gap_limit).await?;
Ok(())
let addresses = crate::taddr::scan_transparent_accounts(c.chain.network(), &mut client, gap_limit).await?;
let mut builder = flatbuffers::FlatBufferBuilder::new();
let mut addrs = vec![];
for a in addresses {
let address = builder.create_string(&a.address);
let ab = AddressBalance::create(&mut builder, &AddressBalanceArgs {
index: a.index,
address: Some(address),
balance: a.balance,
});
addrs.push(ab);
}
let addrs = builder.create_vector(&addrs);
let addrs = AddressBalanceVec::create(&mut builder, &AddressBalanceVecArgs {
values: Some(addrs)
});
builder.finish(addrs, None);
let data = builder.finished_data().to_vec();
Ok(data)
}
/// Get the backup string. It is either the passphrase, the secret key or the viewing key

View File

@ -493,9 +493,9 @@ pub async unsafe extern "C" fn shield_taddr(
#[tokio::main]
#[no_mangle]
pub async unsafe extern "C" fn scan_transparent_accounts(gap_limit: u32) {
pub async unsafe extern "C" fn scan_transparent_accounts(gap_limit: u32) -> CResult<*const u8> {
let res = crate::api::account::scan_transparent_accounts(gap_limit as usize).await;
log_error(res)
to_cresult_bytes(res)
}
#[tokio::main]
@ -964,7 +964,7 @@ pub unsafe extern "C" fn get_pnl_txs(coin: u8, id: u32, timestamp: u32) -> CResu
}
#[no_mangle]
pub unsafe extern "C" fn get_historical_prices(coin: u8, id: u32, timestamp: u32, currency: *mut c_char) -> CResult<*const u8> {
pub unsafe extern "C" fn get_historical_prices(coin: u8, timestamp: u32, currency: *mut c_char) -> CResult<*const u8> {
from_c_str!(currency);
let res = |connection: &Connection| {
let data = crate::db::read::get_historical_prices(connection, timestamp, &currency)?;
@ -982,6 +982,24 @@ pub unsafe extern "C" fn get_spendings(coin: u8, id: u32, timestamp: u32) -> CRe
to_cresult_bytes(with_account(coin, id, res))
}
#[no_mangle]
pub unsafe extern "C" fn update_excluded(coin: u8, id: u32, excluded: bool) -> CResult<u8> {
let res = |connection: &Connection| {
crate::db::read::update_excluded(connection, id, excluded)?;
Ok(0)
};
to_cresult(with_account(coin, id, res))
}
#[no_mangle]
pub unsafe extern "C" fn invert_excluded(coin: u8, id: u32) -> CResult<u8> {
let res = |connection: &Connection| {
crate::db::read::invert_excluded(connection, id)?;
Ok(0)
};
to_cresult(with_account(coin, id, res))
}
#[no_mangle]
pub unsafe extern "C" fn has_cuda() -> bool {
crate::gpu::has_cuda()

View File

@ -1102,25 +1102,7 @@ impl DbAdapter {
)?;
Ok(())
}
pub fn store_t_scan(&self, addresses: &[TBalance]) -> anyhow::Result<()> {
self.connection.execute(
"CREATE TABLE IF NOT EXISTS taddr_scan(\
id INTEGER NOT NULL PRIMARY KEY,
address TEXT NOT NULL,
value INTEGER NOT NULL,
aindex INTEGER NOT NULL)",
[],
)?;
for addr in addresses.iter() {
self.connection.execute(
"INSERT INTO taddr_scan(address, value, aindex) VALUES (?1, ?2, ?3)",
params![addr.address, addr.balance, addr.index],
)?;
}
Ok(())
}
pub fn get_accounts(&self) -> anyhow::Result<Vec<AccountRec>> {
let mut s = self
.connection

View File

@ -3853,5 +3853,311 @@ impl SpendingVecT {
})
}
}
pub enum AddressBalanceOffset {}
#[derive(Copy, Clone, PartialEq)]
pub struct AddressBalance<'a> {
pub _tab: flatbuffers::Table<'a>,
}
impl<'a> flatbuffers::Follow<'a> for AddressBalance<'a> {
type Inner = AddressBalance<'a>;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self { _tab: flatbuffers::Table::new(buf, loc) }
}
}
impl<'a> AddressBalance<'a> {
pub const VT_INDEX: flatbuffers::VOffsetT = 4;
pub const VT_ADDRESS: flatbuffers::VOffsetT = 6;
pub const VT_BALANCE: flatbuffers::VOffsetT = 8;
#[inline]
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
AddressBalance { _tab: table }
}
#[allow(unused_mut)]
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
args: &'args AddressBalanceArgs<'args>
) -> flatbuffers::WIPOffset<AddressBalance<'bldr>> {
let mut builder = AddressBalanceBuilder::new(_fbb);
builder.add_balance(args.balance);
if let Some(x) = args.address { builder.add_address(x); }
builder.add_index(args.index);
builder.finish()
}
pub fn unpack(&self) -> AddressBalanceT {
let index = self.index();
let address = self.address().map(|x| {
x.to_string()
});
let balance = self.balance();
AddressBalanceT {
index,
address,
balance,
}
}
#[inline]
pub fn index(&self) -> u32 {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<u32>(AddressBalance::VT_INDEX, Some(0)).unwrap()}
}
#[inline]
pub fn address(&self) -> Option<&'a str> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(AddressBalance::VT_ADDRESS, None)}
}
#[inline]
pub fn balance(&self) -> u64 {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<u64>(AddressBalance::VT_BALANCE, Some(0)).unwrap()}
}
}
impl flatbuffers::Verifiable for AddressBalance<'_> {
#[inline]
fn run_verifier(
v: &mut flatbuffers::Verifier, pos: usize
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
use self::flatbuffers::Verifiable;
v.visit_table(pos)?
.visit_field::<u32>("index", Self::VT_INDEX, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("address", Self::VT_ADDRESS, false)?
.visit_field::<u64>("balance", Self::VT_BALANCE, false)?
.finish();
Ok(())
}
}
pub struct AddressBalanceArgs<'a> {
pub index: u32,
pub address: Option<flatbuffers::WIPOffset<&'a str>>,
pub balance: u64,
}
impl<'a> Default for AddressBalanceArgs<'a> {
#[inline]
fn default() -> Self {
AddressBalanceArgs {
index: 0,
address: None,
balance: 0,
}
}
}
pub struct AddressBalanceBuilder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
}
impl<'a: 'b, 'b> AddressBalanceBuilder<'a, 'b> {
#[inline]
pub fn add_index(&mut self, index: u32) {
self.fbb_.push_slot::<u32>(AddressBalance::VT_INDEX, index, 0);
}
#[inline]
pub fn add_address(&mut self, address: flatbuffers::WIPOffset<&'b str>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(AddressBalance::VT_ADDRESS, address);
}
#[inline]
pub fn add_balance(&mut self, balance: u64) {
self.fbb_.push_slot::<u64>(AddressBalance::VT_BALANCE, balance, 0);
}
#[inline]
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> AddressBalanceBuilder<'a, 'b> {
let start = _fbb.start_table();
AddressBalanceBuilder {
fbb_: _fbb,
start_: start,
}
}
#[inline]
pub fn finish(self) -> flatbuffers::WIPOffset<AddressBalance<'a>> {
let o = self.fbb_.end_table(self.start_);
flatbuffers::WIPOffset::new(o.value())
}
}
impl core::fmt::Debug for AddressBalance<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut ds = f.debug_struct("AddressBalance");
ds.field("index", &self.index());
ds.field("address", &self.address());
ds.field("balance", &self.balance());
ds.finish()
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct AddressBalanceT {
pub index: u32,
pub address: Option<String>,
pub balance: u64,
}
impl Default for AddressBalanceT {
fn default() -> Self {
Self {
index: 0,
address: None,
balance: 0,
}
}
}
impl AddressBalanceT {
pub fn pack<'b>(
&self,
_fbb: &mut flatbuffers::FlatBufferBuilder<'b>
) -> flatbuffers::WIPOffset<AddressBalance<'b>> {
let index = self.index;
let address = self.address.as_ref().map(|x|{
_fbb.create_string(x)
});
let balance = self.balance;
AddressBalance::create(_fbb, &AddressBalanceArgs{
index,
address,
balance,
})
}
}
pub enum AddressBalanceVecOffset {}
#[derive(Copy, Clone, PartialEq)]
pub struct AddressBalanceVec<'a> {
pub _tab: flatbuffers::Table<'a>,
}
impl<'a> flatbuffers::Follow<'a> for AddressBalanceVec<'a> {
type Inner = AddressBalanceVec<'a>;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self { _tab: flatbuffers::Table::new(buf, loc) }
}
}
impl<'a> AddressBalanceVec<'a> {
pub const VT_VALUES: flatbuffers::VOffsetT = 4;
#[inline]
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
AddressBalanceVec { _tab: table }
}
#[allow(unused_mut)]
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
args: &'args AddressBalanceVecArgs<'args>
) -> flatbuffers::WIPOffset<AddressBalanceVec<'bldr>> {
let mut builder = AddressBalanceVecBuilder::new(_fbb);
if let Some(x) = args.values { builder.add_values(x); }
builder.finish()
}
pub fn unpack(&self) -> AddressBalanceVecT {
let values = self.values().map(|x| {
x.iter().map(|t| t.unpack()).collect()
});
AddressBalanceVecT {
values,
}
}
#[inline]
pub fn values(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<AddressBalance<'a>>>> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<AddressBalance>>>>(AddressBalanceVec::VT_VALUES, None)}
}
}
impl flatbuffers::Verifiable for AddressBalanceVec<'_> {
#[inline]
fn run_verifier(
v: &mut flatbuffers::Verifier, pos: usize
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
use self::flatbuffers::Verifiable;
v.visit_table(pos)?
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<AddressBalance>>>>("values", Self::VT_VALUES, false)?
.finish();
Ok(())
}
}
pub struct AddressBalanceVecArgs<'a> {
pub values: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<AddressBalance<'a>>>>>,
}
impl<'a> Default for AddressBalanceVecArgs<'a> {
#[inline]
fn default() -> Self {
AddressBalanceVecArgs {
values: None,
}
}
}
pub struct AddressBalanceVecBuilder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
}
impl<'a: 'b, 'b> AddressBalanceVecBuilder<'a, 'b> {
#[inline]
pub fn add_values(&mut self, values: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<AddressBalance<'b >>>>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(AddressBalanceVec::VT_VALUES, values);
}
#[inline]
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> AddressBalanceVecBuilder<'a, 'b> {
let start = _fbb.start_table();
AddressBalanceVecBuilder {
fbb_: _fbb,
start_: start,
}
}
#[inline]
pub fn finish(self) -> flatbuffers::WIPOffset<AddressBalanceVec<'a>> {
let o = self.fbb_.end_table(self.start_);
flatbuffers::WIPOffset::new(o.value())
}
}
impl core::fmt::Debug for AddressBalanceVec<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut ds = f.debug_struct("AddressBalanceVec");
ds.field("values", &self.values());
ds.finish()
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct AddressBalanceVecT {
pub values: Option<Vec<AddressBalanceT>>,
}
impl Default for AddressBalanceVecT {
fn default() -> Self {
Self {
values: None,
}
}
}
impl AddressBalanceVecT {
pub fn pack<'b>(
&self,
_fbb: &mut flatbuffers::FlatBufferBuilder<'b>
) -> flatbuffers::WIPOffset<AddressBalanceVec<'b>> {
let values = self.values.as_ref().map(|x|{
let w: Vec<_> = x.iter().map(|t| t.pack(_fbb)).collect();_fbb.create_vector(&w)
});
AddressBalanceVec::create(_fbb, &AddressBalanceVecArgs{
values,
})
}
}
} // pub mod fb

View File

@ -458,7 +458,19 @@ pub fn get_spendings(connection: &Connection, id: u32, timestamp: u32) -> Result
let data = builder.finished_data().to_vec();
Ok(data)
}
pub fn update_excluded(connection: &Connection, id: u32, excluded: bool) -> Result<()> {
connection.execute("UPDATE received_notes SET excluded = ?2 WHERE id_note = ?1", params![id, excluded])?;
Ok(())
}
pub fn invert_excluded(connection: &Connection, id: u32) -> Result<()> {
connection.execute("UPDATE received_notes SET excluded = NOT(COALESCE(excluded, 0)) WHERE account = ?1", [id])?;
Ok(())
}
/*
,
"SELECT timestamp, value FROM transactions WHERE account = ?1 AND timestamp >= ?2 ORDER BY timestamp DESC",

View File

@ -49,7 +49,7 @@ pub async fn scan_transparent_accounts(
network: &Network,
client: &mut CompactTxStreamerClient<Channel>,
gap_limit: usize,
) -> anyhow::Result<()> {
) -> anyhow::Result<Vec<TBalance>> {
let c = CoinConfig::get_active();
let mut addresses = vec![];
let db = c.db()?;
@ -77,8 +77,7 @@ pub async fn scan_transparent_accounts(
aindex += 1;
}
}
db.store_t_scan(&addresses)?;
Ok(())
Ok(addresses)
}
pub fn derive_tkeys(