refactor: restructure balance

This commit is contained in:
Matthew 2023-11-15 15:57:02 -06:00
parent e5ded1a726
commit 05ce7dad31
No known key found for this signature in database
GPG Key ID: 8D4FCD82DD54DDD2
15 changed files with 54 additions and 71 deletions

View File

@ -14,9 +14,9 @@ class LiveTxBuilderTest {
val esploraClient = EsploraClient("https://mempool.space/testnet/api") val esploraClient = EsploraClient("https://mempool.space/testnet/api")
val update = esploraClient.scan(wallet, 10uL, 1uL) val update = esploraClient.scan(wallet, 10uL, 1uL)
wallet.applyUpdate(update) wallet.applyUpdate(update)
println("Balance: ${wallet.getBalance().total()}") println("Balance: ${wallet.getBalance().total}")
assert(wallet.getBalance().total() > 0uL) assert(wallet.getBalance().total > 0uL)
val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET) val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
val psbt: PartiallySignedTransaction = TxBuilder() val psbt: PartiallySignedTransaction = TxBuilder()

View File

@ -12,14 +12,13 @@ class LiveWalletTest {
val descriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET) val descriptor: Descriptor = Descriptor("wpkh(tprv8ZgxMBicQKsPf2qfrEygW6fdYseJDDrVnDv26PH5BHdvSuG6ecCbHqLVof9yZcMoM31z9ur3tTYbSnr1WBqbGX97CbXcmp5H6qeMpyvx35B/84h/1h/0h/0/*)", Network.TESTNET)
val wallet: Wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET) val wallet: Wallet = Wallet.newNoPersist(descriptor, null, Network.TESTNET)
val esploraClient: EsploraClient = EsploraClient("https://mempool.space/testnet/api") val esploraClient: EsploraClient = EsploraClient("https://mempool.space/testnet/api")
// val esploraClient = EsploraClient("https://blockstream.info/testnet/api")
val update = esploraClient.scan(wallet, 10uL, 1uL) val update = esploraClient.scan(wallet, 10uL, 1uL)
wallet.applyUpdate(update) wallet.applyUpdate(update)
println("Balance: ${wallet.getBalance().total()}") println("Balance: ${wallet.getBalance().total}")
val balance: Balance = wallet.getBalance() val balance: Balance = wallet.getBalance()
println("Balance: $balance") println("Balance: $balance")
assert(wallet.getBalance().total() > 0uL) assert(wallet.getBalance().total > 0uL)
} }
@Test @Test
@ -30,10 +29,10 @@ class LiveWalletTest {
val update = esploraClient.scan(wallet, 10uL, 1uL) val update = esploraClient.scan(wallet, 10uL, 1uL)
wallet.applyUpdate(update) wallet.applyUpdate(update)
println("Balance: ${wallet.getBalance().total()}") println("Balance: ${wallet.getBalance().total}")
println("New address: ${wallet.getAddress(AddressIndex.New).address}") println("New address: ${wallet.getAddress(AddressIndex.New).address}")
assert(wallet.getBalance().total() > 0uL) { assert(wallet.getBalance().total > 0uL) {
"Wallet balance must be greater than 0! Please send funds to ${wallet.getAddress(AddressIndex.New).address} and try again." "Wallet balance must be greater than 0! Please send funds to ${wallet.getAddress(AddressIndex.New).address} and try again."
} }

View File

@ -50,7 +50,7 @@ class OfflineWalletTest {
assertEquals( assertEquals(
expected = 0uL, expected = 0uL,
actual = wallet.getBalance().total() actual = wallet.getBalance().total
) )
} }
} }

View File

