mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-05-28 23:20:55 +08:00
@@ -584,6 +584,7 @@ mod test {
|
||||
new_tip.block_height = parent_header_info.block_height + 1;
|
||||
new_tip.consensus_hash = ConsensusHash(Hash160::from_data(&Sha512Trunc256Sum::from_data(&parent_header_info.consensus_hash.0).0).0);
|
||||
new_tip.burn_header_hash = BurnchainHeaderHash(Sha512Trunc256Sum::from_data(&parent_header_info.consensus_hash.0).0);
|
||||
new_tip.burn_header_height = parent_header_info.burn_header_height + 1;
|
||||
|
||||
block_reward.parent_consensus_hash = parent_header_info.consensus_hash.clone();
|
||||
block_reward.parent_block_hash = parent_header_info.anchored_header.block_hash().clone();
|
||||
@@ -602,6 +603,7 @@ mod test {
|
||||
&new_tip.anchored_header,
|
||||
&new_tip.consensus_hash,
|
||||
&new_tip.burn_header_hash,
|
||||
new_tip.burn_header_height,
|
||||
new_tip.burn_header_timestamp,
|
||||
new_tip.microblock_tail.clone(),
|
||||
&block_reward,
|
||||
|
||||
@@ -122,7 +122,6 @@ pub struct StagingMicroblock {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct StagingBlock {
|
||||
pub consensus_hash: ConsensusHash,
|
||||
pub burn_header_timestamp: u64,
|
||||
pub anchored_block_hash: BlockHeaderHash,
|
||||
pub parent_consensus_hash: ConsensusHash,
|
||||
pub parent_anchored_block_hash: BlockHeaderHash,
|
||||
@@ -281,7 +280,6 @@ impl FromRow<StagingBlock> for StagingBlock {
|
||||
let anchored_block_hash : BlockHeaderHash = BlockHeaderHash::from_column(row, "anchored_block_hash")?;
|
||||
let parent_anchored_block_hash : BlockHeaderHash = BlockHeaderHash::from_column(row, "parent_anchored_block_hash")?;
|
||||
let consensus_hash : ConsensusHash = ConsensusHash::from_column(row, "consensus_hash")?;
|
||||
let burn_header_timestamp = u64::from_column(row, "burn_header_timestamp")?;
|
||||
let parent_consensus_hash: ConsensusHash = ConsensusHash::from_column(row, "parent_consensus_hash")?;
|
||||
let parent_microblock_hash : BlockHeaderHash = BlockHeaderHash::from_column(row, "parent_microblock_hash")?;
|
||||
let parent_microblock_seq : u16 = row.get("parent_microblock_seq");
|
||||
@@ -302,7 +300,6 @@ impl FromRow<StagingBlock> for StagingBlock {
|
||||
anchored_block_hash,
|
||||
parent_anchored_block_hash,
|
||||
consensus_hash,
|
||||
burn_header_timestamp,
|
||||
parent_consensus_hash,
|
||||
parent_microblock_hash,
|
||||
parent_microblock_seq,
|
||||
@@ -421,7 +418,6 @@ const STACKS_BLOCK_INDEX_SQL : &'static [&'static str]= &[
|
||||
CREATE TABLE staging_blocks(anchored_block_hash TEXT NOT NULL,
|
||||
parent_anchored_block_hash TEXT NOT NULL,
|
||||
consensus_hash TEXT NOT NULL,
|
||||
burn_header_timestamp INT NOT NULL,
|
||||
parent_consensus_hash TEXT NOT NULL,
|
||||
parent_microblock_hash TEXT NOT NULL,
|
||||
parent_microblock_seq INT NOT NULL,
|
||||
@@ -1143,11 +1139,10 @@ impl StacksChainState {
|
||||
/// Store a preprocessed block, queuing it up for subsequent processing.
|
||||
/// The caller should at least verify that the block is attached to some fork in the burn
|
||||
/// chain.
|
||||
fn store_staging_block<'a>(tx: &mut BlocksDBTx<'a>, consensus_hash: &ConsensusHash, burn_header_timestamp: u64, block: &StacksBlock, parent_consensus_hash: &ConsensusHash, commit_burn: u64, sortition_burn: u64) -> Result<(), Error> {
|
||||
fn store_staging_block<'a>(tx: &mut BlocksDBTx<'a>, consensus_hash: &ConsensusHash, block: &StacksBlock, parent_consensus_hash: &ConsensusHash, commit_burn: u64, sortition_burn: u64) -> Result<(), Error> {
|
||||
debug!("Store anchored block {}/{}, parent in {}", consensus_hash, block.block_hash(), parent_consensus_hash);
|
||||
assert!(commit_burn < i64::max_value() as u64);
|
||||
assert!(sortition_burn < i64::max_value() as u64);
|
||||
assert!(burn_header_timestamp < i64::max_value() as u64);
|
||||
|
||||
let block_hash = block.block_hash();
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(&consensus_hash, &block_hash);
|
||||
@@ -1173,7 +1168,6 @@ impl StacksChainState {
|
||||
(anchored_block_hash, \
|
||||
parent_anchored_block_hash, \
|
||||
consensus_hash, \
|
||||
burn_header_timestamp, \
|
||||
parent_consensus_hash, \
|
||||
parent_microblock_hash, \
|
||||
parent_microblock_seq, \
|
||||
@@ -1185,12 +1179,11 @@ impl StacksChainState {
|
||||
commit_burn, \
|
||||
sortition_burn, \
|
||||
index_block_hash) \
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15)";
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)";
|
||||
let args: &[&dyn ToSql] = &[
|
||||
&block_hash,
|
||||
&block.header.parent_block,
|
||||
&consensus_hash,
|
||||
&u64_to_sql(burn_header_timestamp)?,
|
||||
&parent_consensus_hash,
|
||||
&block.header.parent_microblock,
|
||||
&block.header.parent_microblock_sequence,
|
||||
@@ -2263,7 +2256,7 @@ impl StacksChainState {
|
||||
///
|
||||
/// TODO: consider how full the block is (i.e. how much computational budget it consumes) when
|
||||
/// deciding whether or not it can be processed.
|
||||
pub fn preprocess_anchored_block(&mut self, sort_ic: &SortitionDBConn, consensus_hash: &ConsensusHash, burn_header_timestamp: u64, block: &StacksBlock, parent_consensus_hash: &ConsensusHash) -> Result<bool, Error> {
|
||||
pub fn preprocess_anchored_block(&mut self, sort_ic: &SortitionDBConn, consensus_hash: &ConsensusHash, block: &StacksBlock, parent_consensus_hash: &ConsensusHash) -> Result<bool, Error> {
|
||||
debug!("preprocess anchored block {}/{}", consensus_hash, block.block_hash());
|
||||
|
||||
let sort_handle = SortitionHandleConn::open_reader_consensus(sort_ic, consensus_hash)?;
|
||||
@@ -2310,7 +2303,7 @@ impl StacksChainState {
|
||||
debug!("Storing staging block");
|
||||
|
||||
// queue block up for processing
|
||||
StacksChainState::store_staging_block(&mut block_tx, consensus_hash, burn_header_timestamp, &block, parent_consensus_hash, commit_burn, sortition_burn)?;
|
||||
StacksChainState::store_staging_block(&mut block_tx, consensus_hash, &block, parent_consensus_hash, commit_burn, sortition_burn)?;
|
||||
|
||||
// store users who burned for this block so they'll get rewarded if we process it
|
||||
StacksChainState::store_staging_block_user_burn_supports(&mut block_tx, consensus_hash, &block.block_hash(), &user_burns)?;
|
||||
@@ -2404,7 +2397,7 @@ impl StacksChainState {
|
||||
sn
|
||||
};
|
||||
|
||||
self.preprocess_anchored_block(sort_ic, &snapshot.consensus_hash, snapshot.burn_header_timestamp, block, &parent_sn.consensus_hash)?;
|
||||
self.preprocess_anchored_block(sort_ic, &snapshot.consensus_hash, block, &parent_sn.consensus_hash)?;
|
||||
let block_hash = block.block_hash();
|
||||
for mblock in microblocks.iter() {
|
||||
self.preprocess_streamed_microblock(&snapshot.consensus_hash, &block_hash, mblock)?;
|
||||
@@ -2772,6 +2765,7 @@ impl StacksChainState {
|
||||
parent_chain_tip: &StacksHeaderInfo,
|
||||
chain_tip_consensus_hash: &ConsensusHash,
|
||||
chain_tip_burn_header_hash: &BurnchainHeaderHash,
|
||||
chain_tip_burn_header_height: u32,
|
||||
chain_tip_burn_header_timestamp: u64,
|
||||
block: &StacksBlock,
|
||||
microblocks: &Vec<StacksMicroblock>, // parent microblocks
|
||||
@@ -2909,6 +2903,7 @@ impl StacksChainState {
|
||||
&block.header,
|
||||
chain_tip_consensus_hash,
|
||||
chain_tip_burn_header_hash,
|
||||
chain_tip_burn_header_height,
|
||||
chain_tip_burn_header_timestamp,
|
||||
microblock_tail_opt,
|
||||
&scheduled_miner_reward,
|
||||
@@ -2964,8 +2959,8 @@ impl StacksChainState {
|
||||
}
|
||||
};
|
||||
|
||||
let burn_header_hash = match SortitionDB::get_block_snapshot_consensus(sort_tx, &next_staging_block.consensus_hash)? {
|
||||
Some(sn) => sn.burn_header_hash,
|
||||
let (burn_header_hash, burn_header_height, burn_header_timestamp) = match SortitionDB::get_block_snapshot_consensus(sort_tx, &next_staging_block.consensus_hash)? {
|
||||
Some(sn) => (sn.burn_header_hash, sn.block_height as u32, sn.burn_header_timestamp),
|
||||
None => {
|
||||
// shouldn't happen
|
||||
panic!("CORRUPTION: staging block {}/{} does not correspond to a burn block", &next_staging_block.consensus_hash, &next_staging_block.anchored_block_hash);
|
||||
@@ -3102,7 +3097,8 @@ impl StacksChainState {
|
||||
&parent_block_header_info,
|
||||
&next_staging_block.consensus_hash,
|
||||
&burn_header_hash,
|
||||
next_staging_block.burn_header_timestamp,
|
||||
burn_header_height,
|
||||
burn_header_timestamp,
|
||||
&block,
|
||||
&next_microblocks,
|
||||
next_staging_block.commit_burn,
|
||||
@@ -3637,9 +3633,9 @@ pub mod test {
|
||||
assert!(StacksChainState::has_block_indexed(&chainstate.blocks_path, &index_block_hash).unwrap());
|
||||
}
|
||||
|
||||
pub fn store_staging_block(chainstate: &mut StacksChainState, consensus_hash: &ConsensusHash, consensus_hash_timestamp: u64, block: &StacksBlock, parent_consensus_hash: &ConsensusHash, commit_burn: u64, sortition_burn: u64) {
|
||||
pub fn store_staging_block(chainstate: &mut StacksChainState, consensus_hash: &ConsensusHash, block: &StacksBlock, parent_consensus_hash: &ConsensusHash, commit_burn: u64, sortition_burn: u64) {
|
||||
let mut tx = chainstate.blocks_tx_begin().unwrap();
|
||||
StacksChainState::store_staging_block(&mut tx, consensus_hash, consensus_hash_timestamp, block, parent_consensus_hash, commit_burn, sortition_burn).unwrap();
|
||||
StacksChainState::store_staging_block(&mut tx, consensus_hash, block, parent_consensus_hash, commit_burn, sortition_burn).unwrap();
|
||||
tx.commit().unwrap();
|
||||
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(consensus_hash, &block.block_hash());
|
||||
@@ -3765,7 +3761,7 @@ pub mod test {
|
||||
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &ConsensusHash([2u8; 20]), &block.block_hash()).unwrap().is_none());
|
||||
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), get_epoch_time_secs(), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
|
||||
assert_block_staging_not_processed(&mut chainstate, &ConsensusHash([2u8; 20]), &block);
|
||||
assert_block_not_stored(&mut chainstate, &ConsensusHash([2u8; 20]), &block);
|
||||
@@ -3789,7 +3785,7 @@ pub mod test {
|
||||
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &ConsensusHash([2u8; 20]), &block.block_hash()).unwrap().is_none());
|
||||
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), get_epoch_time_secs(), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
|
||||
assert_block_staging_not_processed(&mut chainstate, &ConsensusHash([2u8; 20]), &block);
|
||||
assert_block_not_stored(&mut chainstate, &ConsensusHash([2u8; 20]), &block);
|
||||
@@ -3842,7 +3838,7 @@ pub mod test {
|
||||
assert!(StacksChainState::load_staging_microblock(&chainstate.blocks_db, &ConsensusHash([2u8; 20]), &block.block_hash(), µblocks[0].block_hash()).unwrap().is_none());
|
||||
assert!(StacksChainState::load_staging_microblock_stream(&chainstate.blocks_db, &chainstate.blocks_path, &ConsensusHash([2u8; 20]), &block.block_hash(), u16::max_value()).unwrap().is_none());
|
||||
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), get_epoch_time_secs(), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
for mb in microblocks.iter() {
|
||||
store_staging_microblock(&mut chainstate, &ConsensusHash([2u8; 20]), &block.block_hash(), mb);
|
||||
}
|
||||
@@ -3894,7 +3890,7 @@ pub mod test {
|
||||
assert!(StacksChainState::load_staging_microblock(&chainstate.blocks_db, &ConsensusHash([2u8; 20]), &block.block_hash(), µblocks[0].block_hash()).unwrap().is_none());
|
||||
assert!(StacksChainState::load_staging_microblock_stream(&chainstate.blocks_db, &chainstate.blocks_path, &ConsensusHash([2u8; 20]), &block.block_hash(), u16::max_value()).unwrap().is_none());
|
||||
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), get_epoch_time_secs(), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
store_staging_block(&mut chainstate, &ConsensusHash([2u8; 20]), &block, &ConsensusHash([1u8; 20]), 1, 2);
|
||||
for mb in microblocks.iter() {
|
||||
store_staging_microblock(&mut chainstate, &ConsensusHash([2u8; 20]), &block.block_hash(), mb);
|
||||
}
|
||||
@@ -4222,7 +4218,7 @@ pub mod test {
|
||||
// store each block
|
||||
for ((block, consensus_hash), parent_consensus_hash) in blocks.iter().zip(&consensus_hashes).zip(&parent_consensus_hashes) {
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, consensus_hash, &block.block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, consensus_hash, get_epoch_time_secs(), block, parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, consensus_hash, block, parent_consensus_hash, 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, consensus_hash, block);
|
||||
}
|
||||
|
||||
@@ -4292,7 +4288,7 @@ pub mod test {
|
||||
// store each block, in reverse order!
|
||||
for ((block, consensus_hash), parent_consensus_hash) in blocks.iter().zip(&consensus_hashes).zip(&parent_consensus_hashes).rev() {
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, consensus_hash, &block.block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, consensus_hash, get_epoch_time_secs(), block, parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, consensus_hash, block, parent_consensus_hash, 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, consensus_hash, block);
|
||||
}
|
||||
|
||||
@@ -4370,7 +4366,7 @@ pub mod test {
|
||||
// store each block in reverse order, except for block_1
|
||||
for ((block, consensus_hash), parent_consensus_hash) in blocks[1..].iter().zip(&consensus_hashes[1..]).zip(&parent_consensus_hashes[1..]).rev() {
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, consensus_hash, &block.block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, consensus_hash, get_epoch_time_secs(), block, parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, consensus_hash, block, parent_consensus_hash, 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, consensus_hash, block);
|
||||
}
|
||||
|
||||
@@ -4384,7 +4380,7 @@ pub mod test {
|
||||
|
||||
// store block 1
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &consensus_hashes[0], &block_1.block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[0], get_epoch_time_secs(), &block_1, &parent_consensus_hashes[0], 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[0], &block_1, &parent_consensus_hashes[0], 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, &consensus_hashes[0], &block_1);
|
||||
|
||||
// first block is attachable
|
||||
@@ -4466,7 +4462,7 @@ pub mod test {
|
||||
|
||||
// store block 1 to staging
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &consensus_hashes[0], &blocks[0].block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[0], get_epoch_time_secs(), &blocks[0], &parent_consensus_hashes[0], 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[0], &blocks[0], &parent_consensus_hashes[0], 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, &consensus_hashes[0], &blocks[0]);
|
||||
|
||||
set_block_processed(&mut chainstate, &consensus_hashes[0], &blocks[0].block_hash(), true);
|
||||
@@ -4478,7 +4474,7 @@ pub mod test {
|
||||
// this is what happens at the end of append_block()
|
||||
// store block to staging and process it
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &consensus_hashes[i], &blocks[i].block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[i], get_epoch_time_secs(), &blocks[i], &parent_consensus_hashes[i], 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[i], &blocks[i], &parent_consensus_hashes[i], 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, &consensus_hashes[i], &blocks[i]);
|
||||
|
||||
// set different parts of this stream as confirmed
|
||||
@@ -4550,7 +4546,7 @@ pub mod test {
|
||||
// store blocks to staging
|
||||
for i in 0..blocks.len() {
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &consensus_hashes[i], &blocks[i].block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[i], get_epoch_time_secs(), &blocks[i], &parent_consensus_hashes[i], 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[i], &blocks[i], &parent_consensus_hashes[i], 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, &consensus_hashes[i], &blocks[i]);
|
||||
}
|
||||
|
||||
@@ -4615,7 +4611,7 @@ pub mod test {
|
||||
|
||||
// store block to staging
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &consensus_hash, &block.block_hash()).unwrap().is_none());
|
||||
store_staging_block(&mut chainstate, &consensus_hash, get_epoch_time_secs(), &block, &parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hash, &block, &parent_consensus_hash, 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, &consensus_hash, &block);
|
||||
|
||||
// drop microblocks
|
||||
@@ -4676,7 +4672,7 @@ pub mod test {
|
||||
}
|
||||
|
||||
// store block to staging
|
||||
store_staging_block(&mut chainstate, &consensus_hash, get_epoch_time_secs(), &block, &parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hash, &block, &parent_consensus_hash, 1, 2);
|
||||
assert!(StacksChainState::has_block_indexed(&chainstate.blocks_path, &index_block_header).unwrap());
|
||||
|
||||
// accept it
|
||||
@@ -4787,7 +4783,7 @@ pub mod test {
|
||||
assert_eq!(stream, stream_2);
|
||||
|
||||
// store block to staging
|
||||
store_staging_block(&mut chainstate, &consensus_hash, get_epoch_time_secs(), &block, &parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hash, &block, &parent_consensus_hash, 1, 2);
|
||||
|
||||
// stream it back
|
||||
let mut all_block_bytes = vec![];
|
||||
@@ -4918,7 +4914,7 @@ pub mod test {
|
||||
}
|
||||
|
||||
// store block to staging
|
||||
store_staging_block(&mut chainstate, &consensus_hash, get_epoch_time_secs(), &block, &parent_consensus_hash, 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hash, &block, &parent_consensus_hash, 1, 2);
|
||||
|
||||
// accept it
|
||||
set_block_processed(&mut chainstate, &consensus_hash, &block.block_hash(), true);
|
||||
@@ -5026,7 +5022,7 @@ pub mod test {
|
||||
test_debug!("Store block {} to staging", i);
|
||||
assert!(StacksChainState::load_staging_block_data(&chainstate.blocks_db, &chainstate.blocks_path, &consensus_hashes[i], &blocks[i].block_hash()).unwrap().is_none());
|
||||
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[i], get_epoch_time_secs(), &blocks[i], &parent_consensus_hashes[i], 1, 2);
|
||||
store_staging_block(&mut chainstate, &consensus_hashes[i], &blocks[i], &parent_consensus_hashes[i], 1, 2);
|
||||
assert_block_staging_not_processed(&mut chainstate, &consensus_hashes[i], &blocks[i]);
|
||||
|
||||
// some anchored blocks are stored (to staging)
|
||||
|
||||
@@ -123,6 +123,7 @@ impl StacksChainState {
|
||||
let consensus_hash = &tip_info.consensus_hash;
|
||||
let burn_header_hash = &tip_info.burn_header_hash;
|
||||
let block_height = tip_info.block_height;
|
||||
let burn_header_height = tip_info.burn_header_height;
|
||||
let burn_header_timestamp = tip_info.burn_header_timestamp;
|
||||
|
||||
let total_work_str = format!("{}", header.total_work.work);
|
||||
@@ -136,7 +137,8 @@ impl StacksChainState {
|
||||
let args: &[&dyn ToSql] = &[
|
||||
&header.version, &total_burn_str, &total_work_str, &header.proof, &header.parent_block, &header.parent_microblock, &header.parent_microblock_sequence,
|
||||
&header.tx_merkle_root, &header.state_index_root, &header.microblock_pubkey_hash,
|
||||
&block_hash, &index_block_hash, &consensus_hash, &burn_header_hash, &(burn_header_timestamp as i64), &(block_height as i64), &index_root];
|
||||
&block_hash, &index_block_hash, &consensus_hash, &burn_header_hash, &(burn_header_height as i64),
|
||||
&(burn_header_timestamp as i64), &(block_height as i64), &index_root];
|
||||
|
||||
tx.execute("INSERT INTO block_headers \
|
||||
(version, \
|
||||
@@ -153,10 +155,11 @@ impl StacksChainState {
|
||||
index_block_hash, \
|
||||
consensus_hash, \
|
||||
burn_header_hash, \
|
||||
burn_header_height, \
|
||||
burn_header_timestamp, \
|
||||
block_height, \
|
||||
index_root) \
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17)", args)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18)", args)
|
||||
.map_err(|e| Error::DBError(db_error::SqliteError(e)))?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -161,6 +161,7 @@ pub struct StacksHeaderInfo {
|
||||
pub index_root: TrieHash,
|
||||
pub consensus_hash: ConsensusHash,
|
||||
pub burn_header_hash: BurnchainHeaderHash,
|
||||
pub burn_header_height: u32,
|
||||
pub burn_header_timestamp: u64
|
||||
}
|
||||
|
||||
@@ -190,6 +191,7 @@ impl StacksHeaderInfo {
|
||||
block_height: 0,
|
||||
index_root: root_hash,
|
||||
burn_header_hash: FIRST_BURNCHAIN_BLOCK_HASH.clone(),
|
||||
burn_header_height: FIRST_BURNCHAIN_BLOCK_HEIGHT,
|
||||
consensus_hash: FIRST_BURNCHAIN_CONSENSUS_HASH.clone(),
|
||||
burn_header_timestamp: FIRST_BURNCHAIN_BLOCK_TIMESTAMP
|
||||
}
|
||||
@@ -222,6 +224,7 @@ impl FromRow<StacksHeaderInfo> for StacksHeaderInfo {
|
||||
let index_root = TrieHash::from_column(row, "index_root")?;
|
||||
let consensus_hash = ConsensusHash::from_column(row, "consensus_hash")?;
|
||||
let burn_header_hash = BurnchainHeaderHash::from_column(row, "burn_header_hash")?;
|
||||
let burn_header_height = u64::from_column(row, "burn_header_height")? as u32;
|
||||
let burn_header_timestamp = u64::from_column(row, "burn_header_timestamp")?;
|
||||
let stacks_header = StacksBlockHeader::from_row(row)?;
|
||||
|
||||
@@ -236,6 +239,7 @@ impl FromRow<StacksHeaderInfo> for StacksHeaderInfo {
|
||||
index_root: index_root,
|
||||
consensus_hash: consensus_hash,
|
||||
burn_header_hash: burn_header_hash,
|
||||
burn_header_height: burn_header_height,
|
||||
burn_header_timestamp: burn_header_timestamp
|
||||
})
|
||||
}
|
||||
@@ -400,6 +404,7 @@ const STACKS_CHAIN_STATE_SQL : &'static [&'static str]= &[
|
||||
index_root TEXT NOT NULL, -- root hash of the internal, not-consensus-critical MARF that allows us to track chainstate /fork metadata
|
||||
consensus_hash TEXT UNIQUE NOT NULL, -- all consensus hashes are guaranteed to be unique
|
||||
burn_header_hash TEXT NOT NULL, -- burn header hash corresponding to the consensus hash (NOT guaranteed to be unique, since we can have 2+ blocks per burn block if there's a PoX fork)
|
||||
burn_header_height INT NOT NULL, -- height of the burnchain block header that generated this consensus hash
|
||||
burn_header_timestamp INT NOT NULL, -- timestamp from burnchain block header that generated this consensus hash
|
||||
|
||||
PRIMARY KEY(consensus_hash,block_hash)
|
||||
@@ -878,6 +883,8 @@ impl StacksChainState {
|
||||
Ok((chainstate_tx, clarity_instance))
|
||||
}
|
||||
|
||||
// NOTE: used for testing in the stacks testnet code.
|
||||
// DO NOT CALL FROM PRODUCTION
|
||||
pub fn clarity_eval_read_only(&mut self, parent_id_bhh: &StacksBlockId,
|
||||
contract: &QualifiedContractIdentifier, code: &str) -> Value {
|
||||
let result = self.clarity_state.eval_read_only(parent_id_bhh, &self.headers_db, contract, code);
|
||||
@@ -1051,6 +1058,7 @@ impl StacksChainState {
|
||||
new_tip: &StacksBlockHeader,
|
||||
new_consensus_hash: &ConsensusHash,
|
||||
new_burn_header_hash: &BurnchainHeaderHash,
|
||||
new_burnchain_height: u32,
|
||||
new_burnchain_timestamp: u64,
|
||||
microblock_tail_opt: Option<StacksMicroblockHeader>,
|
||||
block_reward: &MinerPaymentSchedule,
|
||||
@@ -1090,6 +1098,7 @@ impl StacksChainState {
|
||||
block_height: new_tip.total_work.work,
|
||||
consensus_hash: new_consensus_hash.clone(),
|
||||
burn_header_hash: new_burn_header_hash.clone(),
|
||||
burn_header_height: new_burnchain_height,
|
||||
burn_header_timestamp: new_burnchain_timestamp
|
||||
};
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ impl StacksBlockBuilder {
|
||||
builder
|
||||
}
|
||||
|
||||
fn first_pubkey_hash(miner_id: usize, genesis_consensus_hash: &ConsensusHash, genesis_burn_header_hash: &BurnchainHeaderHash, genesis_burn_header_timestamp: u64, proof: &VRFProof, pubkh: Hash160) -> StacksBlockBuilder {
|
||||
fn first_pubkey_hash(miner_id: usize, genesis_consensus_hash: &ConsensusHash, genesis_burn_header_hash: &BurnchainHeaderHash, genesis_burn_header_height: u32, genesis_burn_header_timestamp: u64, proof: &VRFProof, pubkh: Hash160) -> StacksBlockBuilder {
|
||||
let genesis_chain_tip = StacksHeaderInfo {
|
||||
anchored_header: StacksBlockHeader::genesis_block_header(),
|
||||
microblock_tail: None,
|
||||
@@ -319,7 +319,8 @@ impl StacksBlockBuilder {
|
||||
index_root: TrieHash([0u8; 32]),
|
||||
consensus_hash: genesis_consensus_hash.clone(),
|
||||
burn_header_hash: genesis_burn_header_hash.clone(),
|
||||
burn_header_timestamp: genesis_burn_header_timestamp
|
||||
burn_header_timestamp: genesis_burn_header_timestamp,
|
||||
burn_header_height: genesis_burn_header_height,
|
||||
};
|
||||
|
||||
let mut builder = StacksBlockBuilder::from_parent_pubkey_hash(miner_id, &genesis_chain_tip, &StacksWorkScore::initial(), proof, pubkh);
|
||||
@@ -327,12 +328,12 @@ impl StacksBlockBuilder {
|
||||
builder
|
||||
}
|
||||
|
||||
pub fn first(miner_id: usize, genesis_consensus_hash: &ConsensusHash, genesis_burn_header_hash: &BurnchainHeaderHash, genesis_burn_header_timestamp: u64, proof: &VRFProof, microblock_privkey: &StacksPrivateKey) -> StacksBlockBuilder {
|
||||
pub fn first(miner_id: usize, genesis_consensus_hash: &ConsensusHash, genesis_burn_header_hash: &BurnchainHeaderHash, genesis_burn_header_height: u32, genesis_burn_header_timestamp: u64, proof: &VRFProof, microblock_privkey: &StacksPrivateKey) -> StacksBlockBuilder {
|
||||
let mut pubk = StacksPublicKey::from_private(microblock_privkey);
|
||||
pubk.set_compressed(true);
|
||||
let pubkh = Hash160::from_data(&pubk.to_bytes());
|
||||
|
||||
let mut builder = StacksBlockBuilder::first_pubkey_hash(miner_id, genesis_consensus_hash, genesis_burn_header_hash, genesis_burn_header_timestamp, proof, pubkh);
|
||||
let mut builder = StacksBlockBuilder::first_pubkey_hash(miner_id, genesis_consensus_hash, genesis_burn_header_hash, genesis_burn_header_height, genesis_burn_header_timestamp, proof, pubkh);
|
||||
builder.miner_privkey = microblock_privkey.clone();
|
||||
builder
|
||||
}
|
||||
@@ -642,7 +643,7 @@ impl StacksBlockBuilder {
|
||||
|
||||
let builder =
|
||||
if stacks_parent_header.consensus_hash == FIRST_BURNCHAIN_CONSENSUS_HASH {
|
||||
StacksBlockBuilder::first_pubkey_hash(0, &FIRST_BURNCHAIN_CONSENSUS_HASH, &FIRST_BURNCHAIN_BLOCK_HASH, FIRST_BURNCHAIN_BLOCK_TIMESTAMP, &proof, pubkey_hash)
|
||||
StacksBlockBuilder::first_pubkey_hash(0, &FIRST_BURNCHAIN_CONSENSUS_HASH, &FIRST_BURNCHAIN_BLOCK_HASH, FIRST_BURNCHAIN_BLOCK_HEIGHT, FIRST_BURNCHAIN_BLOCK_TIMESTAMP, &proof, pubkey_hash)
|
||||
}
|
||||
else {
|
||||
// building off an existing stacks block
|
||||
@@ -1258,7 +1259,13 @@ pub mod test {
|
||||
let (builder, parent_block_snapshot_opt) = match parent_stacks_block {
|
||||
None => {
|
||||
// first stacks block
|
||||
let builder = StacksBlockBuilder::first(miner.id, &burn_block.parent_snapshot.consensus_hash, &burn_block.parent_snapshot.burn_header_hash, burn_block.parent_snapshot.burn_header_timestamp, &proof, &miner.next_microblock_privkey());
|
||||
let builder = StacksBlockBuilder::first(miner.id,
|
||||
&burn_block.parent_snapshot.consensus_hash,
|
||||
&burn_block.parent_snapshot.burn_header_hash,
|
||||
burn_block.parent_snapshot.block_height as u32,
|
||||
burn_block.parent_snapshot.burn_header_timestamp,
|
||||
&proof,
|
||||
&miner.next_microblock_privkey());
|
||||
(builder, None)
|
||||
},
|
||||
Some(parent_stacks_block) => {
|
||||
@@ -1325,7 +1332,7 @@ pub mod test {
|
||||
|
||||
// "discover" this stacks block
|
||||
test_debug!("\n\nPreprocess Stacks block {}/{} ({})", &commit_snapshot.consensus_hash, &block_hash, StacksBlockHeader::make_index_block_hash(&commit_snapshot.consensus_hash, &block_hash));
|
||||
let block_res = node.chainstate.preprocess_anchored_block(&ic, &commit_snapshot.consensus_hash, commit_snapshot.burn_header_timestamp, &stacks_block, &parent_block_consensus_hash).unwrap();
|
||||
let block_res = node.chainstate.preprocess_anchored_block(&ic, &commit_snapshot.consensus_hash, &stacks_block, &parent_block_consensus_hash).unwrap();
|
||||
|
||||
// "discover" this stacks microblock stream
|
||||
for mblock in stacks_microblocks.iter() {
|
||||
|
||||
@@ -42,6 +42,7 @@ pub const NETWORK_P2P_PORT : u16 = 6265;
|
||||
// first burnchain block hash
|
||||
pub const FIRST_BURNCHAIN_CONSENSUS_HASH : ConsensusHash = ConsensusHash([0u8; 20]);
|
||||
pub const FIRST_BURNCHAIN_BLOCK_HASH : BurnchainHeaderHash = BurnchainHeaderHash([0u8; 32]);
|
||||
pub const FIRST_BURNCHAIN_BLOCK_HEIGHT : u32 = 0;
|
||||
pub const FIRST_BURNCHAIN_BLOCK_TIMESTAMP : u64 = 0;
|
||||
|
||||
pub const FIRST_BURNCHAIN_BLOCK_HASH_TESTNET : BurnchainHeaderHash = BurnchainHeaderHash([1u8; 32]);
|
||||
|
||||
@@ -2100,7 +2100,7 @@ pub mod test {
|
||||
};
|
||||
|
||||
let ic = sortdb.index_conn();
|
||||
node.chainstate.preprocess_anchored_block(&ic, &sn.consensus_hash, sn.burn_header_timestamp, block, &parent_sn.consensus_hash)
|
||||
node.chainstate.preprocess_anchored_block(&ic, &sn.consensus_hash, block, &parent_sn.consensus_hash)
|
||||
.map_err(|e| format!("Failed to preprocess anchored block: {:?}", &e))
|
||||
};
|
||||
self.sortdb = Some(sortdb);
|
||||
|
||||
@@ -474,14 +474,6 @@ impl Relayer {
|
||||
|
||||
/// Insert a staging block
|
||||
pub fn process_new_anchored_block(sort_ic: &SortitionDBConn, chainstate: &mut StacksChainState, consensus_hash: &ConsensusHash, block: &StacksBlock) -> Result<bool, chainstate_error> {
|
||||
let sn = match SortitionDB::get_block_snapshot_consensus(sort_ic.conn, consensus_hash)? {
|
||||
Some(sn) => sn,
|
||||
None => {
|
||||
debug!("Received unknown block {}/{}", consensus_hash, block.block_hash());
|
||||
return Ok(false);
|
||||
}
|
||||
};
|
||||
|
||||
// find the snapshot of the parent of this block
|
||||
let db_handle = SortitionHandleConn::open_reader_consensus(sort_ic, consensus_hash)?;
|
||||
let parent_block_snapshot = match db_handle.get_block_snapshot_of_parent_stacks_block(consensus_hash, &block.block_hash())? {
|
||||
@@ -492,7 +484,7 @@ impl Relayer {
|
||||
}
|
||||
};
|
||||
|
||||
chainstate.preprocess_anchored_block(sort_ic, consensus_hash, sn.burn_header_timestamp, block, &parent_block_snapshot.consensus_hash)
|
||||
chainstate.preprocess_anchored_block(sort_ic, consensus_hash, block, &parent_block_snapshot.consensus_hash)
|
||||
}
|
||||
|
||||
/// Coalesce a set of microblocks into relayer hints and MicroblocksData messages, as calculated by
|
||||
|
||||
@@ -1606,7 +1606,7 @@ mod test {
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(&peer_server_consensus_hash, &peer_server_block.block_hash());
|
||||
|
||||
test_debug!("Store peer server index block {:?}", &index_block_hash);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, get_epoch_time_secs(), &peer_server_block, &ConsensusHash([0x03; 20]), 456, 123);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, &peer_server_block, &ConsensusHash([0x03; 20]), 456, 123);
|
||||
|
||||
*server_block_cell.borrow_mut() = Some(peer_server_block);
|
||||
|
||||
@@ -1642,7 +1642,7 @@ mod test {
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(&peer_server_consensus_hash, &peer_server_block.block_hash());
|
||||
|
||||
test_debug!("Store peer server index block {:?}", &index_block_hash);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, get_epoch_time_secs(), &peer_server_block, &ConsensusHash([0x03; 20]), 456, 123);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, &peer_server_block, &ConsensusHash([0x03; 20]), 456, 123);
|
||||
set_block_processed(peer_server.chainstate(), &peer_server_consensus_hash, &peer_server_block.block_hash(), true);
|
||||
|
||||
*server_block_cell.borrow_mut() = Some(peer_server_block);
|
||||
|
||||
@@ -729,7 +729,7 @@ mod test {
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(&peer_server_consensus_hash, &peer_server_block.block_hash());
|
||||
|
||||
test_debug!("Store peer server index block {:?}", &index_block_hash);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, get_epoch_time_secs(), &peer_server_block, &ConsensusHash([client_id as u8; 20]), 456, 123);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, &peer_server_block, &ConsensusHash([client_id as u8; 20]), 456, 123);
|
||||
|
||||
let mut request = HttpRequestType::GetBlock(HttpRequestMetadata::from_host(PeerHost::from_host_port("127.0.0.1".to_string(), 51021)), index_block_hash);
|
||||
request.metadata_mut().keep_alive = false;
|
||||
@@ -764,7 +764,7 @@ mod test {
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(&peer_server_consensus_hash, &peer_server_block.block_hash());
|
||||
|
||||
test_debug!("Store peer server index block {:?}", &index_block_hash);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, get_epoch_time_secs(), &peer_server_block, &ConsensusHash([client_id as u8; 20]), 456, 123);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, &peer_server_block, &ConsensusHash([client_id as u8; 20]), 456, 123);
|
||||
|
||||
let mut request = HttpRequestType::GetBlock(HttpRequestMetadata::from_host(PeerHost::from_host_port("127.0.0.1".to_string(), 51031)), index_block_hash);
|
||||
request.metadata_mut().keep_alive = false;
|
||||
@@ -965,7 +965,7 @@ mod test {
|
||||
let index_block_hash = StacksBlockHeader::make_index_block_hash(&peer_server_consensus_hash, &peer_server_block.block_hash());
|
||||
|
||||
test_debug!("Store peer server index block {:?}", &index_block_hash);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, get_epoch_time_secs(), &peer_server_block, &ConsensusHash([client_id as u8; 20]), 456, 123);
|
||||
store_staging_block(peer_server.chainstate(), &peer_server_consensus_hash, &peer_server_block, &ConsensusHash([client_id as u8; 20]), 456, 123);
|
||||
|
||||
let mut request = HttpRequestType::GetBlock(HttpRequestMetadata::from_host(PeerHost::from_host_port("127.0.0.1".to_string(), 51071)), index_block_hash);
|
||||
request.metadata_mut().keep_alive = false;
|
||||
|
||||
@@ -57,6 +57,7 @@ pub trait HeadersDB {
|
||||
fn get_burn_header_hash_for_block(&self, id_bhh: &StacksBlockId) -> Option<BurnchainHeaderHash>;
|
||||
fn get_vrf_seed_for_block(&self, id_bhh: &StacksBlockId) -> Option<VRFSeed>;
|
||||
fn get_burn_block_time_for_block(&self, id_bhh: &StacksBlockId) -> Option<u64>;
|
||||
fn get_burn_block_height_for_block(&self, id_bhh: &StacksBlockId) -> Option<u32>;
|
||||
fn get_miner_address(&self, id_bhh: &StacksBlockId) -> Option<StacksAddress>;
|
||||
}
|
||||
|
||||
@@ -92,6 +93,11 @@ impl HeadersDB for DBConn {
|
||||
.map(|x| x.burn_header_timestamp)
|
||||
}
|
||||
|
||||
fn get_burn_block_height_for_block(&self, id_bhh: &StacksBlockId) -> Option<u32> {
|
||||
get_stacks_header_info(self, id_bhh)
|
||||
.map(|x| x.burn_header_height)
|
||||
}
|
||||
|
||||
fn get_vrf_seed_for_block(&self, id_bhh: &StacksBlockId) -> Option<VRFSeed> {
|
||||
get_stacks_header_info(self, id_bhh)
|
||||
.map(|x| VRFSeed::from_proof(&x.anchored_header.proof))
|
||||
@@ -116,6 +122,9 @@ impl HeadersDB for &dyn HeadersDB {
|
||||
fn get_burn_block_time_for_block(&self, bhh: &StacksBlockId) -> Option<u64> {
|
||||
(*self).get_burn_block_time_for_block(bhh)
|
||||
}
|
||||
fn get_burn_block_height_for_block(&self, bhh: &StacksBlockId) -> Option<u32> {
|
||||
(*self).get_burn_block_height_for_block(bhh)
|
||||
}
|
||||
fn get_miner_address(&self, bhh: &StacksBlockId) -> Option<StacksAddress> {
|
||||
(*self).get_miner_address(bhh)
|
||||
}
|
||||
@@ -138,6 +147,9 @@ impl HeadersDB for NullHeadersDB {
|
||||
fn get_burn_block_time_for_block(&self, _id_bhh: &StacksBlockId) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn get_burn_block_height_for_block(&self, _id_bhh: &StacksBlockId) -> Option<u32> {
|
||||
None
|
||||
}
|
||||
fn get_miner_address(&self, _id_bhh: &StacksBlockId) -> Option<StacksAddress> {
|
||||
None
|
||||
}
|
||||
@@ -297,6 +309,13 @@ impl <'a> ClarityDatabase <'a> {
|
||||
self.store.get_current_block_height()
|
||||
}
|
||||
|
||||
pub fn get_current_burnchain_block_height(&mut self) -> u32 {
|
||||
let cur_stacks_height = self.store.get_current_block_height();
|
||||
let cur_id_bhh = self.get_index_block_header_hash(cur_stacks_height);
|
||||
self.get_burnchain_block_height(&cur_id_bhh)
|
||||
.expect("Block header hash must return for provided burn block height")
|
||||
}
|
||||
|
||||
pub fn get_block_header_hash(&mut self, block_height: u32) -> BlockHeaderHash {
|
||||
let id_bhh = self.get_index_block_header_hash(block_height);
|
||||
self.headers_db.get_stacks_block_header_hash_for_block(&id_bhh)
|
||||
@@ -314,6 +333,10 @@ impl <'a> ClarityDatabase <'a> {
|
||||
self.headers_db.get_burn_header_hash_for_block(&id_bhh)
|
||||
.expect("Failed to get block data.")
|
||||
}
|
||||
|
||||
pub fn get_burnchain_block_height(&mut self, id_bhh: &StacksBlockId) -> Option<u32> {
|
||||
self.headers_db.get_burn_block_height_for_block(id_bhh)
|
||||
}
|
||||
|
||||
pub fn get_block_vrf_seed(&mut self, block_height: u32) -> VRFSeed {
|
||||
let id_bhh = self.get_index_block_header_hash(block_height);
|
||||
|
||||
@@ -55,10 +55,17 @@ struct DefineAPI {
|
||||
const BLOCK_HEIGHT: KeywordAPI = KeywordAPI {
|
||||
name: "block-height",
|
||||
output_type: "uint",
|
||||
description: "Returns the current block height of the Stacks blockchain as an int",
|
||||
description: "Returns the current block height of the Stacks blockchain as an uint",
|
||||
example: "(> block-height 1000) ;; returns true if the current block-height has passed 1000 blocks."
|
||||
};
|
||||
|
||||
const BURN_BLOCK_HEIGHT: KeywordAPI = KeywordAPI {
|
||||
name: "burn-block-height",
|
||||
output_type: "uint",
|
||||
description: "Returns the current block height of the underlying burn blockchain as a uint",
|
||||
example: "(> burn-block-height 1000) ;; returns true if the current height of the underlying burn blockchain has passed 1000 blocks."
|
||||
};
|
||||
|
||||
const CONTRACT_CALLER_KEYWORD: KeywordAPI = KeywordAPI {
|
||||
name: "contract-caller",
|
||||
output_type: "principal",
|
||||
@@ -1392,7 +1399,7 @@ fn make_keyword_reference(variable: &NativeVariables) -> Option<KeywordAPI> {
|
||||
NativeVariables::NativeTrue => Some(TRUE_KEYWORD.clone()),
|
||||
NativeVariables::NativeFalse => Some(FALSE_KEYWORD.clone()),
|
||||
NativeVariables::BlockHeight => Some(BLOCK_HEIGHT.clone()),
|
||||
NativeVariables::BurnBlockHeight => None,
|
||||
NativeVariables::BurnBlockHeight => Some(BURN_BLOCK_HEIGHT.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1490,6 +1497,9 @@ mod test {
|
||||
fn get_burn_block_time_for_block(&self, _id_bhh: &StacksBlockId) -> Option<u64> {
|
||||
Some(1557860301)
|
||||
}
|
||||
fn get_burn_block_height_for_block(&self, _id_bhh: &StacksBlockId) -> Option<u32> {
|
||||
Some(567890)
|
||||
}
|
||||
fn get_miner_address(&self, _id_bhh: &StacksBlockId) -> Option<StacksAddress> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ pub fn lookup_reserved_variable(name: &str, _context: &LocalContext, env: &mut E
|
||||
Ok(Some(Value::UInt(block_height as u128)))
|
||||
},
|
||||
NativeVariables::BurnBlockHeight => {
|
||||
Err(RuntimeErrorType::NotImplemented.into())
|
||||
let burn_block_height = env.global_context.database.get_current_burnchain_block_height();
|
||||
Ok(Some(Value::UInt(burn_block_height as u128)))
|
||||
},
|
||||
NativeVariables::NativeNone => {
|
||||
Ok(Some(Value::none()))
|
||||
|
||||
@@ -29,7 +29,6 @@ use stacks::chainstate::stacks::StacksPublicKey;
|
||||
|
||||
use stacks::core::mempool::MemPoolDB;
|
||||
use stacks::util::vrf::VRFPublicKey;
|
||||
use stacks::util::get_epoch_time_secs;
|
||||
use stacks::util::strings::UrlString;
|
||||
use stacks::util::hash::{
|
||||
Hash160, Sha256Sum, to_hex
|
||||
@@ -123,7 +122,6 @@ fn inner_process_tenure(
|
||||
chain_state.preprocess_anchored_block(
|
||||
&ic,
|
||||
consensus_hash,
|
||||
get_epoch_time_secs(),
|
||||
&anchored_block,
|
||||
&parent_consensus_hash)?;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ use stacks::net::{
|
||||
};
|
||||
|
||||
use stacks::util::vrf::VRFPublicKey;
|
||||
use stacks::util::get_epoch_time_secs;
|
||||
use stacks::util::strings::UrlString;
|
||||
use stacks::util::hash::Sha256Sum;
|
||||
use stacks::util::secp256k1::Secp256k1PrivateKey;
|
||||
@@ -488,7 +487,6 @@ impl Node {
|
||||
self.chain_state.preprocess_anchored_block(
|
||||
&ic,
|
||||
consensus_hash,
|
||||
get_epoch_time_secs(),
|
||||
&anchored_block,
|
||||
&parent_consensus_hash).unwrap();
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ const GET_INFO_CONTRACT: &'static str = "
|
||||
(define-private (test-8) (get-block-info? miner-address u1))
|
||||
(define-private (test-9) (get-block-info? miner-address block-height))
|
||||
(define-private (test-10) (get-block-info? miner-address u100000))
|
||||
(define-private (test-11) burn-block-height)
|
||||
|
||||
(define-private (get-block-id-hash (height uint)) (unwrap-panic
|
||||
(get id-hash (map-get? block-data ((height height))))))
|
||||
@@ -258,6 +259,13 @@ fn integration_test_get_info() {
|
||||
chain_state.clarity_eval_read_only(
|
||||
bhh, &contract_identifier, "(test-10)"),
|
||||
Value::none());
|
||||
|
||||
// verify we can read the burn block height (should be 3, since we sent the
|
||||
// contract at block 2)
|
||||
assert_eq!(
|
||||
chain_state.clarity_eval_read_only(
|
||||
bhh, &contract_identifier, "(test-11)"),
|
||||
Value::UInt(3));
|
||||
|
||||
},
|
||||
3 => {
|
||||
|
||||
Reference in New Issue
Block a user