Skip to content

Commit

Permalink
[feature] #3371: Split validator entrypoint
Browse files Browse the repository at this point in the history
Signed-off-by: Daniil Polyakov <arjentix@gmail.com>
  • Loading branch information
Arjentix authored and appetrosyan committed Jul 28, 2023
1 parent d64e49a commit e049f5b
Show file tree
Hide file tree
Showing 18 changed files with 998 additions and 624 deletions.
61 changes: 41 additions & 20 deletions cli/src/torii/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,35 +94,57 @@ async fn handle_queries(

cursor: ForwardCursor,
) -> Result<Scale<VersionedBatchedResponse<Value>>> {
// TODO: Remove wsv clone
let mut wsv = sumeragi.wsv_clone();
let valid_request = ValidQueryRequest::validate(request, &mut wsv)?;
let valid_request = sumeragi.apply_wsv(|wsv| ValidQueryRequest::validate(request, wsv))?;
let request_id = (&valid_request, &sorting, &pagination);

let (query_id, curr_cursor, mut live_query) = if let Some(query_id) = cursor.query_id {
if let Some(query_id) = cursor.query_id {
let live_query = query_store
.remove(&query_id, &request_id)
.ok_or(Error::UnknownCursor)?;

(query_id, cursor.cursor.map(NonZeroU64::get), live_query)
} else {
let res = valid_request.execute(&wsv).map_err(ValidationFail::from)?;
return construct_query_response(
request_id,
&query_store,
query_id,
cursor.cursor.map(NonZeroU64::get),
live_query,
);
}

sumeragi.apply_wsv(|wsv| {
let res = valid_request.execute(wsv).map_err(ValidationFail::from)?;

match res {
LazyValue::Value(batch) => {
let cursor = ForwardCursor::default();
let result = BatchedResponse { batch, cursor };
return Ok(Scale(result.into()));
Ok(Scale(result.into()))
}
LazyValue::Iter(iter) => {
let live_query = apply_sorting_and_pagination(iter, &sorting, pagination);
let query_id = uuid::Uuid::new_v4().to_string();

(query_id, Some(0), live_query.batched(fetch_size))
let curr_cursor = Some(0);
let live_query = live_query.batched(fetch_size);
construct_query_response(
request_id,
&query_store,
query_id,
curr_cursor,
live_query,
)
}
}
};
})
}

fn construct_query_response(
request_id: (&ValidQueryRequest, &Sorting, &Pagination),
query_store: &LiveQueryStore,
query_id: String,
curr_cursor: Option<u64>,
mut live_query: Batched<Vec<Value>>,
) -> Result<Scale<VersionedBatchedResponse<Value>>> {
let (batch, next_cursor) = live_query.next_batch(curr_cursor)?;

if !live_query.is_depleted() {
Expand Down Expand Up @@ -202,16 +224,15 @@ async fn handle_pending_transactions(
sumeragi: SumeragiHandle,
pagination: Pagination,
) -> Result<Scale<Vec<VersionedSignedTransaction>>> {
// TODO: Don't clone wsv here
let wsv = sumeragi.wsv_clone();

let query_response = queue
.all_transactions(&wsv)
.map(Into::into)
.paginate(pagination)
.collect::<Vec<_>>();
// TODO:
//.batched(fetch_size)
let query_response = sumeragi.apply_wsv(|wsv| {
queue
.all_transactions(wsv)
.map(Into::into)
.paginate(pagination)
.collect::<Vec<_>>()
// TODO:
//.batched(fetch_size)
});

Ok(Scale(query_response))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! If authority is not `admin@admin` then [`DefaultValidator`] is used as a backup.

#![no_std]
#![allow(missing_docs, clippy::missing_errors_doc)]

use iroha_validator::{
data_model::evaluate::{EvaluationError, ExpressionEvaluator},
Expand Down Expand Up @@ -114,29 +115,37 @@ impl ExpressionEvaluator for CustomValidator {
}
}

/// Migration entrypoint.
#[entrypoint]
pub fn migrate() -> MigrationResult {
CustomValidator::migrate()
}

/// Allow operation if authority is `admin@admin` and if not,
/// fallback to [`DefaultValidator::validate()`].
#[entrypoint(params = "[authority, operation]")]
pub fn validate(authority: AccountId, operation: NeedsValidationBox) -> Result {
#[entrypoint]
pub fn validate_transaction(
authority: AccountId,
transaction: VersionedSignedTransaction,
) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

match operation {
NeedsValidationBox::Transaction(transaction) => {
validator.visit_transaction(&authority, &transaction);
}
NeedsValidationBox::Instruction(instruction) => {
validator.visit_instruction(&authority, &instruction);
}
NeedsValidationBox::Query(query) => {
validator.visit_query(&authority, &query);
}
}
validator.visit_transaction(&authority, &transaction);

validator.0.verdict
}

#[entrypoint]
pub fn validate_instruction(authority: AccountId, instruction: InstructionBox) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

validator.visit_instruction(&authority, &instruction);

validator.0.verdict
}

#[entrypoint]
pub fn validate_query(authority: AccountId, query: QueryBox) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

validator.visit_query(&authority, &query);

validator.0.verdict
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! get access to control all domains. Remember that this is just a test example.

#![no_std]
#![allow(missing_docs, clippy::missing_errors_doc)]

extern crate alloc;

Expand Down Expand Up @@ -276,28 +277,37 @@ impl ExpressionEvaluator for CustomValidator {
}
}

/// Migration entrypoint.
#[entrypoint]
pub fn migrate() -> MigrationResult {
CustomValidator::migrate()
}

/// Validate operation
#[entrypoint(params = "[authority, operation]")]
pub fn validate(authority: AccountId, operation: NeedsValidationBox) -> Result {
#[entrypoint]
pub fn validate_transaction(
authority: AccountId,
transaction: VersionedSignedTransaction,
) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

match operation {
NeedsValidationBox::Transaction(transaction) => {
validator.visit_transaction(&authority, &transaction);
}
NeedsValidationBox::Instruction(instruction) => {
validator.visit_instruction(&authority, &instruction);
}
NeedsValidationBox::Query(query) => {
validator.visit_query(&authority, &query);
}
}
validator.visit_transaction(&authority, &transaction);

validator.0.verdict
}

#[entrypoint]
pub fn validate_instruction(authority: AccountId, instruction: InstructionBox) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

validator.visit_instruction(&authority, &instruction);

validator.0.verdict
}

