Add kotlin BlockchainConfig and DatabaseConfig

This commit is contained in:
Steve Myers 2021-06-25 23:40:38 -07:00
parent 13e7217ffd
commit 91ae8dd537
6 changed files with 154 additions and 18 deletions

104
src/blockchain.rs Normal file
View File

@ -0,0 +1,104 @@
use ::safer_ffi::prelude::*;
use bdk::blockchain::{AnyBlockchainConfig, ElectrumBlockchainConfig};
use safer_ffi::boxed::Box;
use safer_ffi::char_p::char_p_ref;
#[derive_ReprC]
#[ReprC::opaque]
#[derive(Debug)]
pub struct BlockchainConfig {
pub raw: AnyBlockchainConfig,
}
#[ffi_export]
fn new_electrum_config(
url: char_p_ref,
socks5: Option<char_p_ref>,
retry: i16,
timeout: i16,
) -> Box<BlockchainConfig> {
let url = url.to_string();
let socks5 = socks5.map(|s| s.to_string());
let retry = short_to_u8(retry);
let timeout = short_to_optional_u8(timeout);
let electrum_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
url,
socks5,
retry,
timeout,
});
Box::new(BlockchainConfig {
raw: electrum_config,
})
}
#[ffi_export]
fn free_blockchain_config(blockchain_config: Box<BlockchainConfig>) {
drop(blockchain_config);
}
// TODO compact_filter rocksdb not compiling on android, switch to sqlite?
//#[derive_ReprC]
//#[repr(C)]
//#[derive(Debug)]
//pub struct BitcoinPeerConfig {
// pub address: char_p_boxed,
// pub socks5: Option<char_p_boxed>,
// pub socks5_credentials: Option<Box<Tuple2<char_p_boxed, char_p_boxed>>>,
//}
//
//impl From<&BitcoinPeerConfig> for BdkBitcoinPeerConfig {
// fn from(config: &BitcoinPeerConfig) -> Self {
// let address = config.address.to_string();
// let socks5 = config.socks5.as_ref().map(|p| p.to_string());
// let socks5_credentials = config
// .socks5_credentials.as_ref()
// .map(|c| (c._0.to_string(), c._1.to_string()));
//
// BdkBitcoinPeerConfig {
// address,
// socks5: socks5,
// socks5_credentials: socks5_credentials,
// }
// }
//}
//
//
//#[ffi_export]
//fn new_compact_filters_config<'lt>(
// peers: c_slice::Ref<'lt, BitcoinPeerConfig>,
// network: char_p_ref,
// storage_dir: char_p_ref,
// skip_blocks: usize,
//) -> Box<BlockchainConfig> {
// let peers = peers.iter().map(|p| p.into()).collect();
// let network = Network::from_str(network.to_str()).unwrap();
// let storage_dir = storage_dir.to_string();
// let skip_blocks = Some(skip_blocks);
// let cf_config = AnyBlockchainConfig::CompactFilters(CompactFiltersBlockchainConfig {
// peers,
// network,
// storage_dir,
// skip_blocks,
// });
// Box::new(BlockchainConfig { raw: cf_config })
//}
// utility functions
fn short_to_optional_u8(short: i16) -> Option<u8> {
if short < 0 {
None
} else {
Some(short_to_u8(short))
}
}
fn short_to_u8(short: i16) -> u8 {
if short < 0 {
u8::MIN
} else {
u8::try_from(short).unwrap_or(u8::MAX)
}
}

32
src/database.rs Normal file
View File

