Skip to content

Commit

Permalink
feat: realistic burn and stacks block times
Browse files Browse the repository at this point in the history
  • Loading branch information
hugocaillard committed Sep 20, 2024
1 parent dec2294 commit b35e449
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 113 deletions.
132 changes: 77 additions & 55 deletions components/clarity-repl/src/repl/datastore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub struct ClarityDatastore {
}

#[derive(Clone, Debug)]
pub struct BurnBlockInfo {
struct BurnBlockInfo {
burn_block_time: u64,
burn_block_height: u32,
}
Expand All @@ -59,11 +59,6 @@ pub struct StacksBlockInfo {
consensus_hash: ConsensusHash,
vrf_seed: VRFSeed,
stacks_block_time: u64,
miner: StacksAddress,
burnchain_tokens_spent_for_block: u128,
get_burnchain_tokens_spent_for_winning_block: u128,
tokens_earned_for_block: u128,
pox_payout_addrs: (Vec<TupleData>, u128),
}

#[derive(Clone, Debug)]
Expand All @@ -76,6 +71,7 @@ pub struct StacksConstants {

#[derive(Clone, Debug)]
pub struct Datastore {
genesis_id: StacksBlockId,
burn_chain_height: u32,
burn_blocks: HashMap<BurnchainHeaderHash, BurnBlockInfo>,
stacks_chain_height: u32,
Expand All @@ -85,7 +81,6 @@ pub struct Datastore {
current_epoch: StacksEpochId,
current_epoch_start_height: u32,
constants: StacksConstants,
genesis_time: u64,
}

// fn height_to_hashed_bytes(height: u32) -> [u8; 32] {
Expand Down Expand Up @@ -364,12 +359,7 @@ impl Datastore {
burn_block_header_hash: first_burn_block_header_hash,
consensus_hash: ConsensusHash([0x00; 20]),
vrf_seed: VRFSeed([0x00; 32]),
stacks_block_time: genesis_time,
miner: StacksAddress::burn_address(false),
burnchain_tokens_spent_for_block: 0,
get_burnchain_tokens_spent_for_winning_block: 0,
tokens_earned_for_block: 0,
pox_payout_addrs: (vec![], 0),
stacks_block_time: genesis_time + 10,
};

let sortition_lookup = HashMap::from([(sortition_id, id)]);
Expand All @@ -378,6 +368,7 @@ impl Datastore {
let stacks_blocks = HashMap::from([(id, genesis_block)]);

Datastore {
genesis_id: id,
burn_chain_height: 0,
burn_blocks,
stacks_chain_height: 0,
Expand All @@ -387,7 +378,6 @@ impl Datastore {
current_epoch: StacksEpochId::Epoch2_05,
current_epoch_start_height: 0,
constants,
genesis_time,
}
}

Expand All @@ -403,10 +393,24 @@ impl Datastore {
self.burn_chain_height
}

fn build_stacks_block(&self) -> StacksBlockInfo {
fn build_next_stacks_block(&self, clarity_datastore: &ClarityDatastore) -> StacksBlockInfo {
let burn_chain_height = self.burn_chain_height;
let stacks_block_height = self.stacks_chain_height;

let last_stacks_block = self
.stacks_blocks
.get(&clarity_datastore.current_chain_tip)
.expect("current chain tip missing in stacks block table");
let last_burn_block = self
.burn_blocks
.get(&height_to_burn_block_header_hash(burn_chain_height))
.expect("burn block missing in burn block table");

let last_block_time = std::cmp::max(
last_stacks_block.stacks_block_time,
last_burn_block.burn_block_time,
);

let bytes = height_to_hashed_bytes(stacks_block_height);

let block_header_hash = {
Expand All @@ -425,25 +429,14 @@ impl Datastore {
buffer[0] = 4;
VRFSeed(buffer)
};
let time_since_genesis: u64 = (stacks_block_height * 600).into();
let stacks_block_time: u64 = self.genesis_time + time_since_genesis;
let miner = StacksAddress::burn_address(true);
let burnchain_tokens_spent_for_block = 2000;
let get_burnchain_tokens_spent_for_winning_block = 2000;
let tokens_earned_for_block = 5000;
let pox_payout_addrs = (vec![], 0_u128);
let stacks_block_time: u64 = last_block_time + 10;

StacksBlockInfo {
block_header_hash,
burn_block_header_hash,
consensus_hash,
vrf_seed,
stacks_block_time,
miner,
burnchain_tokens_spent_for_block,
get_burnchain_tokens_spent_for_winning_block,
tokens_earned_for_block,
pox_payout_addrs,
}
}

Expand All @@ -452,13 +445,25 @@ impl Datastore {
clarity_datastore: &mut ClarityDatastore,
count: u32,
) -> u32 {
let genesis_time = self.genesis_time;

for _ in 1..=count {
let last_stacks_block = self
.stacks_blocks
.get(&clarity_datastore.current_chain_tip)
.unwrap();
let last_burn_block = self
.burn_blocks
.get(&last_stacks_block.burn_block_header_hash)
.unwrap();

let mut next_burn_block_time = last_burn_block.burn_block_time + 600;
if last_stacks_block.stacks_block_time > next_burn_block_time {
next_burn_block_time = last_stacks_block.stacks_block_time + 10;
}

let height = self.burn_chain_height + 1;
let hash = height_to_burn_block_header_hash(height);
let burn_block_info = BurnBlockInfo {
burn_block_time: genesis_time + ((height * 600) as u64),
burn_block_time: next_burn_block_time,
burn_block_height: height,
};

Expand All @@ -480,23 +485,27 @@ impl Datastore {
.get(&clarity_datastore.open_chain_tip)
.expect("Open chain tip missing in block id lookup table");

for i in 1..=count {
let height = self.stacks_chain_height + i;
let bytes = height_to_hashed_bytes(height);
for _ in 1..=count {
self.stacks_chain_height += 1;

let bytes = height_to_hashed_bytes(self.stacks_chain_height);
let id = StacksBlockId(bytes);
let sortition_id = SortitionId(bytes);
let block_info = self.build_stacks_block();
clarity_datastore
.block_id_lookup
.insert(id, current_lookup_id);
clarity_datastore.height_at_chain_tip.insert(id, height);
let block_info = self.build_next_stacks_block(clarity_datastore);

self.sortition_lookup.insert(sortition_id, id);
self.consensus_hash_lookup
.insert(block_info.consensus_hash, sortition_id);
self.stacks_blocks.insert(id, block_info);

clarity_datastore
.block_id_lookup
.insert(id, current_lookup_id);
clarity_datastore
.height_at_chain_tip
.insert(id, self.stacks_chain_height);
}

self.stacks_chain_height += count;
clarity_datastore.open_chain_tip = height_to_id(self.stacks_chain_height);
clarity_datastore.current_chain_tip = clarity_datastore.open_chain_tip;
self.stacks_chain_height
Expand Down Expand Up @@ -573,37 +582,49 @@ impl HeadersDB for Datastore {
id_bhh: &StacksBlockId,
_epoch_id: &StacksEpochId,
) -> Option<StacksAddress> {
self.stacks_blocks.get(id_bhh).map(|id| id.miner)
if self.get_burn_block_height_for_block(id_bhh).is_some() {
return StacksAddress::burn_address(id_bhh != &self.genesis_id).into();
}
None
}

fn get_burnchain_tokens_spent_for_block(
&self,
id_bhh: &StacksBlockId,
_epoch_id: &StacksEpochId,
) -> Option<u128> {
self.stacks_blocks
.get(id_bhh)
.map(|id| id.burnchain_tokens_spent_for_block)
if id_bhh == &self.genesis_id {
return Some(0);
};
if self.get_burn_block_height_for_block(id_bhh).is_some() {
return Some(2000);
};
None
}

fn get_burnchain_tokens_spent_for_winning_block(
&self,
id_bhh: &StacksBlockId,
_epoch_id: &StacksEpochId,
) -> Option<u128> {
self.stacks_blocks
.get(id_bhh)
.map(|id| id.get_burnchain_tokens_spent_for_winning_block)
if id_bhh == &self.genesis_id {
return Some(0);
};
None
}

fn get_tokens_earned_for_block(
&self,
id_bhh: &StacksBlockId,
_epoch_id: &StacksEpochId,
) -> Option<u128> {
self.stacks_blocks
.get(id_bhh)
.map(|id| id.tokens_earned_for_block)
if id_bhh == &self.genesis_id {
return Some(0);
};
if self.get_burn_block_height_for_block(id_bhh).is_some() {
return Some(5000);
}
None
}
}

Expand Down Expand Up @@ -708,13 +729,14 @@ impl BurnStateDB for Datastore {
/// Get the PoX payout addresses for a given burnchain block
fn get_pox_payout_addrs(
&self,
_height: u32,
sortition_id: &SortitionId,
height: u32,
_sortition_id: &SortitionId,
) -> Option<(Vec<TupleData>, u128)> {
self.sortition_lookup
.get(sortition_id)
.and_then(|id| self.stacks_blocks.get(id))
.map(|block_info| block_info.pox_payout_addrs.clone())
if height <= self.burn_chain_height {
Some((vec![], 0))
} else {
None
}
}

fn get_ast_rules(&self, _height: u32) -> clarity::vm::ast::ASTRules {
Expand Down
13 changes: 0 additions & 13 deletions components/clarity-repl/src/repl/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,23 +1095,10 @@ impl ClarityInterpreter {
self.datastore.set_current_epoch(epoch);
}

pub fn advance_chain_tip(&mut self, count: u32) -> u32 {
let current_epoch = self.datastore.get_current_epoch();
if current_epoch < StacksEpochId::Epoch30 {
self.advance_burn_chain_tip(count)
} else {
match self.advance_stacks_chain_tip(count) {
Ok(count) => count,
Err(_) => unreachable!("Epoch checked already"),
}
}
}

pub fn advance_burn_chain_tip(&mut self, count: u32) -> u32 {
let new_height = self
.datastore
.advance_burn_chain_tip(&mut self.clarity_datastore, count);
// let _ = self.datastore.advance_stacks_chain_tip(count);
self.set_tenure_height();
new_height
}
Expand Down
Loading

0 comments on commit b35e449

Please sign in to comment.