-
Notifications
You must be signed in to change notification settings - Fork 39
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
feat: abci state sync #2413
base: v1.8-dev
Are you sure you want to change the base?
feat: abci state sync #2413
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,100 @@ | ||
use crate::abci::app::{BlockExecutionApplication, PlatformApplication, TransactionalApplication}; | ||
use crate::abci::app::{ | ||
BlockExecutionApplication, PlatformApplication, SnapshotFetchingApplication, | ||
SnapshotManagerApplication, TransactionalApplication, | ||
}; | ||
use crate::abci::handler; | ||
use crate::abci::handler::error::error_into_exception; | ||
use crate::error::execution::ExecutionError; | ||
use crate::error::Error; | ||
use crate::execution::types::block_execution_context::BlockExecutionContext; | ||
use crate::platform_types::platform::Platform; | ||
use crate::platform_types::snapshot::{SnapshotFetchingSession, SnapshotManager}; | ||
use crate::rpc::core::CoreRPCLike; | ||
use dpp::version::PlatformVersion; | ||
use drive::grovedb::Transaction; | ||
use std::fmt::Debug; | ||
use std::sync::RwLock; | ||
use tenderdash_abci::proto::abci as proto; | ||
use dapi_grpc::tonic; | ||
Check warning on line 18 in packages/rs-drive-abci/src/abci/app/consensus.rs GitHub Actions / Rust packages (drive-abci) / Lintingunused import: `dapi_grpc::tonic`
|
||
|
||
/// AbciApp is an implementation of ABCI Application, as defined by Tenderdash. | ||
/// | ||
/// AbciApp implements logic that should be triggered when Tenderdash performs various operations, like | ||
/// creating new proposal or finalizing new block. | ||
pub struct ConsensusAbciApplication<'a, C> { | ||
/// 'p: 'tx, means that Platform must outlive the transaction | ||
pub struct ConsensusAbciApplication<'p, C> { | ||
/// Platform | ||
platform: &'a Platform<C>, | ||
platform: &'p Platform<C>, | ||
/// The current GroveDb transaction | ||
transaction: RwLock<Option<Transaction<'a>>>, | ||
transaction: RwLock<Option<Transaction<'p>>>, | ||
/// The current block execution context | ||
block_execution_context: RwLock<Option<BlockExecutionContext>>, | ||
/// The State sync session | ||
snapshot_fetching_session: RwLock<Option<SnapshotFetchingSession<'p>>>, | ||
/// The snapshot manager | ||
snapshot_manager: SnapshotManager, | ||
} | ||
|
||
impl<'a, C> ConsensusAbciApplication<'a, C> { | ||
impl<'p, C> ConsensusAbciApplication<'p, C> { | ||
/// Create new ABCI app | ||
pub fn new(platform: &'a Platform<C>) -> Self { | ||
pub fn new(platform: &'p Platform<C>) -> Self { | ||
let snapshot_manager = SnapshotManager::new( | ||
platform | ||
.config | ||
.state_sync_config | ||
.checkpoints_path | ||
.to_str() | ||
.unwrap() | ||
Comment on lines
+46
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle potential Using Apply this diff to handle the potential -let snapshot_manager = SnapshotManager::new(
- platform
- .config
- .state_sync_config
- .checkpoints_path
- .to_str()
- .unwrap()
- .to_string(),
+let checkpoints_path_str = platform
+ .config
+ .state_sync_config
+ .checkpoints_path
+ .to_str()
+ .ok_or_else(|| {
+ Error::InitializationError("Invalid checkpoints path: non-UTF8 characters present".to_string())
+ })?
+ .to_string();
+
+let snapshot_manager = SnapshotManager::new(
+ checkpoints_path_str,
platform.config.state_sync_config.max_num_snapshots,
platform.config.state_sync_config.snapshots_frequency,
);
|
||
.to_string(), | ||
platform.config.state_sync_config.max_num_snapshots, | ||
platform.config.state_sync_config.snapshots_frequency, | ||
); | ||
Self { | ||
platform, | ||
transaction: Default::default(), | ||
block_execution_context: Default::default(), | ||
snapshot_fetching_session: Default::default(), | ||
snapshot_manager, | ||
} | ||
} | ||
} | ||
|
||
impl<'a, C> PlatformApplication<C> for ConsensusAbciApplication<'a, C> { | ||
impl<'p, C> PlatformApplication<C> for ConsensusAbciApplication<'p, C> { | ||
Check warning on line 62 in packages/rs-drive-abci/src/abci/app/consensus.rs GitHub Actions / Rust packages (drive-abci) / Lintingthe following explicit lifetimes could be elided: 'p
|
||
fn platform(&self) -> &Platform<C> { | ||
self.platform | ||
} | ||
} | ||
|
||
impl<'a, C> BlockExecutionApplication for ConsensusAbciApplication<'a, C> { | ||
impl<'p, C> SnapshotManagerApplication for ConsensusAbciApplication<'p, C> { | ||
Check warning on line 68 in packages/rs-drive-abci/src/abci/app/consensus.rs GitHub Actions / Rust packages (drive-abci) / Lintingthe following explicit lifetimes could be elided: 'p
|
||
fn snapshot_manager(&self) -> &SnapshotManager { | ||
&self.snapshot_manager | ||
} | ||
} | ||
|
||
impl<'p, C> SnapshotFetchingApplication<'p, C> for ConsensusAbciApplication<'p, C> { | ||
fn snapshot_fetching_session(&self) -> &RwLock<Option<SnapshotFetchingSession<'p>>> { | ||
&self.snapshot_fetching_session | ||
} | ||
|
||
fn platform(&self) -> &'p Platform<C> { | ||
self.platform | ||
} | ||
} | ||
|
||
impl<'p, C> BlockExecutionApplication for ConsensusAbciApplication<'p, C> { | ||
Check warning on line 84 in packages/rs-drive-abci/src/abci/app/consensus.rs GitHub Actions / Rust packages (drive-abci) / Lintingthe following explicit lifetimes could be elided: 'p
|
||
fn block_execution_context(&self) -> &RwLock<Option<BlockExecutionContext>> { | ||
&self.block_execution_context | ||
} | ||
} | ||
|
||
impl<'a, C> TransactionalApplication<'a> for ConsensusAbciApplication<'a, C> { | ||
impl<'p, C> TransactionalApplication<'p> for ConsensusAbciApplication<'p, C> { | ||
/// create and store a new transaction | ||
fn start_transaction(&self) { | ||
let transaction = self.platform.drive.grove.start_transaction(); | ||
self.transaction.write().unwrap().replace(transaction); | ||
} | ||
|
||
fn transaction(&self) -> &RwLock<Option<Transaction<'a>>> { | ||
fn transaction(&self) -> &RwLock<Option<Transaction<'p>>> { | ||
&self.transaction | ||
} | ||
|
||
|
@@ -77,13 +116,13 @@ | |
} | ||
} | ||
|
||
impl<'a, C> Debug for ConsensusAbciApplication<'a, C> { | ||
impl<'p, C> Debug for ConsensusAbciApplication<'p, C> { | ||
Check warning on line 119 in packages/rs-drive-abci/src/abci/app/consensus.rs GitHub Actions / Rust packages (drive-abci) / Lintingthe following explicit lifetimes could be elided: 'p
|
||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "<ConsensusAbciApplication>") | ||
} | ||
} | ||
|
||
impl<'a, C> tenderdash_abci::Application for ConsensusAbciApplication<'a, C> | ||
impl<'p, C> tenderdash_abci::Application for ConsensusAbciApplication<'p, C> | ||
Check warning on line 125 in packages/rs-drive-abci/src/abci/app/consensus.rs GitHub Actions / Rust packages (drive-abci) / Lintingthe following explicit lifetimes could be elided: 'p
|
||
where | ||
C: CoreRPCLike, | ||
{ | ||
|
@@ -149,4 +188,32 @@ | |
) -> Result<proto::ResponseVerifyVoteExtension, proto::ResponseException> { | ||
handler::verify_vote_extension(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn offer_snapshot( | ||
&self, | ||
request: proto::RequestOfferSnapshot, | ||
) -> Result<proto::ResponseOfferSnapshot, proto::ResponseException> { | ||
handler::offer_snapshot(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn apply_snapshot_chunk( | ||
&self, | ||
request: proto::RequestApplySnapshotChunk, | ||
) -> Result<proto::ResponseApplySnapshotChunk, proto::ResponseException> { | ||
handler::apply_snapshot_chunk(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn list_snapshots( | ||
&self, | ||
request: proto::RequestListSnapshots, | ||
) -> Result<proto::ResponseListSnapshots, proto::ResponseException> { | ||
handler::list_snapshots(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn load_snapshot_chunk( | ||
&self, | ||
request: proto::RequestLoadSnapshotChunk, | ||
) -> Result<proto::ResponseLoadSnapshotChunk, proto::ResponseException> { | ||
handler::load_snapshot_chunk(self, request).map_err(error_into_exception) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,14 @@ | ||
use crate::abci::app::{BlockExecutionApplication, PlatformApplication, TransactionalApplication}; | ||
use crate::abci::app::{ | ||
BlockExecutionApplication, PlatformApplication, SnapshotFetchingApplication, | ||
SnapshotManagerApplication, TransactionalApplication, | ||
}; | ||
use crate::abci::handler; | ||
use crate::abci::handler::error::error_into_exception; | ||
use crate::error::execution::ExecutionError; | ||
use crate::error::Error; | ||
use crate::execution::types::block_execution_context::BlockExecutionContext; | ||
use crate::platform_types::platform::Platform; | ||
use crate::platform_types::snapshot::{SnapshotFetchingSession, SnapshotManager}; | ||
use crate::rpc::core::CoreRPCLike; | ||
use dpp::version::PlatformVersion; | ||
use drive::grovedb::Transaction; | ||
|
@@ -23,15 +27,32 @@ pub struct FullAbciApplication<'a, C> { | |
pub transaction: RwLock<Option<Transaction<'a>>>, | ||
/// The current block execution context | ||
pub block_execution_context: RwLock<Option<BlockExecutionContext>>, | ||
/// The State sync session | ||
pub snapshot_fetching_session: RwLock<Option<SnapshotFetchingSession<'a>>>, | ||
/// The snapshot manager | ||
pub snapshot_manager: SnapshotManager, | ||
} | ||
|
||
impl<'a, C> FullAbciApplication<'a, C> { | ||
/// Create new ABCI app | ||
pub fn new(platform: &'a Platform<C>) -> Self { | ||
let snapshot_manager = SnapshotManager::new( | ||
platform | ||
.config | ||
.state_sync_config | ||
.checkpoints_path | ||
.to_str() | ||
.unwrap() | ||
.to_string(), | ||
platform.config.state_sync_config.max_num_snapshots, | ||
Comment on lines
+45
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle potential Similar to the previous comment, using Apply this diff to handle the potential -let snapshot_manager = SnapshotManager::new(
- platform
- .config
- .state_sync_config
- .checkpoints_path
- .to_str()
- .unwrap()
- .to_string(),
+let checkpoints_path_str = platform
+ .config
+ .state_sync_config
+ .checkpoints_path
+ .to_str()
+ .ok_or_else(|| {
+ Error::InitializationError("Invalid checkpoints path: non-UTF8 characters present".to_string())
+ })?
+ .to_string();
+
+let snapshot_manager = SnapshotManager::new(
+ checkpoints_path_str,
platform.config.state_sync_config.max_num_snapshots,
platform.config.state_sync_config.snapshots_frequency,
);
|
||
platform.config.state_sync_config.snapshots_frequency, | ||
); | ||
Self { | ||
platform, | ||
transaction: Default::default(), | ||
block_execution_context: Default::default(), | ||
snapshot_fetching_session: Default::default(), | ||
snapshot_manager, | ||
} | ||
} | ||
} | ||
|
@@ -42,6 +63,22 @@ impl<'a, C> PlatformApplication<C> for FullAbciApplication<'a, C> { | |
} | ||
} | ||
|
||
impl<'a, C> SnapshotManagerApplication for FullAbciApplication<'a, C> { | ||
fn snapshot_manager(&self) -> &SnapshotManager { | ||
&self.snapshot_manager | ||
} | ||
} | ||
|
||
impl<'a, C> SnapshotFetchingApplication<'a, C> for FullAbciApplication<'a, C> { | ||
fn snapshot_fetching_session(&self) -> &RwLock<Option<SnapshotFetchingSession<'a>>> { | ||
&self.snapshot_fetching_session | ||
} | ||
|
||
fn platform(&self) -> &'a Platform<C> { | ||
self.platform | ||
} | ||
} | ||
|
||
impl<'a, C> BlockExecutionApplication for FullAbciApplication<'a, C> { | ||
fn block_execution_context(&self) -> &RwLock<Option<BlockExecutionContext>> { | ||
&self.block_execution_context | ||
|
@@ -150,4 +187,32 @@ where | |
) -> Result<proto::ResponseVerifyVoteExtension, proto::ResponseException> { | ||
handler::verify_vote_extension(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn offer_snapshot( | ||
&self, | ||
request: proto::RequestOfferSnapshot, | ||
) -> Result<proto::ResponseOfferSnapshot, proto::ResponseException> { | ||
handler::offer_snapshot(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn apply_snapshot_chunk( | ||
&self, | ||
request: proto::RequestApplySnapshotChunk, | ||
) -> Result<proto::ResponseApplySnapshotChunk, proto::ResponseException> { | ||
handler::apply_snapshot_chunk(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn list_snapshots( | ||
&self, | ||
request: proto::RequestListSnapshots, | ||
) -> Result<proto::ResponseListSnapshots, proto::ResponseException> { | ||
handler::list_snapshots(self, request).map_err(error_into_exception) | ||
} | ||
|
||
fn load_snapshot_chunk( | ||
&self, | ||
request: proto::RequestLoadSnapshotChunk, | ||
) -> Result<proto::ResponseLoadSnapshotChunk, proto::ResponseException> { | ||
handler::load_snapshot_chunk(self, request).map_err(error_into_exception) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
The codebase has a proper default production path (
/var/lib/dash-platform/data
), but it's being overridden by environment files to use temporary storage:.env.mainnet
:DB_PATH=/tmp/db
.env.testnet
:DB_PATH=/tmp/db
This configuration will lead to data loss on system reboot. Update the environment files to use persistent storage paths instead of
/tmp/db
.🔗 Analysis chain
Verify database paths for production environments.
Both
CHECKPOINTS_PATH
andGROVEDB_LATEST_FILE
inherit fromDB_PATH
which is set to/tmp/db
. While this is fine for local development, using/tmp
in production could lead to data loss as it's typically cleared on system reboot.Run this script to check if there are any production environment files with similar configuration:
Also applies to: 19-19
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 702
Script:
Length of output: 2638