mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-04 19:29:09 -07:00
workspace: reorg
This commit is contained in:
194
indexer/src/structs/addressbytes.rs
Normal file
194
indexer/src/structs/addressbytes.rs
Normal file
@@ -0,0 +1,194 @@
|
||||
use biter::bitcoin::ScriptBuf;
|
||||
use color_eyre::eyre::eyre;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
|
||||
use super::Addresstype;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Addressbytes {
|
||||
P2PK65(P2PK65AddressBytes),
|
||||
P2PK33(P2PK33AddressBytes),
|
||||
P2PKH(P2PKHAddressBytes),
|
||||
P2SH(P2SHAddressBytes),
|
||||
P2WPKH(P2WPKHAddressBytes),
|
||||
P2WSH(P2WSHAddressBytes),
|
||||
P2TR(P2TRAddressBytes),
|
||||
}
|
||||
|
||||
impl Addressbytes {
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
match self {
|
||||
Addressbytes::P2PK65(bytes) => &bytes[..],
|
||||
Addressbytes::P2PK33(bytes) => &bytes[..],
|
||||
Addressbytes::P2PKH(bytes) => &bytes[..],
|
||||
Addressbytes::P2SH(bytes) => &bytes[..],
|
||||
Addressbytes::P2WPKH(bytes) => &bytes[..],
|
||||
Addressbytes::P2WSH(bytes) => &bytes[..],
|
||||
Addressbytes::P2TR(bytes) => &bytes[..],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(&ScriptBuf, Addresstype)> for Addressbytes {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(tuple: (&ScriptBuf, Addresstype)) -> Result<Self, Self::Error> {
|
||||
let (script, addresstype) = tuple;
|
||||
|
||||
match addresstype {
|
||||
Addresstype::P2PK65 => {
|
||||
let bytes = script.as_bytes();
|
||||
let bytes = match bytes.len() {
|
||||
67 => &bytes[1..66],
|
||||
_ => {
|
||||
dbg!(bytes);
|
||||
return Err(eyre!("Wrong len"));
|
||||
}
|
||||
};
|
||||
Ok(Self::P2PK65(P2PK65AddressBytes(U8x65::from(bytes))))
|
||||
}
|
||||
Addresstype::P2PK33 => {
|
||||
let bytes = script.as_bytes();
|
||||
let bytes = match bytes.len() {
|
||||
35 => &bytes[1..34],
|
||||
_ => {
|
||||
dbg!(bytes);
|
||||
return Err(eyre!("Wrong len"));
|
||||
}
|
||||
};
|
||||
Ok(Self::P2PK33(P2PK33AddressBytes(U8x33::from(bytes))))
|
||||
}
|
||||
Addresstype::P2PKH => {
|
||||
let bytes = &script.as_bytes()[3..23];
|
||||
Ok(Self::P2PKH(P2PKHAddressBytes(U8x20::from(bytes))))
|
||||
}
|
||||
Addresstype::P2SH => {
|
||||
let bytes = &script.as_bytes()[2..22];
|
||||
Ok(Self::P2SH(P2SHAddressBytes(U8x20::from(bytes))))
|
||||
}
|
||||
Addresstype::P2WPKH => {
|
||||
let bytes = &script.as_bytes()[2..];
|
||||
Ok(Self::P2WPKH(P2WPKHAddressBytes(U8x20::from(bytes))))
|
||||
}
|
||||
Addresstype::P2WSH => {
|
||||
let bytes = &script.as_bytes()[2..];
|
||||
Ok(Self::P2WSH(P2WSHAddressBytes(U8x32::from(bytes))))
|
||||
}
|
||||
Addresstype::P2TR => {
|
||||
let bytes = &script.as_bytes()[2..];
|
||||
Ok(Self::P2TR(P2TRAddressBytes(U8x32::from(bytes))))
|
||||
}
|
||||
Addresstype::Multisig => Err(eyre!("multisig address type")),
|
||||
Addresstype::PushOnly => Err(eyre!("push_only address type")),
|
||||
Addresstype::Unknown => Err(eyre!("unknown address type")),
|
||||
Addresstype::Empty => Err(eyre!("empty address type")),
|
||||
Addresstype::OpReturn => Err(eyre!("op_return address type")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<P2PK65AddressBytes> for Addressbytes {
|
||||
fn from(value: P2PK65AddressBytes) -> Self {
|
||||
Self::P2PK65(value)
|
||||
}
|
||||
}
|
||||
impl From<P2PK33AddressBytes> for Addressbytes {
|
||||
fn from(value: P2PK33AddressBytes) -> Self {
|
||||
Self::P2PK33(value)
|
||||
}
|
||||
}
|
||||
impl From<P2PKHAddressBytes> for Addressbytes {
|
||||
fn from(value: P2PKHAddressBytes) -> Self {
|
||||
Self::P2PKH(value)
|
||||
}
|
||||
}
|
||||
impl From<P2SHAddressBytes> for Addressbytes {
|
||||
fn from(value: P2SHAddressBytes) -> Self {
|
||||
Self::P2SH(value)
|
||||
}
|
||||
}
|
||||
impl From<P2WPKHAddressBytes> for Addressbytes {
|
||||
fn from(value: P2WPKHAddressBytes) -> Self {
|
||||
Self::P2WPKH(value)
|
||||
}
|
||||
}
|
||||
impl From<P2WSHAddressBytes> for Addressbytes {
|
||||
fn from(value: P2WSHAddressBytes) -> Self {
|
||||
Self::P2WSH(value)
|
||||
}
|
||||
}
|
||||
impl From<P2TRAddressBytes> for Addressbytes {
|
||||
fn from(value: P2TRAddressBytes) -> Self {
|
||||
Self::P2TR(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2PK65AddressBytes(U8x65);
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2PK33AddressBytes(U8x33);
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2PKHAddressBytes(U8x20);
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2SHAddressBytes(U8x20);
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2WPKHAddressBytes(U8x20);
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2WSHAddressBytes(U8x32);
|
||||
|
||||
#[derive(Debug, Clone, Deref, PartialEq, Eq)]
|
||||
pub struct P2TRAddressBytes(U8x32);
|
||||
|
||||
#[derive(Debug, Clone, Deref, DerefMut, PartialEq, Eq)]
|
||||
pub struct U8x20([u8; 20]);
|
||||
impl From<&[u8]> for U8x20 {
|
||||
fn from(slice: &[u8]) -> Self {
|
||||
let mut arr = [0; 20];
|
||||
arr.copy_from_slice(slice);
|
||||
Self(arr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deref, DerefMut, PartialEq, Eq)]
|
||||
pub struct U8x32([u8; 32]);
|
||||
impl From<&[u8]> for U8x32 {
|
||||
fn from(slice: &[u8]) -> Self {
|
||||
let mut arr = [0; 32];
|
||||
arr.copy_from_slice(slice);
|
||||
Self(arr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deref, DerefMut, PartialEq, Eq)]
|
||||
pub struct U8x33([u8; 33]);
|
||||
impl From<&[u8]> for U8x33 {
|
||||
fn from(slice: &[u8]) -> Self {
|
||||
let mut arr = [0; 33];
|
||||
arr.copy_from_slice(slice);
|
||||
Self(arr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deref, DerefMut, PartialEq, Eq)]
|
||||
pub struct U8x64([u8; 64]);
|
||||
impl From<&[u8]> for U8x64 {
|
||||
fn from(slice: &[u8]) -> Self {
|
||||
let mut arr = [0; 64];
|
||||
arr.copy_from_slice(slice);
|
||||
Self(arr)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deref, DerefMut, PartialEq, Eq)]
|
||||
pub struct U8x65([u8; 65]);
|
||||
impl From<&[u8]> for U8x65 {
|
||||
fn from(slice: &[u8]) -> Self {
|
||||
let mut arr = [0; 65];
|
||||
arr.copy_from_slice(slice);
|
||||
Self(arr)
|
||||
}
|
||||
}
|
||||
63
indexer/src/structs/addressindex.rs
Normal file
63
indexer/src/structs/addressindex.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
use unsafe_slice_serde::UnsafeSliceSerde;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
|
||||
pub struct Addressindex(u32);
|
||||
// direct_repr!(Addressindex);
|
||||
|
||||
impl Addressindex {
|
||||
pub const BYTES: usize = size_of::<Self>();
|
||||
|
||||
pub fn decremented(self) -> Self {
|
||||
Self(*self - 1)
|
||||
}
|
||||
|
||||
pub fn increment(&mut self) {
|
||||
self.0 += 1;
|
||||
}
|
||||
|
||||
pub fn incremented(self) -> Self {
|
||||
Self(*self + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Addressindex {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Addressindex {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Addressindex> for u64 {
|
||||
fn from(value: Addressindex) -> Self {
|
||||
value.0 as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Addressindex {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Addressindex> for usize {
|
||||
fn from(value: Addressindex) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<fjall::Slice> for Addressindex {
|
||||
type Error = unsafe_slice_serde::Error;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<Addressindex> for fjall::Slice {
|
||||
fn from(value: Addressindex) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
54
indexer/src/structs/addresstype.rs
Normal file
54
indexer/src/structs/addresstype.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use biter::bitcoin::ScriptBuf;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Addresstype {
|
||||
P2PK65,
|
||||
P2PK33,
|
||||
P2PKH,
|
||||
P2SH,
|
||||
P2WPKH,
|
||||
P2WSH,
|
||||
P2TR,
|
||||
Multisig = 251,
|
||||
PushOnly = 252,
|
||||
OpReturn = 253,
|
||||
Empty = 254,
|
||||
Unknown = 255,
|
||||
}
|
||||
|
||||
impl From<&ScriptBuf> for Addresstype {
|
||||
fn from(script: &ScriptBuf) -> Self {
|
||||
if script.is_p2pk() {
|
||||
let bytes = script.as_bytes();
|
||||
|
||||
match bytes.len() {
|
||||
67 => Self::P2PK65,
|
||||
35 => Self::P2PK33,
|
||||
_ => {
|
||||
dbg!(bytes);
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
} else if script.is_p2pkh() {
|
||||
Self::P2PKH
|
||||
} else if script.is_p2sh() {
|
||||
Self::P2SH
|
||||
} else if script.is_p2wpkh() {
|
||||
Self::P2WPKH
|
||||
} else if script.is_p2wsh() {
|
||||
Self::P2WSH
|
||||
} else if script.is_p2tr() {
|
||||
Self::P2TR
|
||||
} else if script.is_empty() {
|
||||
Self::Empty
|
||||
} else if script.is_op_return() {
|
||||
Self::OpReturn
|
||||
} else if script.is_push_only() {
|
||||
Self::PushOnly
|
||||
} else if script.is_multisig() {
|
||||
Self::Multisig
|
||||
} else {
|
||||
Self::Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
54
indexer/src/structs/addresstypeindex.rs
Normal file
54
indexer/src/structs/addresstypeindex.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
|
||||
pub struct Addresstypeindex(u32);
|
||||
// direct_repr!(Addresstypeindex);
|
||||
|
||||
impl Addresstypeindex {
|
||||
pub fn decremented(self) -> Self {
|
||||
Self(*self - 1)
|
||||
}
|
||||
|
||||
pub fn increment(&mut self) {
|
||||
self.0 += 1;
|
||||
}
|
||||
|
||||
pub fn incremented(self) -> Self {
|
||||
Self(*self + 1)
|
||||
}
|
||||
|
||||
pub fn clone_then_increment(&mut self) -> Self {
|
||||
let i = *self;
|
||||
self.increment();
|
||||
i
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Addresstypeindex {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Addresstypeindex {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Addresstypeindex> for u64 {
|
||||
fn from(value: Addresstypeindex) -> Self {
|
||||
value.0 as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Addresstypeindex {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Addresstypeindex> for usize {
|
||||
fn from(value: Addresstypeindex) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
90
indexer/src/structs/amount.rs
Normal file
90
indexer/src/structs/amount.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use std::{
|
||||
iter::Sum,
|
||||
ops::{Add, AddAssign, Mul, Sub, SubAssign},
|
||||
};
|
||||
|
||||
use biter::bitcoin;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
|
||||
use super::Height;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
|
||||
pub struct Amount(bitcoin::Amount);
|
||||
// direct_repr!(Amount);
|
||||
|
||||
impl Amount {
|
||||
pub const ZERO: Self = Self(bitcoin::Amount::ZERO);
|
||||
pub const ONE_BTC_F32: f32 = 100_000_000.0;
|
||||
pub const ONE_BTC_F64: f64 = 100_000_000.0;
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
*self == Self::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Amount {
|
||||
type Output = Amount;
|
||||
fn add(self, rhs: Amount) -> Self::Output {
|
||||
Amount::from(self.to_sat() + rhs.to_sat())
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for Amount {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = Amount::from(self.to_sat() + rhs.to_sat());
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Amount {
|
||||
type Output = Amount;
|
||||
fn sub(self, rhs: Amount) -> Self::Output {
|
||||
Amount::from(self.to_sat() - rhs.to_sat())
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign for Amount {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = Amount::from(self.to_sat() - rhs.to_sat());
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Amount> for Amount {
|
||||
type Output = Amount;
|
||||
fn mul(self, rhs: Amount) -> Self::Output {
|
||||
Amount::from(self.to_sat() * rhs.to_sat())
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<u64> for Amount {
|
||||
type Output = Amount;
|
||||
fn mul(self, rhs: u64) -> Self::Output {
|
||||
Amount::from(self.to_sat() * rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Height> for Amount {
|
||||
type Output = Amount;
|
||||
fn mul(self, rhs: Height) -> Self::Output {
|
||||
Amount::from(self.to_sat() * *rhs as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sum for Amount {
|
||||
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
|
||||
let sats: u64 = iter.map(|amt| amt.to_sat()).sum();
|
||||
Amount::from(sats)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Amount {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(bitcoin::Amount::from_sat(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::Amount> for Amount {
|
||||
fn from(value: bitcoin::Amount) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
94
indexer/src/structs/compressed.rs
Normal file
94
indexer/src/structs/compressed.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use std::hash::Hasher;
|
||||
|
||||
use biter::bitcoin::{BlockHash, Txid};
|
||||
use derive_deref::Deref;
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
use unsafe_slice_serde::UnsafeSliceSerde;
|
||||
|
||||
use super::{Addressbytes, Addresstype, SliceExtended};
|
||||
|
||||
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct AddressHash([u8; 8]);
|
||||
// direct_repr!(AddressHash);
|
||||
impl From<(&Addressbytes, Addresstype)> for AddressHash {
|
||||
fn from((addressbytes, addresstype): (&Addressbytes, Addresstype)) -> Self {
|
||||
let mut hasher = rapidhash::RapidHasher::default();
|
||||
hasher.write(addressbytes.as_slice());
|
||||
let mut slice = hasher.finish().to_le_bytes();
|
||||
slice[0] = slice[0].wrapping_add(addresstype as u8);
|
||||
Self(slice)
|
||||
}
|
||||
}
|
||||
impl From<[u8; 8]> for AddressHash {
|
||||
fn from(value: [u8; 8]) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<fjall::Slice> for AddressHash {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<&AddressHash> for fjall::Slice {
|
||||
fn from(value: &AddressHash) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
impl From<AddressHash> for fjall::Slice {
|
||||
fn from(value: AddressHash) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct BlockHashPrefix([u8; 8]);
|
||||
// direct_repr!(BlockHashPrefix);
|
||||
impl TryFrom<&BlockHash> for BlockHashPrefix {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: &BlockHash) -> Result<Self, Self::Error> {
|
||||
Ok(Self((&value[..]).read_8x_u8()?))
|
||||
}
|
||||
}
|
||||
impl TryFrom<fjall::Slice> for BlockHashPrefix {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<&BlockHashPrefix> for fjall::Slice {
|
||||
fn from(value: &BlockHashPrefix) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
impl From<BlockHashPrefix> for fjall::Slice {
|
||||
fn from(value: BlockHashPrefix) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct TxidPrefix([u8; 8]);
|
||||
// direct_repr!(TxidPrefix);
|
||||
impl TryFrom<&Txid> for TxidPrefix {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: &Txid) -> Result<Self, Self::Error> {
|
||||
Ok(Self((&value[..]).read_8x_u8()?))
|
||||
}
|
||||
}
|
||||
impl TryFrom<fjall::Slice> for TxidPrefix {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<&TxidPrefix> for fjall::Slice {
|
||||
fn from(value: &TxidPrefix) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
impl From<TxidPrefix> for fjall::Slice {
|
||||
fn from(value: TxidPrefix) -> Self {
|
||||
Self::from(&value)
|
||||
}
|
||||
}
|
||||
133
indexer/src/structs/height.rs
Normal file
133
indexer/src/structs/height.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use std::{
|
||||
fmt, fs, io,
|
||||
ops::{Add, AddAssign, Rem, Sub},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use biter::rpc::{self, RpcApi};
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
use unsafe_slice_serde::UnsafeSliceSerde;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deref, DerefMut, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||
pub struct Height(u32);
|
||||
// direct_repr!(Height);
|
||||
|
||||
impl Height {
|
||||
pub fn write(&self, path: &Path) -> Result<(), io::Error> {
|
||||
fs::write(path, self.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<u64> for Height {
|
||||
fn eq(&self, other: &u64) -> bool {
|
||||
**self == *other as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<u32> for Height {
|
||||
type Output = Height;
|
||||
|
||||
fn add(self, rhs: u32) -> Self::Output {
|
||||
Self::from(*self + rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for Height {
|
||||
type Output = Height;
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
Self::from(*self + rhs as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Height> for Height {
|
||||
type Output = Height;
|
||||
|
||||
fn sub(self, rhs: Height) -> Self::Output {
|
||||
Self::from(*self - *rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<i32> for Height {
|
||||
type Output = Height;
|
||||
fn sub(self, rhs: i32) -> Self::Output {
|
||||
Self::from(*self - rhs as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<u32> for Height {
|
||||
type Output = Height;
|
||||
fn sub(self, rhs: u32) -> Self::Output {
|
||||
Self::from(*self - rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<usize> for Height {
|
||||
type Output = Height;
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
Self::from(*self - rhs as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<usize> for Height {
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
*self = self.add(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
impl Rem<usize> for Height {
|
||||
type Output = Height;
|
||||
fn rem(self, rhs: usize) -> Self::Output {
|
||||
Self(self.abs_diff(Height::from(rhs).0))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Height {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", **self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Height {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Height {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Height> for usize {
|
||||
fn from(value: Height) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&Path> for Height {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: &Path) -> Result<Self, Self::Error> {
|
||||
Ok(Self::unsafe_try_from_slice(fs::read(value)?.as_slice())?.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&rpc::Client> for Height {
|
||||
type Error = rpc::Error;
|
||||
fn try_from(value: &rpc::Client) -> Result<Self, Self::Error> {
|
||||
Ok((value.get_blockchain_info()?.blocks as usize - 1).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<fjall::Slice> for Height {
|
||||
type Error = unsafe_slice_serde::Error;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<Height> for fjall::Slice {
|
||||
fn from(value: Height) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
31
indexer/src/structs/mod.rs
Normal file
31
indexer/src/structs/mod.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
mod addressbytes;
|
||||
mod addressindex;
|
||||
mod addresstype;
|
||||
mod addresstypeindex;
|
||||
mod amount;
|
||||
mod compressed;
|
||||
mod height;
|
||||
mod slice;
|
||||
mod timestamp;
|
||||
mod txindex;
|
||||
mod txinindex;
|
||||
mod txoutindex;
|
||||
mod version;
|
||||
mod vin;
|
||||
mod vout;
|
||||
|
||||
pub use addressbytes::*;
|
||||
pub use addressindex::*;
|
||||
pub use addresstype::*;
|
||||
pub use addresstypeindex::*;
|
||||
pub use amount::*;
|
||||
pub use compressed::*;
|
||||
pub use height::*;
|
||||
pub use slice::*;
|
||||
pub use timestamp::*;
|
||||
pub use txindex::*;
|
||||
pub use txinindex::*;
|
||||
pub use txoutindex::*;
|
||||
pub use version::*;
|
||||
pub use vin::*;
|
||||
pub use vout::*;
|
||||
55
indexer/src/structs/slice.rs
Normal file
55
indexer/src/structs/slice.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use color_eyre::eyre::eyre;
|
||||
|
||||
#[allow(unused)]
|
||||
pub trait SliceExtended {
|
||||
fn read_8x_u8(&self) -> color_eyre::Result<[u8; 8]>;
|
||||
fn read_be_u8(&self) -> color_eyre::Result<u8>;
|
||||
fn read_be_u16(&self) -> color_eyre::Result<u16>;
|
||||
fn read_be_u32(&self) -> color_eyre::Result<u32>;
|
||||
fn read_be_u64(&self) -> color_eyre::Result<u64>;
|
||||
fn read_exact(&self, buf: &mut [u8]) -> color_eyre::Result<()>;
|
||||
}
|
||||
|
||||
impl SliceExtended for &[u8] {
|
||||
fn read_8x_u8(&self) -> color_eyre::Result<[u8; 8]> {
|
||||
let mut buf: [u8; 8] = [0; 8];
|
||||
(&self[..8]).read_exact(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
fn read_be_u8(&self) -> color_eyre::Result<u8> {
|
||||
let mut buf: [u8; 1] = [0; 1];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u8::from_be_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_be_u16(&self) -> color_eyre::Result<u16> {
|
||||
let mut buf: [u8; 2] = [0; 2];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u16::from_be_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_be_u32(&self) -> color_eyre::Result<u32> {
|
||||
let mut buf: [u8; 4] = [0; 4];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u32::from_be_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_be_u64(&self) -> color_eyre::Result<u64> {
|
||||
let mut buf: [u8; 8] = [0; 8];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u64::from_be_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_exact(&self, buf: &mut [u8]) -> color_eyre::Result<()> {
|
||||
let buf_len = buf.len();
|
||||
if self.len() != buf_len {
|
||||
dbg!(self.len(), buf_len);
|
||||
return Err(eyre!("Not exact len"));
|
||||
}
|
||||
self.iter().take(buf_len).enumerate().for_each(|(i, r)| {
|
||||
buf[i] = *r;
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
11
indexer/src/structs/timestamp.rs
Normal file
11
indexer/src/structs/timestamp.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use derive_deref::Deref;
|
||||
|
||||
#[derive(Debug, Deref, Clone)]
|
||||
pub struct Timestamp(jiff::Timestamp);
|
||||
|
||||
impl TryFrom<u32> for Timestamp {
|
||||
type Error = jiff::Error;
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
Ok(Self(jiff::Timestamp::from_second(value as i64)?))
|
||||
}
|
||||
}
|
||||
72
indexer/src/structs/txindex.rs
Normal file
72
indexer/src/structs/txindex.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
use unsafe_slice_serde::UnsafeSliceSerde;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
|
||||
pub struct Txindex(u32);
|
||||
// direct_repr!(Txindex);
|
||||
|
||||
impl Txindex {
|
||||
pub fn incremented(self) -> Self {
|
||||
Self(*self + 1)
|
||||
}
|
||||
|
||||
pub fn decremented(self) -> Self {
|
||||
Self(*self - 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Txindex> for Txindex {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Txindex) -> Self::Output {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Txindex> for Txindex {
|
||||
fn add_assign(&mut self, rhs: Txindex) {
|
||||
self.0 += rhs.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Txindex {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Txindex {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Txindex> for u64 {
|
||||
fn from(value: Txindex) -> Self {
|
||||
value.0 as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Txindex {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
impl From<Txindex> for usize {
|
||||
fn from(value: Txindex) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<fjall::Slice> for Txindex {
|
||||
type Error = unsafe_slice_serde::Error;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<Txindex> for fjall::Slice {
|
||||
fn from(value: Txindex) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
62
indexer/src/structs/txinindex.rs
Normal file
62
indexer/src/structs/txinindex.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
|
||||
use super::Vout;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
|
||||
pub struct Txinindex(u64);
|
||||
// direct_repr!(Txinindex);
|
||||
|
||||
impl Txinindex {
|
||||
pub fn incremented(self) -> Self {
|
||||
Self(*self + 1)
|
||||
}
|
||||
|
||||
pub fn decremented(self) -> Self {
|
||||
Self(*self - 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Txinindex> for Txinindex {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Txinindex) -> Self::Output {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Vout> for Txinindex {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Vout) -> Self::Output {
|
||||
Self(self.0 + u64::from(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Txinindex> for Txinindex {
|
||||
fn add_assign(&mut self, rhs: Txinindex) {
|
||||
self.0 += rhs.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Txinindex {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
impl From<Txinindex> for u64 {
|
||||
fn from(value: Txinindex) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Txinindex {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u64)
|
||||
}
|
||||
}
|
||||
impl From<Txinindex> for usize {
|
||||
fn from(value: Txinindex) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
68
indexer/src/structs/txoutindex.rs
Normal file
68
indexer/src/structs/txoutindex.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
// use snkrj::{direct_repr, Storable, UnsizedStorable};
|
||||
|
||||
use super::Vout;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deref, DerefMut, Default)]
|
||||
pub struct Txoutindex(u64);
|
||||
// direct_repr!(Txoutindex);
|
||||
|
||||
impl Txoutindex {
|
||||
pub const COINBASE: Self = Self(u64::MAX);
|
||||
|
||||
pub fn incremented(self) -> Self {
|
||||
Self(*self + 1)
|
||||
}
|
||||
|
||||
pub fn decremented(self) -> Self {
|
||||
Self(*self - 1)
|
||||
}
|
||||
|
||||
pub fn is_coinbase(self) -> bool {
|
||||
self == Self::COINBASE
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Txoutindex> for Txoutindex {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Txoutindex) -> Self::Output {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Vout> for Txoutindex {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Vout) -> Self::Output {
|
||||
Self(self.0 + u64::from(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Txoutindex> for Txoutindex {
|
||||
fn add_assign(&mut self, rhs: Txoutindex) {
|
||||
self.0 += rhs.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Txoutindex {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
impl From<Txoutindex> for u64 {
|
||||
fn from(value: Txoutindex) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Txoutindex {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u64)
|
||||
}
|
||||
}
|
||||
impl From<Txoutindex> for usize {
|
||||
fn from(value: Txoutindex) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
37
indexer/src/structs/version.rs
Normal file
37
indexer/src/structs/version.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use std::{fs, io, path::Path};
|
||||
|
||||
use unsafe_slice_serde::UnsafeSliceSerde;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Version(u32);
|
||||
|
||||
impl Version {
|
||||
pub fn write(&self, path: &Path) -> Result<(), io::Error> {
|
||||
fs::write(path, self.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Version {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&Path> for Version {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: &Path) -> Result<Self, Self::Error> {
|
||||
Ok(Self::unsafe_try_from_slice(fs::read(value)?.as_slice())?.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<fjall::Slice> for Version {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: fjall::Slice) -> Result<Self, Self::Error> {
|
||||
Ok(*Self::unsafe_try_from_slice(&value)?)
|
||||
}
|
||||
}
|
||||
impl From<Version> for fjall::Slice {
|
||||
fn from(value: Version) -> Self {
|
||||
Self::new(value.unsafe_as_slice())
|
||||
}
|
||||
}
|
||||
30
indexer/src/structs/vin.rs
Normal file
30
indexer/src/structs/vin.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use derive_deref::Deref;
|
||||
|
||||
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Vin(u32);
|
||||
|
||||
impl Vin {
|
||||
const ZERO: Self = Vin(0_u32);
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
*self == Self::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Vin {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Vin {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vin> for u64 {
|
||||
fn from(value: Vin) -> Self {
|
||||
value.0 as u64
|
||||
}
|
||||
}
|
||||
30
indexer/src/structs/vout.rs
Normal file
30
indexer/src/structs/vout.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use derive_deref::Deref;
|
||||
|
||||
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Vout(u32);
|
||||
|
||||
impl Vout {
|
||||
const ZERO: Self = Vout(0_u32);
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
*self == Self::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Vout {
|
||||
fn from(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Vout {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vout> for u64 {
|
||||
fn from(value: Vout) -> Self {
|
||||
value.0 as u64
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user