@ -49,18 +49,18 @@ enum ChangeSpendPolicy {
"ChangeForbidden" "ChangeForbidden"
}; };
interface Balance { dictionary Balance {
u64 immature(); u64 immature;
u64 trusted_pending(); u64 trusted_pending;
u64 untrusted_pending(); u64 untrusted_pending;
u64 confirmed(); u64 confirmed;
u64 trusted_spendable(); u64 trusted_spendable;
u64 total(); u64 total;
}; };
dictionary AddressInfo { dictionary AddressInfo {

View File

@ -177,47 +177,33 @@ impl From<&BdkAddressIndex> for AddressIndex {
// } // }
pub struct Balance { pub struct Balance {
pub inner: BdkBalance, // All coinbase outputs not yet matured
pub immature: u64,
/// Unconfirmed UTXOs generated by a wallet tx
pub trusted_pending: u64,
/// Unconfirmed UTXOs received from an external wallet
pub untrusted_pending: u64,
/// Confirmed and immediately spendable balance
pub confirmed: u64,
/// Get sum of trusted_pending and confirmed coins
pub trusted_spendable: u64,
/// Get the whole balance visible to the wallet
pub total: u64,
} }
impl Balance { impl From<BdkBalance> for Balance {
/// All coinbase outputs not yet matured. fn from(bdk_balance: BdkBalance) -> Self {
fn immature(&self) -> u64 { Balance {
self.inner.immature immature: bdk_balance.immature,
} trusted_pending: bdk_balance.trusted_pending,
untrusted_pending: bdk_balance.untrusted_pending,
/// Unconfirmed UTXOs generated by a wallet tx. confirmed: bdk_balance.confirmed,
fn trusted_pending(&self) -> u64 { trusted_spendable: bdk_balance.trusted_spendable(),
self.inner.trusted_pending total: bdk_balance.total(),
} }
/// Unconfirmed UTXOs received from an external wallet.
fn untrusted_pending(&self) -> u64 {
self.inner.untrusted_pending
}
/// Confirmed and immediately spendable balance.
fn confirmed(&self) -> u64 {
self.inner.confirmed
}
/// Get sum of trusted_pending and confirmed coins.
fn trusted_spendable(&self) -> u64 {
self.inner.trusted_spendable()
}
/// Get the whole balance visible to the wallet.
fn total(&self) -> u64 {
self.inner.total()
} }
} }
// impl From<BdkBalance> for Balance {
// fn from(bdk_balance: BdkBalance) -> Self {
// Balance { inner: bdk_balance }
// }
// }
// /// A transaction output, which defines new coins to be created from old ones. // /// A transaction output, which defines new coins to be created from old ones.
// #[derive(Debug, Clone)] // #[derive(Debug, Clone)]
// pub struct TxOut { // pub struct TxOut {

View File

@ -55,11 +55,9 @@ impl Wallet {
.into() .into()
} }
// TODO 16: Why is the Arc required here? pub fn get_balance(&self) -> Balance {
pub fn get_balance(&self) -> Arc<Balance> { let bdk_balance: bdk::wallet::Balance = self.get_wallet().get_balance();
let bdk_balance = self.get_wallet().get_balance(); Balance::from(bdk_balance)
let balance = Balance { inner: bdk_balance };
Arc::new(balance)
} }
pub fn apply_update(&self, update: Arc<Update>) -> Result<(), BdkError> { pub fn apply_update(&self, update: Arc<Update>) -> Result<(), BdkError> {

View File

@ -12,9 +12,9 @@ class LiveTxBuilderTest {
val esploraClient = EsploraClient("https://mempool.space/testnet/api") val esploraClient = EsploraClient("https://mempool.space/testnet/api")
val update = esploraClient.scan(wallet, 10uL, 1uL) val update = esploraClient.scan(wallet, 10uL, 1uL)
wallet.applyUpdate(update) wallet.applyUpdate(update)
println("Balance: ${wallet.getBalance().total()}") println("Balance: ${wallet.getBalance().total}")
assert(wallet.getBalance().total() > 0uL) assert(wallet.getBalance().total > 0uL)
val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET) val recipient: Address = Address("tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", Network.TESTNET)
val psbt: PartiallySignedTransaction = TxBuilder() val psbt: PartiallySignedTransaction = TxBuilder()

View File

@ -12,9 +12,9 @@ class LiveWalletTest {
// val esploraClient = EsploraClient("https://blockstream.info/testnet/api") // val esploraClient = EsploraClient("https://blockstream.info/testnet/api")
val update = esploraClient.scan(wallet, 10uL, 1uL) val update = esploraClient.scan(wallet, 10uL, 1uL)
wallet.applyUpdate(update) wallet.applyUpdate(update)
println("Balance: ${wallet.getBalance().total()}") println("Balance: ${wallet.getBalance().total}")
assert(wallet.getBalance().total() > 0uL) assert(wallet.getBalance().total > 0uL)
} }
@Test @Test
@ -25,10 +25,10 @@ class LiveWalletTest {
val update = esploraClient.scan(wallet, 10uL, 1uL) val update = esploraClient.scan(wallet, 10uL, 1uL)
wallet.applyUpdate(update) wallet.applyUpdate(update)
println("Balance: ${wallet.getBalance().total()}") println("Balance: ${wallet.getBalance().total}")
println("New address: ${wallet.getAddress(AddressIndex.New).address.asString()}") println("New address: ${wallet.getAddress(AddressIndex.New).address.asString()}")
assert(wallet.getBalance().total() > 0uL) { assert(wallet.getBalance().total > 0uL) {
"Wallet balance must be greater than 0! Please send funds to ${wallet.getAddress(AddressIndex.New).address} and try again." "Wallet balance must be greater than 0! Please send funds to ${wallet.getAddress(AddressIndex.New).address} and try again."
} }

View File

@ -47,7 +47,7 @@ class OfflineWalletTest {
assertEquals( assertEquals(
expected = 0uL, expected = 0uL,
actual = wallet.getBalance().total() actual = wallet.getBalance().total
) )
} }
} }

