diff --git a/.vscode/launch.json b/.vscode/launch.json index 5afc269b6..cce81568d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,16 +12,17 @@ "args": [ "test", "--no-run", - "--lib", - "--package=blockstack-core", + "--workspace" ], "filter": { - "name": "blockstack_lib", - "kind": "lib", - + "name": "stacks-node", + "kind": "bin" } }, - "args": ["mine_anchored_empty_blocks_single"], + "env": { + "BITCOIND_TEST": "1", + }, + "args": ["--test-threads", "1", "--ignored", "bitcoind_integration_test"], "cwd": "${workspaceFolder}" }, { diff --git a/src/burnchains/burnchain.rs b/src/burnchains/burnchain.rs index c52a15102..bc9e997bf 100644 --- a/src/burnchains/burnchain.rs +++ b/src/burnchains/burnchain.rs @@ -422,7 +422,7 @@ impl Burnchain { let sortitiondb = SortitionDB::connect(&db_path, first_block_height, &first_block_header_hash, first_block_header_timestamp, readwrite)?; - let burnchaindb = BurnchainDb::connect(&burnchain_db_path, readwrite)?; + let burnchaindb = BurnchainDb::connect(&burnchain_db_path, first_block_height, &first_block_header_hash, first_block_header_timestamp, readwrite)?; Ok((sortitiondb, burnchaindb)) } @@ -658,7 +658,7 @@ impl Burnchain { let (mut burndb, mut burnchain_db) = self.connect_db(indexer, true)?; let burn_chain_tip = burnchain_db.get_canonical_burn_chain_tip() .map_err(|e| { - error!("Failed to query burn chain tip from burn DB"); + error!("Failed to query burn chain tip from burn DB: {}", e); e })?; diff --git a/src/burnchains/db.rs b/src/burnchains/db.rs index 0e0a3daf6..a6ec51913 100644 --- a/src/burnchains/db.rs +++ b/src/burnchains/db.rs @@ -1,7 +1,10 @@ +use std::{ + fs, io +}; use serde_json; use rusqlite::{ Connection, Transaction, types::ToSql, NO_PARAMS, - OptionalExtension, Row + OptionalExtension, Row, OpenFlags }; use burnchains::{ @@ -16,6 +19,10 @@ use chainstate::burn::operations::{ BlockstackOperationType }; +use chainstate::stacks::index::{ + MarfTrieId +}; + use util::db::{ u64_to_sql, query_row, FromRow, FromColumn, Error as DBError }; @@ -67,6 +74,25 @@ impl FromRow for BurnchainBlockHeader { } } +const BURNCHAIN_DB_SCHEMA: &'static str = " +CREATE TABLE burnchain_db_block_headers ( + block_height INTEGER NOT NULL, + block_hash TEXT UNIQUE NOT NULL, + parent_block_hash TEXT NOT NULL, + num_txs INTEGER NOT NULL, + timestamp INTEGER NOT NULL, + + PRIMARY KEY(block_hash) +); + +CREATE TABLE burnchain_db_block_ops ( + block_hash TEXT NOT NULL, + op TEXT NOT NULL, + + FOREIGN KEY(block_hash) REFERENCES burnchain_db_block_headers(block_hash) +); +"; + impl <'a> BurnchainDbTransaction <'a> { fn store_burnchain_db_entry(&self, header: &BurnchainBlockHeader) -> Result { let sql = "INSERT INTO burnchain_db_block_headers @@ -83,14 +109,14 @@ impl <'a> BurnchainDbTransaction <'a> { } } - fn store_blockstack_ops(&self, header_identifier: i64, block_ops: &[BlockstackOperationType]) -> Result<(), BurnchainError> { - let sql = "INSERT INTO burnchain_db_bock_ops - (burnchain_db_block_id, op) VALUES (?, ?)"; + fn store_blockstack_ops(&self, block_hash: &BurnchainHeaderHash, block_ops: &[BlockstackOperationType]) -> Result<(), BurnchainError> { + let sql = "INSERT INTO burnchain_db_block_ops + (block_hash, op) VALUES (?, ?)"; let mut stmt = self.sql_tx.prepare(sql)?; for op in block_ops.iter() { let serialized_op = serde_json::to_string(op) .expect("Failed to serialize parsed BlockstackOp"); - let args: &[&dyn ToSql] = &[&header_identifier, + let args: &[&dyn ToSql] = &[block_hash, &serialized_op]; stmt.execute(args)?; } @@ -104,12 +130,68 @@ impl <'a> BurnchainDbTransaction <'a> { } impl BurnchainDb { - pub fn connect(path: &str, readwrite: bool) -> Result { - panic!("Not implemented: {} {}", path, readwrite); + pub fn connect(path: &str, first_block_height: u64, first_burn_header_hash: &BurnchainHeaderHash, + first_burn_header_timestamp: u64, readwrite: bool) -> Result { + let mut create_flag = false; + let open_flags = match fs::metadata(path) { + Err(e) => { + if e.kind() == io::ErrorKind::NotFound { + // need to create + if readwrite { + create_flag = true; + OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE + } else { + return Err(BurnchainError::from(DBError::NoDBError)); + } + } else { + return Err(BurnchainError::from(DBError::IOError(e))); + } + }, + Ok(_md) => { + // can just open + if readwrite { + OpenFlags::SQLITE_OPEN_READ_WRITE + } + else { + OpenFlags::SQLITE_OPEN_READ_ONLY + } + } + }; + + let mut db = BurnchainDb { + conn: Connection::open_with_flags(path, open_flags) + .expect(&format!("FAILED to open: {}", path)) + }; + + if create_flag { + let db_tx = db.start_transaction()?; + db_tx.sql_tx.execute_batch(BURNCHAIN_DB_SCHEMA)?; + + let first_block_header = BurnchainBlockHeader { + block_height: first_block_height, + block_hash: first_burn_header_hash.clone(), + timestamp: first_burn_header_timestamp, + num_txs: 0, + parent_block_hash: BurnchainHeaderHash::sentinel() + }; + + + let header_identifier = db_tx.store_burnchain_db_entry(&first_block_header)?; + db_tx.commit()?; + } + + Ok(db) } pub fn open(path: &str, readwrite: bool) -> Result { - panic!("Not implemented: {} {}", path, readwrite); + let open_flags = if readwrite { + OpenFlags::SQLITE_OPEN_READ_WRITE + } else { + OpenFlags::SQLITE_OPEN_READ_ONLY + }; + let conn = Connection::open_with_flags(path, open_flags)?; + + Ok(BurnchainDb { conn }) } fn start_transaction<'a>(&'a mut self) -> Result, BurnchainError> { @@ -137,7 +219,7 @@ impl BurnchainDb { let db_tx = self.start_transaction()?; let header_identifier = db_tx.store_burnchain_db_entry(&header)?; - db_tx.store_blockstack_ops(header_identifier, &blockstack_ops)?; + db_tx.store_blockstack_ops(&header.block_hash, &blockstack_ops)?; db_tx.commit()?; diff --git a/src/chainstate/burn/db/burndb.rs b/src/chainstate/burn/db/burndb.rs index 7bc93962b..50466a780 100644 --- a/src/chainstate/burn/db/burndb.rs +++ b/src/chainstate/burn/db/burndb.rs @@ -376,7 +376,7 @@ const BURNDB_SETUP : &'static [&'static str]= &[ address TEXT NOT NULL, PRIMARY KEY(txid,sortition_id), - FOREIGN KEY(burn_header_hash) REFERENCES snapshots(burn_header_hash) + FOREIGN KEY(sortition_id) REFERENCES snapshots(sortition_id) );"#, r#" CREATE TABLE block_commits( @@ -398,7 +398,7 @@ const BURNDB_SETUP : &'static [&'static str]= &[ input TEXT NOT NULL, -- must match `address` in leader_keys PRIMARY KEY(txid,sortition_id), - FOREIGN KEY(burn_header_hash) REFERENCES snapshots(burn_header_hash) + FOREIGN KEY(sortition_id) REFERENCES snapshots(sortition_id) );"#, r#" CREATE TABLE user_burn_support( @@ -418,7 +418,7 @@ const BURNDB_SETUP : &'static [&'static str]= &[ burn_fee TEXT NOT NULL, PRIMARY KEY(txid,sortition_id), - FOREIGN KEY(burn_header_hash) REFERENCES snapshots(burn_header_hash) + FOREIGN KEY(sortition_id) REFERENCES snapshots(sortition_id) );"#, r#" CREATE TABLE canonical_accepted_stacks_blocks( @@ -572,11 +572,10 @@ impl <'a> SortitionHandleTx <'a> { } let tx = tx_begin_immediate(&mut conn.conn)?; - let mut handle = SortitionHandleTx::new( + let handle = SortitionHandleTx::new( tx, &mut conn.marf, SortitionHandleContext { chain_tip: parent_chain_tip.clone(), first_block_height: conn.first_block_height }); -// handle.put_indexed_begin(parent_chain_tip, chain_tip)?; Ok(handle) } @@ -1387,7 +1386,7 @@ impl SortitionDB { /// Get all user burns registered in a block on is fork. /// Returns list of user burns in order by vtxindex. - pub fn get_user_burns_by_block<'a>(conn: &Connection, sortition: &SortitionId) -> Result, db_error> { + pub fn get_user_burns_by_block(conn: &Connection, sortition: &SortitionId) -> Result, db_error> { let qry = "SELECT * FROM user_burn_support WHERE sortition_id = ?1 ORDER BY vtxindex ASC"; let args: &[&dyn ToSql] = &[sortition]; @@ -1403,6 +1402,25 @@ impl SortitionDB { query_rows(conn, qry, args) } + /// Get all leader keys registered in a block on the burn chain's history in this fork. + /// Returns the list of leader keys in order by vtxindex. + pub fn get_leader_keys_by_block(conn: &Connection, sortition: &SortitionId) -> Result, db_error> { + let qry = "SELECT * FROM leader_keys WHERE sortition_id = ?1 ORDER BY vtxindex ASC"; + let args: &[&dyn ToSql] = &[sortition]; + + query_rows(conn, qry, args) + } + + pub fn get_block_winning_vtxindex(conn: &Connection, sortition: &SortitionId) -> Result, db_error> { + let qry = "SELECT vtxindex FROM block_commits WHERE sortition_id = ?1 + AND txid = ( + SELECT winning_block_txid FROM snapshots WHERE sortition_id = ?2 LIMIT 1) LIMIT 1"; + let args: &[&dyn ToSql] = &[sortition, sortition]; + conn.query_row(qry, args, |row| row.get(0)).optional() + .map_err(db_error::from) + } + + /// Given the fork index hash of a chain tip, and a block height that is an ancestor of the last /// block in this fork, find the snapshot of the block at that height. pub fn get_ancestor_snapshot(ic: &IndexDBConn<'_, C, SortitionId>, ancestor_block_height: u64, tip_block_hash: &SortitionId) -> Result, db_error> { diff --git a/src/util/db.rs b/src/util/db.rs index 8530626ee..b751560fc 100644 --- a/src/util/db.rs +++ b/src/util/db.rs @@ -255,7 +255,7 @@ where if let Some(value) = result.next() { return_value = Some(value?); } - assert!(result.next().is_some(), + assert!(result.next().is_none(), "FATAL: Multiple values returned for query that expected a single result:\n {}", sql_query); Ok(return_value) } @@ -264,7 +264,7 @@ pub fn query_row_panic(conn: &Connection, sql_query: &str, sql_args: P, where P: IntoIterator, P::Item: ToSql, - T: FromRow, + T: FromRow, F: FnOnce () -> String { let mut stmt = conn.prepare(sql_query)?; diff --git a/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs b/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs index b4a8be610..354fd9db3 100644 --- a/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs +++ b/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs @@ -24,7 +24,7 @@ use stacks::burnchains::bitcoin::address::{BitcoinAddress, BitcoinAddressType}; use stacks::burnchains::bitcoin::indexer::{BitcoinIndexer, BitcoinIndexerRuntime, BitcoinIndexerConfig}; use stacks::burnchains::bitcoin::spv::SpvClient; use stacks::burnchains::PublicKey; -use stacks::chainstate::burn::db::burndb::BurnDB; +use stacks::chainstate::burn::db::burndb::SortitionDB; use stacks::chainstate::burn::operations::{ LeaderBlockCommitOp, LeaderKeyRegisterOp, @@ -50,7 +50,7 @@ use stacks::monitoring::{ pub struct BitcoinRegtestController { config: Config, indexer_config: BitcoinIndexerConfig, - db: Option, + db: Option, chain_tip: Option, } @@ -531,11 +531,11 @@ impl BitcoinRegtestController { impl BurnchainController for BitcoinRegtestController { - fn burndb_ref(&self) -> &BurnDB { + fn burndb_ref(&self) -> &SortitionDB { self.db.as_ref().expect("BUG: did not instantiate the burn DB") } - fn burndb_mut(&mut self) -> &mut BurnDB { + fn burndb_mut(&mut self) -> &mut SortitionDB { let network = "regtest".to_string(); let working_dir = self.config.get_burn_db_path(); let burnchain = match Burnchain::new(&working_dir, &self.config.burnchain.chain, &network) { @@ -546,7 +546,7 @@ impl BurnchainController for BitcoinRegtestController { } }; - let db = burnchain.open_db(true).unwrap(); + let (db, _) = burnchain.open_db(true).unwrap(); self.db = Some(db); match self.db { diff --git a/testnet/stacks-node/src/burnchains/mocknet_controller.rs b/testnet/stacks-node/src/burnchains/mocknet_controller.rs index cbd048c28..ebc1ac582 100644 --- a/testnet/stacks-node/src/burnchains/mocknet_controller.rs +++ b/testnet/stacks-node/src/burnchains/mocknet_controller.rs @@ -7,7 +7,9 @@ use super::super::operations::BurnchainOpSigner; use stacks::burnchains::{Burnchain, BurnchainBlockHeader, BurnchainHeaderHash, BurnchainBlock, Txid, BurnchainStateTransition}; use stacks::burnchains::bitcoin::BitcoinBlock; -use stacks::chainstate::burn::db::burndb::{BurnDB}; +use stacks::chainstate::burn::db::burndb::{ + SortitionDB, SortitionId, SortitionHandleTx +}; use stacks::chainstate::burn::{BlockSnapshot}; use stacks::chainstate::burn::operations::{ LeaderBlockCommitOp, @@ -22,7 +24,7 @@ use stacks::util::get_epoch_time_secs; pub struct MocknetController { config: Config, burnchain: Burnchain, - db: Option, + db: Option, chain_tip: Option, queued_operations: VecDeque, } @@ -57,17 +59,17 @@ impl MocknetController { ¤t_block.burn_header_hash, &vec![], get_epoch_time_secs())); - block.header(¤t_block) + block.header() } } impl BurnchainController for MocknetController { - fn burndb_ref(&self) -> &BurnDB { + fn burndb_ref(&self) -> &SortitionDB { self.db.as_ref().expect("BUG: did not instantiate burn DB") } - fn burndb_mut(&mut self) -> &mut BurnDB { + fn burndb_mut(&mut self) -> &mut SortitionDB { match self.db { Some(ref mut burndb) => burndb, None => { @@ -88,11 +90,11 @@ impl BurnchainController for MocknetController { } fn start(&mut self) -> BurnchainTip { - let db = match BurnDB::connect(&self.config.get_burn_db_file_path(), 0, &BurnchainHeaderHash([0u8; 32]), get_epoch_time_secs(), true) { + let db = match SortitionDB::connect(&self.config.get_burn_db_file_path(), 0, &BurnchainHeaderHash([0u8; 32]), get_epoch_time_secs(), true) { Ok(db) => db, Err(_) => panic!("Error while connecting to burnchain db") }; - let block_snapshot = BurnDB::get_canonical_burn_chain_tip(db.conn()) + let block_snapshot = SortitionDB::get_canonical_burn_chain_tip_stubbed(db.conn()) .expect("FATAL: failed to get canonical chain tip"); self.db = Some(db); @@ -183,13 +185,11 @@ impl BurnchainController for MocknetController { unreachable!(); }, Some(ref mut burn_db) => { - let mut burn_tx = burn_db.tx_begin().unwrap(); - let new_chain_tip = Burnchain::process_block_ops( - &mut burn_tx, - &self.burnchain, - &chain_tip.block_snapshot, - &next_block_header, - &ops).unwrap(); + let mut burn_tx = SortitionHandleTx::begin( + burn_db, &chain_tip.block_snapshot.sortition_id, + &SortitionId([0;32])).unwrap(); + let new_chain_tip = burn_tx.process_block_ops( + &self.burnchain, &chain_tip.block_snapshot, &next_block_header, ops).unwrap(); burn_tx.commit().unwrap(); new_chain_tip } diff --git a/testnet/stacks-node/src/burnchains/mod.rs b/testnet/stacks-node/src/burnchains/mod.rs index 9896456a0..b36b0ddac 100644 --- a/testnet/stacks-node/src/burnchains/mod.rs +++ b/testnet/stacks-node/src/burnchains/mod.rs @@ -9,16 +9,16 @@ use super::operations::BurnchainOpSigner; use std::time::Instant; use stacks::burnchains::BurnchainStateTransition; -use stacks::chainstate::burn::db::burndb::{BurnDB}; -use stacks::chainstate::burn::{BlockSnapshot}; +use stacks::chainstate::burn::BlockSnapshot; +use stacks::chainstate::burn::db::burndb::SortitionDB; use stacks::chainstate::burn::operations::BlockstackOperationType; pub trait BurnchainController { fn start(&mut self) -> BurnchainTip; fn submit_operation(&mut self, operation: BlockstackOperationType, op_signer: &mut BurnchainOpSigner) -> bool; fn sync(&mut self) -> BurnchainTip; - fn burndb_ref(&self) -> &BurnDB; - fn burndb_mut(&mut self) -> &mut BurnDB; + fn burndb_ref(&self) -> &SortitionDB; + fn burndb_mut(&mut self) -> &mut SortitionDB; fn get_chain_tip(&mut self) -> BurnchainTip; #[cfg(test)] diff --git a/testnet/stacks-node/src/config.rs b/testnet/stacks-node/src/config.rs index 6e685c2b6..62e615f0b 100644 --- a/testnet/stacks-node/src/config.rs +++ b/testnet/stacks-node/src/config.rs @@ -429,7 +429,7 @@ impl Config { } pub fn get_burn_db_file_path(&self) -> String { - format!("{}/burnchain/db/{}/{}/burn.db/", self.node.working_dir, self.burnchain.chain, "regtest") + format!("{}/burnchain/db/{}/{}/sortition.db/", self.node.working_dir, self.burnchain.chain, "regtest") } diff --git a/testnet/stacks-node/src/neon_node.rs b/testnet/stacks-node/src/neon_node.rs index ce5e2fc54..a02a6e426 100644 --- a/testnet/stacks-node/src/neon_node.rs +++ b/testnet/stacks-node/src/neon_node.rs @@ -9,7 +9,7 @@ use std::collections::VecDeque; use std::default::Default; use stacks::burnchains::{Burnchain, BurnchainHeaderHash, Txid, PublicKey}; -use stacks::chainstate::burn::db::burndb::{BurnDB}; +use stacks::chainstate::burn::db::burndb::{SortitionDB, SortitionId}; use stacks::chainstate::stacks::db::{StacksChainState, StacksHeaderInfo, ClarityTx}; use stacks::chainstate::stacks::events::StacksTransactionReceipt; use stacks::chainstate::stacks::{ @@ -111,7 +111,7 @@ fn inner_process_tenure( anchored_block: &StacksBlock, burn_header_hash: &BurnchainHeaderHash, parent_burn_header_hash: &BurnchainHeaderHash, - burn_db: &mut BurnDB, + burn_db: &mut SortitionDB, chain_state: &mut StacksChainState, dispatcher: &mut EventDispatcher) -> Result<(), ChainstateError> { { @@ -238,7 +238,7 @@ fn spawn_peer(mut this: PeerNetwork, p2p_sock: &SocketAddr, rpc_sock: &SocketAdd this.bind(p2p_sock, rpc_sock).unwrap(); let (mut dns_resolver, mut dns_client) = DNSResolver::new(10); - let burndb = BurnDB::open(&burn_db_path, false) + let burndb = SortitionDB::open(&burn_db_path, false) .map_err(NetError::DBError)?; let mut chainstate = StacksChainState::open_with_block_limit( @@ -326,7 +326,7 @@ fn spawn_miner_relayer(mut relayer: Relayer, local_peer: LocalPeer, // the relayer _should not_ be modifying the burndb, // however, it needs a mut reference to create read TXs. // should address via #1449 - let mut burndb = BurnDB::open(&burn_db_path, true) + let mut burndb = SortitionDB::open(&burn_db_path, true) .map_err(NetError::DBError)?; let mut chainstate = StacksChainState::open_with_block_limit( @@ -499,7 +499,7 @@ fn spawn_miner_relayer(mut relayer: Relayer, local_peer: LocalPeer, fn dispatcher_announce_block(blocks_path: &str, event_dispatcher: &mut EventDispatcher, metadata: StacksHeaderInfo, parent_burn_header_hash: Option<&BurnchainHeaderHash>, - burndb: &mut BurnDB, + burndb: &mut SortitionDB, receipts: Vec) { let block: StacksBlock = { let block_path = StacksChainState::get_block_path( @@ -535,8 +535,8 @@ impl InitializedNeonNode { miner: bool, blocks_processed: BlocksProcessedCounter) -> InitializedNeonNode { // we can call _open_ here rather than _connect_, since connect is first called in // make_genesis_block - let burndb = BurnDB::open(&config.get_burn_db_file_path(), false) - .expect("Error while instantiating burnchain db"); + let burndb = SortitionDB::open(&config.get_burn_db_file_path(), false) + .expect("Error while instantiating sortition db"); let burnchain = Burnchain::new( &config.get_burn_db_path(), @@ -545,7 +545,9 @@ impl InitializedNeonNode { let view = { let ic = burndb.index_conn(); - BurnDB::get_burnchain_view(&ic, &burnchain).unwrap() + let sortition_tip = SortitionDB::get_canonical_burn_chain_tip_stubbed(&ic) + .expect("Failed to get sortition tip"); + ic.get_burnchain_view(&burnchain, &sortition_tip).unwrap() }; // create a new peerdb @@ -715,7 +717,7 @@ impl InitializedNeonNode { // the burn header hash of the burnchain tip fn relayer_run_tenure(registered_key: RegisteredKey, chain_state: &mut StacksChainState, - burn_db: &BurnDB, + burn_db: &SortitionDB, burn_block: BlockSnapshot, keychain: &mut Keychain, mem_pool: &mut MemPoolDB, @@ -750,23 +752,24 @@ impl InitializedNeonNode { // the stacks block I'm mining off of's burn header hash and vtx index: let parent_burn_hash = stacks_tip.burn_header_hash.clone(); + let parent_sortition_id = SortitionId::stubbed(&parent_burn_hash); let parent_winning_vtxindex = - match BurnDB::get_block_winning_vtxindex(burn_db.conn(), &parent_burn_hash) - .expect("BurnDB failure.") { + match SortitionDB::get_block_winning_vtxindex(burn_db.conn(), &parent_sortition_id) + .expect("SortitionDB failure.") { Some(x) => x, None => { - warn!("Failed to find winning vtx index for the parent burn block {}", - &parent_burn_hash); + warn!("Failed to find winning vtx index for the parent sortition {}", + &parent_sortition_id); return None } }; - let parent_block = match BurnDB::get_block_snapshot(burn_db.conn(), &parent_burn_hash) - .expect("BurnDB failure.") { + let parent_block = match SortitionDB::get_block_snapshot(burn_db.conn(), &parent_sortition_id) + .expect("SortitionDB failure.") { Some(x) => x, None => { - warn!("Failed to find block snapshot for the parent burn block {}", - &parent_burn_hash); + warn!("Failed to find block snapshot for the parent sortition {}", + &parent_sortition_id); return None } }; @@ -832,21 +835,21 @@ impl InitializedNeonNode { }) } - /// Process an state coming from the burnchain, by extracting the validated KeyRegisterOp + /// Process a state coming from the burnchain, by extracting the validated KeyRegisterOp /// and inspecting if a sortition was won. - pub fn process_burnchain_state(&mut self, burndb: &BurnDB, burn_hash: &BurnchainHeaderHash) -> (Option, bool) { + pub fn process_burnchain_state(&mut self, burndb: &SortitionDB, sort_id: &SortitionId) -> (Option, bool) { let mut last_sortitioned_block = None; let mut won_sortition = false; let ic = burndb.index_conn(); - let block_snapshot = BurnDB::get_block_snapshot(&ic, burn_hash) + let block_snapshot = SortitionDB::get_block_snapshot(&ic, sort_id) .expect("Failed to obtain block snapshot for processed burn block.") .expect("Failed to obtain block snapshot for processed burn block."); let block_height = block_snapshot.block_height; - let block_commits = BurnDB::get_block_commits_by_block(&ic, block_height, burn_hash) - .expect("Unexpected BurnDB error fetching block commits"); + let block_commits = SortitionDB::get_block_commits_by_block(&ic, &block_snapshot.sortition_id) + .expect("Unexpected SortitionDB error fetching block commits"); for op in block_commits.into_iter() { if op.txid == block_snapshot.winning_block_txid { info!("Received burnchain block #{} including block_commit_op (winning) - {}", block_height, op.input.to_testnet_address()); @@ -865,8 +868,8 @@ impl InitializedNeonNode { - let key_registers = BurnDB::get_leader_keys_by_block(&ic, block_height, burn_hash) - .expect("Unexpected BurnDB error fetching key registers"); + let key_registers = SortitionDB::get_leader_keys_by_block(&ic, &block_snapshot.sortition_id) + .expect("Unexpected SortitionDB error fetching key registers"); for op in key_registers.into_iter() { if self.is_miner { info!("Received burnchain block #{} including key_register_op - {}", block_height, op.address); diff --git a/testnet/stacks-node/src/node.rs b/testnet/stacks-node/src/node.rs index bba4b88b0..60eb386a6 100644 --- a/testnet/stacks-node/src/node.rs +++ b/testnet/stacks-node/src/node.rs @@ -7,7 +7,7 @@ use std::net::SocketAddr; use std::default::Default; use stacks::burnchains::{Burnchain, BurnchainHeaderHash, Txid}; -use stacks::chainstate::burn::db::burndb::{BurnDB}; +use stacks::chainstate::burn::db::burndb::{SortitionDB}; use stacks::chainstate::stacks::db::{StacksChainState, StacksHeaderInfo, ClarityTx}; use stacks::chainstate::stacks::events::StacksTransactionReceipt; use stacks::chainstate::stacks::{ @@ -79,7 +79,7 @@ fn spawn_peer(mut this: PeerNetwork, p2p_sock: &SocketAddr, rpc_sock: &SocketAdd loop { - let burndb = match BurnDB::open(&burn_db_path, false) { + let burndb = match SortitionDB::open(&burn_db_path, false) { Ok(x) => x, Err(e) => { warn!("Error while connecting burnchain db in peer loop: {}", e); @@ -198,7 +198,7 @@ impl Node { node.spawn_peer_server(); loop { - let burndb = BurnDB::open(&burndb_path, false).expect("BUG: failed to open burn database"); + let burndb = SortitionDB::open(&burndb_path, false).expect("BUG: failed to open burn database"); if let Ok(Some(ref chain_tip)) = node.chain_state.get_stacks_chain_tip(&burndb) { if chain_tip.burn_header_hash == burnchain_tip.block_snapshot.burn_header_hash { info!("Syncing Stacks blocks - completed"); @@ -217,7 +217,7 @@ impl Node { pub fn spawn_peer_server(&mut self) { // we can call _open_ here rather than _connect_, since connect is first called in // make_genesis_block - let burndb = BurnDB::open(&self.config.get_burn_db_file_path(), true) + let burndb = SortitionDB::open(&self.config.get_burn_db_file_path(), true) .expect("Error while instantiating burnchain db"); let burnchain = Burnchain::new( @@ -225,9 +225,12 @@ impl Node { &self.config.burnchain.chain, "regtest").expect("Error while instantiating burnchain"); + let view = { let ic = burndb.index_conn(); - BurnDB::get_burnchain_view(&ic, &burnchain).unwrap() + let sortition_tip = SortitionDB::get_canonical_burn_chain_tip_stubbed(&ic) + .expect("Failed to get sortition tip"); + ic.get_burnchain_view(&burnchain, &sortition_tip).unwrap() }; // create a new peerdb @@ -473,7 +476,7 @@ impl Node { burn_header_hash: &BurnchainHeaderHash, parent_burn_header_hash: &BurnchainHeaderHash, microblocks: Vec, - db: &mut BurnDB) -> ChainTip { + db: &mut SortitionDB) -> ChainTip { { // let mut db = burn_db.lock().unwrap(); diff --git a/testnet/stacks-node/src/run_loop/neon.rs b/testnet/stacks-node/src/run_loop/neon.rs index fdeb94549..7b95b40c3 100644 --- a/testnet/stacks-node/src/run_loop/neon.rs +++ b/testnet/stacks-node/src/run_loop/neon.rs @@ -3,7 +3,7 @@ use std::thread; use crate::{Config, NeonGenesisNode, BurnchainController, BitcoinRegtestController, Keychain}; -use stacks::chainstate::burn::db::burndb::BurnDB; +use stacks::chainstate::burn::db::burndb::SortitionDB; use stacks::burnchains::bitcoin::address::BitcoinAddress; use stacks::burnchains::Address; use stacks::burnchains::bitcoin::{BitcoinNetworkType, @@ -128,6 +128,7 @@ impl RunLoop { loop { burnchain_tip = burnchain.sync(); + let sortition_tip = &burnchain_tip.block_snapshot.sortition_id; let next_height = burnchain_tip.block_snapshot.block_height; if next_height <= block_height { warn!("burnchain.sync() did not progress block height"); @@ -138,16 +139,15 @@ impl RunLoop { for block_to_process in (block_height+1)..(next_height+1) { let block = { let ic = burnchain.burndb_ref().index_conn(); - BurnDB::get_ancestor_snapshot( - &ic, block_to_process, &burnchain_tip.block_snapshot.burn_header_hash) + SortitionDB::get_ancestor_snapshot(&ic, block_to_process, sortition_tip) .unwrap() .expect("Failed to find block in fork processed by bitcoin indexer") }; - let burn_header_hash = block.burn_header_hash; + let sortition_id = &block.sortition_id; // Have the node process the new block, that can include, or not, a sortition. node.process_burnchain_state(burnchain.burndb_mut(), - &burn_header_hash); + sortition_id); // Now, tell the relayer to check if it won a sortition during this block, // and, if so, to process and advertize the block //