Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove access to chainstate database without a transaction #1335

Merged
merged 9 commits into from
Nov 3, 2023
8 changes: 7 additions & 1 deletion chainstate/launcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mod storage_compatibility;
use std::sync::Arc;

use chainstate::InitializationError;
use chainstate_storage::Transactional;
use storage_lmdb::resize_callback::MapResizeCallback;

// Some useful reexports
Expand All @@ -42,8 +43,13 @@ fn make_chainstate_and_storage_impl<B: 'static + storage::Backend>(
let storage = chainstate_storage::Store::new(storage_backend, &chain_config)
.map_err(|e| Error::FailedToInitializeChainstate(e.into()))?;

storage_compatibility::check_storage_compatibility(&storage, chain_config.as_ref())
let db_tx = storage
.transaction_ro()
.map_err(|e| Error::FailedToInitializeChainstate(e.into()))?;

storage_compatibility::check_storage_compatibility(&db_tx, chain_config.as_ref())
.map_err(InitializationError::StorageCompatibilityCheckError)?;
drop(db_tx);

let chainstate = chainstate::make_chainstate(
chain_config,
Expand Down
13 changes: 9 additions & 4 deletions chainstate/src/detail/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,15 @@ impl<S: BlockchainStorage, V: TransactionVerificationStrategy> Chainstate<S, V>
) -> Result<Self, crate::ChainstateError> {
use crate::ChainstateError;

let best_block_id = chainstate_storage
.get_best_block_id()
.map_err(|e| ChainstateError::FailedToInitializeChainstate(e.into()))
.log_err()?;
let best_block_id = {
let db_tx = chainstate_storage
.transaction_ro()
.map_err(|e| ChainstateError::FailedToInitializeChainstate(e.into()))?;
db_tx
.get_best_block_id()
.map_err(|e| ChainstateError::FailedToInitializeChainstate(e.into()))
.log_err()?
};

let mut chainstate = Self::new_no_genesis(
chain_config,
Expand Down
140 changes: 74 additions & 66 deletions chainstate/storage/src/internal/expensive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,56 @@
use super::*;

use crate::schema::{self as db};
use common::chain::UtxoOutPoint;
use storage::MakeMapRef;
use utxo::Utxo;

impl<B: storage::Backend> Store<B> {
impl<B: storage::Backend> StoreTxRo<'_, B> {
/// Dump raw database contents
pub fn dump_raw(&self) -> crate::Result<storage::raw::StorageContents<Schema>> {
self.0.dump_raw().map_err(crate::Error::from)
}

/// Collect and return all utxos from the storage
pub fn read_utxo_set(&self) -> crate::Result<BTreeMap<UtxoOutPoint, Utxo>> {
let db = self.transaction_ro()?;
db.0.get::<db::DBUtxo, _>()
self.0
.get::<db::DBUtxo, _>()
.prefix_iter_decoded(&())
.map(Iterator::collect)
.map_err(crate::Error::from)
}

/// Collect and return all tip accounting data from storage
pub fn read_pos_accounting_data_tip(&self) -> crate::Result<pos_accounting::PoSAccountingData> {
let db = self.transaction_ro()?;

let pool_data =
db.0.get::<db::DBAccountingPoolDataTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_balances =
db.0.get::<db::DBAccountingPoolBalancesTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_data =
db.0.get::<db::DBAccountingDelegationDataTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_balances =
db.0.get::<db::DBAccountingDelegationBalancesTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_delegation_shares =
db.0.get::<db::DBAccountingPoolDelegationSharesTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();
let pool_data = self
.0
.get::<db::DBAccountingPoolDataTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_balances = self
.0
.get::<db::DBAccountingPoolBalancesTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_data = self
.0
.get::<db::DBAccountingDelegationDataTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_balances = self
.0
.get::<db::DBAccountingDelegationBalancesTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_delegation_shares = self
.0
.get::<db::DBAccountingPoolDelegationSharesTip, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

Ok(pos_accounting::PoSAccountingData {
pool_data,
Expand All @@ -75,32 +80,35 @@ impl<B: storage::Backend> Store<B> {
pub fn read_pos_accounting_data_sealed(
&self,
) -> crate::Result<pos_accounting::PoSAccountingData> {
let db = self.transaction_ro()?;

let pool_data =
db.0.get::<db::DBAccountingPoolDataSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_balances =
db.0.get::<db::DBAccountingPoolBalancesSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_data =
db.0.get::<db::DBAccountingDelegationDataSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_balances =
db.0.get::<db::DBAccountingDelegationBalancesSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_delegation_shares =
db.0.get::<db::DBAccountingPoolDelegationSharesSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();
let pool_data = self
.0
.get::<db::DBAccountingPoolDataSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_balances = self
.0
.get::<db::DBAccountingPoolBalancesSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_data = self
.0
.get::<db::DBAccountingDelegationDataSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let delegation_balances = self
.0
.get::<db::DBAccountingDelegationBalancesSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let pool_delegation_shares = self
.0
.get::<db::DBAccountingPoolDelegationSharesSealed, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

Ok(pos_accounting::PoSAccountingData {
pool_data,
Expand All @@ -114,17 +122,17 @@ impl<B: storage::Backend> Store<B> {
pub fn read_tokens_accounting_data(
&self,
) -> crate::Result<tokens_accounting::TokensAccountingData> {
let db = self.transaction_ro()?;

let token_data =
db.0.get::<db::DBTokensData, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let circulating_supply =
db.0.get::<db::DBTokensCirculatingSupply, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();
let token_data = self
.0
.get::<db::DBTokensData, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

let circulating_supply = self
.0
.get::<db::DBTokensCirculatingSupply, _>()
.prefix_iter_decoded(&())?
.collect::<BTreeMap<_, _>>();

Ok(tokens_accounting::TokensAccountingData {
token_data,
Expand Down
Loading