Skip to content

Commit

Permalink
[feature] #4126: Add chain_id to prevent replay attacks
Browse files Browse the repository at this point in the history
Signed-off-by: Marin Veršić <[email protected]>
  • Loading branch information
mversic committed Jan 9, 2024
1 parent f147295 commit f7678d7
Show file tree
Hide file tree
Showing 49 changed files with 918 additions and 615 deletions.
162 changes: 81 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ impl Iroha {
let kura_thread_handler = Kura::start(Arc::clone(&kura));

let sumeragi = SumeragiHandle::start(SumeragiStartArgs {
chain_id: config.chain_id,
configuration: &config.sumeragi,
events_sender: events_sender.clone(),
wsv,
Expand All @@ -271,6 +272,7 @@ impl Iroha {
.start();

let gossiper = TransactionGossiper::from_configuration(
config.chain_id,
&config.sumeragi,
network.clone(),
Arc::clone(&queue),
Expand Down Expand Up @@ -300,6 +302,7 @@ impl Iroha {
let kiso = KisoHandle::new(config.clone());

let torii = Torii::new(
config.chain_id,
kiso.clone(),
&config.torii,
Arc::clone(&queue),
Expand Down Expand Up @@ -579,7 +582,7 @@ pub fn read_config(
.wrap_err("Invalid genesis configuration")?
{
Some(
GenesisNetwork::new(raw_block, &key_pair)
GenesisNetwork::new(raw_block, config.chain_id, &key_pair)
.wrap_err("Failed to construct the genesis")?,
)
} else {
Expand Down Expand Up @@ -631,9 +634,9 @@ mod tests {

fn config_factory() -> Result<ConfigurationProxy> {
let mut base = ConfigurationProxy::default();
base.chain_id = Some(1);

let key_pair = KeyPair::generate()?;

base.public_key = Some(key_pair.public_key().clone());
base.private_key = Some(key_pair.private_key().clone());

Expand Down
4 changes: 2 additions & 2 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ iroha_version = { workspace = true, features = ["http"] }

attohttpc = { version = "0.26.1", default-features = false }
eyre = { workspace = true }
http = "0.2.9"
http = "0.2.11"
url = { workspace = true }
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
Expand All @@ -71,7 +71,7 @@ parity-scale-codec = { workspace = true, default-features = false, features = ["
tokio = { workspace = true, features = ["rt"] }
tokio-tungstenite = { workspace = true }
tungstenite = { workspace = true }
futures-util = "0.3.28"
futures-util = "0.3.30"

[dev-dependencies]
iroha_wasm_builder = { workspace = true }
Expand Down
5 changes: 5 additions & 0 deletions client/benches/torii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ fn get_genesis_key_pair(config: &iroha_config::iroha::Configuration) -> KeyPair
}

fn query_requests(criterion: &mut Criterion) {
let chain_id = 0;

let mut peer = <TestPeer>::new().expect("Failed to create peer");
let configuration = get_config(unique_vec![peer.id.clone()], Some(get_key_pair()));

Expand All @@ -45,6 +47,7 @@ fn query_requests(criterion: &mut Criterion) {
construct_executor("../default_executor").expect("Failed to construct executor"),
)
.build(),
chain_id,
&get_genesis_key_pair(&configuration),
)
.expect("genesis creation failed");
Expand Down Expand Up @@ -128,6 +131,7 @@ fn query_requests(criterion: &mut Criterion) {

fn instruction_submits(criterion: &mut Criterion) {
println!("instruction submits");
let chain_id = 0;
let rt = Runtime::test();
let mut peer = <TestPeer>::new().expect("Failed to create peer");
let configuration = get_config(unique_vec![peer.id.clone()], Some(get_key_pair()));
Expand All @@ -143,6 +147,7 @@ fn instruction_submits(criterion: &mut Criterion) {
construct_executor("../default_executor").expect("Failed to construct executor"),
)
.build(),
chain_id,
&get_genesis_key_pair(&configuration),
)
.expect("failed to create genesis");
Expand Down
4 changes: 3 additions & 1 deletion client/benches/tps/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ impl MeasurerUnit {

/// Spawn who periodically submits transactions
fn spawn_transaction_submitter(&self, shutdown_signal: mpsc::Receiver<()>) -> JoinHandle<()> {
let chain_id = 0;

let submitter = self.client.clone();
let interval_us_per_tx = self.config.interval_us_per_tx;
let instructions = self.instructions();
Expand All @@ -218,7 +220,7 @@ impl MeasurerUnit {
for instruction in instructions {
match shutdown_signal.try_recv() {
Err(mpsc::TryRecvError::Empty) => {
let mut transaction = TransactionBuilder::new(alice_id.clone())
let mut transaction = TransactionBuilder::new(chain_id, alice_id.clone())
.with_instructions([instruction]);
transaction.set_nonce(nonce); // Use nonce to avoid transaction duplication within the same thread

Expand Down
158 changes: 158 additions & 0 deletions client/cbindgen.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# This is a template cbindgen.toml file with all of the default values.
# Some values are commented out because their absence is the real default.
#
# See https://github.com/mozilla/cbindgen/blob/master/docs.md#cbindgentoml
# for detailed documentation of every option here.



language = "C"



############## Options for Wrapping the Contents of the Header #################

# header = "/* Text to put at the beginning of the generated file. Probably a license. */"
# trailer = "/* Text to put at the end of the generated file */"
# include_guard = "my_bindings_h"
# pragma_once = true
# autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
include_version = false
# namespace = "my_namespace"
namespaces = []
using_namespaces = []
sys_includes = []
includes = []
no_includes = false
after_includes = ""




############################ Code Style Options ################################

braces = "SameLine"
line_length = 100
tab_width = 2
documentation = true
documentation_style = "auto"
documentation_length = "full"
line_endings = "LF" # also "CR", "CRLF", "Native"




############################# Codegen Options ##################################

style = "both"
sort_by = "Name" # default for `fn.sort_by` and `const.sort_by`
usize_is_size_t = true



[defines]
# "target_os = freebsd" = "DEFINE_FREEBSD"
# "feature = serde" = "DEFINE_SERDE"



[export]
include = []
exclude = []
# prefix = "CAPI_"
item_types = []
renaming_overrides_prefixing = false



[export.rename]



[export.body]


[export.mangle]


[fn]
rename_args = "None"
# must_use = "MUST_USE_FUNC"
# deprecated = "DEPRECATED_FUNC"
# deprecated_with_note = "DEPRECATED_FUNC_WITH_NOTE"
# no_return = "NO_RETURN"
# prefix = "START_FUNC"
# postfix = "END_FUNC"
args = "auto"
sort_by = "Name"




[struct]
rename_fields = "None"
# must_use = "MUST_USE_STRUCT"
# deprecated = "DEPRECATED_STRUCT"
# deprecated_with_note = "DEPRECATED_STRUCT_WITH_NOTE"
derive_constructor = false
derive_eq = false
derive_neq = false
derive_lt = false
derive_lte = false
derive_gt = false
derive_gte = false




[enum]
rename_variants = "None"
# must_use = "MUST_USE_ENUM"
# deprecated = "DEPRECATED_ENUM"
# deprecated_with_note = "DEPRECATED_ENUM_WITH_NOTE"
add_sentinel = false
prefix_with_name = false
derive_helper_methods = false
derive_const_casts = false
derive_mut_casts = false
# cast_assert_name = "ASSERT"
derive_tagged_enum_destructor = false
derive_tagged_enum_copy_constructor = false
enum_class = true
private_default_tagged_enum_constructor = false




[const]
allow_static_const = true
allow_constexpr = false
sort_by = "Name"




[macro_expansion]
bitflags = false






############## Options for How Your Rust library Should Be Parsed ##############

[parse]
parse_deps = true
include = ["iroha_ffi"]
exclude = []
clean = false
extra_bindings = []



[parse.expand]
crates = ["iroha_client"]
all_features = false
default_features = true
features = []
4 changes: 3 additions & 1 deletion client/examples/million_accounts_genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ fn generate_genesis(num_domains: u32) -> RawGenesisBlock {
}

fn main_genesis() {
let chain_id = 0;

let mut peer = <TestPeer>::new().expect("Failed to create peer");
let configuration = get_config(unique_vec![peer.id.clone()], Some(get_key_pair()));
let rt = Runtime::test();
let genesis = GenesisNetwork::new(generate_genesis(1_000_000_u32), &{
let genesis = GenesisNetwork::new(generate_genesis(1_000_000_u32), chain_id, &{
let private_key = configuration
.genesis
.private_key
Expand Down
5 changes: 4 additions & 1 deletion client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ impl_query_output! {
)]
#[display(fmt = "{}@{torii_url}", "key_pair.public_key()")]
pub struct Client {
/// Unique id of the blockchain. Used for simple replay attack protection.
pub chain_id: u16,
/// Url for accessing iroha node
pub torii_url: Url,
/// Accounts keypair
Expand Down Expand Up @@ -440,6 +442,7 @@ impl Client {
}

Ok(Self {
chain_id: configuration.chain_id,
torii_url: configuration.torii_api_url.clone(),
key_pair: KeyPair::new(
configuration.public_key.clone(),
Expand All @@ -466,7 +469,7 @@ impl Client {
instructions: impl Into<Executable>,
metadata: UnlimitedMetadata,
) -> Result<SignedTransaction> {
let tx_builder = TransactionBuilder::new(self.account_id.clone());
let tx_builder = TransactionBuilder::new(self.chain_id, self.account_id.clone());

let mut tx_builder = match instructions.into() {
Executable::Instructions(instructions) => tx_builder.with_instructions(instructions),
Expand Down
10 changes: 6 additions & 4 deletions client/tests/integration/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,12 @@ fn find_rate_and_make_exchange_isi_should_succeed() {
alice_id.clone(),
);

let grant_asset_transfer_tx = TransactionBuilder::new(asset_id.account_id().clone())
.with_instructions([allow_alice_to_transfer_asset])
.sign(owner_keypair)
.expect("Failed to sign seller transaction");
let chain_id = 0;
let grant_asset_transfer_tx =
TransactionBuilder::new(chain_id, asset_id.account_id().clone())
.with_instructions([allow_alice_to_transfer_asset])
.sign(owner_keypair)
.expect("Failed to sign seller transaction");

test_client
.submit_transaction_blocking(&grant_asset_transfer_tx)
Expand Down
2 changes: 1 addition & 1 deletion client/tests/integration/burn_public_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fn submit(
eyre::Result<HashOf<TransactionPayload>>,
) {
let tx = if let Some((account_id, keypair)) = submitter {
TransactionBuilder::new(account_id)
TransactionBuilder::new(0, account_id)
.with_instructions(instructions)
.sign(keypair)
.unwrap()
Expand Down
4 changes: 2 additions & 2 deletions client/tests/integration/domain_owner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn domain_owner_asset_definition_permissions() -> Result<()> {

// register asset definitions by "bob@kingdom" so he is owner of it
let coin = AssetDefinition::quantity(coin_id.clone());
let transaction = TransactionBuilder::new(bob_id.clone())
let transaction = TransactionBuilder::new(0, bob_id.clone())
.with_instructions([Register::asset_definition(coin)])
.sign(bob_keypair)?;
test_client.submit_transaction_blocking(&transaction)?;
Expand Down Expand Up @@ -181,7 +181,7 @@ fn domain_owner_asset_permissions() -> Result<()> {
// register asset definitions by "bob@kingdom" so he is owner of it
let coin = AssetDefinition::quantity(coin_id.clone());
let store = AssetDefinition::store(store_id.clone());
let transaction = TransactionBuilder::new(bob_id.clone())
let transaction = TransactionBuilder::new(0, bob_id.clone())
.with_instructions([
Register::asset_definition(coin),
Register::asset_definition(store),
Expand Down
Loading

0 comments on commit f7678d7

Please sign in to comment.