#[entrypoint]
pub fn validate_query(authority: AccountId, query: QueryBox) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

validator.visit_query(&authority, &query);

validator.0.verdict
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Runtime Validator which copies [`DefaultValidator`] logic but forbids any queries and fails to migrate.

#![no_std]
#![allow(missing_docs, clippy::missing_errors_doc)]

#[cfg(not(test))]
extern crate panic_halt;
Expand Down Expand Up @@ -136,22 +137,32 @@ pub fn migrate() -> MigrationResult {
CustomValidator::migrate()
}

/// Validation entrypoint.
#[entrypoint(params = "[authority, operation]")]
pub fn validate(authority: AccountId, operation: NeedsValidationBox) -> Result {
#[entrypoint]
pub fn validate_transaction(
authority: AccountId,
transaction: VersionedSignedTransaction,
) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

match operation {
NeedsValidationBox::Transaction(transaction) => {
validator.visit_transaction(&authority, &transaction);
}
NeedsValidationBox::Instruction(instruction) => {
validator.visit_instruction(&authority, &instruction);
}
NeedsValidationBox::Query(query) => {
validator.visit_query(&authority, &query);
}
}
validator.visit_transaction(&authority, &transaction);

validator.0.verdict
}

#[entrypoint]
pub fn validate_instruction(authority: AccountId, instruction: InstructionBox) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

validator.visit_instruction(&authority, &instruction);

validator.0.verdict
}

#[entrypoint]
pub fn validate_query(authority: AccountId, query: QueryBox) -> Result {
let mut validator = CustomValidator(DefaultValidator::new());

validator.visit_query(&authority, &query);

validator.0.verdict
}
Binary file modified configs/peer/validator.wasm
Binary file not shown.
7 changes: 3 additions & 4 deletions core/src/smartcontracts/isi/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl ValidQueryRequest {
/// - Account has incorrect permissions
pub fn validate(
query: VersionedSignedQuery,
wsv: &mut WorldStateView,
wsv: &WorldStateView,
) -> Result<Self, ValidationFail> {
let account_has_public_key = wsv
.map_account(query.authority(), |account| {
Expand All @@ -82,9 +82,8 @@ impl ValidQueryRequest {
))
.into());
}
wsv.validator_view()
.clone()
.validate(wsv, query.authority(), query.query().clone())?;
wsv.validator()
.validate_query(wsv, query.authority(), query.query().clone())?;
Ok(Self(query))
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/smartcontracts/isi/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ pub mod isi {
})?;

let world = wsv.world_mut();
let _ = world.upgraded_validator.insert(new_validator);
let _ = world.validator.insert(new_validator);

wsv.emit_events(std::iter::once(ValidatorEvent::Upgraded));

Expand Down
Loading

0 comments on commit e049f5b

Please sign in to comment.