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

fix(drive): inconsistent platform state and version during ABCI calls #1733

Merged
merged 112 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from 105 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
3686dcf
feat: parallel query and check tx
shumkov Feb 9, 2024
4be5574
fix: storage error on drive drop
shumkov Feb 10, 2024
92f8b46
feat: full app for strategy tests
shumkov Feb 10, 2024
5245c13
reactor: abci server
shumkov Feb 10, 2024
a66e02e
fix: incorrect signals and errors handling
shumkov Feb 10, 2024
d786149
feat: update platform cache in query app
shumkov Feb 10, 2024
7004d13
chore: revert back wait for core
shumkov Feb 10, 2024
c38bc62
refactor: some renamings
shumkov Feb 11, 2024
8a19970
build: use 1.76 toolchain
shumkov Feb 11, 2024
82cdf06
chore: call finalize block for query app
shumkov Feb 12, 2024
9e6e6f9
chore(release): bump version 1.0.0-pr.1694.1
shumkov Feb 12, 2024
630fff5
chore: update tenderdash image
shumkov Feb 13, 2024
e75ea4e
Merge branch 'v1.0-dev' into feat/drive/read-only-thread
shumkov Feb 13, 2024
4fc9ba0
Merge v1-dev
shumkov Feb 13, 2024
162e282
chore: log catch up time
shumkov Feb 13, 2024
5a96288
chore(release): bump version to 1.0.0-pr.1694.2
shumkov Feb 13, 2024
c2bc6a1
refactor: shared platform and locks optimization
shumkov Feb 14, 2024
03d807d
chore: bump version to 1.0.0-pr.1694.3
shumkov Feb 14, 2024
332b8f9
fix: block cache is not cleaned up
shumkov Feb 15, 2024
dd4855d
chore: switch to correct bls and grovedb versions
shumkov Feb 15, 2024
b1eafd4
chore(release): bump version to 1.0.0-pr.1694.4
shumkov Feb 15, 2024
f4770c1
feat: relax state locks
shumkov Feb 16, 2024
01e8a38
chore(release): bump to version 1.0.0-pr.1694.5
shumkov Feb 16, 2024
785f75c
Merge branch 'v1.0-dev' into feat/drive/read-only-thread2
shumkov Feb 16, 2024
1769bcb
chore: handle check tx timeout error
shumkov Feb 16, 2024
d6db275
fix: typo
shumkov Feb 16, 2024
dfabe42
chore: handle check tx timeout properly
shumkov Feb 16, 2024
99ae2f8
fix: nilled state after restart
shumkov Feb 16, 2024
70a9ede
refactor: block info as ref
shumkov Feb 16, 2024
9a500cd
fix: invalid state to process STs
shumkov Feb 17, 2024
f92d915
perf: route platform queries directly to Drive
shumkov Feb 21, 2024
472a20b
perf: handle check tx in parallel
shumkov Feb 21, 2024
dd9b237
chore(release): bump version to 1.0.0-pr.1694.6
shumkov Feb 21, 2024
ef7d2af
fix(strategy-tests): drive dependency missing "fixtures-and-mocks" fe…
lklimek Feb 21, 2024
e67730a
chore: tell runtime that thread is blocked
shumkov Feb 21, 2024
c8133b7
Merge remote-tracking branch 'origin/feat/drive/read-only-thread' int…
shumkov Feb 21, 2024
221b6cb
docs: todos
shumkov Feb 21, 2024
7770011
chore: log threads
shumkov Feb 22, 2024
38e2785
feat: handle requests in separate threads
shumkov Feb 26, 2024
bc6beda
build: change tenderdash revision
lklimek Feb 26, 2024
30f9f21
fix: thread::scope commented out as it deadlocks
lklimek Feb 26, 2024
04f4964
refactor: versioned queries return corresponding version of response …
shumkov Feb 26, 2024
9c10d16
Merge remote-tracking branch 'origin/feat/drive/read-only-thread' int…
shumkov Feb 26, 2024
8e1bb97
fix: undeclared console_subscriber
shumkov Feb 26, 2024
65e4ce2
feat: init tokio console
shumkov Feb 27, 2024
016edc1
chore(release): bump version to 1.0.0-pr.1694.7
shumkov Feb 27, 2024
db9705c
docs: move todo
shumkov Feb 27, 2024
60f3447
feat: configure tokio console
shumkov Feb 27, 2024
f3bd89c
fix: missing package: @dashevo/wasm-dpp@workspace:packages/wasm-dpp
shumkov Feb 27, 2024
2f85dc1
refactor: better code structure
shumkov Feb 29, 2024
9d27ffa
Merge branch 'v1.0-dev' into feat/drive/read-only-thread
shumkov Mar 1, 2024
049c8a2
fix: multiple errors after merging v1
shumkov Mar 1, 2024
da1862d
revert: some changes in github actions
shumkov Mar 1, 2024
64d3287
fix(dapi): internal error on broadcast ST
shumkov Mar 1, 2024
e17dad6
chore: update tenderdash image
shumkov Mar 1, 2024
a432766
docs: remove todo
shumkov Mar 1, 2024
9c0bcdf
refactor: rename system data contract getters
shumkov Mar 4, 2024
2b4af0f
refactor: move module to abci app
shumkov Mar 4, 2024
32b6a55
refactor: remove unnecessary variable
shumkov Mar 4, 2024
a101f7c
refactor: rename block_info field
shumkov Mar 4, 2024
6567263
refactor: query_identity_v0 should return response v0
shumkov Mar 4, 2024
337a05d
revert: unnecessary changes and artifacts
shumkov Mar 4, 2024
4eacb97
fix: invalid module path
shumkov Mar 4, 2024
3aa81e0
fix: build errors
shumkov Mar 4, 2024
16c8fd1
fix: missing gRPC server
shumkov Mar 4, 2024
0d170e0
chore: spwan named thread only if flag is enabled
shumkov Mar 4, 2024
4f02957
chore: request tokio_unstable for console feature
shumkov Mar 4, 2024
b061a1c
refactor: rename variable
shumkov Mar 4, 2024
aa8ca6e
revert: platform state in PlatformRef
shumkov Mar 4, 2024
435472a
revert: adding latest block info to PlatformRef
shumkov Mar 4, 2024
ae0d2c2
revert: adding version to PlatformRef
shumkov Mar 4, 2024
ee5dc8b
Merge branch 'v1.0-dev' into feat/drive/read-only-thread
shumkov Mar 4, 2024
9eddca0
revert: removed state debug output (by mistake)
shumkov Mar 5, 2024
ae2f9fa
revert: using any block info instead of last committed
shumkov Mar 5, 2024
25b11be
revert: fix skipping validation logic if block time is absent
shumkov Mar 5, 2024
2f4c409
revert: populating test platform with genesis time
shumkov Mar 5, 2024
7ec3aa6
revert: unnecessary changes
shumkov Mar 5, 2024
da9548b
refactor: spawn tasks with name if supported
shumkov Mar 5, 2024
8b4e018
refactor: remove unused imports
shumkov Mar 5, 2024
eac7f7e
chore: remove extra feature in strategy tests
shumkov Mar 5, 2024
9eca981
docs: add todo
shumkov Mar 5, 2024
3238be3
docs: mistype in changelog
shumkov Mar 5, 2024
0fc6f4b
test: added removed tests for contract history
shumkov Mar 5, 2024
09c91b9
revert: change log
shumkov Mar 5, 2024
2476484
refactor: rename any_block_info to last_block_info
shumkov Mar 5, 2024
4a65593
chore: remove unused dependencies
shumkov Mar 5, 2024
e0713eb
chore: kick off CI
shumkov Mar 5, 2024
2026281
style(dashmate): fix linter
shumkov Mar 5, 2024
91e317a
perf(drive): fast read locks
shumkov Mar 5, 2024
31de57a
test: fix tests
shumkov Mar 5, 2024
ad73b70
Merge branch 'v1.0-dev' into feat/drive/fast-read-locks
shumkov Mar 6, 2024
4378c0a
pref: remove unnecessary shared locks
shumkov Mar 6, 2024
c9d7f96
docs: update docs
shumkov Mar 6, 2024
d723f7f
docs: remove todo
shumkov Mar 6, 2024
92def69
docs: add documentation for Platfrom.state
shumkov Mar 6, 2024
1434bbb
fix: inconsistent platform state in queries
shumkov Mar 6, 2024
01d9e1a
Merge branch 'v1.0-dev' into feat/drive/fast-read-locks
shumkov Mar 6, 2024
93d2f8d
fix: additional state load
shumkov Mar 6, 2024
76d2c04
chore: remove unused dependency
shumkov Mar 6, 2024
f20bf26
chore: cargo lock
shumkov Mar 6, 2024
373c014
fix(dashmate): wait for readiness flag doesn't ensure that network is…
shumkov Mar 6, 2024
059c44f
Merge branch 'v1.0-dev' into feat/drive/fast-read-locks
shumkov Mar 6, 2024
eb058e6
build: fix npm packages constraints
shumkov Mar 6, 2024
575aafa
refactor: remove mut
shumkov Mar 6, 2024
69f6103
Merge branch 'v1.0-dev' into feat/drive/fast-read-locks
shumkov Mar 7, 2024
9594ac2
chore: use rwlocks instead of refcell
shumkov Mar 7, 2024
78e7e8f
Merge branch 'v1.0-dev' into feat/drive/fast-read-locks
shumkov Mar 8, 2024
527c0a5
Merge branch 'v1.0-dev' into feat/drive/fast-read-locks
shumkov Mar 8, 2024
988163b
revert: use current protocol version for finalize block that uses new…
shumkov Mar 8, 2024
c8397df
docs: describe why we are using load_full
shumkov Mar 8, 2024
db7b6f0
docs: fix comment
shumkov Mar 8, 2024
ead8f7f
docs: fix another comment
shumkov Mar 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/dashmate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"ajv-formats": "^2.1.1",
"awilix": "^4.2.6",
"begoo": "^2.0.2",
"bs58": "^4.0.1",
"chalk": "^4.1.0",
"cron": "^2.1.0",
"dockerode": "^3.3.5",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import DAPIClient from '@dashevo/dapi-client';
import bs58 from 'bs58';
import { Listr } from 'listr2';
import WithdrawalsContract from '@dashevo/withdrawals-contract/lib/systemIds.js';
import wait from '../../../util/wait.js';

