From 6f01c38a71ce7fd2bf875d01a11a3aa67f7b33b6 Mon Sep 17 00:00:00 2001 From: Sudarsan Balaji Date: Thu, 14 Oct 2021 04:23:17 +0530 Subject: [PATCH] Allow using configs for database --- .../src/main/kotlin/uniffi/bdk/bdk.kt | 133 ++++++++++++++++-- .../src/test/kotlin/uniffi/bdk/LibTest.kt | 6 +- src/bdk.udl | 13 +- src/lib.rs | 19 ++- 4 files changed, 150 insertions(+), 21 deletions(-) diff --git a/bindings/bdk-kotlin/src/main/kotlin/uniffi/bdk/bdk.kt b/bindings/bdk-kotlin/src/main/kotlin/uniffi/bdk/bdk.kt index a91f847..1398b9e 100644 --- a/bindings/bdk-kotlin/src/main/kotlin/uniffi/bdk/bdk.kt +++ b/bindings/bdk-kotlin/src/main/kotlin/uniffi/bdk/bdk.kt @@ -44,15 +44,15 @@ open class RustBuffer : Structure() { companion object { internal fun alloc(size: Int = 0) = rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_a71d_rustbuffer_alloc(size, status) + _UniFFILib.INSTANCE.ffi_bdk_f91_rustbuffer_alloc(size, status) } internal fun free(buf: RustBuffer.ByValue) = rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_a71d_rustbuffer_free(buf, status) + _UniFFILib.INSTANCE.ffi_bdk_f91_rustbuffer_free(buf, status) } internal fun reserve(buf: RustBuffer.ByValue, additional: Int) = rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_a71d_rustbuffer_reserve(buf, additional, status) + _UniFFILib.INSTANCE.ffi_bdk_f91_rustbuffer_reserve(buf, additional, status) } } @@ -247,6 +247,18 @@ internal fun String.write(buf: RustBufferBuilder) { + + + + + + + + + + + + @@ -283,31 +295,31 @@ internal interface _UniFFILib : Library { } } - fun ffi_bdk_a71d_OfflineWallet_object_free(ptr: Pointer, + fun ffi_bdk_f91_OfflineWallet_object_free(ptr: Pointer, uniffi_out_err: RustCallStatus ): Unit - fun bdk_a71d_OfflineWallet_new(descriptor: RustBuffer.ByValue, + fun bdk_f91_OfflineWallet_new(descriptor: RustBuffer.ByValue,database_config: RustBuffer.ByValue, uniffi_out_err: RustCallStatus ): Pointer - fun bdk_a71d_OfflineWallet_get_new_address(ptr: Pointer, + fun bdk_f91_OfflineWallet_get_new_address(ptr: Pointer, uniffi_out_err: RustCallStatus ): RustBuffer.ByValue - fun ffi_bdk_a71d_rustbuffer_alloc(size: Int, + fun ffi_bdk_f91_rustbuffer_alloc(size: Int, uniffi_out_err: RustCallStatus ): RustBuffer.ByValue - fun ffi_bdk_a71d_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue, + fun ffi_bdk_f91_rustbuffer_from_bytes(bytes: ForeignBytes.ByValue, uniffi_out_err: RustCallStatus ): RustBuffer.ByValue - fun ffi_bdk_a71d_rustbuffer_free(buf: RustBuffer.ByValue, + fun ffi_bdk_f91_rustbuffer_free(buf: RustBuffer.ByValue, uniffi_out_err: RustCallStatus ): Unit - fun ffi_bdk_a71d_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int, + fun ffi_bdk_f91_rustbuffer_reserve(buf: RustBuffer.ByValue,additional: Int, uniffi_out_err: RustCallStatus ): RustBuffer.ByValue @@ -481,6 +493,66 @@ abstract class FFIObject( // Public interface members begin here. // Public facing enums + + + + + + + + +sealed class DatabaseConfig { + + data class Memory( + val junk: String + ) : DatabaseConfig() + + data class Sled( + val configuration: SledDbConfiguration + ) : DatabaseConfig() + + + companion object { + internal fun lift(rbuf: RustBuffer.ByValue): DatabaseConfig { + return liftFromRustBuffer(rbuf) { buf -> DatabaseConfig.read(buf) } + } + + internal fun read(buf: ByteBuffer): DatabaseConfig { + return when(buf.getInt()) { + 1 -> DatabaseConfig.Memory( + String.read(buf) + ) + 2 -> DatabaseConfig.Sled( + SledDbConfiguration.read(buf) + ) + else -> throw RuntimeException("invalid enum value, something is very wrong!!") + } + } + } + + internal fun lower(): RustBuffer.ByValue { + return lowerIntoRustBuffer(this, {v, buf -> v.write(buf)}) + } + + internal fun write(buf: RustBufferBuilder) { + when(this) { + is DatabaseConfig.Memory -> { + buf.putInt(1) + this.junk.write(buf) + + } + is DatabaseConfig.Sled -> { + buf.putInt(2) + this.configuration.write(buf) + + } + }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } + } + + + +} + // Error definitions @Structure.FieldOrder("code", "error_buf") internal open class RustCallStatus : Structure() { @@ -649,6 +721,39 @@ private inline fun rustCall(callback: (RustCallStatus) -> U): U { // Public facing records +data class SledDbConfiguration ( + var path: String, + var treeName: String +) { + companion object { + internal fun lift(rbuf: RustBuffer.ByValue): SledDbConfiguration { + return liftFromRustBuffer(rbuf) { buf -> SledDbConfiguration.read(buf) } + } + + internal fun read(buf: ByteBuffer): SledDbConfiguration { + return SledDbConfiguration( + String.read(buf), + String.read(buf) + ) + } + } + + internal fun lower(): RustBuffer.ByValue { + return lowerIntoRustBuffer(this, {v, buf -> v.write(buf)}) + } + + internal fun write(buf: RustBufferBuilder) { + this.path.write(buf) + + this.treeName.write(buf) + + } + + + +} + + // Namespace functions @@ -664,10 +769,10 @@ public interface OfflineWalletInterface { class OfflineWallet( pointer: Pointer ) : FFIObject(pointer), OfflineWalletInterface { - constructor(descriptor: String ) : + constructor(descriptor: String, databaseConfig: DatabaseConfig ) : this( rustCallWithError(BdkException) { status -> - _UniFFILib.INSTANCE.bdk_a71d_OfflineWallet_new(descriptor.lower() ,status) + _UniFFILib.INSTANCE.bdk_f91_OfflineWallet_new(descriptor.lower(), databaseConfig.lower() ,status) }) /** @@ -680,7 +785,7 @@ class OfflineWallet( */ override protected fun freeRustArcPtr() { rustCall() { status -> - _UniFFILib.INSTANCE.ffi_bdk_a71d_OfflineWallet_object_free(this.pointer, status) + _UniFFILib.INSTANCE.ffi_bdk_f91_OfflineWallet_object_free(this.pointer, status) } } @@ -695,7 +800,7 @@ class OfflineWallet( override fun getNewAddress(): String = callWithPointer { rustCall() { status -> - _UniFFILib.INSTANCE.bdk_a71d_OfflineWallet_get_new_address(it, status) + _UniFFILib.INSTANCE.bdk_f91_OfflineWallet_get_new_address(it, status) } }.let { String.lift(it) diff --git a/bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt b/bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt index 2c869a6..c2bfec9 100644 --- a/bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt +++ b/bindings/bdk-kotlin/src/test/kotlin/uniffi/bdk/LibTest.kt @@ -14,7 +14,8 @@ class LibTest { @Test fun walletNewAddress() { - val wallet = OfflineWallet(desc) + val config = DatabaseConfig.Memory("") + val wallet = OfflineWallet(desc, config) val address = wallet.getNewAddress() assertNotNull(address) assertEquals(address, "bcrt1qzg4mckdh50nwdm9hkzq06528rsu73hjxytqkxs") @@ -22,6 +23,7 @@ class LibTest { @Test(expected=BdkException.Descriptor::class) fun invalidDescriptorExceptionIsThrown() { - OfflineWallet("invalid-descriptor") + val config = DatabaseConfig.Memory("") + OfflineWallet("invalid-descriptor", config) } } diff --git a/src/bdk.udl b/src/bdk.udl index 597833b..e79ddcc 100644 --- a/src/bdk.udl +++ b/src/bdk.udl @@ -44,8 +44,19 @@ enum BdkError { "Sled", }; +dictionary SledDbConfiguration { + string path; + string tree_name; +}; + +[Enum] +interface DatabaseConfig { + Memory(string junk); + Sled(SledDbConfiguration configuration); +}; + interface OfflineWallet { [Throws=BdkError] - constructor(string descriptor); + constructor(string descriptor, DatabaseConfig database_config); string get_new_address(); }; diff --git a/src/lib.rs b/src/lib.rs index 5d8cd69..db824ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ use bdk::bitcoin::Network; -use bdk::database::MemoryDatabase; +use bdk::database::any::{AnyDatabase, SledDbConfiguration}; +use bdk::database::{AnyDatabaseConfig, ConfigurableDatabase}; use bdk::wallet::AddressIndex; use bdk::Error; use bdk::Wallet; @@ -8,14 +9,24 @@ use std::sync::Mutex; type BdkError = Error; +pub enum DatabaseConfig { + Memory { junk: String }, + Sled { configuration: SledDbConfiguration }, +} + uniffi_macros::include_scaffolding!("bdk"); + struct OfflineWallet { - wallet: Mutex>, + wallet: Mutex>, } impl OfflineWallet { - fn new(descriptor: String) -> Result { - let database = MemoryDatabase::default(); + fn new(descriptor: String, database_config: DatabaseConfig) -> Result { + let any_database_config = match database_config { + DatabaseConfig::Memory { .. } => AnyDatabaseConfig::Memory(()), + DatabaseConfig::Sled { configuration } => AnyDatabaseConfig::Sled(configuration), + }; + let database = AnyDatabase::from_config(&any_database_config)?; let wallet = Mutex::new(Wallet::new_offline( &descriptor, None,