Skip to content

Commit

Permalink
Unlock runes in first block of interval (#2861)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Dec 15, 2023
1 parent cfc20c0 commit 8b20495
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 50 deletions.
8 changes: 4 additions & 4 deletions src/runes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ mod tests {

#[test]
fn runes_must_be_greater_than_or_equal_to_minimum_for_height() {
const SECOND_BLOCK_LOCKED_RUNE: u128 = 99235208761673842;
let block_two_minimum: u128 = Rune::minimum_at_height(Chain::Regtest, Height(2)).0;

{
let context = Context::builder()
Expand All @@ -191,7 +191,7 @@ mod tests {
output: 0,
}],
etching: Some(Etching {
rune: Some(Rune(SECOND_BLOCK_LOCKED_RUNE - 1)),
rune: Some(Rune(block_two_minimum - 1)),
..Default::default()
}),
..Default::default()
Expand Down Expand Up @@ -221,7 +221,7 @@ mod tests {
output: 0,
}],
etching: Some(Etching {
rune: Some(Rune(SECOND_BLOCK_LOCKED_RUNE)),
rune: Some(Rune(block_two_minimum)),
..Default::default()
}),
..Default::default()
Expand All @@ -243,7 +243,7 @@ mod tests {
id,
RuneEntry {
etching: txid,
rune: Rune(SECOND_BLOCK_LOCKED_RUNE),
rune: Rune(block_two_minimum),
supply: u128::max_value(),
timestamp: 2,
..Default::default()
Expand Down
98 changes: 54 additions & 44 deletions src/runes/rune.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,23 @@ impl Rune {
];

pub(crate) fn minimum_at_height(chain: Chain, height: Height) -> Self {
let offset = height.0.saturating_add(1);

const INTERVAL: u32 = SUBSIDY_HALVING_INTERVAL / 12;

let start = chain.first_rune_height();

let end = start + SUBSIDY_HALVING_INTERVAL;

if height.0 < start {
if offset < start {
return Rune(Self::STEPS[12]);
}

if height.0 >= end {
if offset >= end {
return Rune(0);
}

let progress = height.0.saturating_sub(start);
let progress = offset.saturating_sub(start);

let length = 12u32.saturating_sub(progress / INTERVAL);

Expand Down Expand Up @@ -210,66 +212,69 @@ mod tests {

case(0, "AAAAAAAAAAAAA");
case(START / 2, "AAAAAAAAAAAAA");
case(START, "AAAAAAAAAAAAA");
case(START + 1, "ZZYZXBRKWXVA");
case(END - 1, "B");
case(START, "ZZYZXBRKWXVA");
case(START + 1, "ZZXZUDIVTVQA");
case(END - 1, "A");
case(END, "A");
case(END + 1, "A");
case(u32::max_value(), "A");

case(START + INTERVAL * 00 - 1, "AAAAAAAAAAAAA");
case(START + INTERVAL * 00 + 0, "AAAAAAAAAAAAA");
case(START + INTERVAL * 00 + 1, "ZZYZXBRKWXVA");
case(START + INTERVAL * 00 + 0, "ZZYZXBRKWXVA");
case(START + INTERVAL * 00 + 1, "ZZXZUDIVTVQA");

case(START + INTERVAL * 01 - 1, "AABACYIPDCFB");
case(START + INTERVAL * 01 + 0, "AAAAAAAAAAAA");
case(START + INTERVAL * 01 + 1, "ZZYZXBRKWXV");
case(START + INTERVAL * 01 - 1, "AAAAAAAAAAAA");
case(START + INTERVAL * 01 + 0, "ZZYZXBRKWXV");
case(START + INTERVAL * 01 + 1, "ZZXZUDIVTVQ");

case(START + INTERVAL * 02 - 1, "AABACYIPDCG");
case(START + INTERVAL * 02 + 0, "AAAAAAAAAAA");
case(START + INTERVAL * 02 + 1, "ZZYZXBRKWY");
case(START + INTERVAL * 02 - 1, "AAAAAAAAAAA");
case(START + INTERVAL * 02 + 0, "ZZYZXBRKWY");
case(START + INTERVAL * 02 + 1, "ZZXZUDIVTW");

case(START + INTERVAL * 03 - 1, "AABACYIPDD");
case(START + INTERVAL * 03 + 0, "AAAAAAAAAA");
case(START + INTERVAL * 03 + 1, "ZZYZXBRKX");
case(START + INTERVAL * 03 - 1, "AAAAAAAAAA");
case(START + INTERVAL * 03 + 0, "ZZYZXBRKX");
case(START + INTERVAL * 03 + 1, "ZZXZUDIVU");

case(START + INTERVAL * 04 - 1, "AABACYIPE");
case(START + INTERVAL * 04 + 0, "AAAAAAAAA");
case(START + INTERVAL * 04 + 1, "ZZYZXBRL");
case(START + INTERVAL * 04 - 1, "AAAAAAAAA");
case(START + INTERVAL * 04 + 0, "ZZYZXBRL");
case(START + INTERVAL * 04 + 1, "ZZXZUDIW");

case(START + INTERVAL * 05 - 1, "AABACYIQ");
case(START + INTERVAL * 05 + 0, "AAAAAAAA");
case(START + INTERVAL * 05 + 1, "ZZYZXBS");
case(START + INTERVAL * 05 - 1, "AAAAAAAA");
case(START + INTERVAL * 05 + 0, "ZZYZXBS");
case(START + INTERVAL * 05 + 1, "ZZXZUDJ");

case(START + INTERVAL * 06 - 1, "AABACYJ");
case(START + INTERVAL * 06 + 0, "AAAAAAA");
case(START + INTERVAL * 06 + 1, "ZZYZXC");
case(START + INTERVAL * 06 - 1, "AAAAAAA");
case(START + INTERVAL * 06 + 0, "ZZYZXC");
case(START + INTERVAL * 06 + 1, "ZZXZUE");

case(START + INTERVAL * 07 - 1, "AABACZ");
case(START + INTERVAL * 07 + 0, "AAAAAA");
case(START + INTERVAL * 07 + 1, "ZZYZY");
case(START + INTERVAL * 07 - 1, "AAAAAA");
case(START + INTERVAL * 07 + 0, "ZZYZY");
case(START + INTERVAL * 07 + 1, "ZZXZV");

case(START + INTERVAL * 08 - 1, "AABAD");
case(START + INTERVAL * 08 + 0, "AAAAA");
case(START + INTERVAL * 08 + 1, "ZZZA");
case(START + INTERVAL * 08 - 1, "AAAAA");
case(START + INTERVAL * 08 + 0, "ZZZA");
case(START + INTERVAL * 08 + 1, "ZZYA");

case(START + INTERVAL * 09 - 1, "AABB");
case(START + INTERVAL * 09 + 0, "AAAA");
case(START + INTERVAL * 09 + 1, "ZZZ");
case(START + INTERVAL * 09 - 1, "AAAA");
case(START + INTERVAL * 09 + 0, "ZZZ");
case(START + INTERVAL * 09 + 1, "ZZY");

case(START + INTERVAL * 10 - 1, "AAC");
case(START + INTERVAL * 10 - 2, "AAC");
case(START + INTERVAL * 10 - 1, "AAA");
case(START + INTERVAL * 10 + 0, "AAA");
case(START + INTERVAL * 10 + 1, "AAA");

case(START + INTERVAL * 10 + INTERVAL / 2, "NA");

case(START + INTERVAL * 11 - 1, "AB");
case(START + INTERVAL * 11 - 2, "AB");
case(START + INTERVAL * 11 - 1, "AA");
case(START + INTERVAL * 11 + 0, "AA");
case(START + INTERVAL * 11 + 1, "AA");

case(START + INTERVAL * 11 + INTERVAL / 2, "N");

case(START + INTERVAL * 12 - 1, "B");
case(START + INTERVAL * 12 - 2, "B");
case(START + INTERVAL * 12 - 1, "A");
case(START + INTERVAL * 12 + 0, "A");
case(START + INTERVAL * 12 + 1, "A");
}
Expand All @@ -287,20 +292,25 @@ mod tests {
case(Chain::Testnet, 0, "AAAAAAAAAAAAA");
case(
Chain::Testnet,
SUBSIDY_HALVING_INTERVAL * 12,
SUBSIDY_HALVING_INTERVAL * 12 - 1,
"AAAAAAAAAAAAA",
);
case(
Chain::Testnet,
SUBSIDY_HALVING_INTERVAL * 12 + 1,
SUBSIDY_HALVING_INTERVAL * 12,
"ZZYZXBRKWXVA",
);
case(
Chain::Testnet,
SUBSIDY_HALVING_INTERVAL * 12 + 1,
"ZZXZUDIVTVQA",
);

case(Chain::Signet, 0, "AAAAAAAAAAAAA");
case(Chain::Signet, 1, "ZZYZXBRKWXVA");
case(Chain::Signet, 0, "ZZYZXBRKWXVA");
case(Chain::Signet, 1, "ZZXZUDIVTVQA");

case(Chain::Regtest, 0, "AAAAAAAAAAAAA");
case(Chain::Regtest, 1, "ZZYZXBRKWXVA");
case(Chain::Regtest, 0, "ZZYZXBRKWXVA");
case(Chain::Regtest, 1, "ZZXZUDIVTVQA");
}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions tests/etch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ fn rune_below_minimum_is_an_error() {
CommandBuilder::new(
format!(
"--index-runes --regtest wallet etch --rune {} --divisibility 0 --fee-rate 1 --supply 1000 --symbol ¢",
Rune(99235208761673842 - 1),
Rune(99229755678436031 - 1),
))
.rpc_server(&rpc_server)
.expected_stderr("error: rune is less than minimum for next block: ZZXZUDIVTVPZ < ZZXZUDIVTVQA\n")
.expected_stderr("error: rune is less than minimum for next block: ZZWZRFAGQTKY < ZZWZRFAGQTKZ\n")
.expected_exit_code(1)
.run_and_extract_stdout();
}
Expand Down

0 comments on commit 8b20495

Please sign in to comment.