mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-05-25 10:12:40 +08:00
move code that doesn't directly call a SQL query out of this module
This commit is contained in:
@@ -33,25 +33,20 @@ use chainstate::burn::db::Error as db_error;
|
||||
|
||||
use chainstate::burn::CHAINSTATE_VERSION;
|
||||
use chainstate::burn::CONSENSUS_HASH_LIFETIME;
|
||||
use chainstate::burn::{ConsensusHash, VRFSeed, BlockHeaderHash, OpsHash};
|
||||
use chainstate::burn::{ConsensusHash, VRFSeed, BlockHeaderHash, OpsHash, BlockSnapshot};
|
||||
|
||||
use chainstate::burn::operations::{BlockstackOperationType, BlockstackOperation};
|
||||
use chainstate::burn::operations::leader_block_commit::LeaderBlockCommitOp;
|
||||
use chainstate::burn::operations::leader_block_commit::OPCODE as LeaderBlockCommitOp_OPCODE;
|
||||
use chainstate::burn::operations::leader_block_commit::OPCODE as LeaderBlockCommitOpcode;
|
||||
use chainstate::burn::operations::leader_key_register::LeaderKeyRegisterOp;
|
||||
use chainstate::burn::operations::leader_key_register::OPCODE as LeaderKeyRegisterOp_OPCODE;
|
||||
use chainstate::burn::operations::leader_key_register::OPCODE as LeaderKeyRegisterOpcode;
|
||||
use chainstate::burn::operations::user_burn_support::UserBurnSupportOp;
|
||||
use chainstate::burn::operations::user_burn_support::OPCODE as UserBurnSupportOp_OPCODE;
|
||||
use chainstate::burn::operations::Error as op_error;
|
||||
use chainstate::burn::operations::user_burn_support::OPCODE as UserBurnSupportOpcode;
|
||||
|
||||
use burnchains::BurnchainTxInput;
|
||||
use burnchains::BurnchainTransaction;
|
||||
use burnchains::BurnchainBlock;
|
||||
use burnchains::{Txid, BurnchainHeaderHash, PublicKey, Address};
|
||||
|
||||
use util::vrf::ECVRF_public_key_to_hex;
|
||||
use util::hash::{to_hex, hex_bytes, Hash160};
|
||||
use util::log;
|
||||
|
||||
use ed25519_dalek::PublicKey as VRFPublicKey;
|
||||
|
||||
@@ -147,25 +142,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// a row in the "snapshots" table
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SnapshotRow {
|
||||
pub block_height: u64,
|
||||
pub burn_header_hash: BurnchainHeaderHash,
|
||||
pub consensus_hash: ConsensusHash,
|
||||
pub ops_hash: OpsHash,
|
||||
pub total_burn: u64,
|
||||
pub canonical: bool
|
||||
}
|
||||
|
||||
impl RowOrder for SnapshotRow {
|
||||
impl RowOrder for BlockSnapshot {
|
||||
fn row_order() -> Vec<&'static str> {
|
||||
vec!["block_height","burn_header_hash","consensus_hash","ops_hash","total_burn","canonical"]
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRow<SnapshotRow> for SnapshotRow {
|
||||
fn from_row<'a>(row: &'a Row, index: usize) -> Result<SnapshotRow, db_error> {
|
||||
impl FromRow<BlockSnapshot> for BlockSnapshot {
|
||||
fn from_row<'a>(row: &'a Row, index: usize) -> Result<BlockSnapshot, db_error> {
|
||||
let block_height_i64 : i64 = row.get(0 + index);
|
||||
let burn_header_hash = BurnchainHeaderHash::from_row(row, 1 + index)?;
|
||||
let consensus_hash = ConsensusHash::from_row(row, 2 + index)?;
|
||||
@@ -180,7 +164,7 @@ impl FromRow<SnapshotRow> for SnapshotRow {
|
||||
let total_burn = total_burn_str.parse::<u64>()
|
||||
.map_err(|_e| db_error::ParseError)?;
|
||||
|
||||
let snapshot = SnapshotRow {
|
||||
let snapshot = BlockSnapshot {
|
||||
block_height: block_height_i64 as u64,
|
||||
burn_header_hash: burn_header_hash,
|
||||
consensus_hash: consensus_hash,
|
||||
@@ -232,7 +216,7 @@ where
|
||||
vtxindex: vtxindex,
|
||||
block_number: block_number as u64,
|
||||
burn_header_hash: burn_header_hash,
|
||||
op: LeaderKeyRegisterOp_OPCODE,
|
||||
op: LeaderKeyRegisterOpcode,
|
||||
|
||||
consensus_hash: consensus_hash,
|
||||
public_key: public_key,
|
||||
@@ -307,7 +291,7 @@ where
|
||||
burn_fee: burn_fee,
|
||||
input: input,
|
||||
|
||||
op: LeaderBlockCommitOp_OPCODE,
|
||||
op: LeaderBlockCommitOpcode,
|
||||
txid: txid,
|
||||
vtxindex: vtxindex,
|
||||
block_number: block_height as u64,
|
||||
@@ -366,7 +350,7 @@ where
|
||||
memo: memo,
|
||||
burn_fee: burn_fee,
|
||||
|
||||
op: UserBurnSupportOp_OPCODE,
|
||||
op: UserBurnSupportOpcode,
|
||||
txid: txid,
|
||||
vtxindex: vtxindex,
|
||||
block_number: block_height as u64,
|
||||
@@ -494,7 +478,7 @@ where
|
||||
fn instantiate(&mut self) -> Result<(), db_error> {
|
||||
|
||||
// create first (sentinel) snapshot
|
||||
let first_snapshot = SnapshotRow {
|
||||
let first_snapshot = BlockSnapshot {
|
||||
block_height: self.first_block_height,
|
||||
burn_header_hash: self.first_burn_header_hash.clone(),
|
||||
consensus_hash: ConsensusHash::from_hex("0000000000000000000000000000000000000000").unwrap(),
|
||||
@@ -513,9 +497,9 @@ where
|
||||
tx.execute("INSERT INTO db_version (version) VALUES (?1)", &[&CHAINSTATE_VERSION])
|
||||
.map_err(|e| db_error::SqliteError(e))?;
|
||||
|
||||
BurnDB::<A, K>::insert_snapshot_row(&mut tx, &first_snapshot)?;
|
||||
BurnDB::<A, K>::insert_block_snapshot(&mut tx, &first_snapshot)?;
|
||||
tx.commit()
|
||||
.map_err(db_error::SqliteError);
|
||||
.map_err(db_error::SqliteError)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -567,6 +551,7 @@ where
|
||||
}
|
||||
|
||||
/// Open a burn database in memory (used for testing)
|
||||
#[allow(dead_code)]
|
||||
pub fn connect_memory(first_block_height: u64, first_burn_hash: &BurnchainHeaderHash) -> Result<BurnDB<A, K>, db_error> {
|
||||
let conn = Connection::open_in_memory()
|
||||
.map_err(|e| db_error::SqliteError(e))?;
|
||||
@@ -590,56 +575,22 @@ where
|
||||
&self.conn
|
||||
}
|
||||
|
||||
/// Get the previous consensus hashes that must be hashed to find
|
||||
/// the *next* consensus hash at a particular block.
|
||||
/// The resulting list will include the consensus hash at block_height.
|
||||
fn get_prev_consensus_hashes(conn: &Connection, block_height: u64, first_block_height: u64) -> Result<Vec<ConsensusHash>, db_error> {
|
||||
let mut i = 0;
|
||||
let mut prev_chs = vec![];
|
||||
while block_height - (((1 as u64) << i) - 1) >= first_block_height {
|
||||
let prev_block : u64 = block_height - (((1 as u64) << i) - 1);
|
||||
let prev_ch_opt = BurnDB::<A, K>::get_consensus_at(conn, prev_block)?;
|
||||
match prev_ch_opt {
|
||||
Some(prev_ch) => {
|
||||
debug!("Consensus at {}: {}", prev_block, &prev_ch.to_hex());
|
||||
prev_chs.push(prev_ch.clone());
|
||||
i += 1;
|
||||
|
||||
if block_height < (((1 as u64) << i) - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
error!("Failed to read consensus hash for block height {}", prev_block);
|
||||
return Err(db_error::Corruption);
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(prev_chs)
|
||||
}
|
||||
|
||||
/// Make a new consensus hash, given the ops hash
|
||||
fn make_consensus_hash(conn: &Connection, opshash: &OpsHash, block_height: u64, first_block_height: u64, total_burn: u64) -> Result<ConsensusHash, db_error> {
|
||||
let prev_consensus_hashes = BurnDB::<A, K>::get_prev_consensus_hashes(conn, block_height - 1, first_block_height)?;
|
||||
Ok(ConsensusHash::from_ops(opshash, total_burn, &prev_consensus_hashes))
|
||||
}
|
||||
|
||||
/// Find out how any burn tokens were destroyed in a given (canonical) block
|
||||
fn find_block_burn_amount<'a>(tx: &mut Transaction<'a>, block_height: u64) -> Result<u64, db_error>
|
||||
pub fn get_block_burn_amount<'a>(tx: &mut Transaction<'a>, block_height: u64) -> Result<u64, db_error>
|
||||
{
|
||||
let user_burns = BurnDB::<A, K>::get_user_burns_by_block(tx, block_height)?;
|
||||
let block_commits = BurnDB::<A, K>::get_block_commits_by_block(tx, block_height)?;
|
||||
let mut burn_total = 0;
|
||||
let mut burn_total : u64 = 0;
|
||||
|
||||
for i in 0..user_burns.len() {
|
||||
if burn_total + user_burns[i].burn_fee < 0 {
|
||||
if burn_total.checked_add(user_burns[i].burn_fee).is_none() {
|
||||
return Err(db_error::Overflow);
|
||||
}
|
||||
|
||||
burn_total += user_burns[i].burn_fee;
|
||||
}
|
||||
for i in 0..block_commits.len() {
|
||||
if burn_total + user_burns[i].burn_fee < 0 {
|
||||
if burn_total.checked_add(user_burns[i].burn_fee).is_none() {
|
||||
return Err(db_error::Overflow);
|
||||
}
|
||||
|
||||
@@ -648,21 +599,6 @@ where
|
||||
Ok(burn_total)
|
||||
}
|
||||
|
||||
/// Make a block snapshot
|
||||
fn make_snapshot_row(conn: &Connection, block_height: u64, burn_header_hash: &BurnchainHeaderHash, first_block_height: u64, txids: &Vec<Txid>, total_burn: u64) -> Result<SnapshotRow, db_error> {
|
||||
let ops_hash = OpsHash::from_txids(txids);
|
||||
let ch = BurnDB::<A, K>::make_consensus_hash(conn, &ops_hash, block_height, first_block_height, total_burn)?;
|
||||
|
||||
Ok(SnapshotRow {
|
||||
block_height: block_height,
|
||||
burn_header_hash: burn_header_hash.clone(),
|
||||
consensus_hash: ch,
|
||||
ops_hash: ops_hash,
|
||||
total_burn: total_burn,
|
||||
canonical: true
|
||||
})
|
||||
}
|
||||
|
||||
/// Process a burn chain reorganization -- given the height at which the reorg starts,
|
||||
/// invalidate all blocks and transactions processed since then.
|
||||
pub fn burnchain_history_reorg<'a>(tx: &mut Transaction<'a>, reorg_height: u64) -> Result<(), db_error> {
|
||||
@@ -717,7 +653,7 @@ where
|
||||
}
|
||||
|
||||
/// Insert a snapshots row from a block's-worth of operations.
|
||||
fn insert_snapshot_row<'a>(tx: &mut Transaction<'a>, snapshot: &SnapshotRow) -> Result<(), db_error> {
|
||||
pub fn insert_block_snapshot<'a>(tx: &mut Transaction<'a>, snapshot: &BlockSnapshot) -> Result<(), db_error> {
|
||||
if snapshot.block_height > ((1 as u64) << 63 - 1) {
|
||||
return Err(db_error::TypeError);
|
||||
}
|
||||
@@ -837,15 +773,15 @@ where
|
||||
}
|
||||
|
||||
/// Get a canonical snapshot row
|
||||
pub fn get_block_snapshot(conn: &Connection, block_height: u64) -> Result<Option<SnapshotRow>, db_error> {
|
||||
pub fn get_block_snapshot(conn: &Connection, block_height: u64) -> Result<Option<BlockSnapshot>, db_error> {
|
||||
if block_height > ((1 as u64) << 63) - 1 {
|
||||
return Err(db_error::TypeError);
|
||||
}
|
||||
|
||||
let row_order = SnapshotRow::row_order().join(",");
|
||||
let row_order = BlockSnapshot::row_order().join(",");
|
||||
let qry = format!("SELECT {} FROM snapshots WHERE canonical = 1 AND block_height = ?1", row_order);
|
||||
let args = [&(block_height as i64) as &ToSql];
|
||||
let rows = BurnDB::<A, K>::query_rows::<SnapshotRow, _>(conn, &qry.to_string(), &args)?;
|
||||
let rows = BurnDB::<A, K>::query_rows::<BlockSnapshot, _>(conn, &qry.to_string(), &args)?;
|
||||
|
||||
match rows.len() {
|
||||
0 => Ok(None),
|
||||
@@ -887,7 +823,7 @@ where
|
||||
let row_order_list : Vec<String> = LeaderKeyRegisterOp::row_order().iter().map(|r| format!("leader_keys.{}", r)).collect();
|
||||
let row_order = row_order_list.join(",");
|
||||
|
||||
let qry = format!("SELECT {} FROM leader_keys JOIN history ON leader_keys.txid = history.txid WHERE history.canonical = 1 AND leader_keys.block_height = ?1 AND leader_keys.vtxindex = ?2 ORDER BY leader_keys.vtxindex ASC", row_order);
|
||||
let qry = format!("SELECT {} FROM leader_keys JOIN history ON leader_keys.txid = history.txid WHERE history.canonical = 1 AND leader_keys.block_height = ?1 AND leader_keys.vtxindex = ?2", row_order);
|
||||
let args = [&(block_height as i64) as &ToSql, &vtxindex as &ToSql];
|
||||
let rows = BurnDB::<A, K>::query_rows::<LeaderKeyRegisterOp<A, K>, _>(conn, &qry.to_string(), &args)?;
|
||||
|
||||
@@ -918,6 +854,33 @@ where
|
||||
|
||||
BurnDB::<A, K>::query_rows::<LeaderBlockCommitOp<A, K>, _>(conn, &qry.to_string(), &args)
|
||||
}
|
||||
|
||||
/// Get a block commit at a specific location in the burn chain's canonical history.
|
||||
/// Returns None if there is no block commit at this location.
|
||||
pub fn get_block_commit(conn: &Connection, block_height: u64, vtxindex: u32) -> Result<Option<LeaderBlockCommitOp<A, K>>, db_error>
|
||||
where
|
||||
LeaderBlockCommitOp<A, K>: FromRow<LeaderBlockCommitOp<A, K>> + RowOrder
|
||||
{
|
||||
if block_height > ((1 as u64) << 63) - 1 {
|
||||
return Err(db_error::TypeError);
|
||||
}
|
||||
|
||||
let row_order_list : Vec<String> = LeaderBlockCommitOp::row_order().iter().map(|r| format!("block_commits.{}", r)).collect();
|
||||
let row_order = row_order_list.join(",");
|
||||
|
||||
let qry = format!("SELECT {} FROM block_commits JOIN history ON block_commits.txid = history.txid WHERE history.canonical = 1 AND block_commits.block_height = ?1 AND block_commits.vtxindex = ?2", row_order);
|
||||
let args = [&(block_height as i64) as &ToSql, &vtxindex as &ToSql];
|
||||
let rows = BurnDB::<A, K>::query_rows::<LeaderBlockCommitOp<A, K>, _>(conn, &qry.to_string(), &args)?;
|
||||
|
||||
match rows.len() {
|
||||
0 => Ok(None),
|
||||
1 => Ok(Some(rows[0].clone())),
|
||||
_ => {
|
||||
// should never happen
|
||||
panic!("FATAL: multiple block commits at block {} vtxindex {}", block_height, vtxindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get all user burns registered in a block on the burn chain's canonical history
|
||||
pub fn get_user_burns_by_block(conn: &Connection, block_height: u64) -> Result<Vec<UserBurnSupportOp<A, K>>, db_error>
|
||||
@@ -938,6 +901,7 @@ where
|
||||
}
|
||||
|
||||
/// Find out whether or not a particular VRF key was used before in the canonical burnchain history
|
||||
#[allow(non_snake_case)]
|
||||
pub fn has_VRF_public_key(conn: &Connection, key: &VRFPublicKey) -> Result<bool, db_error> {
|
||||
let qry = "SELECT COUNT(leader_keys.public_key) FROM leader_keys JOIN history ON leader_keys.txid = history.txid WHERE history.canonical = 1 AND leader_keys.public_key = ?1 AND history.canonical = 1";
|
||||
let args = [&ECVRF_public_key_to_hex(&key)];
|
||||
@@ -984,184 +948,6 @@ where
|
||||
})
|
||||
.map_err(|e| db_error::SqliteError(e))
|
||||
}
|
||||
|
||||
/// Classify a burnchain transaction as a burn database operation
|
||||
pub fn classify_transaction(block_height: u64, block_hash: &BurnchainHeaderHash, burn_tx: &BurnchainTransaction<A, K>) -> Option<BlockstackOperationType<A, K>> {
|
||||
match burn_tx.opcode {
|
||||
LeaderKeyRegisterOp_OPCODE => {
|
||||
match LeaderKeyRegisterOp::from_tx(block_height, block_hash, burn_tx) {
|
||||
Ok(op) => {
|
||||
Some(BlockstackOperationType::LeaderKeyRegister(op))
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Failed to parse leader key register tx {} data {}: {:?}", &burn_tx.txid.to_hex(), &to_hex(&burn_tx.data[..]), e);
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
LeaderBlockCommitOp_OPCODE => {
|
||||
match LeaderBlockCommitOp::from_tx(block_height, block_hash, burn_tx) {
|
||||
Ok(op) => {
|
||||
Some(BlockstackOperationType::LeaderBlockCommit(op))
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Failed to parse leader block commit tx {} data {}: {:?}", &burn_tx.txid.to_hex(), &to_hex(&burn_tx.data[..]), e);
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
UserBurnSupportOp_OPCODE => {
|
||||
match UserBurnSupportOp::from_tx(block_height, block_hash, burn_tx) {
|
||||
Ok(op) => {
|
||||
Some(BlockstackOperationType::UserBurnSupport(op))
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("Failed to parse user burn support tx {} data {}: {:?}", &burn_tx.txid.to_hex(), &to_hex(&burn_tx.data[..]), e);
|
||||
None
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check a burnchain transaction to determine if it is valid -- i.e. that it can be committed
|
||||
pub fn check_transaction(conn: &Connection, blockstack_op: &BlockstackOperationType<A, K>) -> Result<bool, op_error> {
|
||||
match blockstack_op {
|
||||
BlockstackOperationType::LeaderKeyRegister(ref op) => {
|
||||
LeaderKeyRegisterOp::check(op, conn)
|
||||
.and_then(|res| {
|
||||
if res {
|
||||
info!("ACCEPT leader key register {}", &op.txid.to_hex());
|
||||
}
|
||||
else {
|
||||
warn!("REJECT leader key register {}", &op.txid.to_hex());
|
||||
}
|
||||
Ok(res)
|
||||
})
|
||||
},
|
||||
BlockstackOperationType::LeaderBlockCommit(ref op) => {
|
||||
LeaderBlockCommitOp::check(op, conn)
|
||||
.and_then(|res| {
|
||||
if res {
|
||||
info!("ACCEPT leader block commit {}", &op.txid.to_hex());
|
||||
}
|
||||
else {
|
||||
warn!("REJECT leader block commit {}", &op.txid.to_hex());
|
||||
}
|
||||
Ok(res)
|
||||
})
|
||||
},
|
||||
BlockstackOperationType::UserBurnSupport(ref op) => {
|
||||
UserBurnSupportOp::check(op, conn)
|
||||
.and_then(|res| {
|
||||
if res {
|
||||
info!("ACCEPT user burn support {}", &op.txid.to_hex());
|
||||
}
|
||||
else {
|
||||
warn!("REJECT user burn support {}", &op.txid.to_hex());
|
||||
}
|
||||
Ok(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// commit a transaction
|
||||
pub fn commit_transaction<'a>(tx: &mut Transaction<'a>, blockstack_op: &BlockstackOperationType<A, K>) -> Result<(), db_error> {
|
||||
match blockstack_op {
|
||||
BlockstackOperationType::LeaderKeyRegister(ref op) => {
|
||||
info!("COMMIT leader key register {}", &op.txid.to_hex());
|
||||
BurnDB::insert_leader_key(tx, op)
|
||||
},
|
||||
BlockstackOperationType::LeaderBlockCommit(ref op) => {
|
||||
info!("COMMIT leader block commit {}", &op.txid.to_hex());
|
||||
BurnDB::insert_block_commit(tx, op)
|
||||
},
|
||||
BlockstackOperationType::UserBurnSupport(ref op) => {
|
||||
info!("COMMIT user burn support {}", &op.txid.to_hex());
|
||||
BurnDB::insert_user_burn(tx, op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Process a burnchain block from Bitcoin. Check each transaction and commit the valid ones.
|
||||
/// Panics if any database operation fails.
|
||||
pub fn process_block(&mut self, block: &BurnchainBlock<A, K>) -> Result<(), db_error>
|
||||
{
|
||||
let first_block_height = self.first_block_height;
|
||||
debug!("Process block {} {}", block.block_height, &block.block_hash.to_hex());
|
||||
|
||||
let mut tx = self.tx_begin()?;
|
||||
|
||||
// commit each transaction
|
||||
for i in 0..block.txs.len() {
|
||||
match BurnDB::classify_transaction(block.block_height, &block.block_hash, &block.txs[i]) {
|
||||
None => {
|
||||
continue;
|
||||
},
|
||||
Some(ref blockstack_op) => {
|
||||
match BurnDB::check_transaction(&tx, blockstack_op) {
|
||||
Err(op_error) => {
|
||||
panic!("FATAL ERROR when processing burnchain transaction {}", &block.txs[i].txid.to_hex());
|
||||
},
|
||||
Ok(res) => {
|
||||
if res {
|
||||
// accepted, so commit
|
||||
match BurnDB::commit_transaction(&mut tx, blockstack_op) {
|
||||
Err(db_error) => {
|
||||
panic!("FATAL ERROR when inserting burnchain transaction {}", &block.txs[i].txid.to_hex());
|
||||
}
|
||||
Ok(_) => {}
|
||||
};
|
||||
}
|
||||
else {
|
||||
// rejected
|
||||
continue;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// snapshot
|
||||
let txids : Vec<Txid> = block.txs.iter()
|
||||
.map(|tx| tx.txid.clone())
|
||||
.collect();
|
||||
|
||||
let block_burn_total = BurnDB::<A, K>::find_block_burn_amount(&mut tx, block.block_height)
|
||||
.map_err(|e| panic!("FATAL ERROR when trying to query burn amount for block {}", block.block_height))?;
|
||||
|
||||
let last_block_snapshot_opt = BurnDB::<A, K>::get_block_snapshot(&mut tx, block.block_height - 1)
|
||||
.map_err(|e| panic!("FATAL ERROR when trying to get block snapshot for block {}", block.block_height))?;
|
||||
|
||||
let chain_burn_total =
|
||||
match last_block_snapshot_opt {
|
||||
Some(prev_snapshot) => prev_snapshot.total_burn,
|
||||
None => 0
|
||||
};
|
||||
|
||||
if block_burn_total + chain_burn_total < 0 {
|
||||
panic!("FATAL ERROR burn total overflow ({} + {})", block_burn_total, chain_burn_total);
|
||||
}
|
||||
|
||||
let snapshot = BurnDB::<A, K>::make_snapshot_row(&mut tx, block.block_height, &block.block_hash, first_block_height, &txids, block_burn_total + chain_burn_total)
|
||||
.map_err(|e| panic!("FATAL ERROR when taking snapshot at block {} ({}): {:?}", block.block_height, &block.block_hash.to_hex(), e))?;
|
||||
|
||||
BurnDB::<A, K>::insert_snapshot_row(&mut tx, &snapshot)
|
||||
.map_err(|e| panic!("FATAL ERROR when inserting snapshot for block {} ({}): {:?}", block.block_height, &block.block_hash.to_hex(), e))?;
|
||||
|
||||
info!("OPSHASH({}): {}", block.block_height, &snapshot.ops_hash.to_hex());
|
||||
info!("CONSENSUS({}): {}", block.block_height, &snapshot.consensus_hash.to_hex());
|
||||
|
||||
// commit everything!
|
||||
tx.commit()
|
||||
.map_err(db_error::SqliteError);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, K> ChainstateDB for BurnDB<A, K>
|
||||
@@ -1184,9 +970,9 @@ mod tests {
|
||||
|
||||
use chainstate::burn::operations::leader_block_commit::LeaderBlockCommitOp;
|
||||
use chainstate::burn::operations::leader_key_register::LeaderKeyRegisterOp;
|
||||
use chainstate::burn::operations::leader_key_register::OPCODE as LeaderKeyRegisterOp_OPCODE;
|
||||
use chainstate::burn::operations::leader_key_register::OPCODE as LeaderKeyRegisterOpcode;
|
||||
use chainstate::burn::operations::user_burn_support::UserBurnSupportOp;
|
||||
use chainstate::burn::operations::user_burn_support::OPCODE as UserBurnSupportOp_OPCODE;
|
||||
use chainstate::burn::operations::user_burn_support::OPCODE as UserBurnSupportOpcode;
|
||||
|
||||
use burnchains::BurnchainTxInput;
|
||||
use burnchains::BurnchainInputType;
|
||||
@@ -1227,7 +1013,7 @@ mod tests {
|
||||
memo: vec![01, 02, 03, 04, 05],
|
||||
address: BitcoinAddress::from_scriptpubkey(BitcoinNetworkType::testnet, &hex_bytes("76a9140be3e286a15ea85882761618e366586b5574100d88ac").unwrap()).unwrap(),
|
||||
|
||||
op: LeaderKeyRegisterOp_OPCODE,
|
||||
op: LeaderKeyRegisterOpcode,
|
||||
txid: Txid::from_bytes_be(&hex_bytes("1bfa831b5fc56c858198acb8e77e5863c1e9d8ac26d49ddb914e24d8d4083562").unwrap()).unwrap(),
|
||||
vtxindex: vtxindex,
|
||||
block_number: block_height,
|
||||
@@ -1337,7 +1123,7 @@ mod tests {
|
||||
memo: vec![0x01, 0x02, 0x03, 0x04, 0x05],
|
||||
burn_fee: 12345,
|
||||
|
||||
op: UserBurnSupportOp_OPCODE,
|
||||
op: UserBurnSupportOpcode,
|
||||
txid: Txid::from_bytes_be(&hex_bytes("1d5cbdd276495b07f0e0bf0181fa57c175b217bc35531b078d62fc20986c716c").unwrap()).unwrap(),
|
||||
vtxindex: vtxindex,
|
||||
block_number: block_height,
|
||||
@@ -1380,7 +1166,7 @@ mod tests {
|
||||
memo: vec![01, 02, 03, 04, 05],
|
||||
address: BitcoinAddress::from_scriptpubkey(BitcoinNetworkType::testnet, &hex_bytes("76a9140be3e286a15ea85882761618e366586b5574100d88ac").unwrap()).unwrap(),
|
||||
|
||||
op: LeaderKeyRegisterOp_OPCODE,
|
||||
op: LeaderKeyRegisterOpcode,
|
||||
txid: Txid::from_bytes_be(&hex_bytes("1bfa831b5fc56c858198acb8e77e5863c1e9d8ac26d49ddb914e24d8d4083562").unwrap()).unwrap(),
|
||||
vtxindex: vtxindex,
|
||||
block_number: block_height,
|
||||
@@ -1410,7 +1196,7 @@ mod tests {
|
||||
{
|
||||
let mut tx = db.tx_begin().unwrap();
|
||||
for i in 0..256 {
|
||||
let snapshot_row = SnapshotRow {
|
||||
let snapshot_row = BlockSnapshot {
|
||||
block_height: i,
|
||||
burn_header_hash: BurnchainHeaderHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
consensus_hash: ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
@@ -1418,7 +1204,7 @@ mod tests {
|
||||
total_burn: i,
|
||||
canonical: true
|
||||
};
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_snapshot_row(&mut tx, &snapshot_row).unwrap();
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_block_snapshot(&mut tx, &snapshot_row).unwrap();
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
@@ -1449,7 +1235,7 @@ mod tests {
|
||||
{
|
||||
let mut tx = db.tx_begin().unwrap();
|
||||
for i in 0..256 {
|
||||
let snapshot_row = SnapshotRow {
|
||||
let snapshot_row = BlockSnapshot {
|
||||
block_height: i,
|
||||
burn_header_hash: BurnchainHeaderHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
consensus_hash: ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
@@ -1457,7 +1243,7 @@ mod tests {
|
||||
total_burn: i,
|
||||
canonical: true
|
||||
};
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_snapshot_row(&mut tx, &snapshot_row).unwrap();
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_block_snapshot(&mut tx, &snapshot_row).unwrap();
|
||||
|
||||
// should succeed within the tx
|
||||
let ch_opt = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_consensus_at(&tx, i).unwrap();
|
||||
@@ -1478,165 +1264,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_prev_consensus_hashes() {
|
||||
let first_burn_hash = BurnchainHeaderHash::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||
let mut db : BurnDB<BitcoinAddress, BitcoinPublicKey> = BurnDB::connect_memory(123, &first_burn_hash).unwrap();
|
||||
{
|
||||
let mut tx = db.tx_begin().unwrap();
|
||||
for i in 0..256 {
|
||||
let snapshot_row = SnapshotRow {
|
||||
block_height: i,
|
||||
burn_header_hash: BurnchainHeaderHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
consensus_hash: ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
ops_hash: OpsHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i as u8]).unwrap(),
|
||||
total_burn: i,
|
||||
canonical: true
|
||||
};
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_snapshot_row(&mut tx, &snapshot_row).unwrap();
|
||||
}
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
let prev_chs_0 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 0, 0).unwrap();
|
||||
assert_eq!(prev_chs_0, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
|
||||
let prev_chs_1 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 1, 0).unwrap();
|
||||
assert_eq!(prev_chs_1, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
|
||||
let prev_chs_2 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 2, 0).unwrap();
|
||||
assert_eq!(prev_chs_2, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]).unwrap()]);
|
||||
|
||||
let prev_chs_3 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 3, 0).unwrap();
|
||||
assert_eq!(prev_chs_3, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
|
||||
let prev_chs_4 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 4, 0).unwrap();
|
||||
assert_eq!(prev_chs_4, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]).unwrap()]);
|
||||
|
||||
let prev_chs_5 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 5, 0).unwrap();
|
||||
assert_eq!(prev_chs_5, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2]).unwrap()]);
|
||||
|
||||
let prev_chs_6 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 6, 0).unwrap();
|
||||
assert_eq!(prev_chs_6, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3]).unwrap()]);
|
||||
|
||||
let prev_chs_7 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 7, 0).unwrap();
|
||||
assert_eq!(prev_chs_7, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
|
||||
let prev_chs_8 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 8, 0).unwrap();
|
||||
assert_eq!(prev_chs_8, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]).unwrap()]);
|
||||
|
||||
let prev_chs_62 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 62, 0).unwrap();
|
||||
assert_eq!(prev_chs_62, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,61]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,47]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31]).unwrap()]);
|
||||
|
||||
let prev_chs_63 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 63, 0).unwrap();
|
||||
assert_eq!(prev_chs_63, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
|
||||
let prev_chs_64 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 64, 0).unwrap();
|
||||
assert_eq!(prev_chs_64, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,61]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,57]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]).unwrap()]);
|
||||
|
||||
let prev_chs_126 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 126, 0).unwrap();
|
||||
assert_eq!(prev_chs_126, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,123]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,119]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,111]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63]).unwrap()]);
|
||||
|
||||
let prev_chs_127 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 127, 0).unwrap();
|
||||
assert_eq!(prev_chs_127, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
|
||||
let prev_chs_128 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 128, 0).unwrap();
|
||||
assert_eq!(prev_chs_128, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,121]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]).unwrap()]);
|
||||
|
||||
let prev_chs_254 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 254, 0).unwrap();
|
||||
assert_eq!(prev_chs_254, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,253]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,251]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,247]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,239]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,191]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127]).unwrap()]);
|
||||
|
||||
let prev_chs_255 = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_prev_consensus_hashes(db.conn(), 255, 0).unwrap();
|
||||
assert_eq!(prev_chs_255, vec![
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128]).unwrap(),
|
||||
ConsensusHash::from_bytes(&[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]).unwrap()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn find_block_burn_amount() {
|
||||
fn get_block_burn_amount() {
|
||||
let first_burn_hash = BurnchainHeaderHash::from_hex("0000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||
let block_height = 500;
|
||||
|
||||
@@ -1707,7 +1335,7 @@ mod tests {
|
||||
memo: vec![0x01, 0x02, 0x03, 0x04, 0x05],
|
||||
burn_fee: 2,
|
||||
|
||||
op: UserBurnSupportOp_OPCODE,
|
||||
op: UserBurnSupportOpcode,
|
||||
txid: Txid::from_bytes_be(&hex_bytes("1d5cbdd276495b07f0e0bf0181fa57c175b217bc35531b078d62fc20986c716c").unwrap()).unwrap(),
|
||||
vtxindex: 1,
|
||||
block_number: block_height,
|
||||
@@ -1724,7 +1352,7 @@ mod tests {
|
||||
memo: vec![0x01, 0x02, 0x03, 0x04, 0x05],
|
||||
burn_fee: 20,
|
||||
|
||||
op: UserBurnSupportOp_OPCODE,
|
||||
op: UserBurnSupportOpcode,
|
||||
txid: Txid::from_bytes_be(&hex_bytes("1d5cbdd276495b07f0e0bf0181fa57c175b217bc35531b078d62fc20986c716c").unwrap()).unwrap(),
|
||||
vtxindex: 1,
|
||||
block_number: block_height,
|
||||
@@ -1737,29 +1365,29 @@ mod tests {
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_block_commit(&mut tx, &block_commit_noncanonical).unwrap();
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_user_burn(&mut tx, &user_burn_noncanonical).unwrap();
|
||||
|
||||
let burn_amount_noncanonical = BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height).unwrap();
|
||||
let burn_amount_noncanonical = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height).unwrap();
|
||||
assert_eq!(burn_amount_noncanonical, 30);
|
||||
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height - 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height + 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height - 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height + 1).unwrap(), 0);
|
||||
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::burnchain_history_reorg(&mut tx, block_height).unwrap();
|
||||
|
||||
let burn_amount_postreorg = BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height).unwrap();
|
||||
let burn_amount_postreorg = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height).unwrap();
|
||||
assert_eq!(burn_amount_postreorg, 0);
|
||||
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height - 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height + 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height - 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height + 1).unwrap(), 0);
|
||||
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_block_commit(&mut tx, &block_commit).unwrap();
|
||||
BurnDB::<BitcoinAddress, BitcoinPublicKey>::insert_user_burn(&mut tx, &user_burn).unwrap();
|
||||
|
||||
// only the canonical ops should show up
|
||||
let burn_amount = BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height).unwrap();
|
||||
let burn_amount = BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height).unwrap();
|
||||
assert_eq!(burn_amount, 3);
|
||||
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height - 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::find_block_burn_amount(&mut tx, block_height + 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height - 1).unwrap(), 0);
|
||||
assert_eq!(BurnDB::<BitcoinAddress, BitcoinPublicKey>::get_block_burn_amount(&mut tx, block_height + 1).unwrap(), 0);
|
||||
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user