1use core::cmp::{self, Ordering};
42use core::convert::TryInto;
43use core::fmt::{self, Display, Formatter};
44
45use hashes::{siphash24, Hash};
46use internals::write_err;
47
48use crate::blockdata::block::Block;
49use crate::blockdata::script::Script;
50use crate::blockdata::transaction::OutPoint;
51use crate::consensus::encode::VarInt;
52use crate::consensus::{Decodable, Encodable};
53use crate::hash_types::{BlockHash, FilterHash, FilterHeader};
54use crate::io;
55use crate::prelude::*;
56
57const P: u8 = 19;
59const M: u64 = 784931;
60
61#[derive(Debug)]
63#[non_exhaustive]
64pub enum Error {
65 UtxoMissing(OutPoint),
67 Io(io::Error),
69}
70
71impl Display for Error {
72 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
73 use Error::*;
74
75 match *self {
76 UtxoMissing(ref coin) => write!(f, "unresolved UTXO {}", coin),
77 Io(ref e) => write_err!(f, "IO error"; e),
78 }
79 }
80}
81
82#[cfg(feature = "std")]
83impl std::error::Error for Error {
84 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
85 use Error::*;
86
87 match *self {
88 UtxoMissing(_) => None,
89 Io(ref e) => Some(e),
90 }
91 }
92}
93
94impl From<io::Error> for Error {
95 fn from(io: io::Error) -> Self {
96 Error::Io(io)
97 }
98}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
102pub struct BlockFilter {
103 pub content: Vec<u8>,
105}
106
107impl FilterHash {
108 pub fn filter_header(&self, previous_filter_header: &FilterHeader) -> FilterHeader {
110 let mut header_data = [0u8; 64];
111 header_data[0..32].copy_from_slice(&self[..]);
112 header_data[32..64].copy_from_slice(&previous_filter_header[..]);
113 FilterHeader::hash(&header_data)
114 }
115}
116
117impl BlockFilter {
118 pub fn new(content: &[u8]) -> BlockFilter {
120 BlockFilter { content: content.to_vec() }
121 }
122
123 pub fn new_script_filter<M, S>(block: &Block, script_for_coin: M) -> Result<BlockFilter, Error>
125 where
126 M: Fn(&OutPoint) -> Result<S, Error>,
127 S: Borrow<Script>,
128 {
129 let mut out = Vec::new();
130 let mut writer = BlockFilterWriter::new(&mut out, block);
131
132 writer.add_output_scripts();
133 writer.add_input_scripts(script_for_coin)?;
134 writer.finish()?;
135
136 Ok(BlockFilter { content: out })
137 }
138
139 pub fn filter_header(&self, previous_filter_header: &FilterHeader) -> FilterHeader {
143 let filter_hash = FilterHash::hash(self.content.as_slice());
144 filter_hash.filter_header(previous_filter_header)
145 }
146
147 pub fn match_any<I>(&self, block_hash: &BlockHash, query: I) -> Result<bool, Error>
149 where
150 I: Iterator,
151 I::Item: Borrow<[u8]>,
152 {
153 let filter_reader = BlockFilterReader::new(block_hash);
154 filter_reader.match_any(&mut self.content.as_slice(), query)
155 }
156
157 pub fn match_all<I>(&self, block_hash: &BlockHash, query: I) -> Result<bool, Error>
159 where
160 I: Iterator,
161 I::Item: Borrow<[u8]>,
162 {
163 let filter_reader = BlockFilterReader::new(block_hash);
164 filter_reader.match_all(&mut self.content.as_slice(), query)
165 }
166}
167
168pub struct BlockFilterWriter<'a, W> {
170 block: &'a Block,
171 writer: GcsFilterWriter<'a, W>,
172}
173
174impl<'a, W: io::Write> BlockFilterWriter<'a, W> {
175 pub fn new(writer: &'a mut W, block: &'a Block) -> BlockFilterWriter<'a, W> {
177 let block_hash_as_int = block.block_hash().to_byte_array();
178 let k0 = u64::from_le_bytes(block_hash_as_int[0..8].try_into().expect("8 byte slice"));
179 let k1 = u64::from_le_bytes(block_hash_as_int[8..16].try_into().expect("8 byte slice"));
180 let writer = GcsFilterWriter::new(writer, k0, k1, M, P);
181 BlockFilterWriter { block, writer }
182 }
183
184 pub fn add_output_scripts(&mut self) {
186 for transaction in &self.block.txdata {
187 for output in &transaction.output {
188 if !output.script_pubkey.is_op_return() {
189 self.add_element(output.script_pubkey.as_bytes());
190 }
191 }
192 }
193 }
194
195 pub fn add_input_scripts<M, S>(&mut self, script_for_coin: M) -> Result<(), Error>
197 where
198 M: Fn(&OutPoint) -> Result<S, Error>,
199 S: Borrow<Script>,
200 {
201 for script in self
202 .block
203 .txdata
204 .iter()
205 .skip(1) .flat_map(|t| t.input.iter().map(|i| &i.previous_output))
207 .map(script_for_coin)
208 {
209 match script {
210 Ok(script) => self.add_element(script.borrow().as_bytes()),
211 Err(e) => return Err(e),
212 }
213 }
214 Ok(())
215 }
216
217 pub fn add_element(&mut self, data: &[u8]) {
219 self.writer.add_element(data);
220 }
221
222 pub fn finish(&mut self) -> Result<usize, io::Error> {
224 self.writer.finish()
225 }
226}
227
228pub struct BlockFilterReader {
230 reader: GcsFilterReader,
231}
232
233impl BlockFilterReader {
234 pub fn new(block_hash: &BlockHash) -> BlockFilterReader {
236 let block_hash_as_int = block_hash.to_byte_array();
237 let k0 = u64::from_le_bytes(block_hash_as_int[0..8].try_into().expect("8 byte slice"));
238 let k1 = u64::from_le_bytes(block_hash_as_int[8..16].try_into().expect("8 byte slice"));
239 BlockFilterReader { reader: GcsFilterReader::new(k0, k1, M, P) }
240 }
241
242 pub fn match_any<I, R>(&self, reader: &mut R, query: I) -> Result<bool, Error>
244 where
245 I: Iterator,
246 I::Item: Borrow<[u8]>,
247 R: io::Read + ?Sized,
248 {
249 self.reader.match_any(reader, query)
250 }
251
252 pub fn match_all<I, R>(&self, reader: &mut R, query: I) -> Result<bool, Error>
254 where
255 I: Iterator,
256 I::Item: Borrow<[u8]>,
257 R: io::Read + ?Sized,
258 {
259 self.reader.match_all(reader, query)
260 }
261}
262
263pub struct GcsFilterReader {
265 filter: GcsFilter,
266 m: u64,
267}
268
269impl GcsFilterReader {
270 pub fn new(k0: u64, k1: u64, m: u64, p: u8) -> GcsFilterReader {
272 GcsFilterReader { filter: GcsFilter::new(k0, k1, p), m }
273 }
274
275 pub fn match_any<I, R>(&self, reader: &mut R, query: I) -> Result<bool, Error>
277 where
278 I: Iterator,
279 I::Item: Borrow<[u8]>,
280 R: io::Read + ?Sized,
281 {
282 let mut decoder = reader;
283 let n_elements: VarInt = Decodable::consensus_decode(&mut decoder).unwrap_or(VarInt(0));
284 let reader = &mut decoder;
285 let nm = n_elements.0 * self.m;
287 let mut mapped =
288 query.map(|e| map_to_range(self.filter.hash(e.borrow()), nm)).collect::<Vec<_>>();
289 mapped.sort_unstable();
291 if mapped.is_empty() {
292 return Ok(true);
293 }
294 if n_elements.0 == 0 {
295 return Ok(false);
296 }
297
298 let mut reader = BitStreamReader::new(reader);
300 let mut data = self.filter.golomb_rice_decode(&mut reader)?;
301 let mut remaining = n_elements.0 - 1;
302 for p in mapped {
303 loop {
304 match data.cmp(&p) {
305 Ordering::Equal => return Ok(true),
306 Ordering::Less => {
307 if remaining > 0 {
308 data += self.filter.golomb_rice_decode(&mut reader)?;
309 remaining -= 1;
310 } else {
311 return Ok(false);
312 }
313 }
314 Ordering::Greater => break,
315 }
316 }
317 }
318 Ok(false)
319 }
320
321 pub fn match_all<I, R>(&self, reader: &mut R, query: I) -> Result<bool, Error>
323 where
324 I: Iterator,
325 I::Item: Borrow<[u8]>,
326 R: io::Read + ?Sized,
327 {
328 let mut decoder = reader;
329 let n_elements: VarInt = Decodable::consensus_decode(&mut decoder).unwrap_or(VarInt(0));
330 let reader = &mut decoder;
331 let nm = n_elements.0 * self.m;
333 let mut mapped =
334 query.map(|e| map_to_range(self.filter.hash(e.borrow()), nm)).collect::<Vec<_>>();
335 mapped.sort_unstable();
337 mapped.dedup();
338 if mapped.is_empty() {
339 return Ok(true);
340 }
341 if n_elements.0 == 0 {
342 return Ok(false);
343 }
344
345 let mut reader = BitStreamReader::new(reader);
347 let mut data = self.filter.golomb_rice_decode(&mut reader)?;
348 let mut remaining = n_elements.0 - 1;
349 for p in mapped {
350 loop {
351 match data.cmp(&p) {
352 Ordering::Equal => break,
353 Ordering::Less => {
354 if remaining > 0 {
355 data += self.filter.golomb_rice_decode(&mut reader)?;
356 remaining -= 1;
357 } else {
358 return Ok(false);
359 }
360 }
361 Ordering::Greater => return Ok(false),
362 }
363 }
364 }
365 Ok(true)
366 }
367}
368
369fn map_to_range(hash: u64, nm: u64) -> u64 {
371 ((hash as u128 * nm as u128) >> 64) as u64
372}
373
374pub struct GcsFilterWriter<'a, W> {
376 filter: GcsFilter,
377 writer: &'a mut W,
378 elements: BTreeSet<Vec<u8>>,
379 m: u64,
380}
381
382impl<'a, W: io::Write> GcsFilterWriter<'a, W> {
383 pub fn new(writer: &'a mut W, k0: u64, k1: u64, m: u64, p: u8) -> GcsFilterWriter<'a, W> {
385 GcsFilterWriter { filter: GcsFilter::new(k0, k1, p), writer, elements: BTreeSet::new(), m }
386 }
387
388 pub fn add_element(&mut self, element: &[u8]) {
390 if !element.is_empty() {
391 self.elements.insert(element.to_vec());
392 }
393 }
394
395 pub fn finish(&mut self) -> Result<usize, io::Error> {
397 let nm = self.elements.len() as u64 * self.m;
398
399 let mut mapped: Vec<_> = self
401 .elements
402 .iter()
403 .map(|e| map_to_range(self.filter.hash(e.as_slice()), nm))
404 .collect();
405 mapped.sort_unstable();
406
407 let mut wrote = VarInt::from(mapped.len()).consensus_encode(&mut self.writer)?;
409
410 let mut writer = BitStreamWriter::new(self.writer);
412 let mut last = 0;
413 for data in mapped {
414 wrote += self.filter.golomb_rice_encode(&mut writer, data - last)?;
415 last = data;
416 }
417 wrote += writer.flush()?;
418 Ok(wrote)
419 }
420}
421
422struct GcsFilter {
424 k0: u64, k1: u64, p: u8,
427}
428
429impl GcsFilter {
430 fn new(k0: u64, k1: u64, p: u8) -> GcsFilter {
432 GcsFilter { k0, k1, p }
433 }
434
435 fn golomb_rice_encode<W>(
437 &self,
438 writer: &mut BitStreamWriter<'_, W>,
439 n: u64,
440 ) -> Result<usize, io::Error>
441 where
442 W: io::Write,
443 {
444 let mut wrote = 0;
445 let mut q = n >> self.p;
446 while q > 0 {
447 let nbits = cmp::min(q, 64);
448 wrote += writer.write(!0u64, nbits as u8)?;
449 q -= nbits;
450 }
451 wrote += writer.write(0, 1)?;
452 wrote += writer.write(n, self.p)?;
453 Ok(wrote)
454 }
455
456 fn golomb_rice_decode<R>(&self, reader: &mut BitStreamReader<R>) -> Result<u64, io::Error>
458 where
459 R: io::Read,
460 {
461 let mut q = 0u64;
462 while reader.read(1)? == 1 {
463 q += 1;
464 }
465 let r = reader.read(self.p)?;
466 Ok((q << self.p) + r)
467 }
468
469 fn hash(&self, element: &[u8]) -> u64 {
471 siphash24::Hash::hash_to_u64_with_keys(self.k0, self.k1, element)
472 }
473}
474
475pub struct BitStreamReader<'a, R> {
477 buffer: [u8; 1],
478 offset: u8,
479 reader: &'a mut R,
480}
481
482impl<'a, R: io::Read> BitStreamReader<'a, R> {
483 pub fn new(reader: &'a mut R) -> BitStreamReader<'a, R> {
485 BitStreamReader { buffer: [0u8], reader, offset: 8 }
486 }
487
488 pub fn read(&mut self, mut nbits: u8) -> Result<u64, io::Error> {
500 if nbits > 64 {
501 return Err(io::Error::new(
502 io::ErrorKind::Other,
503 "can not read more than 64 bits at once",
504 ));
505 }
506 let mut data = 0u64;
507 while nbits > 0 {
508 if self.offset == 8 {
509 self.reader.read_exact(&mut self.buffer)?;
510 self.offset = 0;
511 }
512 let bits = cmp::min(8 - self.offset, nbits);
513 data <<= bits;
514 data |= ((self.buffer[0] << self.offset) >> (8 - bits)) as u64;
515 self.offset += bits;
516 nbits -= bits;
517 }
518 Ok(data)
519 }
520}
521
522pub struct BitStreamWriter<'a, W> {
524 buffer: [u8; 1],
525 offset: u8,
526 writer: &'a mut W,
527}
528
529impl<'a, W: io::Write> BitStreamWriter<'a, W> {
530 pub fn new(writer: &'a mut W) -> BitStreamWriter<'a, W> {
532 BitStreamWriter { buffer: [0u8], writer, offset: 0 }
533 }
534
535 pub fn write(&mut self, data: u64, mut nbits: u8) -> Result<usize, io::Error> {
537 if nbits > 64 {
538 return Err(io::Error::new(
539 io::ErrorKind::Other,
540 "can not write more than 64 bits at once",
541 ));
542 }
543 let mut wrote = 0;
544 while nbits > 0 {
545 let bits = cmp::min(8 - self.offset, nbits);
546 self.buffer[0] |= ((data << (64 - nbits)) >> (64 - 8 + self.offset)) as u8;
547 self.offset += bits;
548 nbits -= bits;
549 if self.offset == 8 {
550 wrote += self.flush()?;
551 }
552 }
553 Ok(wrote)
554 }
555
556 pub fn flush(&mut self) -> Result<usize, io::Error> {
558 if self.offset > 0 {
559 self.writer.write_all(&self.buffer)?;
560 self.buffer[0] = 0u8;
561 self.offset = 0;
562 Ok(1)
563 } else {
564 Ok(0)
565 }
566 }
567}