fix p2pk hash-prefix lookup

This commit is contained in:
Matt Faltyn
2026-07-14 20:28:05 +02:00
parent 8d43f340a0
commit a1cd6fa3da
+69 -35
View File
@@ -16,50 +16,57 @@ impl Query {
}
let prefix = AddrHashPrefix::parse(prefix)?;
let store = self
.indexer()
.stores
.addr_type_to_addr_hash_to_addr_index
.get(addr_type)
.data()?;
let safe_type_index = self.safe_lengths().to_type_index(addr_type);
let addr_readers = self.indexer().vecs.addrs.addr_readers();
let mut addresses = Vec::new();
let max_hash = AddrHash::new(u64::MAX);
if let Some(upper) = prefix.upper {
for (_, type_index) in store.range(prefix.lower..upper) {
if type_index >= safe_type_index {
continue;
for &search_type in matching_addr_types(&addr_type) {
let store = self
.indexer()
.stores
.addr_type_to_addr_hash_to_addr_index
.get(search_type)
.data()?;
let safe_type_index = self.safe_lengths().to_type_index(search_type);
if let Some(upper) = prefix.upper {
for (_, type_index) in store.range(prefix.lower..upper) {
if type_index >= safe_type_index {
continue;
}
let script = addr_readers.script_pubkey(search_type, type_index);
addresses.push(Addr::try_from((&script, search_type))?);
if addresses.len() > ADDR_HASH_PREFIX_MATCH_LIMIT {
break;
}
}
} else {
for (_, type_index) in store.range(prefix.lower..max_hash) {
if type_index >= safe_type_index {
continue;
}
let script = addr_readers.script_pubkey(search_type, type_index);
addresses.push(Addr::try_from((&script, search_type))?);
if addresses.len() > ADDR_HASH_PREFIX_MATCH_LIMIT {
break;
}
}
let script = addr_readers.script_pubkey(addr_type, type_index);
addresses.push(Addr::try_from((&script, addr_type))?);
if addresses.len() > ADDR_HASH_PREFIX_MATCH_LIMIT {
break;
}
}
} else {
for (_, type_index) in store.range(prefix.lower..max_hash) {
if type_index >= safe_type_index {
continue;
}
let script = addr_readers.script_pubkey(addr_type, type_index);
addresses.push(Addr::try_from((&script, addr_type))?);
if addresses.len() > ADDR_HASH_PREFIX_MATCH_LIMIT {
break;
if addresses.len() <= ADDR_HASH_PREFIX_MATCH_LIMIT
&& let Some(type_index) = store.get(&max_hash)?.map(|cow| cow.into_owned())
&& type_index < safe_type_index
{
let script = addr_readers.script_pubkey(search_type, type_index);
addresses.push(Addr::try_from((&script, search_type))?);
}
}
if addresses.len() <= ADDR_HASH_PREFIX_MATCH_LIMIT
&& let Some(type_index) = store.get(&max_hash)?.map(|cow| cow.into_owned())
&& type_index < safe_type_index
{
let script = addr_readers.script_pubkey(addr_type, type_index);
addresses.push(Addr::try_from((&script, addr_type))?);
if addresses.len() > ADDR_HASH_PREFIX_MATCH_LIMIT {
break;
}
}
@@ -75,6 +82,13 @@ impl Query {
}
}
fn matching_addr_types(addr_type: &OutputType) -> &[OutputType] {
match addr_type {
OutputType::P2PK65 | OutputType::P2PK33 => &[OutputType::P2PK65, OutputType::P2PK33],
_ => std::slice::from_ref(addr_type),
}
}
struct AddrHashPrefix {
text: String,
lower: AddrHash,
@@ -113,3 +127,23 @@ impl AddrHashPrefix {
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn p2pk_wire_type_searches_both_internal_types() {
let wire_type: OutputType = serde_json::from_str(r#""p2pk""#).unwrap();
assert_eq!(wire_type, OutputType::P2PK65);
assert_eq!(
matching_addr_types(&wire_type),
&[OutputType::P2PK65, OutputType::P2PK33]
);
assert_eq!(
matching_addr_types(&OutputType::P2PKH),
&[OutputType::P2PKH]
);
}
}