Skip to content

Commit

Permalink
Return None for assets when asset index does not exist (#4141)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Dec 20, 2024
1 parent 83d87d4 commit a0da0c1
Show file tree
Hide file tree
Showing 22 changed files with 229 additions and 188 deletions.
12 changes: 6 additions & 6 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ pub struct Inscriptions {
pub struct Output {
pub address: Option<Address<NetworkUnchecked>>,
pub indexed: bool,
pub inscriptions: Vec<InscriptionId>,
pub inscriptions: Option<Vec<InscriptionId>>,
pub outpoint: OutPoint,
pub runes: BTreeMap<SpacedRune, Pile>,
pub runes: Option<BTreeMap<SpacedRune, Pile>>,
pub sat_ranges: Option<Vec<(u64, u64)>>,
pub script_pubkey: ScriptBuf,
pub spent: bool,
Expand All @@ -168,11 +168,11 @@ pub struct Output {
impl Output {
pub fn new(
chain: Chain,
inscriptions: Vec<InscriptionId>,
inscriptions: Option<Vec<InscriptionId>>,
outpoint: OutPoint,
tx_out: TxOut,
indexed: bool,
runes: BTreeMap<SpacedRune, Pile>,
runes: Option<BTreeMap<SpacedRune, Pile>>,
sat_ranges: Option<Vec<(u64, u64)>>,
spent: bool,
) -> Self {
Expand Down Expand Up @@ -229,7 +229,7 @@ pub struct SatInscriptions {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct AddressInfo {
pub outputs: Vec<OutPoint>,
pub inscriptions: Vec<InscriptionId>,
pub inscriptions: Option<Vec<InscriptionId>>,
pub sat_balance: u64,
pub runes_balances: Vec<(SpacedRune, Decimal, Option<char>)>,
pub runes_balances: Option<Vec<(SpacedRune, Decimal, Option<char>)>>,
}
84 changes: 57 additions & 27 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,15 +1020,19 @@ impl Index {
pub fn get_rune_balances_for_output(
&self,
outpoint: OutPoint,
) -> Result<BTreeMap<SpacedRune, Pile>> {
) -> Result<Option<BTreeMap<SpacedRune, Pile>>> {
if !self.index_runes {
return Ok(None);
}

let rtx = self.database.begin_read()?;

let outpoint_to_balances = rtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?;

let id_to_rune_entries = rtx.open_table(RUNE_ID_TO_RUNE_ENTRY)?;

let Some(balances) = outpoint_to_balances.get(&outpoint.store())? else {
return Ok(BTreeMap::new());
return Ok(Some(BTreeMap::new()));
};

let balances_buffer = balances.value();
Expand All @@ -1051,7 +1055,7 @@ impl Index {
);
}

Ok(balances)
Ok(Some(balances))
}

pub fn get_rune_balance_map(&self) -> Result<BTreeMap<SpacedRune, BTreeMap<OutPoint, Pile>>> {
Expand Down Expand Up @@ -1534,7 +1538,11 @@ impl Index {
pub fn get_inscriptions_on_output_with_satpoints(
&self,
outpoint: OutPoint,
) -> Result<Vec<(SatPoint, InscriptionId)>> {
) -> Result<Option<Vec<(SatPoint, InscriptionId)>>> {
if !self.index_inscriptions {
return Ok(None);
}

let rtx = self.database.begin_read()?;
let outpoint_to_utxo_entry = rtx.open_table(OUTPOINT_TO_UTXO_ENTRY)?;
let sequence_number_to_inscription_entry =
Expand All @@ -1547,31 +1555,40 @@ impl Index {
)
}

pub fn get_inscriptions_for_output(&self, outpoint: OutPoint) -> Result<Vec<InscriptionId>> {
Ok(
self
.get_inscriptions_on_output_with_satpoints(outpoint)?
pub fn get_inscriptions_for_output(
&self,
outpoint: OutPoint,
) -> Result<Option<Vec<InscriptionId>>> {
let Some(inscriptions) = self.get_inscriptions_on_output_with_satpoints(outpoint)? else {
return Ok(None);
};

Ok(Some(
inscriptions
.iter()
.map(|(_satpoint, inscription_id)| *inscription_id)
.collect(),
)
))
}

pub fn get_inscriptions_for_outputs(
&self,
outpoints: &Vec<OutPoint>,
) -> Result<Vec<InscriptionId>> {
let mut inscriptions = Vec::new();
) -> Result<Option<Vec<InscriptionId>>> {
let mut result = Vec::new();
for outpoint in outpoints {
inscriptions.extend(
self
.get_inscriptions_on_output_with_satpoints(*outpoint)?
let Some(inscriptions) = self.get_inscriptions_on_output_with_satpoints(*outpoint)? else {
return Ok(None);
};

result.extend(
inscriptions
.iter()
.map(|(_satpoint, inscription_id)| *inscription_id),
);
}

Ok(inscriptions)
Ok(Some(result))
}

pub fn get_transaction(&self, txid: Txid) -> Result<Option<Transaction>> {
Expand Down Expand Up @@ -2247,13 +2264,13 @@ impl Index {
outpoint_to_utxo_entry: &'a impl ReadableTable<&'static OutPointValue, &'static UtxoEntry>,
sequence_number_to_inscription_entry: &'a impl ReadableTable<u32, InscriptionEntryValue>,
outpoint: OutPoint,
) -> Result<Vec<(SatPoint, InscriptionId)>> {
) -> Result<Option<Vec<(SatPoint, InscriptionId)>>> {
if !self.index_inscriptions {
return Ok(Vec::new());
return Ok(None);
}

let Some(utxo_entry) = outpoint_to_utxo_entry.get(&outpoint.store())? else {
return Ok(Vec::new());
return Ok(Some(Vec::new()));
};

let mut inscriptions = utxo_entry.value().parse(self).parse_inscriptions();
Expand All @@ -2266,10 +2283,13 @@ impl Index {
let entry = sequence_number_to_inscription_entry
.get(sequence_number)?
.unwrap();

let satpoint = SatPoint { outpoint, offset };

Ok((satpoint, InscriptionEntry::load(entry.value()).id))
})
.collect::<Result<_>>()
.map(Some)
}

pub fn get_address_info(&self, address: &Address) -> Result<Vec<OutPoint>> {
Expand All @@ -2289,11 +2309,13 @@ impl Index {
pub(crate) fn get_aggregated_rune_balances_for_outputs(
&self,
outputs: &Vec<OutPoint>,
) -> Result<Vec<(SpacedRune, Decimal, Option<char>)>> {
) -> Result<Option<Vec<(SpacedRune, Decimal, Option<char>)>>> {
let mut runes = BTreeMap::new();

for output in outputs {
let rune_balances = self.get_rune_balances_for_output(*output)?;
let Some(rune_balances) = self.get_rune_balances_for_output(*output)? else {
return Ok(None);
};

for (spaced_rune, pile) in rune_balances {
runes
Expand All @@ -2312,12 +2334,12 @@ impl Index {
}
}

Ok(
Ok(Some(
runes
.into_iter()
.map(|(spaced_rune, (decimal, symbol))| (spaced_rune, decimal, symbol))
.collect(),
)
))
}

pub(crate) fn get_sat_balances_for_outputs(&self, outputs: &Vec<OutPoint>) -> Result<u64> {
Expand Down Expand Up @@ -3476,7 +3498,8 @@ mod tests {
context
.index
.get_inscriptions_for_output(OutPoint { txid, vout: 0 })
.unwrap(),
.unwrap()
.unwrap_or_default(),
[]
);

Expand All @@ -3486,7 +3509,8 @@ mod tests {
context
.index
.get_inscriptions_for_output(OutPoint { txid, vout: 0 })
.unwrap(),
.unwrap()
.unwrap_or_default(),
[inscription_id]
);

Expand All @@ -3501,7 +3525,8 @@ mod tests {
context
.index
.get_inscriptions_for_output(OutPoint { txid, vout: 0 })
.unwrap(),
.unwrap()
.unwrap_or_default(),
[]
);

Expand All @@ -3512,7 +3537,8 @@ mod tests {
txid: send_id,
vout: 0,
})
.unwrap(),
.unwrap()
.unwrap_or_default(),
[inscription_id]
);
}
Expand Down Expand Up @@ -3542,7 +3568,8 @@ mod tests {
txid: first,
vout: 0
})
.unwrap(),
.unwrap()
.unwrap_or_default(),
[inscription_id]
);

Expand Down Expand Up @@ -4420,6 +4447,7 @@ mod tests {
.index
.get_inscriptions_on_output_with_satpoints(OutPoint { txid, vout: 0 })
.unwrap()
.unwrap_or_default()
.iter()
.map(|(_satpoint, inscription_id)| *inscription_id)
.collect::<Vec<InscriptionId>>()
Expand Down Expand Up @@ -4484,6 +4512,7 @@ mod tests {
.index
.get_inscriptions_on_output_with_satpoints(OutPoint { txid, vout: 0 })
.unwrap()
.unwrap_or_default()
)
}
}
Expand Down Expand Up @@ -4533,6 +4562,7 @@ mod tests {
vout: 0
})
.unwrap()
.unwrap_or_default()
)
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/subcommand/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ pub(crate) struct List {
pub struct Output {
pub address: Option<Address<NetworkUnchecked>>,
pub indexed: bool,
pub inscriptions: Vec<InscriptionId>,
pub runes: BTreeMap<SpacedRune, Pile>,
pub inscriptions: Option<Vec<InscriptionId>>,
pub runes: Option<BTreeMap<SpacedRune, Pile>>,
pub sat_ranges: Option<Vec<Range>>,
pub script_pubkey: String,
pub spent: bool,
Expand Down
42 changes: 26 additions & 16 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -758,13 +758,21 @@ impl Server {
OutputType::Cardinal => {
index
.get_inscriptions_on_output_with_satpoints(output)?
.unwrap_or_default()
.is_empty()
&& index.get_rune_balances_for_output(output)?.is_empty()
&& index
.get_rune_balances_for_output(output)?
.unwrap_or_default()
.is_empty()
}
OutputType::Inscribed => !index
.get_inscriptions_on_output_with_satpoints(output)?
.unwrap_or_default()
.is_empty(),
OutputType::Runic => !index
.get_rune_balances_for_output(output)?
.unwrap_or_default()
.is_empty(),
OutputType::Runic => !index.get_rune_balances_for_output(output)?.is_empty(),
};

if include {
Expand Down Expand Up @@ -3728,21 +3736,23 @@ mod tests {
transaction: txid,
sat_ranges: None,
indexed: true,
inscriptions: Vec::new(),
inscriptions: Some(Vec::new()),
outpoint: output,
runes: vec![(
SpacedRune {
rune: Rune(RUNE),
spacers: 0
},
Pile {
amount: 340282366920938463463374607431768211455,
divisibility: 1,
symbol: None,
}
)]
.into_iter()
.collect(),
runes: Some(
vec![(
SpacedRune {
rune: Rune(RUNE),
spacers: 0
},
Pile {
amount: 340282366920938463463374607431768211455,
divisibility: 1,
symbol: None,
}
)]
.into_iter()
.collect()
),
spent: false,
}
);
Expand Down
21 changes: 7 additions & 14 deletions src/subcommand/wallet/addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,12 @@ pub(crate) fn run(wallet: Wallet) -> SubcommandResult {
for (output, txout) in wallet.utxos() {
let address = wallet.chain().address_from_script(&txout.script_pubkey)?;

let inscriptions = if wallet.has_inscription_index() {
Some(wallet.get_inscriptions_in_output(output))
} else {
None
};
let inscriptions = wallet.get_inscriptions_in_output(output);

let runes = if wallet.has_rune_index() {
Some(
wallet
.get_runes_balances_in_output(output)?
let runes = wallet
.get_runes_balances_in_output(output)?
.map(|balances| {
balances
.iter()
.map(|(rune, pile)| {
(
Expand All @@ -36,11 +32,8 @@ pub(crate) fn run(wallet: Wallet) -> SubcommandResult {
},
)
})
.collect(),
)
} else {
None
};
.collect()
});

let output = Output {
output: *output,
Expand Down
4 changes: 3 additions & 1 deletion src/subcommand/wallet/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ pub(crate) fn run(wallet: Wallet) -> SubcommandResult {
let mut runic = 0;

for (output, txout) in unspent_outputs {
let rune_balances = wallet.get_runes_balances_in_output(output)?;
let rune_balances = wallet
.get_runes_balances_in_output(output)?
.unwrap_or_default();

let is_ordinal = inscription_outputs.contains(output);
let is_runic = !rune_balances.is_empty();
Expand Down
2 changes: 1 addition & 1 deletion src/subcommand/wallet/batch_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Batch {
}
.inscribe(
&locked_utxos.into_keys().collect(),
wallet.get_runic_outputs()?,
wallet.get_runic_outputs()?.unwrap_or_default(),
utxos,
&wallet,
)
Expand Down
Loading

0 comments on commit a0da0c1

Please sign in to comment.