Skip to content

Commit

Permalink
Use constants from rust-bitcoin
Browse files Browse the repository at this point in the history
  • Loading branch information
casey committed Sep 28, 2022
1 parent ec79a14 commit 90b1136
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 63 deletions.
6 changes: 3 additions & 3 deletions src/degree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ impl From<Ordinal> for Degree {
fn from(ordinal: Ordinal) -> Self {
let height = ordinal.height().n();
Degree {
hour: height / (CYCLE_EPOCHS * Epoch::BLOCKS),
minute: height % Epoch::BLOCKS,
second: height % PERIOD_BLOCKS,
hour: height / (CYCLE_EPOCHS * SUBSIDY_HALVING_INTERVAL),
minute: height % SUBSIDY_HALVING_INTERVAL,
second: height % DIFFCHANGE_INTERVAL,
third: ordinal.third(),
}
}
Expand Down
21 changes: 10 additions & 11 deletions src/epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ impl Epoch {
Ordinal(Ordinal::SUPPLY),
];
pub(crate) const FIRST_POST_SUBSIDY: Epoch = Self(33);
pub(crate) const BLOCKS: u64 = 210000;

pub(crate) fn subsidy(self) -> u64 {
if self < Self::FIRST_POST_SUBSIDY {
Expand All @@ -58,7 +57,7 @@ impl Epoch {
}

pub(crate) fn starting_height(self) -> Height {
Height(self.0 * Self::BLOCKS)
Height(self.0 * SUBSIDY_HALVING_INTERVAL)
}
}

Expand All @@ -79,7 +78,7 @@ impl From<Ordinal> for Epoch {

impl From<Height> for Epoch {
fn from(height: Height) -> Self {
Self(height.0 / Self::BLOCKS)
Self(height.0 / SUBSIDY_HALVING_INTERVAL)
}
}

Expand All @@ -92,11 +91,11 @@ mod tests {
assert_eq!(Epoch(0).starting_ordinal(), 0);
assert_eq!(
Epoch(1).starting_ordinal(),
Epoch(0).subsidy() * Epoch::BLOCKS
Epoch(0).subsidy() * SUBSIDY_HALVING_INTERVAL
);
assert_eq!(
Epoch(2).starting_ordinal(),
(Epoch(0).subsidy() + Epoch(1).subsidy()) * Epoch::BLOCKS
(Epoch(0).subsidy() + Epoch(1).subsidy()) * SUBSIDY_HALVING_INTERVAL
);
assert_eq!(Epoch(33).starting_ordinal(), Ordinal(Ordinal::SUPPLY));
assert_eq!(Epoch(34).starting_ordinal(), Ordinal(Ordinal::SUPPLY));
Expand All @@ -110,7 +109,7 @@ mod tests {

for epoch in 0..34 {
epoch_ordinals.push(ordinal);
ordinal += Epoch::BLOCKS * Epoch(epoch).subsidy();
ordinal += SUBSIDY_HALVING_INTERVAL * Epoch(epoch).subsidy();
}

assert_eq!(Epoch::STARTING_ORDINALS, epoch_ordinals);
Expand All @@ -128,21 +127,21 @@ mod tests {
#[test]
fn blocks() {
// c.f. https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp
assert_eq!(Epoch::BLOCKS, 210000);
assert_eq!(SUBSIDY_HALVING_INTERVAL, 210000);
}

#[test]
fn starting_height() {
assert_eq!(Epoch(0).starting_height(), 0);
assert_eq!(Epoch(1).starting_height(), Epoch::BLOCKS);
assert_eq!(Epoch(2).starting_height(), Epoch::BLOCKS * 2);
assert_eq!(Epoch(1).starting_height(), SUBSIDY_HALVING_INTERVAL);
assert_eq!(Epoch(2).starting_height(), SUBSIDY_HALVING_INTERVAL * 2);
}

#[test]
fn from_height() {
assert_eq!(Epoch::from(Height(0)), 0);
assert_eq!(Epoch::from(Height(Epoch::BLOCKS)), 1);
assert_eq!(Epoch::from(Height(Epoch::BLOCKS) + 1), 1);
assert_eq!(Epoch::from(Height(SUBSIDY_HALVING_INTERVAL)), 1);
assert_eq!(Epoch::from(Height(SUBSIDY_HALVING_INTERVAL) + 1), 1);
}

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/height.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl Height {
}

pub(crate) fn period_offset(self) -> u64 {
self.0 % PERIOD_BLOCKS
self.0 % DIFFCHANGE_INTERVAL
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ mod subcommand;

type Result<T = (), E = Error> = std::result::Result<T, E>;

const PERIOD_BLOCKS: u64 = 2016;
const DIFFCHANGE_INTERVAL: u64 = bitcoin::blockdata::constants::DIFFCHANGE_INTERVAL as u64;
const SUBSIDY_HALVING_INTERVAL: u64 =
bitcoin::blockdata::constants::SUBSIDY_HALVING_INTERVAL as u64;
const CYCLE_EPOCHS: u64 = 6;

static INTERRUPTS: AtomicU64 = AtomicU64::new(0);
Expand Down
61 changes: 35 additions & 26 deletions src/ordinal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Ordinal {
}

pub(crate) fn period(self) -> u64 {
self.height().n() / PERIOD_BLOCKS
self.height().n() / DIFFCHANGE_INTERVAL
}

pub(crate) fn third(self) -> u64 {
Expand Down Expand Up @@ -93,35 +93,35 @@ impl Ordinal {
.split_once('′')
.ok_or_else(|| anyhow!("Missing minute symbol"))?;
let epoch_offset = epoch_offset.parse::<u64>()?;
if epoch_offset >= Epoch::BLOCKS {
if epoch_offset >= SUBSIDY_HALVING_INTERVAL {
bail!("Invalid epoch offset");
}

let (period_offset, rest) = rest
.split_once('″')
.ok_or_else(|| anyhow!("Missing second symbol"))?;
let period_offset = period_offset.parse::<u64>()?;
if period_offset >= PERIOD_BLOCKS {
if period_offset >= DIFFCHANGE_INTERVAL {
bail!("Invalid period offset");
}

let cycle_start_epoch = cycle_number * CYCLE_EPOCHS;

const HALVING_INCREMENT: u64 = Epoch::BLOCKS % PERIOD_BLOCKS;
const HALVING_INCREMENT: u64 = SUBSIDY_HALVING_INTERVAL % DIFFCHANGE_INTERVAL;

// For valid degrees the relationship between epoch_offset and period_offset
// will increment by 336 every halving.
let relationship = period_offset + Epoch::BLOCKS * CYCLE_EPOCHS - epoch_offset;
let relationship = period_offset + SUBSIDY_HALVING_INTERVAL * CYCLE_EPOCHS - epoch_offset;

if relationship % HALVING_INCREMENT != 0 {
bail!("Relationship between epoch offset and period offset must be multiple of 336");
}

let epochs_since_cycle_start = relationship % PERIOD_BLOCKS / HALVING_INCREMENT;
let epochs_since_cycle_start = relationship % DIFFCHANGE_INTERVAL / HALVING_INCREMENT;

let epoch = cycle_start_epoch + epochs_since_cycle_start;

let height = Height(epoch * Epoch::BLOCKS + epoch_offset);
let height = Height(epoch * SUBSIDY_HALVING_INTERVAL + epoch_offset);

let (block_offset, rest) = match rest.split_once('‴') {
Some((block_offset, rest)) => (block_offset.parse::<u64>()?, rest),
Expand Down Expand Up @@ -235,8 +235,11 @@ mod tests {
assert_eq!(Ordinal(1).height(), 0);
assert_eq!(Ordinal(Epoch(0).subsidy()).height(), 1);
assert_eq!(Ordinal(Epoch(0).subsidy() * 2).height(), 2);
assert_eq!(Epoch(2).starting_ordinal().height(), Epoch::BLOCKS * 2);
assert_eq!(Ordinal(50 * 100_000_000).height(), 1);
assert_eq!(
Epoch(2).starting_ordinal().height(),
SUBSIDY_HALVING_INTERVAL * 2
);
assert_eq!(Ordinal(50 * COIN_VALUE).height(), 1);
assert_eq!(Ordinal(2099999997689999).height(), 6929999);
assert_eq!(Ordinal(2099999997689998).height(), 6929998);
}
Expand Down Expand Up @@ -268,36 +271,36 @@ mod tests {
assert_eq!(Ordinal(0).degree().to_string(), "0°0′0″0‴");
assert_eq!(Ordinal(1).degree().to_string(), "0°0′0″1‴");
assert_eq!(
Ordinal(50 * 100_000_000 - 1).degree().to_string(),
Ordinal(50 * COIN_VALUE - 1).degree().to_string(),
"0°0′0″4999999999‴"
);
assert_eq!(Ordinal(50 * 100_000_000).degree().to_string(), "0°1′1″0‴");
assert_eq!(Ordinal(50 * COIN_VALUE).degree().to_string(), "0°1′1″0‴");
assert_eq!(
Ordinal(50 * 100_000_000 + 1).degree().to_string(),
Ordinal(50 * COIN_VALUE + 1).degree().to_string(),
"0°1′1″1‴"
);
assert_eq!(
Ordinal(50 * 100_000_000 * 2016 - 1).degree().to_string(),
Ordinal(50 * COIN_VALUE * 2016 - 1).degree().to_string(),
"0°2015′2015″4999999999‴"
);
assert_eq!(
Ordinal(50 * 100_000_000 * 2016).degree().to_string(),
Ordinal(50 * COIN_VALUE * 2016).degree().to_string(),
"0°2016′0″0‴"
);
assert_eq!(
Ordinal(50 * 100_000_000 * 2016 + 1).degree().to_string(),
Ordinal(50 * COIN_VALUE * 2016 + 1).degree().to_string(),
"0°2016′0″1‴"
);
assert_eq!(
Ordinal(50 * 100_000_000 * 210000 - 1).degree().to_string(),
Ordinal(50 * COIN_VALUE * 210000 - 1).degree().to_string(),
"0°209999′335″4999999999‴"
);
assert_eq!(
Ordinal(50 * 100_000_000 * 210000).degree().to_string(),
Ordinal(50 * COIN_VALUE * 210000).degree().to_string(),
"0°0′336″0‴"
);
assert_eq!(
Ordinal(50 * 100_000_000 * 210000 + 1).degree().to_string(),
Ordinal(50 * COIN_VALUE * 210000 + 1).degree().to_string(),
"0°0′336″1‴"
);
assert_eq!(
Expand Down Expand Up @@ -355,7 +358,7 @@ mod tests {
fn epoch() {
assert_eq!(Ordinal(0).epoch(), 0);
assert_eq!(Ordinal(1).epoch(), 0);
assert_eq!(Ordinal(50 * 100_000_000 * 210000).epoch(), 1);
assert_eq!(Ordinal(50 * COIN_VALUE * 210000).epoch(), 1);
assert_eq!(Ordinal(2099999997689999).epoch(), 32);
}

Expand Down Expand Up @@ -435,7 +438,7 @@ mod tests {
fn from_str_decimal() {
assert_eq!(parse("0.0").unwrap(), 0);
assert_eq!(parse("0.1").unwrap(), 1);
assert_eq!(parse("1.0").unwrap(), 50 * 100_000_000);
assert_eq!(parse("1.0").unwrap(), 50 * COIN_VALUE);
assert_eq!(parse("6929999.0").unwrap(), 2099999997689999);
assert!(parse("0.5000000000").is_err());
assert!(parse("6930000.0").is_err());
Expand Down Expand Up @@ -525,13 +528,19 @@ mod tests {

#[test]
fn cycle() {
assert_eq!(Epoch::BLOCKS * CYCLE_EPOCHS % PERIOD_BLOCKS, 0);
assert_eq!(
SUBSIDY_HALVING_INTERVAL * CYCLE_EPOCHS % DIFFCHANGE_INTERVAL,
0
);

for i in 1..CYCLE_EPOCHS {
assert_ne!(i * Epoch::BLOCKS % PERIOD_BLOCKS, 0);
assert_ne!(i * SUBSIDY_HALVING_INTERVAL % DIFFCHANGE_INTERVAL, 0);
}

assert_eq!(CYCLE_EPOCHS * Epoch::BLOCKS % PERIOD_BLOCKS, 0);
assert_eq!(
CYCLE_EPOCHS * SUBSIDY_HALVING_INTERVAL % DIFFCHANGE_INTERVAL,
0
);

assert_eq!(Ordinal(0).cycle(), 0);
assert_eq!(Ordinal(2067187500000000 - 1).cycle(), 0);
Expand All @@ -542,9 +551,9 @@ mod tests {
#[test]
fn third() {
assert_eq!(Ordinal(0).third(), 0);
assert_eq!(Ordinal(50 * 100_000_000 - 1).third(), 4999999999);
assert_eq!(Ordinal(50 * 100_000_000).third(), 0);
assert_eq!(Ordinal(50 * 100_000_000 + 1).third(), 1);
assert_eq!(Ordinal(50 * COIN_VALUE - 1).third(), 4999999999);
assert_eq!(Ordinal(50 * COIN_VALUE).third(), 0);
assert_eq!(Ordinal(50 * COIN_VALUE + 1).third(), 1);
}

#[test]
Expand Down
24 changes: 9 additions & 15 deletions src/rarity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,21 @@ mod tests {
assert_eq!(Ordinal(0).rarity(), Rarity::Mythic);
assert_eq!(Ordinal(1).rarity(), Rarity::Common);

assert_eq!(Ordinal(50 * 100_000_000 - 1).rarity(), Rarity::Common);
assert_eq!(Ordinal(50 * 100_000_000).rarity(), Rarity::Uncommon);
assert_eq!(Ordinal(50 * 100_000_000 + 1).rarity(), Rarity::Common);
assert_eq!(Ordinal(50 * COIN_VALUE - 1).rarity(), Rarity::Common);
assert_eq!(Ordinal(50 * COIN_VALUE).rarity(), Rarity::Uncommon);
assert_eq!(Ordinal(50 * COIN_VALUE + 1).rarity(), Rarity::Common);

assert_eq!(
Ordinal(50 * 100_000_000 * 2016 - 1).rarity(),
Rarity::Common
);
assert_eq!(Ordinal(50 * 100_000_000 * 2016).rarity(), Rarity::Rare);
assert_eq!(
Ordinal(50 * 100_000_000 * 2016 + 1).rarity(),
Rarity::Common
);
assert_eq!(Ordinal(50 * COIN_VALUE * 2016 - 1).rarity(), Rarity::Common);
assert_eq!(Ordinal(50 * COIN_VALUE * 2016).rarity(), Rarity::Rare);
assert_eq!(Ordinal(50 * COIN_VALUE * 2016 + 1).rarity(), Rarity::Common);

assert_eq!(
Ordinal(50 * 100_000_000 * 210000 - 1).rarity(),
Ordinal(50 * COIN_VALUE * 210000 - 1).rarity(),
Rarity::Common
);
assert_eq!(Ordinal(50 * 100_000_000 * 210000).rarity(), Rarity::Epic);
assert_eq!(Ordinal(50 * COIN_VALUE * 210000).rarity(), Rarity::Epic);
assert_eq!(
Ordinal(50 * 100_000_000 * 210000 + 1).rarity(),
Ordinal(50 * COIN_VALUE * 210000 + 1).rarity(),
Rarity::Common
);

Expand Down
4 changes: 2 additions & 2 deletions src/subcommand/server/templates/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ impl ClockSvg {
hour: (min.n() % Epoch::FIRST_POST_SUBSIDY.starting_height().n()) as f64
/ Epoch::FIRST_POST_SUBSIDY.starting_height().n() as f64
* 360.0,
minute: (min.n() % Epoch::BLOCKS) as f64 / Epoch::BLOCKS as f64 * 360.0,
second: height.period_offset() as f64 / PERIOD_BLOCKS as f64 * 360.0,
minute: (min.n() % SUBSIDY_HALVING_INTERVAL) as f64 / SUBSIDY_HALVING_INTERVAL as f64 * 360.0,
second: height.period_offset() as f64 / DIFFCHANGE_INTERVAL as f64 * 360.0,
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use {
wallet::{signer::SignOptions, AddressIndex, SyncOptions, Wallet},
KeychainKind,
},
bitcoin::{hash_types::Txid, network::constants::Network, Block, OutPoint, Script, Transaction},
bitcoin::{
blockdata::constants::COIN_VALUE, hash_types::Txid, network::constants::Network, Block,
OutPoint, Script, Transaction,
},
bitcoincore_rpc::{Client, RawTx, RpcApi},
executable_path::executable_path,
log::LevelFilter,
Expand Down
6 changes: 3 additions & 3 deletions tests/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn null_output() {
.transaction(TransactionOptions {
slots: &[(1, 0, 0)],
output_count: 1,
fee: 50 * 100_000_000,
fee: 50 * COIN_VALUE,
recipient: None,
})
.blocks(1)
Expand All @@ -151,7 +151,7 @@ fn null_input() {
.transaction(TransactionOptions {
slots: &[(1, 0, 0)],
output_count: 1,
fee: 50 * 100_000_000,
fee: 50 * COIN_VALUE,
recipient: None,
})
.blocks(1)
Expand All @@ -174,7 +174,7 @@ fn old_transactions_are_pruned() {
.transaction(TransactionOptions {
slots: &[(1, 0, 0)],
output_count: 1,
fee: 50 * 100_000_000,
fee: 50 * COIN_VALUE,
recipient: None
})
.blocks(1)
Expand Down

0 comments on commit 90b1136

Please sign in to comment.