Bitcoin ScannerFeed

This commit is contained in:
Luke Parker
2024-09-10 07:07:09 -04:00
parent e36b671f37
commit ba3a6f9e91
8 changed files with 84 additions and 7 deletions

View File

@@ -8,10 +8,10 @@ use serai_client::networks::bitcoin::Address;
use primitives::{ReceivedOutput, EventualityTracker};
use crate::{hash_bytes, scanner::scanner, output::Output, transaction::Eventuality};
use crate::{hash_bytes, scan::scanner, output::Output, transaction::Eventuality};
#[derive(Clone, Debug)]
pub(crate) struct BlockHeader(Header);
pub(crate) struct BlockHeader(pub(crate) Header);
impl primitives::BlockHeader for BlockHeader {
fn id(&self) -> [u8; 32] {
hash_bytes(self.0.block_hash().to_raw_hash())
@@ -22,7 +22,7 @@ impl primitives::BlockHeader for BlockHeader {
}
#[derive(Clone, Debug)]
pub(crate) struct Block(BBlock);
pub(crate) struct Block(pub(crate) BBlock);
#[async_trait::async_trait]
impl primitives::Block for Block {

View File

@@ -6,12 +6,19 @@
static ALLOCATOR: zalloc::ZeroizingAlloc<std::alloc::System> =
zalloc::ZeroizingAlloc(std::alloc::System);
mod scanner;
// Internal utilities for scanning transactions
mod scan;
// Output trait satisfaction
mod output;
// Transaction/SignableTransaction/Eventuality trait satisfaction
mod transaction;
// Block trait satisfaction
mod block;
// ScannerFeed trait satisfaction
mod scanner_feed;
pub(crate) fn hash_bytes(hash: bitcoin_serai::bitcoin::hashes::sha256d::Hash) -> [u8; 32] {
use bitcoin_serai::bitcoin::hashes::Hash;

View File

@@ -23,7 +23,7 @@ use serai_client::{
use primitives::{OutputType, ReceivedOutput};
use crate::scanner::{offsets_for_key, presumed_origin, extract_serai_data};
use crate::scan::{offsets_for_key, presumed_origin, extract_serai_data};
#[derive(Clone, PartialEq, Eq, Hash, Debug, Encode, Decode, BorshSerialize, BorshDeserialize)]
pub(crate) struct OutputId([u8; 36]);

View File

@@ -0,0 +1,62 @@
use bitcoin_serai::rpc::{RpcError, Rpc as BRpc};
use serai_client::primitives::{NetworkId, Coin, Amount};
use scanner::ScannerFeed;
use crate::block::{BlockHeader, Block};
#[derive(Clone)]
pub(crate) struct Rpc(BRpc);
#[async_trait::async_trait]
impl ScannerFeed for Rpc {
const NETWORK: NetworkId = NetworkId::Bitcoin;
const CONFIRMATIONS: u64 = 6;
const WINDOW_LENGTH: u64 = 6;
const TEN_MINUTES: u64 = 1;
type Block = Block;
type EphemeralError = RpcError;
async fn latest_finalized_block_number(&self) -> Result<u64, Self::EphemeralError> {
u64::try_from(self.0.get_latest_block_number().await?)
.unwrap()
.checked_sub(Self::CONFIRMATIONS)
.ok_or(RpcError::ConnectionError)
}
async fn unchecked_block_header_by_number(
&self,
number: u64,
) -> Result<<Self::Block as primitives::Block>::Header, Self::EphemeralError> {
Ok(BlockHeader(
self.0.get_block(&self.0.get_block_hash(number.try_into().unwrap()).await?).await?.header,
))
}
async fn unchecked_block_by_number(
&self,
number: u64,
) -> Result<Self::Block, Self::EphemeralError> {
Ok(Block(self.0.get_block(&self.0.get_block_hash(number.try_into().unwrap()).await?).await?))
}
fn dust(coin: Coin) -> Amount {
assert_eq!(coin, Coin::Bitcoin);
// 10,000 satoshis, or $5 if 1 BTC = 50,000 USD
Amount(10_000)
}
async fn cost_to_aggregate(
&self,
coin: Coin,
_reference_block: &Self::Block,
) -> Result<Amount, Self::EphemeralError> {
assert_eq!(coin, Coin::Bitcoin);
// TODO
Ok(Amount(0))
}
}