Skip to content

Upgrade BIP329 #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ bdk_chain = { version = "0.21.0" }
pubport = { version = "0.3.1", features = [] }

# bip329 labels
bip329 = { version = "0.2.0", features = [] }
bip329 = { version = "0.3.0", features = [] }

# bitcoin
bitcoin = { version = "0.32", features = ["serde"] }
Expand Down
4 changes: 2 additions & 2 deletions rust/src/database/key.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod in_out_id;
pub mod outpoint;

pub type InOutIdKey = in_out_id::InOutIdKey;
pub type OutPointKey = outpoint::OutPointKey;
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@ use zerocopy::{FromBytes, Immutable, IntoBytes};

#[derive(FromBytes, IntoBytes, Immutable, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(C)]
pub struct InOutIdKey {
pub struct OutPointKey {
pub id: [u8; 32],
pub index: u32,
}

impl From<&bip329::InOutId> for InOutIdKey {
fn from(id: &bip329::InOutId) -> Self {
Self::new(id.txid, id.index)
impl From<&bitcoin::OutPoint> for OutPointKey {
fn from(id: &bitcoin::OutPoint) -> Self {
Self::new(id.txid, id.vout)
}
}

impl From<bip329::InOutId> for InOutIdKey {
fn from(id: bip329::InOutId) -> Self {
impl From<bitcoin::OutPoint> for OutPointKey {
fn from(id: bitcoin::OutPoint) -> Self {
Self::from(&id)
}
}

impl InOutIdKey {
impl OutPointKey {
pub fn new(id: impl AsRef<[u8; 32]>, index: u32) -> Self {
Self {
id: *id.as_ref(),
Expand All @@ -35,15 +35,15 @@ impl InOutIdKey {
}
}

impl redb::Key for InOutIdKey {
impl redb::Key for OutPointKey {
fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
data1.cmp(data2)
}
}

impl redb::Value for InOutIdKey {
impl redb::Value for OutPointKey {
type SelfType<'a>
= InOutIdKey
= OutPointKey
where
Self: 'a;

Expand Down Expand Up @@ -75,7 +75,7 @@ impl redb::Value for InOutIdKey {
}

fn type_name() -> redb::TypeName {
redb::TypeName::new("InOutId::bip329::InOutId")
redb::TypeName::new("OutPointKey::bitcoin::OutPoint")
}
}

Expand All @@ -87,7 +87,7 @@ mod tests {

#[test]
fn test_in_out_id() {
let id = InOutIdKey::new(
let id = OutPointKey::new(
bitcoin::Txid::from_str(
"d9f76c1c2338eb2010255c16e7cbdf72c1263e81c08a465b5d1d76a36d9980dc",
)
Expand Down
26 changes: 13 additions & 13 deletions rust/src/database/wallet_data/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use redb::{ReadOnlyTable, ReadableTable as _, ReadableTableMetadata as _, TableD
use serde::{Serialize, de::DeserializeOwned};

use crate::{
database::{cbor::Cbor, key::InOutIdKey},
database::{cbor::Cbor, key::OutPointKey},
transaction::TxId,
};

Expand All @@ -29,11 +29,11 @@ const TXN_TABLE: TableDefinition<TxId, SerdeRecord<TransactionRecord>> =
const ADDRESS_TABLE: TableDefinition<Cbor<Address<NetworkUnchecked>>, SerdeRecord<AddressRecord>> =
TableDefinition::new("address_labels.cbor");

const INPUT_TABLE: TableDefinition<InOutIdKey, SerdeRecord<InputRecord>> =
TableDefinition::new("input_records.cbor");
const INPUT_TABLE: TableDefinition<OutPointKey, SerdeRecord<InputRecord>> =
TableDefinition::new("input_records_v2.cbor");

const OUTPUT_TABLE: TableDefinition<InOutIdKey, SerdeRecord<OutputRecord>> =
TableDefinition::new("output_records.cbor");
const OUTPUT_TABLE: TableDefinition<OutPointKey, SerdeRecord<OutputRecord>> =
TableDefinition::new("output_records_v2.cbor");

#[derive(Debug, Clone, uniffi::Object)]
pub struct LabelsTable {
Expand Down Expand Up @@ -155,7 +155,7 @@ impl LabelsTable {
) -> Result<impl Iterator<Item = Record<InputRecord>>, Error> {
let table = self.read_table(INPUT_TABLE)?;

let start_inout_id = InOutIdKey {
let start_inout_id = OutPointKey {
id: *txid.as_ref(),
index: 0,
};
Expand All @@ -174,7 +174,7 @@ impl LabelsTable {
) -> Result<impl Iterator<Item = Record<OutputRecord>>, Error> {
let table = self.read_table(OUTPUT_TABLE)?;

let start_inout_id = InOutIdKey {
let start_inout_id = OutPointKey {
id: *txid.as_ref(),
index: 0,
};
Expand Down Expand Up @@ -221,15 +221,15 @@ impl LabelsTable {

Label::Input(input_record) => {
let table = self.read_table(INPUT_TABLE)?;
let key: InOutIdKey = input_record.ref_.into();
let key: OutPointKey = input_record.ref_.into();

let record = table.get(key)?.map(|record| record.value());
Ok(record.map(|record| record.into()))
}

Label::Output(output_record) => {
let table = self.read_table(OUTPUT_TABLE)?;
let key: InOutIdKey = output_record.ref_.into();
let key: OutPointKey = output_record.ref_.into();

let record = table.get(key)?.map(|record| record.value());
Ok(record.map(|record| record.into()))
Expand Down Expand Up @@ -369,14 +369,14 @@ impl LabelsTable {
}
Label::Input(input) => {
let mut table = write_txn.open_table(INPUT_TABLE)?;
let key = InOutIdKey::from(&input.ref_);
let key = OutPointKey::from(&input.ref_);
let value: Record<InputRecord> = Record::with_timestamps(input, timestamps);

table.insert(key, value)?;
}
Label::Output(output) => {
let mut table = write_txn.open_table(OUTPUT_TABLE)?;
let key = InOutIdKey::from(&output.ref_);
let key = OutPointKey::from(&output.ref_);
let output: Record<OutputRecord> = Record::with_timestamps(output, timestamps);

table.insert(key, output)?;
Expand Down Expand Up @@ -426,12 +426,12 @@ impl LabelsTable {
table.remove(key)?;
}
Label::Input(input) => {
let key = InOutIdKey::from(&input.ref_);
let key = OutPointKey::from(&input.ref_);
let mut table = write_txn.open_table(INPUT_TABLE)?;
table.remove(key)?;
}
Label::Output(output) => {
let key = InOutIdKey::from(&output.ref_);
let key = OutPointKey::from(&output.ref_);
let mut table = write_txn.open_table(OUTPUT_TABLE)?;
table.remove(key)?;
}
Expand Down
36 changes: 21 additions & 15 deletions rust/src/label_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
wallet::{Address, metadata::WalletId},
};
use ahash::AHashMap as HashMap;
use bip329::{AddressRecord, InOutId, InputRecord, Label, Labels, OutputRecord, TransactionRecord};
use bip329::{AddressRecord, InputRecord, Label, Labels, OutputRecord, TransactionRecord};

#[derive(Debug, Clone, uniffi::Object)]
pub struct LabelManager {
Expand Down Expand Up @@ -282,22 +282,22 @@ impl LabelManager {
.labels
.txn_input_records_iter(tx_id.as_ref())
.map_err(|e| LabelManagerError::GetInputRecords(e.to_string()))?
.map(|record| (record.item.ref_.index, record))
.map(|record| (record.item.ref_.vout, record))
.collect::<HashMap<u32, Record<InputRecord>>>();

let mut current_output_records = self
.db
.labels
.txn_output_records_iter(tx_id.as_ref())
.map_err(|e| LabelManagerError::GetOutputRecords(e.to_string()))?
.map(|record| (record.item.ref_.index, record))
.map(|record| (record.item.ref_.vout, record))
.collect::<HashMap<u32, Record<OutputRecord>>>();

let input_records = new_input_records_iter.into_iter().map(|record| {
let index = record.ref_.index;
let vout = record.ref_.vout;
let label: Label = record.into();

match current_input_records.remove(&index) {
match current_input_records.remove(&vout) {
Some(current) => {
let mut timestamps = current.timestamps;
timestamps.updated_at = jiff::Timestamp::now().as_second() as u64;
Expand All @@ -308,10 +308,10 @@ impl LabelManager {
});

let output_records = new_output_records_iter.into_iter().map(|record| {
let index = record.ref_.index;
let vout = record.ref_.vout;
let label: Label = record.into();

match current_output_records.remove(&index) {
match current_output_records.remove(&vout) {
Some(current) => {
let mut timestamps = current.timestamps;
timestamps.updated_at = jiff::Timestamp::now().as_second() as u64;
Expand Down Expand Up @@ -432,7 +432,7 @@ impl LabelManager {
&self,
tx_id: &TxId,
label: &str,
indexs: &[u32],
vouts: &[u32],
direction: TransactionDirection,
) -> Vec<InputRecord> {
// no input lables on incoming transactions
Expand All @@ -444,10 +444,13 @@ impl LabelManager {
// input labels only for outgoing transactions, so all inputs are marked at `input`
let input_label = format!("{label} (input)");

indexs
vouts
.iter()
.map(|index| InputRecord {
ref_: InOutId::new(tx_id.0, *index),
.map(|vout| InputRecord {
ref_: bitcoin::OutPoint {
txid: tx_id.0,
vout: *vout,
},
label: Some(input_label.clone()),
})
.collect()
Expand All @@ -458,7 +461,7 @@ impl LabelManager {
&self,
tx_id: &TxId,
label: &str,
indexs: &[u32],
vouts: &[u32],
direction: TransactionDirection,
) -> Vec<OutputRecord> {
// the outputs for a incoming transaction are received
Expand All @@ -470,10 +473,13 @@ impl LabelManager {

let output_label = format!("{label} ({output_label_suffix})");

indexs
vouts
.iter()
.map(|index| OutputRecord {
ref_: InOutId::new(tx_id.0, *index),
.map(|vout| OutputRecord {
ref_: bitcoin::OutPoint {
txid: tx_id.0,
vout: *vout,
},
label: Some(output_label.clone()),
spendable: true,
})
Expand Down