#[cfg(feature = "wallet_essentials")]
use std::io::{Read, Write};
#[cfg(feature = "wallet_essentials")]
use byteorder::{ReadBytesExt, WriteBytesExt};
#[derive(Default, Debug, Clone, Copy)]
pub enum PerformanceLevel {
Low,
Medium,
#[default]
High,
Maximum,
}
#[cfg(feature = "wallet_essentials")]
impl PerformanceLevel {
fn serialized_version() -> u8 {
0
}
pub fn read<R: Read>(mut reader: R) -> std::io::Result<Self> {
let _version = reader.read_u8()?;
Ok(match reader.read_u8()? {
0 => Self::Low,
1 => Self::Medium,
2 => Self::High,
3 => Self::Maximum,
_ => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"failed to read valid performance level",
));
}
})
}
pub fn write<W: Write>(&mut self, mut writer: W) -> std::io::Result<()> {
writer.write_u8(Self::serialized_version())?;
writer.write_u8(match self {
Self::Low => 0,
Self::Medium => 1,
Self::High => 2,
Self::Maximum => 3,
})?;
Ok(())
}
}
impl std::fmt::Display for PerformanceLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Low => write!(f, "low"),
Self::Medium => write!(f, "medium"),
Self::High => write!(f, "high"),
Self::Maximum => write!(f, "maximum"),
}
}
}
#[derive(Default, Debug, Clone)]
pub struct SyncConfig {
pub transparent_address_discovery: TransparentAddressDiscovery,
pub performance_level: PerformanceLevel,
}
#[cfg(feature = "wallet_essentials")]
impl SyncConfig {
fn serialized_version() -> u8 {
1
}
pub fn read<R: Read>(mut reader: R) -> std::io::Result<Self> {
let version = reader.read_u8()?;
let gap_limit = reader.read_u8()?;
let scopes = reader.read_u8()?;
let performance_level = if version >= 1 {
PerformanceLevel::read(reader)?
} else {
PerformanceLevel::High
};
Ok(Self {
transparent_address_discovery: TransparentAddressDiscovery {
gap_limit,
scopes: TransparentAddressDiscoveryScopes {
external: scopes & 0b1 != 0,
internal: scopes & 0b10 != 0,
refund: scopes & 0b100 != 0,
},
},
performance_level,
})
}
pub fn write<W: Write>(&mut self, mut writer: W) -> std::io::Result<()> {
writer.write_u8(Self::serialized_version())?;
writer.write_u8(self.transparent_address_discovery.gap_limit)?;
let mut scopes = 0;
if self.transparent_address_discovery.scopes.external {
scopes |= 0b1;
}
if self.transparent_address_discovery.scopes.internal {
scopes |= 0b10;
}
if self.transparent_address_discovery.scopes.refund {
scopes |= 0b100;
}
writer.write_u8(scopes)?;
self.performance_level.write(writer)?;
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct TransparentAddressDiscovery {
pub gap_limit: u8,
pub scopes: TransparentAddressDiscoveryScopes,
}
impl Default for TransparentAddressDiscovery {
fn default() -> Self {
Self {
gap_limit: 10,
scopes: TransparentAddressDiscoveryScopes::default(),
}
}
}
impl TransparentAddressDiscovery {
#[must_use]
pub fn minimal() -> Self {
Self {
gap_limit: 1,
scopes: TransparentAddressDiscoveryScopes::default(),
}
}
#[must_use]
pub fn recovery() -> Self {
Self {
gap_limit: 20,
scopes: TransparentAddressDiscoveryScopes::recovery(),
}
}
#[must_use]
pub fn disabled() -> Self {
Self {
gap_limit: 0,
scopes: TransparentAddressDiscoveryScopes {
external: false,
internal: false,
refund: false,
},
}
}
}
#[derive(Debug, Clone)]
pub struct TransparentAddressDiscoveryScopes {
pub external: bool,
pub internal: bool,
pub refund: bool,
}
impl Default for TransparentAddressDiscoveryScopes {
fn default() -> Self {
Self {
external: true,
internal: false,
refund: true,
}
}
}
impl TransparentAddressDiscoveryScopes {
#[must_use]
pub fn recovery() -> Self {
Self {
external: true,
internal: true,
refund: true,
}
}
}