core: init

This commit is contained in:
nym21
2025-02-24 14:08:51 +01:00
parent bc7a76755b
commit 53175c9ed7
65 changed files with 444 additions and 424 deletions

View File

@@ -0,0 +1,197 @@
use bitcoin::ScriptBuf;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::Error;
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 = Error;
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(Error::WrongLength);
}
};
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(Error::WrongLength);
}
};
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(Error::WrongAddressType),
Addresstype::PushOnly => Err(Error::WrongAddressType),
Addresstype::Unknown => Err(Error::WrongAddressType),
Addresstype::Empty => Err(Error::WrongAddressType),
Addresstype::OpReturn => Err(Error::WrongAddressType),
}
}
}
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, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2PK65AddressBytes(U8x65);
#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2PK33AddressBytes(U8x33);
#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2PKHAddressBytes(U8x20);
#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2SHAddressBytes(U8x20);
#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2WPKHAddressBytes(U8x20);
#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2WSHAddressBytes(U8x32);
#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct P2TRAddressBytes(U8x32);
#[derive(Debug, Clone, Deref, DerefMut, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
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, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
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, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct U8x33(#[serde(with = "serde_bytes")] [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, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct U8x64(#[serde(with = "serde_bytes")] [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, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct U8x65(#[serde(with = "serde_bytes")] [u8; 65]);
impl From<&[u8]> for U8x65 {
fn from(slice: &[u8]) -> Self {
let mut arr = [0; 65];
arr.copy_from_slice(slice);
Self(arr)
}
}

View File

@@ -0,0 +1,97 @@
use std::ops::Add;
use byteview::ByteView;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::Error;
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Addressindex(u32);
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<ByteView> for Addressindex {
type Error = Error;
fn try_from(value: ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<Addressindex> for ByteView {
fn from(value: Addressindex) -> Self {
Self::new(value.as_bytes())
}
}
impl Add<usize> for Addressindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs as u32)
}
}
impl Add<Addressindex> for Addressindex {
type Output = Self;
fn add(self, rhs: Addressindex) -> Self::Output {
Self(self.0 + rhs.0)
}
}

View File

@@ -0,0 +1,26 @@
use byteview::ByteView;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::Error;
use super::{Addressindex, Txoutindex};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Immutable, IntoBytes, KnownLayout, FromBytes)]
#[repr(C)]
pub struct AddressindexTxoutindex {
addressindex: Addressindex,
_padding: u32,
txoutindex: Txoutindex,
}
impl TryFrom<ByteView> for AddressindexTxoutindex {
type Error = Error;
fn try_from(value: ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<AddressindexTxoutindex> for ByteView {
fn from(value: AddressindexTxoutindex) -> Self {
Self::new(value.as_bytes())
}
}

View File

@@ -0,0 +1,59 @@
use bitcoin::ScriptBuf;
use serde::Serialize;
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, TryFromBytes, Immutable, IntoBytes, KnownLayout, Serialize,
)]
#[repr(u8)]
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
}
}
}

View File