@ -0,0 +1,32 @@
use ::safer_ffi::prelude::*;
use bdk::database::any::SledDbConfiguration;
use bdk::database::AnyDatabaseConfig;
use safer_ffi::boxed::Box;
use safer_ffi::char_p::char_p_ref;
#[derive_ReprC]
#[ReprC::opaque]
#[derive(Debug)]
pub struct DatabaseConfig {
pub raw: AnyDatabaseConfig,
}
#[ffi_export]
fn new_memory_config() -> Box<DatabaseConfig> {
let memory_config = AnyDatabaseConfig::Memory(());
Box::new(DatabaseConfig { raw: memory_config })
}
#[ffi_export]
fn new_sled_config(path: char_p_ref, tree_name: char_p_ref) -> Box<DatabaseConfig> {
let path = path.to_string();
let tree_name = tree_name.to_string();
let sled_config = AnyDatabaseConfig::Sled(SledDbConfiguration { path, tree_name });
Box::new(DatabaseConfig { raw: sled_config })
}
#[ffi_export]
fn free_database_config(database_config: Box<DatabaseConfig>) {
drop(database_config);
}

View File

@ -38,8 +38,8 @@ pub fn get_name(error: &bdk::Error) -> String {
Error::Hex(_) => "Hex",
Error::Psbt(_) => "Psbt",
Error::Electrum(_) => "Electrum",
// Error::Esplora(_) => {}
// Error::CompactFilters(_) => {}
// Error::Esplora(_) => "Esplora",
// Error::CompactFilters(_) => "CompactFilters",
Error::Sled(_) => "Sled",
}
.to_string()

View File

@ -1,5 +1,7 @@
#![deny(unsafe_code)] /* No `unsafe` needed! */
mod blockchain;
mod database;
mod error;
mod wallet;

View File

@ -10,6 +10,8 @@ use bdk::wallet::AddressIndex::New;
use bdk::{Error, Wallet};
use safer_ffi::boxed::Box;
use safer_ffi::char_p::{char_p_boxed, char_p_ref};
use crate::blockchain::BlockchainConfig;
use crate::database::DatabaseConfig;
#[derive_ReprC]
#[ReprC::opaque]
@ -79,34 +81,30 @@ pub struct WalletResult {
#[ffi_export]
fn new_wallet_result(
name: char_p_ref,
descriptor: char_p_ref,
change_descriptor: Option<char_p_ref>,
blockchain_config: &BlockchainConfig,
database_config: &DatabaseConfig,
) -> Box<WalletResult> {
let name = name.to_string();
let descriptor = descriptor.to_string();
let change_descriptor = change_descriptor.map(|s| s.to_string());
let wallet_result = new_wallet(name, descriptor, change_descriptor);
let bc_config = &blockchain_config.raw;
let db_config = &database_config.raw;
let wallet_result = new_wallet(descriptor, change_descriptor, bc_config, db_config);
Box::new(WalletResult { raw: wallet_result })
}
fn new_wallet(
_name: String,
descriptor: String,
change_descriptor: Option<String>,
blockchain_config: &AnyBlockchainConfig,
database_config: &AnyDatabaseConfig,
) -> Result<Wallet<AnyBlockchain, AnyDatabase>, Error> {
let network = Testnet;
let electrum_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
url: "ssl://electrum.blockstream.info:60002".to_string(),
socks5: None,
retry: 5,
timeout: None,
});
let blockchain_config = electrum_config;
let client = AnyBlockchain::from_config(&blockchain_config)?;
let database_config = AnyDatabaseConfig::Memory(());
let database = AnyDatabase::from_config(&database_config)?;
let client = AnyBlockchain::from_config(blockchain_config)?;
let database = AnyDatabase::from_config(database_config)?;
let descriptor: &str = descriptor.as_str();
let change_descriptor: Option<&str> = change_descriptor.as_deref();

View File

@ -6,9 +6,9 @@ cargo test --features c-headers -- generate_headers
# cc
export LD_LIBRARY_PATH=`pwd`/target/debug
#valgrind --leak-check=full cc/bdk_ffi_test
#valgrind --leak-check=full --show-leak-kinds=all cc/bdk_ffi_test
cc/bdk_ffi_test
# bdk-kotlin
## bdk-kotlin
(cd bdk-kotlin && gradle test)
(cd bdk-kotlin && gradle :android:connectedDebugAndroidTest)