View File

@ -21,7 +21,7 @@ class TestLiveTxBuilder(unittest.TestCase):
) )
wallet.apply_update(update) wallet.apply_update(update)
self.assertGreater(wallet.get_balance().total(), 0) self.assertGreater(wallet.get_balance().total, 0)
recipient = bdk.Address( recipient = bdk.Address(
address = "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", address = "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989",

View File

@ -21,7 +21,7 @@ class TestLiveWallet(unittest.TestCase):
) )
wallet.apply_update(update) wallet.apply_update(update)
self.assertGreater(wallet.get_balance().total(), 0) self.assertGreater(wallet.get_balance().total, 0)
def test_broadcast_transaction(self): def test_broadcast_transaction(self):
descriptor: bdk.Descriptor = bdk.Descriptor( descriptor: bdk.Descriptor = bdk.Descriptor(

View File

@ -28,7 +28,7 @@ class TestSimpleWallet(unittest.TestCase):
bdk.Network.TESTNET bdk.Network.TESTNET
) )
self.assertEqual(wallet.get_balance().total(), 0) self.assertEqual(wallet.get_balance().total, 0)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -20,7 +20,7 @@ final class LiveTxBuilderTests: XCTestCase {
) )
try wallet.applyUpdate(update: update) try wallet.applyUpdate(update: update)
XCTAssertGreaterThan(wallet.getBalance().total(), UInt64(0), "Wallet must have positive balance, please add funds") XCTAssertGreaterThan(wallet.getBalance().total, UInt64(0), "Wallet must have positive balance, please add funds")
let recipient: Address = try Address(address: "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", network: .testnet) let recipient: Address = try Address(address: "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", network: .testnet)
let psbt: PartiallySignedTransaction = try TxBuilder() let psbt: PartiallySignedTransaction = try TxBuilder()

View File

@ -20,7 +20,7 @@ final class LiveWalletTests: XCTestCase {
) )
try wallet.applyUpdate(update: update) try wallet.applyUpdate(update: update)
XCTAssertGreaterThan(wallet.getBalance().total(), UInt64(0)) XCTAssertGreaterThan(wallet.getBalance().total, UInt64(0))
} }
func testBroadcastTransaction() throws { func testBroadcastTransaction() throws {
@ -41,9 +41,9 @@ final class LiveWalletTests: XCTestCase {
) )
try wallet.applyUpdate(update: update) try wallet.applyUpdate(update: update)
XCTAssertGreaterThan(wallet.getBalance().total(), UInt64(0), "Wallet must have positive balance, please add funds") XCTAssertGreaterThan(wallet.getBalance().total, UInt64(0), "Wallet must have positive balance, please add funds")
print("Balance: \(wallet.getBalance().total())") print("Balance: \(wallet.getBalance().total)")
let recipient: Address = try Address(address: "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", network: .testnet) let recipient: Address = try Address(address: "tb1qrnfslnrve9uncz9pzpvf83k3ukz22ljgees989", network: .testnet)
let psbt: PartiallySignedTransaction = try let psbt: PartiallySignedTransaction = try

View File

@ -28,6 +28,6 @@ final class OfflineWalletTests: XCTestCase {
network: .testnet network: .testnet
) )
XCTAssertEqual(wallet.getBalance().total(), 0) XCTAssertEqual(wallet.getBalance().total, 0)
} }
} }