Skip to content

Commit

Permalink
[fix] #2456: Make genesis block unlimited
Browse files Browse the repository at this point in the history
Signed-off-by: Shanin Roman <[email protected]>
  • Loading branch information
Erigara committed Jan 23, 2023
1 parent d9487ff commit af61ca8
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 76 deletions.
2 changes: 1 addition & 1 deletion cli/src/torii/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub(crate) async fn handle_instructions(
transaction: VersionedSignedTransaction,
) -> Result<Empty> {
let transaction: SignedTransaction = transaction.into_v1();
let transaction = VersionedAcceptedTransaction::from_transaction(
let transaction = VersionedAcceptedTransaction::from_transaction::<false>(
transaction,
&iroha_cfg.sumeragi.transaction_limits,
)
Expand Down
2 changes: 1 addition & 1 deletion core/benches/kura.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async fn measure_block_size_for_n_validators(n_validators: u32) {
max_instruction_number: 4096,
max_wasm_size_bytes: 0,
};
let tx = VersionedAcceptedTransaction::from_transaction(tx, &transaction_limits)
let tx = VersionedAcceptedTransaction::from_transaction::<false>(tx, &transaction_limits)
.expect("Failed to accept Transaction.");
let dir = tempfile::tempdir().expect("Could not create tempfile.");
let kura =
Expand Down
25 changes: 16 additions & 9 deletions core/benches/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ fn accept_transaction(criterion: &mut Criterion) {
let mut failures_count = 0;
let _ = criterion.bench_function("accept", |b| {
b.iter(|| {
match AcceptedTransaction::from_transaction(transaction.clone(), &TRANSACTION_LIMITS) {
match AcceptedTransaction::from_transaction::<false>(
transaction.clone(),
&TRANSACTION_LIMITS,
) {
Ok(_) => success_count += 1,
Err(_) => failures_count += 1,
}
Expand All @@ -110,7 +113,7 @@ fn sign_transaction(criterion: &mut Criterion) {

fn validate_transaction(criterion: &mut Criterion) {
let keys = KeyPair::generate().expect("Failed to generate keys");
let transaction = AcceptedTransaction::from_transaction(
let transaction = AcceptedTransaction::from_transaction::<false>(
build_test_transaction(keys.clone()),
&TRANSACTION_LIMITS,
)
Expand Down Expand Up @@ -139,9 +142,11 @@ fn validate_transaction(criterion: &mut Criterion) {

fn chain_blocks(criterion: &mut Criterion) {
let keys = KeyPair::generate().expect("Failed to generate keys");
let transaction =
AcceptedTransaction::from_transaction(build_test_transaction(keys), &TRANSACTION_LIMITS)
.expect("Failed to accept transaction.");
let transaction = AcceptedTransaction::from_transaction::<false>(
build_test_transaction(keys),
&TRANSACTION_LIMITS,
)
.expect("Failed to accept transaction.");
let block = PendingBlock::new(vec![transaction.into()], Vec::new());
let mut previous_block_hash = block.clone().chain_first().hash();
let mut success_count = 0;
Expand All @@ -160,7 +165,7 @@ fn chain_blocks(criterion: &mut Criterion) {

fn sign_blocks(criterion: &mut Criterion) {
let keys = KeyPair::generate().expect("Failed to generate keys");
let transaction = AcceptedTransaction::from_transaction(
let transaction = AcceptedTransaction::from_transaction::<false>(
build_test_transaction(keys.clone()),
&TRANSACTION_LIMITS,
)
Expand Down Expand Up @@ -203,9 +208,11 @@ fn validate_blocks(criterion: &mut Criterion) {
assert!(domain.add_account(account).is_none());
// Pepare test transaction
let keys = KeyPair::generate().expect("Failed to generate keys");
let transaction =
AcceptedTransaction::from_transaction(build_test_transaction(keys), &TRANSACTION_LIMITS)
.expect("Failed to accept transaction.");
let transaction = AcceptedTransaction::from_transaction::<false>(
build_test_transaction(keys),
&TRANSACTION_LIMITS,
)
.expect("Failed to accept transaction.");
let block = PendingBlock::new(vec![transaction.into()], Vec::new()).chain_first();
let transaction_validator = TransactionValidator::new(
TRANSACTION_LIMITS,
Expand Down
28 changes: 20 additions & 8 deletions core/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,15 +482,19 @@ impl VersionedCandidateBlock {
/// # Errors
/// Forward errors from [`CandidateBlock::revalidate`]
#[inline]
pub fn revalidate(
pub fn revalidate<const IS_GENESIS: bool>(
self,
transaction_validator: &TransactionValidator,
wsv: &WorldStateView,
latest_block: Option<HashOf<VersionedCommittedBlock>>,
block_height: u64,
) -> Result<SignedBlock, eyre::Report> {
self.into_v1()
.revalidate(transaction_validator, wsv, latest_block, block_height)
self.into_v1().revalidate::<IS_GENESIS>(
transaction_validator,
wsv,
latest_block,
block_height,
)
}
}

Expand Down Expand Up @@ -549,7 +553,8 @@ impl CandidateBlock {
/// - There is a mismatch between candidate block previous block hash and actual latest block hash
/// - Block header transaction hashes don't match with computed transaction hashes
/// - Error during revalidation of individual transactions
pub fn revalidate(
#[allow(clippy::too_many_lines)]
pub fn revalidate<const IS_GENESIS: bool>(
self,
transaction_validator: &TransactionValidator,
wsv: &WorldStateView,
Expand Down Expand Up @@ -615,7 +620,10 @@ impl CandidateBlock {
.into_iter()
.map(VersionedSignedTransaction::into_v1)
.map(|tx| {
AcceptedTransaction::from_transaction(tx, &transaction_validator.transaction_limits)
AcceptedTransaction::from_transaction::<IS_GENESIS>(
tx,
&transaction_validator.transaction_limits,
)
})
.map(|accepted_tx| {
accepted_tx.and_then(|tx| {
Expand All @@ -638,7 +646,10 @@ impl CandidateBlock {
.into_iter()
.map(VersionedSignedTransaction::into_v1)
.map(|tx| {
AcceptedTransaction::from_transaction(tx, &transaction_validator.transaction_limits)
AcceptedTransaction::from_transaction::<IS_GENESIS>(
tx,
&transaction_validator.transaction_limits,
)
})
.map(|accepted_tx| {
accepted_tx.and_then(|tx| {
Expand Down Expand Up @@ -1181,8 +1192,9 @@ mod tests {
let tx = Transaction::new(alice_id, [create_asset_definition].into(), 4000)
.sign(alice_keys)
.expect("Valid");
let tx = crate::VersionedAcceptedTransaction::from_transaction(tx, &transaction_limits)
.expect("Valid");
let tx =
crate::VersionedAcceptedTransaction::from_transaction::<false>(tx, &transaction_limits)
.expect("Valid");

// Creating a block of two identical transactions and validating it
let transactions = vec![tx.clone(), tx];
Expand Down
80 changes: 42 additions & 38 deletions core/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use std::{collections::HashSet, fmt::Debug, fs::File, io::BufReader, ops::Deref, path::Path};

use derive_more::Deref;
use eyre::{eyre, Result, WrapErr};
use eyre::{bail, eyre, Result, WrapErr};
use iroha_actor::Addr;
use iroha_config::genesis::Configuration;
use iroha_crypto::{KeyPair, PublicKey};
Expand Down Expand Up @@ -147,43 +147,46 @@ impl GenesisNetworkTrait for GenesisNetwork {
genesis_config: Option<&Configuration>,
tx_limits: &TransactionLimits,
) -> Result<Option<GenesisNetwork>> {
#![allow(clippy::unwrap_in_result)]
#![allow(clippy::expect_used)]
if !submit_genesis {
iroha_logger::debug!("Not submitting genesis");
return Ok(None);
}
iroha_logger::debug!("Submitting genesis.");
Ok(Some(GenesisNetwork {
transactions: raw_block
.transactions
.iter()
.map(|raw_transaction| {
let genesis_key_pair = KeyPair::new(
genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.account_public_key
.clone(),
genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.account_private_key
.clone()
.ok_or_else(|| eyre!("Genesis account private key is empty."))?,
)?;

raw_transaction.sign_and_accept(genesis_key_pair, tx_limits)
})
.enumerate()
.filter_map(|(i, res)| {
res.map_err(|error| {
let error_msg = format!("{error:#}");
iroha_logger::error!(error = %error_msg, "Genesis transaction #{i} failed")
})
.ok()
let transactions = raw_block
.transactions
.iter()
.map(|raw_transaction| {
let genesis_key_pair = KeyPair::new(
genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.account_public_key
.clone(),
genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.account_private_key
.clone()
.ok_or_else(|| eyre!("Genesis account private key is empty."))?,
)?;

raw_transaction.sign_and_accept(genesis_key_pair, tx_limits)
})
.enumerate()
.filter_map(|(i, res)| {
res.map_err(|error| {
let error_msg = format!("{error:#}");
iroha_logger::error!(error = %error_msg, "Genesis transaction #{i} failed")
})
.collect(),
.ok()
})
.collect::<Vec<_>>();
if transactions.is_empty() {
iroha_logger::error!("Genesis transaction set contains no valid transactions");
bail!("Genesis transaction set contains no valid transactions");
}
Ok(Some(GenesisNetwork {
transactions,
wait_for_peers_retry_count_limit: genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
Expand Down Expand Up @@ -292,7 +295,7 @@ impl GenesisTransaction {
GENESIS_TRANSACTIONS_TTL_MS,
)
.sign(genesis_key_pair)?;
VersionedAcceptedTransaction::from_transaction(transaction, limits)
VersionedAcceptedTransaction::from_transaction::<true>(transaction, limits)
}

/// Create a [`GenesisTransaction`] with the specified [`Domain`] and [`Account`].
Expand Down Expand Up @@ -435,19 +438,20 @@ mod tests {

#[test]
#[allow(clippy::expect_used)]
fn load_default_genesis_block() -> Result<()> {
let (public_key, private_key) = KeyPair::generate()?.into();
fn load_new_genesis_block() -> Result<()> {
let (genesis_public_key, genesis_private_key) = KeyPair::generate()?.into();
let (alice_public_key, _) = KeyPair::generate()?.into();
let tx_limits = TransactionLimits {
max_instruction_number: 4096,
max_wasm_size_bytes: 0,
};
let _genesis_block = GenesisNetwork::from_configuration(
true,
RawGenesisBlock::default(),
RawGenesisBlock::new("alice".parse()?, "wonderland".parse()?, alice_public_key),
Some(
&ConfigurationProxy {
account_public_key: Some(public_key),
account_private_key: Some(Some(private_key)),
account_public_key: Some(genesis_public_key),
account_private_key: Some(Some(genesis_private_key)),
..ConfigurationProxy::default()
}
.build()
Expand Down
6 changes: 3 additions & 3 deletions core/src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ mod tests {
max_instruction_number: 4096,
max_wasm_size_bytes: 0,
};
VersionedAcceptedTransaction::from_transaction(tx, &limits)
VersionedAcceptedTransaction::from_transaction::<false>(tx, &limits)
.expect("Failed to accept Transaction.")
}

Expand Down Expand Up @@ -706,7 +706,7 @@ mod tests {
for key_pair in &key_pairs[1..] {
signed_tx = signed_tx.sign(key_pair.clone()).expect("Failed to sign");
}
VersionedAcceptedTransaction::from_transaction(signed_tx, &tx_limits)
VersionedAcceptedTransaction::from_transaction::<false>(signed_tx, &tx_limits)
.expect("Failed to accept Transaction.")
};
// Check that fully signed transaction pass signature check
Expand All @@ -716,7 +716,7 @@ mod tests {
));

let get_tx = |key_pair| {
VersionedAcceptedTransaction::from_transaction(
VersionedAcceptedTransaction::from_transaction::<false>(
tx.clone().sign(key_pair).expect("Failed to sign."),
&tx_limits,
)
Expand Down
7 changes: 4 additions & 3 deletions core/src/smartcontracts/isi/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,13 @@ mod tests {
let valid_tx = {
let tx = Transaction::new(ALICE_ID.clone(), Vec::<Instruction>::new().into(), 4000)
.sign(ALICE_KEYS.clone())?;
crate::VersionedAcceptedTransaction::from_transaction(tx, &limits)?
crate::VersionedAcceptedTransaction::from_transaction::<false>(tx, &limits)?
};
let invalid_tx = {
let isi = Instruction::Fail(FailBox::new("fail"));
let tx = Transaction::new(ALICE_ID.clone(), vec![isi.clone(), isi].into(), 4000)
.sign(ALICE_KEYS.clone())?;
crate::VersionedAcceptedTransaction::from_transaction(tx, &huge_limits)?
crate::VersionedAcceptedTransaction::from_transaction::<false>(tx, &huge_limits)?
};

let mut transactions = vec![valid_tx; valid_tx_per_block];
Expand Down Expand Up @@ -400,7 +400,8 @@ mod tests {
max_wasm_size_bytes: 0,
};

let va_tx = crate::VersionedAcceptedTransaction::from_transaction(signed_tx, &tx_limits)?;
let va_tx =
crate::VersionedAcceptedTransaction::from_transaction::<false>(signed_tx, &tx_limits)?;

let mut block = PendingBlock::new(Vec::new(), Vec::new());
block.transactions.push(va_tx.clone());
Expand Down
7 changes: 4 additions & 3 deletions core/src/sumeragi/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ impl<F: FaultInjection> SumeragiWithFault<F> {
"Genesis Round Peer is revalidating the block."
);
let _enter = span.enter();
match block.revalidate(
match block.revalidate::<true>(
&self.transaction_validator,
&state.wsv,
state.latest_block_hash,
Expand Down Expand Up @@ -481,7 +481,8 @@ fn enqueue_transaction<F: FaultInjection>(
let tx = tx.into_v1();

let addr = &sumeragi.peer_id.address;
match VersionedAcceptedTransaction::from_transaction(tx, &sumeragi.transaction_limits) {
match VersionedAcceptedTransaction::from_transaction::<false>(tx, &sumeragi.transaction_limits)
{
Ok(tx) => match sumeragi.queue.push(tx, wsv) {
Ok(_) => {}
Err(crate::queue::Failure {
Expand Down Expand Up @@ -964,7 +965,7 @@ fn vote_for_block<F: FaultInjection>(
let span = span!(Level::TRACE, "block revalidation");
let _enter = span.enter();

match block.revalidate(
match block.revalidate::<false>(
&sumeragi.transaction_validator,
&state.wsv,
state.latest_block_hash,
Expand Down
Loading

0 comments on commit af61ca8

Please sign in to comment.