Skip to content

Commit

Permalink
Move some checks to SignedBlock::deserialize
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Murzin <[email protected]>
  • Loading branch information
dima74 committed Jun 21, 2024
1 parent a419411 commit 446f671
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 32 deletions.
Binary file modified configs/swarm/executor.wasm
Binary file not shown.
34 changes: 2 additions & 32 deletions core/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,6 @@ pub enum InvalidGenesisError {
InvalidSignature,
/// Genesis transaction must be authorized by genesis account
UnexpectedAuthority,
/// Genesis transaction contains error
ContainsErrors,
/// Genesis transaction must contain instructions
InvalidInstructions,
/// First transaction must contain single `Upgrade` instruction to set executor
FirstTransactionMustSetExecutor,
/// Genesis block must have one or two transactions (first with executor upgrade)
InvalidNumberOfTransactions,
}

/// Builder for blocks
Expand Down Expand Up @@ -263,7 +255,7 @@ mod chained {

mod valid {
use indexmap::IndexMap;
use iroha_data_model::{account::AccountId, prelude::InstructionBox, ChainId};
use iroha_data_model::{account::AccountId, ChainId};

use super::*;
use crate::{state::StateBlock, sumeragi::network_topology::Role};
Expand Down Expand Up @@ -680,6 +672,7 @@ mod valid {
}
}

// See also [SignedBlockCandidate::validate_genesis]
fn check_genesis_block(
block: &SignedBlock,
genesis_account: &AccountId,
Expand All @@ -698,30 +691,7 @@ mod valid {
if transaction.value.authority() != genesis_account {
return Err(InvalidGenesisError::UnexpectedAuthority);
}
if transaction.error.is_some() {
return Err(InvalidGenesisError::ContainsErrors);
}
let Executable::Instructions(_) = transaction.value.instructions() else {
return Err(InvalidGenesisError::InvalidInstructions);
};
}

let Some(transaction_executor) = transactions.first() else {
return Err(InvalidGenesisError::FirstTransactionMustSetExecutor);
};
let Executable::Instructions(instructions_executor) =
transaction_executor.value.instructions()
else {
return Err(InvalidGenesisError::InvalidInstructions);
};
let [InstructionBox::Upgrade(_)] = instructions_executor.as_slice() else {
return Err(InvalidGenesisError::FirstTransactionMustSetExecutor);
};

if transactions.len() > 2 {
return Err(InvalidGenesisError::InvalidNumberOfTransactions);
}

Ok(())
}

Expand Down
38 changes: 38 additions & 0 deletions data_model/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ mod candidate {
use parity_scale_codec::Input;

use super::*;
use crate::isi::InstructionBox;

#[derive(Decode, Deserialize)]
struct SignedBlockCandidate {
Expand All @@ -346,13 +347,50 @@ mod candidate {
fn validate(self) -> Result<SignedBlockV1, &'static str> {
self.validate_signatures()?;
self.validate_header()?;
if self.payload.header.height == 1 {
self.validate_genesis()?;
}

Ok(SignedBlockV1 {
signatures: self.signatures,
payload: self.payload,
})
}

fn validate_genesis(&self) -> Result<(), &'static str> {
let transactions = self.payload.transactions.as_slice();
for transaction in transactions {
if transaction.error.is_some() {
return Err("Genesis transaction must not contain errors");
}
let Executable::Instructions(_) = transaction.value.instructions() else {
return Err("Genesis transaction must contain instructions");
};
}

let Some(transaction_executor) = transactions.first() else {
return Err("Genesis block must contain at least one transaction");
};
let Executable::Instructions(instructions_executor) =
transaction_executor.value.instructions()
else {
return Err("Genesis transaction must contain instructions");
};
let [InstructionBox::Upgrade(_)] = instructions_executor.as_slice() else {
return Err(
"First transaction must contain single `Upgrade` instruction to set executor",
);
};

if transactions.len() > 2 {
return Err(
"Genesis block must have one or two transactions (first with executor upgrade)",
);
}

Ok(())
}

fn validate_signatures(&self) -> Result<(), &'static str> {
if self.signatures.is_empty() && self.payload.header.height != 1 {
return Err("Block missing signatures");
Expand Down

0 comments on commit 446f671

Please sign in to comment.