@@ -0,0 +1,566 @@
use std::ops::Add;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Addresstypeindex(u32);
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 copy_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
}
}
impl Add<usize> for Addresstypeindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs as u32)
}
}
impl Add<Addresstypeindex> for Addresstypeindex {
type Output = Self;
fn add(self, rhs: Addresstypeindex) -> Self::Output {
Self(self.0 + rhs.0)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Emptyindex(Addresstypeindex);
impl From<Addresstypeindex> for Emptyindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<Emptyindex> for usize {
fn from(value: Emptyindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for Emptyindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for Emptyindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Multisigindex(Addresstypeindex);
impl From<Addresstypeindex> for Multisigindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<Multisigindex> for usize {
fn from(value: Multisigindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for Multisigindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for Multisigindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Opreturnindex(Addresstypeindex);
impl From<Addresstypeindex> for Opreturnindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<Opreturnindex> for usize {
fn from(value: Opreturnindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for Opreturnindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for Opreturnindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Pushonlyindex(Addresstypeindex);
impl From<Addresstypeindex> for Pushonlyindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<Pushonlyindex> for usize {
fn from(value: Pushonlyindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for Pushonlyindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for Pushonlyindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Unknownindex(Addresstypeindex);
impl From<Addresstypeindex> for Unknownindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<Unknownindex> for usize {
fn from(value: Unknownindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for Unknownindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for Unknownindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2PK33index(Addresstypeindex);
impl From<Addresstypeindex> for P2PK33index {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2PK33index> for usize {
fn from(value: P2PK33index) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2PK33index {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2PK33index {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2PK65index(Addresstypeindex);
impl From<Addresstypeindex> for P2PK65index {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2PK65index> for usize {
fn from(value: P2PK65index) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2PK65index {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2PK65index {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2PKHindex(Addresstypeindex);
impl From<Addresstypeindex> for P2PKHindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2PKHindex> for usize {
fn from(value: P2PKHindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2PKHindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2PKHindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2SHindex(Addresstypeindex);
impl From<Addresstypeindex> for P2SHindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2SHindex> for usize {
fn from(value: P2SHindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2SHindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2SHindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2TRindex(Addresstypeindex);
impl From<Addresstypeindex> for P2TRindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2TRindex> for usize {
fn from(value: P2TRindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2TRindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2TRindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2WPKHindex(Addresstypeindex);
impl From<Addresstypeindex> for P2WPKHindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2WPKHindex> for usize {
fn from(value: P2WPKHindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2WPKHindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2WPKHindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct P2WSHindex(Addresstypeindex);
impl From<Addresstypeindex> for P2WSHindex {
fn from(value: Addresstypeindex) -> Self {
Self(value)
}
}
impl From<P2WSHindex> for usize {
fn from(value: P2WSHindex) -> Self {
Self::from(*value)
}
}
impl From<usize> for P2WSHindex {
fn from(value: usize) -> Self {
Self(Addresstypeindex::from(value))
}
}
impl Add<usize> for P2WSHindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
}
}

View File

@@ -0,0 +1,14 @@
use super::Sats;
#[derive(Debug, Default, Clone, Copy)]
pub struct Bitcoin(f64);
impl Bitcoin {
const ONE: Self = Self(100_000_000.0);
}
impl From<Sats> for Bitcoin {
fn from(value: Sats) -> Self {
Self((*value as f64) / Self::ONE.0)
}
}

View File

@@ -0,0 +1,30 @@
use std::mem;
use bitcoincore_rpc::{Client, RpcApi};
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height;
#[derive(Debug, Deref, Clone, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct BlockHash([u8; 32]);
impl From<bitcoin::BlockHash> for BlockHash {
fn from(value: bitcoin::BlockHash) -> Self {
unsafe { mem::transmute(value) }
}
}
impl From<BlockHash> for bitcoin::BlockHash {
fn from(value: BlockHash) -> Self {
unsafe { mem::transmute(value) }
}
}
impl TryFrom<(&Client, Height)> for BlockHash {
type Error = bitcoincore_rpc::Error;
fn try_from((rpc, height): (&Client, Height)) -> Result<Self, Self::Error> {
Ok(Self::from(rpc.get_block_hash(u64::from(height))?))
}
}

View File

@@ -0,0 +1,29 @@
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Dollars;
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Deref,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Cents(u64);
impl From<Dollars> for Cents {
fn from(value: Dollars) -> Self {
Self((*value * 100.0).floor() as u64)
}
}

View File

@@ -0,0 +1,102 @@
use std::hash::Hasher;
use byteview::ByteView;
use derive_deref::Deref;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::Error;
use super::{Addressbytes, Addresstype, BlockHash, Txid};
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub struct AddressHash([u8; 8]);
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<ByteView> for AddressHash {
type Error = Error;
fn try_from(value: ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<&AddressHash> for ByteView {
fn from(value: &AddressHash) -> Self {
Self::new(value.as_bytes())
}
}
impl From<AddressHash> for ByteView {
fn from(value: AddressHash) -> Self {
Self::from(&value)
}
}
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub struct BlockHashPrefix([u8; 8]);
impl From<&BlockHash> for BlockHashPrefix {
fn from(value: &BlockHash) -> Self {
Self(copy_first_8bytes(&value[..]).unwrap())
}
}
impl TryFrom<ByteView> for BlockHashPrefix {
type Error = Error;
fn try_from(value: ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<&BlockHashPrefix> for ByteView {
fn from(value: &BlockHashPrefix) -> Self {
Self::new(value.as_bytes())
}
}
impl From<BlockHashPrefix> for ByteView {
fn from(value: BlockHashPrefix) -> Self {
Self::from(&value)
}
}
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub struct TxidPrefix([u8; 8]);
impl From<&Txid> for TxidPrefix {
fn from(value: &Txid) -> Self {
Self(copy_first_8bytes(&value[..]).unwrap())
}
}
impl TryFrom<ByteView> for TxidPrefix {
type Error = Error;
fn try_from(value: ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<&TxidPrefix> for ByteView {
fn from(value: &TxidPrefix) -> Self {
Self::new(value.as_bytes())
}
}
impl From<TxidPrefix> for ByteView {
fn from(value: TxidPrefix) -> Self {
Self::from(&value)
}
}
fn copy_first_8bytes(slice: &[u8]) -> Result<[u8; 8], ()> {
let mut buf: [u8; 8] = [0; 8];
let buf_len = buf.len();
if slice.len() < buf_len {
return Err(());
}
slice.iter().take(buf_len).enumerate().for_each(|(i, r)| {
buf[i] = *r;
});
Ok(buf)
}

View File

@@ -0,0 +1,60 @@
use jiff::{Span, civil::Date as Date_, tz::TimeZone};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Dateindex, Timestamp};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub struct Date(u32);
impl Date {
pub const INDEX_ZERO: Self = Self(20090103);
pub const INDEX_ZERO_: Date_ = Date_::constant(2009, 1, 3);
pub const INDEX_ONE: Self = Self(20090109);
pub const INDEX_ONE_: Date_ = Date_::constant(2009, 1, 9);
pub fn year(&self) -> u16 {
(self.0 / 1_00_00) as u16
}
pub fn month(&self) -> u8 {
((self.0 % 1_00_00) / 1_00) as u8
}
pub fn day(&self) -> u8 {
(self.0 % 1_00) as u8
}
}
impl Default for Date {
fn default() -> Self {
Self::INDEX_ZERO
}
}
impl From<Date_> for Date {
fn from(value: Date_) -> Self {
Self(value.year() as u32 * 1_00_00 + value.month() as u32 * 1_00 + value.day() as u32)
}
}
impl From<Date> for Date_ {
fn from(value: Date) -> Self {
Self::new(value.year() as i16, value.month() as i8, value.day() as i8).unwrap()
}
}
impl From<Timestamp> for Date {
fn from(value: Timestamp) -> Self {
Self::from(Date_::from(jiff::Timestamp::from(value).to_zoned(TimeZone::UTC)))
}
}
impl From<Dateindex> for Date {
fn from(value: Dateindex) -> Self {
Self::from(
Self::INDEX_ZERO_
.checked_add(Span::new().days(i64::from(value)))
.unwrap(),
)
}
}

View File

@@ -0,0 +1,54 @@
use std::ops::Add;
// use color_eyre::eyre::eyre;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::Error;
use super::Date;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout)]
pub struct Dateindex(u16);
impl From<Dateindex> for usize {
fn from(value: Dateindex) -> Self {
value.0 as usize
}
}
impl From<usize> for Dateindex {
fn from(value: usize) -> Self {
Self(value as u16)
}
}
impl From<Dateindex> for i64 {
fn from(value: Dateindex) -> Self {
value.0 as i64
}
}
impl Add<usize> for Dateindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs as u16)
}
}
impl TryFrom<Date> for Dateindex {
type Error = Error;
fn try_from(value: Date) -> Result<Self, Self::Error> {
let value_ = jiff::civil::Date::from(value);
if value_ < Date::INDEX_ZERO_ {
Err(Error::UnindexableDate)
} else if value == Date::INDEX_ZERO {
Ok(Self(0))
} else if value_ < Date::INDEX_ONE_ {
Err(Error::UnindexableDate)
} else if value == Date::INDEX_ONE {
Ok(Self(1))
} else {
Ok(Self(Date::INDEX_ONE_.until(value_)?.get_days() as u16 + 1))
}
}
}

View File

@@ -0,0 +1,20 @@
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Cents;
#[derive(Debug, Default, Clone, Copy, Deref, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
pub struct Dollars(f64);
impl From<f64> for Dollars {
fn from(value: f64) -> Self {
Self(value)
}
}
impl From<Cents> for Dollars {
fn from(value: Cents) -> Self {
Self((*value as f64) / 100.0)
}
}

View File

@@ -0,0 +1,4 @@
use derive_deref::Deref;
#[derive(Debug, Deref, Clone, Copy)]
pub struct Feerate(f32);

View File

@@ -0,0 +1,210 @@
use std::{
fmt::{self, Debug},
ops::{Add, AddAssign, Rem, Sub},
};
use bitcoincore_rpc::{Client, RpcApi};
use derive_deref::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[derive(
Debug,
Clone,
Copy,
Deref,
DerefMut,
PartialEq,
Eq,
PartialOrd,
Ord,
Default,
Serialize,
Deserialize,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
)]
pub struct Height(u32);
impl Height {
pub const ZERO: Self = Height(0);
pub const MAX: Self = Height(u32::MAX);
pub fn write(&self, path: &std::path::Path) -> Result<(), std::io::Error> {
std::fs::write(path, self.as_bytes())
}
pub fn increment(&mut self) {
self.0 += 1;
}
pub fn incremented(self) -> Self {
Self(self.0 + 1)
}
pub fn decrement(&mut self) {
self.0 -= 1;
}
pub fn decremented(self) -> Self {
Self(self.0.checked_sub(1).unwrap_or_default())
}
pub fn is_zero(self) -> bool {
self == Self::ZERO
}
}
impl PartialEq<u64> for Height {
fn eq(&self, other: &u64) -> bool {
**self == *other as u32
}
}
impl Add<Height> for Height {
type Output = Height;
fn add(self, rhs: Height) -> Self::Output {
Self::from(self.0 + rhs.0)
}
}
impl Add<u32> for Height {
type Output = Height;
fn add(self, rhs: u32) -> Self::Output {
Self::from(self.0 + 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<Height> for Height {
type Output = Height;
fn rem(self, rhs: Height) -> Self::Output {
Self(self.0.rem(rhs.0))
}
}
impl Rem<usize> for Height {
type Output = Height;
fn rem(self, rhs: usize) -> Self::Output {
Self(self.0.rem(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<u64> for Height {
fn from(value: u64) -> Self {
Self(value as u32)
}
}
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 From<Height> for u64 {
fn from(value: Height) -> Self {
value.0 as u64
}
}
impl TryFrom<&Client> for Height {
type Error = bitcoincore_rpc::Error;
fn try_from(value: &Client) -> Result<Self, Self::Error> {
Ok((value.get_blockchain_info()?.blocks as usize - 1).into())
}
}
impl From<bitcoin::locktime::absolute::Height> for Height {
fn from(value: bitcoin::locktime::absolute::Height) -> Self {
Self(value.to_consensus_u32())
}
}
impl From<Height> for bitcoin::locktime::absolute::Height {
fn from(value: Height) -> Self {
bitcoin::locktime::absolute::Height::from_consensus(*value).unwrap()
}
}
impl TryFrom<&std::path::Path> for Height {
type Error = crate::Error;
fn try_from(value: &std::path::Path) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(std::fs::read(value)?.as_slice())?.to_owned())
}
}
impl TryFrom<byteview::ByteView> for Height {
type Error = crate::Error;
fn try_from(value: byteview::ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<Height> for byteview::ByteView {
fn from(value: Height) -> Self {
Self::new(value.as_bytes())
}
}

View File

@@ -0,0 +1,29 @@
use serde::Serialize;
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
use super::{Height, Timestamp};
#[derive(Debug, Immutable, Clone, Copy, IntoBytes, KnownLayout, TryFromBytes, Serialize)]
#[repr(C)]
pub enum LockTime {
Height(Height),
Timestamp(Timestamp),
}
impl From<bitcoin::absolute::LockTime> for LockTime {
fn from(value: bitcoin::absolute::LockTime) -> Self {
match value {
bitcoin::absolute::LockTime::Blocks(h) => LockTime::Height(h.into()),
bitcoin::absolute::LockTime::Seconds(t) => LockTime::Timestamp(t.into()),
}
}
}
impl From<LockTime> for bitcoin::absolute::LockTime {
fn from(value: LockTime) -> Self {
match value {
LockTime::Height(h) => bitcoin::absolute::LockTime::Blocks(h.into()),
LockTime::Timestamp(t) => bitcoin::absolute::LockTime::Seconds(t.into()),
}
}
}

View File

@@ -0,0 +1,55 @@
mod addressbytes;
mod addressindex;
mod addressindextxoutindex;
mod addresstype;
mod addresstypeindex;
mod bitcoin;
mod blockhash;
mod cents;
mod compressed;
mod date;
mod dateindex;
mod dollars;
mod feerate;
mod height;
mod locktime;
mod ohlc;
mod sats;
mod timestamp;
mod txid;
mod txindex;
mod txinindex;
mod txoutindex;
mod txversion;
mod unit;
mod vin;
mod vout;
mod weight;
pub use addressbytes::*;
pub use addressindex::*;
pub use addressindextxoutindex::*;
pub use addresstype::*;
pub use addresstypeindex::*;
pub use bitcoin::*;
pub use blockhash::*;
pub use cents::*;
pub use compressed::*;
pub use date::*;
pub use dateindex::*;
pub use dollars::*;
pub use feerate::*;
pub use height::*;
pub use locktime::*;
pub use ohlc::*;
pub use sats::*;
pub use timestamp::*;
pub use txid::*;
pub use txindex::*;
pub use txinindex::*;
pub use txoutindex::*;
pub use txversion::*;
pub use unit::*;
pub use vin::*;
pub use vout::*;
pub use weight::*;

View File

@@ -0,0 +1,130 @@
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Cents;
pub type OHLCCents = (Open<Cents>, High<Cents>, Low<Cents>, Close<Cents>);
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Deref,
Serialize,
)]
#[repr(C)]
pub struct Open<T>(T);
impl<T> From<T> for Open<T> {
fn from(value: T) -> Self {
Self(value)
}
}
impl<T> From<Close<T>> for Open<T>
where
T: Copy,
{
fn from(value: Close<T>) -> Self {
Self(*value)
}
}
#[derive(
Debug,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Deref,
Serialize,
)]
#[repr(C)]
pub struct High<T>(T);
impl<T> From<T> for High<T> {
fn from(value: T) -> Self {
Self(value)
}
}
impl<T> From<Close<T>> for High<T>
where
T: Copy,
{
fn from(value: Close<T>) -> Self {
Self(*value)
}
}
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Deref,
Serialize,
)]
#[repr(C)]
pub struct Low<T>(T);
impl<T> From<T> for Low<T> {
fn from(value: T) -> Self {
Self(value)
}
}
impl<T> From<Close<T>> for Low<T>
where
T: Copy,
{
fn from(value: Close<T>) -> Self {
Self(*value)
}
}
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Deref,
Serialize,
)]
#[repr(C)]
pub struct Close<T>(T);
impl<T> From<T> for Close<T> {
fn from(value: T) -> Self {
Self(value)
}
}

View File

@@ -0,0 +1,109 @@
use std::{
iter::Sum,
ops::{Add, AddAssign, Mul, Sub, SubAssign},
};
use bitcoin::Amount;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height;
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Sats(u64);
impl Sats {
pub const ZERO: Self = Self(0);
pub fn is_zero(&self) -> bool {
*self == Self::ZERO
}
}
impl Add for Sats {
type Output = Sats;
fn add(self, rhs: Sats) -> Self::Output {
Sats::from(*self + *rhs)
}
}
impl AddAssign for Sats {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl Sub for Sats {
type Output = Sats;
fn sub(self, rhs: Sats) -> Self::Output {
Sats::from(*self - *rhs)
}
}
impl SubAssign for Sats {
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
impl Mul<Sats> for Sats {
type Output = Sats;
fn mul(self, rhs: Sats) -> Self::Output {
Sats::from(*self * *rhs)
}
}
impl Mul<u64> for Sats {
type Output = Sats;
fn mul(self, rhs: u64) -> Self::Output {
Sats::from(*self * rhs)
}
}
impl Mul<Height> for Sats {
type Output = Sats;
fn mul(self, rhs: Height) -> Self::Output {
Sats::from(*self * *rhs as u64)
}
}
impl Sum for Sats {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sats: u64 = iter.map(|sats| *sats).sum();
Sats::from(sats)
}
}
impl From<u64> for Sats {
fn from(value: u64) -> Self {
Self(value)
}
}
impl From<Amount> for Sats {
fn from(value: Amount) -> Self {
Self(value.to_sat())
}
}
impl From<Sats> for Amount {
fn from(value: Sats) -> Self {
Self::from_sat(value.0)
}
}

View File

@@ -0,0 +1,32 @@
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[derive(
Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize,
)]
pub struct Timestamp(u32);
impl From<u32> for Timestamp {
fn from(value: u32) -> Self {
Self(value)
}
}
impl From<Timestamp> for jiff::Timestamp {
fn from(value: Timestamp) -> Self {
jiff::Timestamp::from_second(*value as i64).unwrap()
}
}
impl From<bitcoin::locktime::absolute::Time> for Timestamp {
fn from(value: bitcoin::locktime::absolute::Time) -> Self {
Self(value.to_consensus_u32())
}
}
impl From<Timestamp> for bitcoin::locktime::absolute::Time {
fn from(value: Timestamp) -> Self {
bitcoin::locktime::absolute::Time::from_consensus(*value).unwrap()
}
}

View File

@@ -0,0 +1,20 @@
use std::mem;
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[derive(Debug, Deref, Clone, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct Txid([u8; 32]);
impl From<bitcoin::Txid> for Txid {
fn from(value: bitcoin::Txid) -> Self {
unsafe { mem::transmute(value) }
}
}
impl From<Txid> for bitcoin::Txid {
fn from(value: Txid) -> Self {
unsafe { mem::transmute(value) }
}
}

View File

@@ -0,0 +1,104 @@
use std::ops::{Add, AddAssign, Sub};
use byteview::ByteView;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::Error;
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Txindex(u32);
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 Add<usize> for Txindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs as u32)
}
}
impl AddAssign<Txindex> for Txindex {
fn add_assign(&mut self, rhs: Txindex) {
self.0 += rhs.0
}
}
impl Sub<Txindex> for Txindex {
type Output = Txindex;
fn sub(self, rhs: Txindex) -> Self::Output {
Self::from(*self - *rhs)
}
}
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<ByteView> for Txindex {
type Error = Error;
fn try_from(value: ByteView) -> Result<Self, Self::Error> {
Ok(Self::read_from_bytes(&value)?)
}
}
impl From<Txindex> for ByteView {
fn from(value: Txindex) -> Self {
Self::new(value.as_bytes())
}
}

View File

@@ -0,0 +1,101 @@
use std::ops::{Add, AddAssign, Sub};
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Vin;
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Txinindex(u64);
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<Vin> for Txinindex {
type Output = Self;
fn add(self, rhs: Vin) -> Self::Output {
Self(self.0 + u64::from(rhs))
}
}
impl Add<usize> for Txinindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs as u64)
}
}
impl AddAssign<Txinindex> for Txinindex {
fn add_assign(&mut self, rhs: Txinindex) {
self.0 += rhs.0
}
}
impl Sub<Txinindex> for Txinindex {
type Output = Self;
fn sub(self, rhs: Txinindex) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl From<Txinindex> for u32 {
fn from(value: Txinindex) -> Self {
if value.0 > u32::MAX as u64 {
panic!()
}
value.0 as u32
}
}
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
}
}

View File

@@ -0,0 +1,107 @@
use std::ops::{Add, AddAssign, Sub};
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Vout;
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
DerefMut,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct Txoutindex(u64);
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 Add<usize> for Txoutindex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs as u64)
}
}
impl AddAssign<Txoutindex> for Txoutindex {
fn add_assign(&mut self, rhs: Txoutindex) {
self.0 += rhs.0
}
}
impl Sub<Txoutindex> for Txoutindex {
type Output = Self;
fn sub(self, rhs: Txoutindex) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl From<Txoutindex> for u32 {
fn from(value: Txoutindex) -> Self {
if value.0 > u32::MAX as u64 {
panic!()
}
value.0 as u32
}
}
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
}
}

View File

@@ -0,0 +1,18 @@
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[derive(Debug, Deref, Clone, Copy, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct TxVersion(i32);
impl From<bitcoin::transaction::Version> for TxVersion {
fn from(value: bitcoin::transaction::Version) -> Self {
Self(value.0)
}
}
impl From<TxVersion> for bitcoin::transaction::Version {
fn from(value: TxVersion) -> Self {
Self(value.0)
}
}

View File

@@ -0,0 +1,13 @@
use byteview::ByteView;
pub struct Unit();
impl From<ByteView> for Unit {
fn from(_: ByteView) -> Self {
Self()
}
}
impl From<Unit> for ByteView {
fn from(_: Unit) -> Self {
Self::new(&[])
}
}

View File

@@ -0,0 +1,31 @@
use derive_deref::Deref;
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Vin(u32);
impl Vin {
pub const ZERO: Self = Vin(0);
pub const ONE: Self = Vin(1);
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
}
}

View 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);
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
}
}

View File

@@ -0,0 +1,18 @@
use derive_deref::Deref;
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
#[derive(Debug, Deref, Clone, Copy, Immutable, IntoBytes, KnownLayout, FromBytes, Serialize)]
pub struct Weight(u64);
impl From<bitcoin::Weight> for Weight {
fn from(value: bitcoin::Weight) -> Self {
Self(value.to_wu())
}
}
impl From<Weight> for bitcoin::Weight {
fn from(value: Weight) -> Self {
Self::from_wu(*value)
}
}