Skip to content

Commit

Permalink
rusk: passing nonce and owner for contract id generation
Browse files Browse the repository at this point in the history
  • Loading branch information
miloszm committed Jul 25, 2024
1 parent ca1dce0 commit 3f54ef8
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 3 deletions.
2 changes: 2 additions & 0 deletions rusk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `gen_contract_id` and 32-byte hash for contract deployment [#1884]
- Add execution of contract deployment [#1882]
- Add first version of RUES, allowing websocket clients to subscribe for events
emitted by block transitions [#931]
Expand Down Expand Up @@ -210,6 +211,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add linking between Rusk and Protobuff structs
- Add build system that generates keys for circuits and caches them.

[#1884]: https://github.com/dusk-network/rusk/issues/1884
[#1882]: https://github.com/dusk-network/rusk/issues/1882
[#1675]: https://github.com/dusk-network/rusk/issues/1675
[#1640]: https://github.com/dusk-network/rusk/issues/1640
Expand Down
1 change: 1 addition & 0 deletions rusk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ rkyv = { version = "0.7", default-features = false, features = ["size_32"] }
bytecheck = { version = "0.6", default-features = false }
dirs = "4"
blake3 = "1"
blake2b_simd = { version = "1", default-features = false }

poseidon-merkle = { version = "0.6", features = ["rkyv-impl", "size_32"] }
sha3 = "0.10"
Expand Down
7 changes: 6 additions & 1 deletion rusk/src/lib/chain/rusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use rusk_profile::to_rusk_state_id_path;
use tokio::sync::broadcast;

use super::{coinbase_value, Rusk, RuskTip};
use crate::gen_id::gen_contract_id;
use crate::http::RuesEvent;
use crate::Error::InvalidCreditsCount;
use crate::{Error, Result};
Expand Down Expand Up @@ -540,7 +541,11 @@ fn contract_deploy(
receipt.data = Err(Panic("failed bytecode hash check".into()))
} else {
let result = session.deploy_raw(
None,
Some(gen_contract_id(
&deploy.bytecode.bytes,
deploy.nonce,
&deploy.owner,
)),
deploy.bytecode.bytes.as_slice(),
deploy.constructor_args.clone(),
deploy.owner.clone(),
Expand Down
53 changes: 53 additions & 0 deletions rusk/src/lib/gen_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::hash::Hasher;
use rusk_abi::ContractId;

/// Generate a [`ContractId`] address from:
/// - slice of bytes,
/// - nonce
/// - owner
pub fn gen_contract_id(
bytes: impl AsRef<[u8]>,
nonce: u64,
owner: impl AsRef<[u8]>,
) -> ContractId {
let mut hasher = Hasher::new();
hasher.update(bytes.as_ref());
hasher.update(nonce.to_le_bytes());
hasher.update(owner.as_ref());
let hash_bytes = hasher.finalize();
ContractId::from_bytes(hash_bytes)
}

#[cfg(test)]
mod tests {
use super::*;
use rand::rngs::StdRng;
use rand::{RngCore, SeedableRng};

#[test]
fn test_gen_contract_id() {
let mut rng = StdRng::seed_from_u64(42);

let mut bytes = vec![0; 1000];
rng.fill_bytes(&mut bytes);

let nonce = rng.next_u64();

let mut owner = vec![0, 100];
rng.fill_bytes(&mut owner);

let contract_id =
gen_contract_id(bytes.as_slice(), nonce, owner.as_slice());

assert_eq!(
hex::encode(contract_id.as_bytes()),
"a138d3b9c87235dac6f62d1d30b75cffbb94601d9cbe5bd540b3e1e5842c8a7d"
);
}
}
44 changes: 44 additions & 0 deletions rusk/src/lib/hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use blake2b_simd::{Params, State};

/// Hashes scalars and arbitrary slices of bytes using Blake2b, returning an
/// array of 32 bytes.
///
/// This hash cannot be proven inside a circuit, if that is desired, use
/// `poseidon_hash` instead.
pub struct Hasher {
state: State,
}

impl Default for Hasher {
fn default() -> Self {
Hasher {
state: Params::new().hash_length(64).to_state(),
}
}
}

impl Hasher {
/// Create new hasher instance.
pub fn new() -> Self {
Self::default()
}

/// Process data, updating the internal state.
pub fn update(&mut self, data: impl AsRef<[u8]>) {
self.state.update(data.as_ref());
}

/// Retrieve result and consume hasher instance.
pub fn finalize(self) -> [u8; 32] {
let hash = self.state.finalize();
let mut a = [0u8; 32];
a.clone_from_slice(&hash.as_array()[..32]);
a
}
}
2 changes: 2 additions & 0 deletions rusk/src/lib/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#[cfg(feature = "node")]
pub mod chain;
mod error;
pub mod gen_id;
mod hash;
pub mod http;
pub mod verifier;
mod version;
Expand Down
11 changes: 9 additions & 2 deletions rusk/tests/services/contract_deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use execution_core::bytecode::Bytecode;
use execution_core::transfer::{ContractDeploy, ContractExec};
use rand::prelude::*;
use rand::rngs::StdRng;
use rusk::gen_id::gen_contract_id;
use rusk::{Result, Rusk};
use rusk_abi::{ContractData, ContractId, PiecrustError};
use rusk_recovery_tools::state;
Expand Down Expand Up @@ -77,7 +78,12 @@ fn initial_state<P: AsRef<Path>>(dir: P, deploy_bob: bool) -> Result<Rusk> {
bob_bytecode,
ContractData::builder()
.owner(OWNER)
.constructor_arg(&BOB_INIT_VALUE),
.constructor_arg(&BOB_INIT_VALUE)
.contract_id(gen_contract_id(
&bob_bytecode,
0u64,
&OWNER,
)),
POINT_LIMIT,
)
.expect("Deploying the alice contract should succeed");
Expand Down Expand Up @@ -121,6 +127,7 @@ fn make_and_execute_transaction_deploy(
},
owner: OWNER.to_vec(),
constructor_args,
nonce: 0,
}),
SENDER_INDEX,
gas_limit,
Expand Down Expand Up @@ -191,7 +198,7 @@ impl Fixture {
"../../../target/dusk/wasm32-unknown-unknown/release/bob.wasm"
)
.to_vec();
let contract_id = bytecode_hash(bob_bytecode.as_slice());
let contract_id = gen_contract_id(&bob_bytecode, 0u64, &OWNER);

let path = tmp.into_path();
Self {
Expand Down

0 comments on commit 3f54ef8

Please sign in to comment.