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 24, 2023
1 parent 66b8e8e commit ac35bda
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 107 deletions.
8 changes: 4 additions & 4 deletions cli/src/torii/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use iroha_core::{
isi::query::{Error as QueryError, ValidQueryRequest},
permissions::prelude::*,
},
tx::TransactionOrigin,
};
use iroha_crypto::SignatureOf;
use iroha_data_model::{
Expand Down Expand Up @@ -108,10 +109,9 @@ pub(crate) async fn handle_instructions(
transaction: VersionedSignedTransaction,
) -> Result<Empty> {
let transaction: SignedTransaction = transaction.into_v1();
let transaction = VersionedAcceptedTransaction::from_transaction(
transaction,
&iroha_cfg.sumeragi.transaction_limits,
)
let transaction = VersionedAcceptedTransaction::from_transaction::<
{ TransactionOrigin::ConsensusBlock },
>(transaction, &iroha_cfg.sumeragi.transaction_limits)
.map_err(Error::AcceptTransaction)?;
#[allow(clippy::map_err_ignore)]
queue
Expand Down
13 changes: 11 additions & 2 deletions core/benches/kura.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ use std::{str::FromStr as _, sync::Arc};

use byte_unit::Byte;
use criterion::{criterion_group, criterion_main, Criterion};
use iroha_core::{kura::BlockStore, prelude::*, tx::TransactionValidator, wsv::World};
use iroha_core::{
kura::BlockStore,
prelude::*,
tx::{TransactionOrigin, TransactionValidator},
wsv::World,
};
use iroha_crypto::KeyPair;
use iroha_data_model::prelude::*;
use iroha_version::scale::EncodeVersioned;
Expand Down Expand Up @@ -33,7 +38,11 @@ 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::<{ TransactionOrigin::ConsensusBlock }>(
tx,
&transaction_limits,
)
.expect("Failed to accept Transaction.");
let dir = tempfile::tempdir().expect("Could not create tempfile.");
let kura =
Expand Down
43 changes: 27 additions & 16 deletions core/benches/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{collections::BTreeSet, str::FromStr as _, sync::Arc};
use criterion::{criterion_group, criterion_main, Criterion};
use iroha_core::{
prelude::*,
tx::{AcceptedTransaction, TransactionValidator},
tx::{AcceptedTransaction, TransactionOrigin, TransactionValidator},
wsv::World,
};
use iroha_data_model::prelude::*;
Expand Down 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::<{ TransactionOrigin::ConsensusBlock }>(
transaction.clone(),
&TRANSACTION_LIMITS,
) {
Ok(_) => success_count += 1,
Err(_) => failures_count += 1,
}
Expand All @@ -110,11 +113,12 @@ 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(
build_test_transaction(keys.clone()),
&TRANSACTION_LIMITS,
)
.expect("Failed to accept transaction.");
let transaction =
AcceptedTransaction::from_transaction::<{ TransactionOrigin::ConsensusBlock }>(
build_test_transaction(keys.clone()),
&TRANSACTION_LIMITS,
)
.expect("Failed to accept transaction.");
let mut success_count = 0;
let mut failure_count = 0;
let _ = criterion.bench_function("validate", move |b| {
Expand All @@ -140,8 +144,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.");
AcceptedTransaction::from_transaction::<{ TransactionOrigin::ConsensusBlock }>(
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,11 +167,12 @@ 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(
build_test_transaction(keys.clone()),
&TRANSACTION_LIMITS,
)
.expect("Failed to accept transaction.");
let transaction =
AcceptedTransaction::from_transaction::<{ TransactionOrigin::ConsensusBlock }>(
build_test_transaction(keys.clone()),
&TRANSACTION_LIMITS,
)
.expect("Failed to accept transaction.");
let transaction_validator = TransactionValidator::new(
TRANSACTION_LIMITS,
Arc::new(AllowAll::new()),
Expand Down Expand Up @@ -204,8 +212,11 @@ fn validate_blocks(criterion: &mut Criterion) {
// 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.");
AcceptedTransaction::from_transaction::<{ TransactionOrigin::ConsensusBlock }>(
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
31 changes: 22 additions & 9 deletions core/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use serde::Serialize;
use crate::{
prelude::*,
sumeragi::network_topology::{Role, Topology},
tx::{TransactionValidator, VersionedAcceptedTransaction},
tx::{TransactionOrigin, TransactionValidator, VersionedAcceptedTransaction},
};

/// Default estimation of consensus duration
Expand Down Expand Up @@ -482,15 +482,19 @@ impl VersionedCandidateBlock {
/// # Errors
/// Forward errors from [`CandidateBlock::revalidate`]
#[inline]
pub fn revalidate(
pub fn revalidate<const TX_ORIGIN: TransactionOrigin>(
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::<TX_ORIGIN>(
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 TX_ORIGIN: TransactionOrigin>(
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::<TX_ORIGIN>(
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::<TX_ORIGIN>(
tx,
&transaction_validator.transaction_limits,
)
})
.map(|accepted_tx| {
accepted_tx.and_then(|tx| {
Expand Down Expand Up @@ -1181,8 +1192,10 @@ 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::<
{ TransactionOrigin::ConsensusBlock },
>(tx, &transaction_limits)
.expect("Valid");

// Creating a block of two identical transactions and validating it
let transactions = vec![tx.clone(), tx];
Expand Down
94 changes: 43 additions & 51 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 All @@ -26,7 +26,7 @@ use tokio::{time, time::Duration};

use crate::{
sumeragi::network_topology::{GenesisBuilder as GenesisTopologyBuilder, Topology},
tx::VersionedAcceptedTransaction,
tx::{TransactionOrigin, VersionedAcceptedTransaction},
IrohaNetwork,
};

Expand Down Expand Up @@ -147,55 +147,43 @@ 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 genesis_config =
genesis_config.expect("Should be `Some` when `submit_genesis` is true");
let genesis_key_pair = KeyPair::new(
genesis_config.account_public_key.clone(),
genesis_config
.account_private_key
.clone()
.ok_or_else(|| eyre!("Genesis account private key is empty."))?,
)?;
let transactions = raw_block
.transactions
.iter()
.map(|raw_transaction| {
raw_transaction.sign_and_accept(genesis_key_pair.clone(), tx_limits)
})
.enumerate()
.filter_map(|(i, res)| {
res.map_err(|error| {
let error_msg = format!("{error:#}");
iroha_logger::error!(error = %error_msg, transaction_num=i, "Genesis transaction failed")
})
.collect(),
wait_for_peers_retry_count_limit: genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.wait_for_peers_retry_count_limit,
wait_for_peers_retry_period_ms: genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.wait_for_peers_retry_period_ms,
genesis_submission_delay_ms: genesis_config
.as_ref()
.expect("Should be `Some` when `submit_genesis` is true")
.genesis_submission_delay_ms,
.ok()
})
.collect::<Vec<_>>();
if transactions.is_empty() {
bail!("Genesis transaction set contains no valid transactions");
}
Ok(Some(GenesisNetwork {
transactions,
wait_for_peers_retry_count_limit: genesis_config.wait_for_peers_retry_count_limit,
wait_for_peers_retry_period_ms: genesis_config.wait_for_peers_retry_period_ms,
genesis_submission_delay_ms: genesis_config.genesis_submission_delay_ms,
}))
}

Expand Down Expand Up @@ -292,7 +280,10 @@ impl GenesisTransaction {
GENESIS_TRANSACTIONS_TTL_MS,
)
.sign(genesis_key_pair)?;
VersionedAcceptedTransaction::from_transaction(transaction, limits)
VersionedAcceptedTransaction::from_transaction::<{ TransactionOrigin::GenesisBlock }>(
transaction,
limits,
)
}

/// Create a [`GenesisTransaction`] with the specified [`Domain`] and [`Account`].
Expand Down Expand Up @@ -435,19 +426,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
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Iroha — A simple, enterprise-grade decentralized ledger.
#![feature(adt_const_params)]

pub mod block;
pub mod block_sync;
Expand Down
Loading

0 comments on commit ac35bda

Please sign in to comment.