/**
Expand Down Expand Up @@ -31,12 +33,16 @@ export default function waitForNodeToBeReadyTaskFactory() {
},
});

const withdrawalsContractId = bs58.decode(WithdrawalsContract.contractId);

let success = false;
do {
const response = await dapiClient.platform.getEpochsInfo(0, 1, {
const response = await dapiClient.platform.getDataContract(withdrawalsContractId, {
retries: 0,
prove: false,
})
.catch(() => {});
.catch(() => {
});

success = Boolean(response);

Expand Down
2 changes: 1 addition & 1 deletion packages/rs-drive-abci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ rust-version = "1.76"
license = "MIT"

[dependencies]
arc-swap = "1.7.0"
bincode = { version = "2.0.0-rc.3", features = ["serde"] }
ciborium = { git = "https://github.com/qrayven/ciborium", branch = "feat-ser-null-as-undefined" }
chrono = "0.4.20"
Expand All @@ -29,7 +30,6 @@ drive = { path = "../rs-drive", default-features = false, features = [
thiserror = "1.0.30"
rand = "0.8.5"
tempfile = "3.3.0"
parking_lot = "0.12.1"
hex = "0.4.3"
indexmap = { version = "1.9.3", features = ["serde"] }
sha2 = "0.10.6"
Expand Down
45 changes: 26 additions & 19 deletions packages/rs-drive-abci/src/abci/app/consensus.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use crate::abci::app::{PlatformApplication, TransactionalApplication};
use crate::abci::app::{BlockExecutionApplication, PlatformApplication, 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::rpc::core::CoreRPCLike;
use dpp::version::PlatformVersion;
use drive::grovedb::Transaction;
use std::cell::{Ref, RefCell, RefMut};
use std::fmt::Debug;
use std::sync::RwLock;
use tenderdash_abci::proto::abci as proto;

/// AbciApp is an implementation of ABCI Application, as defined by Tenderdash.
Expand All @@ -17,16 +19,19 @@ use tenderdash_abci::proto::abci as proto;
pub struct ConsensusAbciApplication<'a, C> {
/// Platform
platform: &'a Platform<C>,
/// The current transaction
transaction: RwLock<Option<Transaction<'a>>>,
/// The current GroveDb transaction
transaction: RefCell<Option<Transaction<'a>>>,
/// The current block execution context
QuantumExplorer marked this conversation as resolved.
Show resolved Hide resolved
block_execution_context: RefCell<Option<BlockExecutionContext>>,
}
QuantumExplorer marked this conversation as resolved.
Show resolved Hide resolved

impl<'a, C> ConsensusAbciApplication<'a, C> {
/// Create new ABCI app
pub fn new(platform: &'a Platform<C>) -> Self {
Self {
platform,
transaction: RwLock::new(None),
transaction: Default::default(),
block_execution_context: Default::default(),
}
}
}
Expand All @@ -37,30 +42,32 @@ impl<'a, C> PlatformApplication<C> for ConsensusAbciApplication<'a, C> {
}
}

impl<'a, C> BlockExecutionApplication for ConsensusAbciApplication<'a, C> {
fn block_execution_context(&self) -> &RefCell<Option<BlockExecutionContext>> {
&self.block_execution_context
}
}

impl<'a, C> TransactionalApplication<'a> for ConsensusAbciApplication<'a, 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);
self.transaction.borrow_mut().replace(transaction);
}

fn transaction(&self) -> &RwLock<Option<Transaction<'a>>> {
fn transaction(&self) -> &RefCell<Option<Transaction<'a>>> {
&self.transaction
}

/// Commit a transaction
fn commit_transaction(&self) -> Result<(), Error> {
let transaction = self
.transaction
.write()
.unwrap()
.take()
.ok_or(Error::Execution(ExecutionError::NotInTransaction(
"trying to commit a transaction, but we are not in one",
)))?;

let platform_state = self.platform.state.read();
let platform_version = platform_state.current_platform_version()?;
fn commit_transaction(&self, platform_version: &PlatformVersion) -> Result<(), Error> {
let transaction =
self.transaction
.take()
.ok_or(Error::Execution(ExecutionError::NotInTransaction(
"trying to commit a transaction, but we are not in one",
)))?;

self.platform
.drive
.commit_transaction(transaction, &platform_version.drive)
Expand Down
47 changes: 29 additions & 18 deletions packages/rs-drive-abci/src/abci/app/full.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
use crate::abci::app::{PlatformApplication, TransactionalApplication};
use crate::abci::app::{
BlockExecutionApplication, ConsensusAbciApplication, PlatformApplication,
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::rpc::core::CoreRPCLike;
use dpp::version::PlatformVersion;
use drive::grovedb::Transaction;
use std::cell::RefCell;
use std::fmt::Debug;
use std::sync::RwLock;
use tenderdash_abci::proto::abci as proto;

/// AbciApp is an implementation of ABCI Application, as defined by Tenderdash.
Expand All @@ -17,16 +22,19 @@ use tenderdash_abci::proto::abci as proto;
pub struct FullAbciApplication<'a, C> {
/// Platform
pub platform: &'a Platform<C>,
/// The current transaction
pub transaction: RwLock<Option<Transaction<'a>>>,
/// The current GroveDB transaction
pub transaction: RefCell<Option<Transaction<'a>>>,
/// The current block execution context
pub block_execution_context: RefCell<Option<BlockExecutionContext>>,
}

impl<'a, C> FullAbciApplication<'a, C> {
/// Create new ABCI app
pub fn new(platform: &'a Platform<C>) -> Self {
Self {
platform,
transaction: RwLock::new(None),
transaction: Default::default(),
block_execution_context: Default::default(),
}
}
}
Expand All @@ -37,29 +45,32 @@ impl<'a, C> PlatformApplication<C> for FullAbciApplication<'a, C> {
}
}

impl<'a, C> BlockExecutionApplication for FullAbciApplication<'a, C> {
fn block_execution_context(&self) -> &RefCell<Option<BlockExecutionContext>> {
&self.block_execution_context
}
}

impl<'a, C> TransactionalApplication<'a> for FullAbciApplication<'a, 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);
self.transaction.borrow_mut().replace(transaction);
}

fn transaction(&self) -> &RwLock<Option<Transaction<'a>>> {
fn transaction(&self) -> &RefCell<Option<Transaction<'a>>> {
&self.transaction
}

/// Commit a transaction
fn commit_transaction(&self) -> Result<(), Error> {
let transaction = self
.transaction
.write()
.unwrap()
.take()
.ok_or(Error::Execution(ExecutionError::NotInTransaction(
"trying to commit a transaction, but we are not in one",
)))?;
let platform_state = self.platform.state.read();
let platform_version = platform_state.current_platform_version()?;
fn commit_transaction(&self, platform_version: &PlatformVersion) -> Result<(), Error> {
let transaction =
self.transaction
.take()
.ok_or(Error::Execution(ExecutionError::NotInTransaction(
"trying to commit a transaction, but we are not in one",
)))?;

self.platform
.drive
.commit_transaction(transaction, &platform_version.drive)
Expand Down
14 changes: 11 additions & 3 deletions packages/rs-drive-abci/src/abci/app/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use crate::error::Error;
use crate::platform_types::platform::Platform;
use drive::grovedb::Transaction;
use std::sync::RwLock;
use std::cell::RefCell;

mod check_tx;
mod consensus;
/// Convert state transition execution result into ABCI response
pub mod execution_result;
mod full;

use crate::execution::types::block_execution_context::BlockExecutionContext;
use crate::rpc::core::DefaultCoreRPC;
pub use check_tx::CheckTxAbciApplication;
pub use consensus::ConsensusAbciApplication;
use dpp::version::PlatformVersion;
pub use full::FullAbciApplication;

/// Platform-based ABCI application
Expand All @@ -26,8 +28,14 @@ pub trait TransactionalApplication<'a> {
fn start_transaction(&self);

/// Returns the current transaction
fn transaction(&self) -> &RwLock<Option<Transaction<'a>>>;
fn transaction(&self) -> &RefCell<Option<Transaction<'a>>>;

/// Commits created transaction
fn commit_transaction(&self) -> Result<(), Error>;
fn commit_transaction(&self, platform_version: &PlatformVersion) -> Result<(), Error>;
}

/// Application that executes blocks and need to keep context between handlers
pub trait BlockExecutionApplication {
/// Returns the current block execution context
fn block_execution_context(&self) -> &RefCell<Option<BlockExecutionContext>>;
}
10 changes: 7 additions & 3 deletions packages/rs-drive-abci/src/abci/handler/check_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ where
{
let _timer = crate::metrics::abci_request_duration("check_tx");

let platform_state = platform.state.read();
let platform_state = platform.state.load();
let platform_version = platform_state.current_platform_version()?;
drop(platform_state);

let proto::RequestCheckTx { tx, r#type } = request;
match platform.check_tx(tx.as_slice(), r#type.try_into()?, platform_version) {
match platform.check_tx(
tx.as_slice(),
r#type.try_into()?,
&platform_state,
platform_version,
) {
Ok(validation_result) => {
let first_consensus_error = validation_result.errors.first();

Expand Down
22 changes: 10 additions & 12 deletions packages/rs-drive-abci/src/abci/handler/extend_vote.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::abci::app::{PlatformApplication, TransactionalApplication};
use crate::abci::app::{BlockExecutionApplication, PlatformApplication, TransactionalApplication};
use crate::abci::AbciError;
use crate::error::execution::ExecutionError;
use crate::error::Error;
Expand All @@ -14,7 +14,7 @@ pub fn extend_vote<'a, A, C>(
request: proto::RequestExtendVote,
) -> Result<proto::ResponseExtendVote, Error>
where
A: PlatformApplication<C> + TransactionalApplication<'a>,
A: PlatformApplication<C> + TransactionalApplication<'a> + BlockExecutionApplication,
C: CoreRPCLike,
{
let _timer = crate::metrics::abci_request_duration("extend_vote");
Expand All @@ -24,24 +24,22 @@ where
height,
round,
} = request;
let guarded_block_execution_context = app.platform().block_execution_context.read().unwrap();
let block_execution_context =
guarded_block_execution_context
.as_ref()
.ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution(
"block execution context must be set in block begin handler for extend vote",
)))?;
let block_execution_context_ref = app.block_execution_context().borrow();
let block_execution_context = block_execution_context_ref
.as_ref()
.ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution(
"block execution context must be set in block begin handler for extend vote",
)))?;

// Verify Tenderdash that it called this handler correctly
let block_state_info = &block_execution_context.block_state_info();

if !block_state_info.matches_current_block(height as u64, round as u32, block_hash.clone())? {
return Err(Error::from(AbciError::RequestForWrongBlockReceived(format!(
return Err(AbciError::RequestForWrongBlockReceived(format!(
"received extend vote request for height: {} round: {}, block: {}; expected height: {} round: {}, block: {}",
height, round, hex::encode(block_hash),
block_state_info.height(), block_state_info.round(), block_state_info.block_hash().map(hex::encode).unwrap_or("None".to_string())
)))
.into());
)).into());
}

// Extend vote with unsigned withdrawal transactions
Expand Down
Loading
Loading