Skip to content

Commit

Permalink
Merge pull request #1006 from dusk-network/block-event-hash-962
Browse files Browse the repository at this point in the history
Add `event_hash` to the block header
  • Loading branch information
Eduardo Leegwater Simões authored Aug 11, 2023
2 parents 9ad1a10 + 9602d97 commit b3e849d
Show file tree
Hide file tree
Showing 17 changed files with 329 additions and 207 deletions.
2 changes: 1 addition & 1 deletion consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ tokio = { version = "1", features = ["full"] }
tracing-subscriber = "0.2"
tracing = "0.1"
dusk-bls12_381-sign = { version = "0.4" }
sha3 = { version = "0.10.2" }
sha3 = { version = "0.10" }
num-bigint = { version = "0.4.3", default-features = false }
hex = { version = "0.4.3" }
libmath = { version = "0.2.1" }
Expand Down
9 changes: 6 additions & 3 deletions consensus/example/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use anyhow::bail;
use dusk_consensus::commons::Database;
use dusk_consensus::contract_state::{
CallParams, Error, Operations, Output, StateRoot,
CallParams, Error, Operations, Output, VerificationOutput,
};
use node_data::ledger::*;

Expand All @@ -20,8 +20,11 @@ impl Operations for Executor {
&self,
_params: CallParams,
_txs: Vec<Transaction>,
) -> Result<StateRoot, Error> {
Ok([0; 32])
) -> Result<VerificationOutput, Error> {
Ok(VerificationOutput {
state_root: [0; 32],
event_hash: [1; 32],
})
}

async fn execute_state_transition(
Expand Down
24 changes: 19 additions & 5 deletions consensus/src/commons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,27 @@ pub fn spawn_send_reduction<T: Operations + 'static>(
)
.await
{
Ok(state_hash) => {
// Ensure state_hash returned from VST call is the one we
// expect to have with current candidate block
if state_hash != candidate.header.state_hash {
Ok(verification_output) => {
// Ensure the `event_hash` and `state_root` returned from
// the VST call are the ones we expect to have with the
// current candidate block.
if verification_output.event_hash
!= candidate.header.event_hash
{
tracing::error!(
"VST failed with invalid event_hash: {}, candidate_event_hash: {}",
hex::encode(verification_output.event_hash),
hex::encode(candidate.header.event_hash),
);
return;
}

if verification_output.state_root
!= candidate.header.state_hash
{
tracing::error!(
"VST failed with invalid state_hash: {}, candidate_state_hash: {}",
hex::encode(state_hash),
hex::encode(verification_output.state_root),
hex::encode(candidate.header.state_hash),
);
return;
Expand Down
29 changes: 24 additions & 5 deletions consensus/src/contract_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,59 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use crate::user::provisioners::Provisioners;
use std::fmt;

use node_data::ledger::{SpentTransaction, Transaction};

use crate::user::provisioners::Provisioners;

pub type StateRoot = [u8; 32];
pub type EventHash = [u8; 32];

#[derive(Debug)]
pub enum Error {
Failed,
}

#[allow(unused)]
#[derive(Default, Clone, Debug)]
pub struct CallParams {
pub round: u64,
pub block_gas_limit: u64,
pub generator_pubkey: node_data::bls::PublicKey,
}

#[allow(unused)]
#[derive(Default)]
pub struct Output {
pub txs: Vec<SpentTransaction>,
pub state_root: StateRoot,
pub verification_output: VerificationOutput,
pub provisioners: Provisioners,
pub discarded_txs: Vec<Transaction>,
}

#[derive(Debug, Default, PartialEq)]
pub struct VerificationOutput {
pub state_root: StateRoot,
pub event_hash: EventHash,
}

impl fmt::Display for VerificationOutput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"VerificationOutput {{ state_root: {}, event_hash: {} }}",
hex::encode(self.state_root),
hex::encode(self.event_hash)
)
}
}

#[async_trait::async_trait]
pub trait Operations: Send + Sync {
async fn verify_state_transition(
&self,
params: CallParams,
txs: Vec<Transaction>,
) -> Result<StateRoot, Error>;
) -> Result<VerificationOutput, Error>;

async fn execute_state_transition(
&self,
Expand Down
3 changes: 2 additions & 1 deletion consensus/src/selection/block_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ impl<T: Operations> Generator<T> {
generator_bls_pubkey: node_data::bls::PublicKeyBytes(
*pubkey.bytes(),
),
state_hash: result.state_root,
state_hash: result.verification_output.state_root,
event_hash: result.verification_output.event_hash,
hash: [0; 32],
cert: Certificate::default(),
txroot,
Expand Down
2 changes: 2 additions & 0 deletions contracts/transfer/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,9 @@ impl TransferState {
/// Note: the method `update_root` needs to be called after the last note is
/// pushed.
pub fn push_note(&mut self, block_height: u64, note: Note) -> Note {
let tree_leaf = TreeLeaf { block_height, note };
let pos = self.tree.push(TreeLeaf { block_height, note });
rusk_abi::emit("TREE_LEAF", (pos, tree_leaf.clone()));
self.get_note(pos)
.expect("There should be a note that was just inserted")
}
Expand Down
7 changes: 7 additions & 0 deletions node-data/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct Header {
pub prev_block_hash: Hash,
pub seed: Seed,
pub state_hash: Hash,
pub event_hash: Hash,
pub generator_bls_pubkey: bls::PublicKeyBytes,
pub txroot: Hash,
pub gas_limit: u64,
Expand Down Expand Up @@ -69,6 +70,7 @@ impl std::fmt::Debug for Header {
.field("prev_block_hash", &to_str(&self.prev_block_hash))
.field("seed", &to_str(&self.seed.inner()))
.field("state_hash", &to_str(&self.state_hash))
.field("event_hash", &to_str(&self.event_hash))
.field("gen_bls_pubkey", &to_str(self.generator_bls_pubkey.inner()))
.field("gas_limit", &self.gas_limit)
.field("hash", &to_str(&self.hash))
Expand Down Expand Up @@ -140,6 +142,7 @@ impl Header {
}

w.write_all(&self.state_hash[..])?;
w.write_all(&self.event_hash[..])?;
w.write_all(&self.generator_bls_pubkey.inner()[..])?;
w.write_all(&self.txroot[..])?;
w.write_all(&self.gas_limit.to_le_bytes())?;
Expand Down Expand Up @@ -172,6 +175,9 @@ impl Header {
let mut state_hash = [0u8; 32];
r.read_exact(&mut state_hash[..])?;

let mut event_hash = [0u8; 32];
r.read_exact(&mut event_hash[..])?;

let mut generator_bls_pubkey = [0u8; 96];
r.read_exact(&mut generator_bls_pubkey[..])?;

Expand All @@ -196,6 +202,7 @@ impl Header {
generator_bls_pubkey: bls::PublicKeyBytes(generator_bls_pubkey),
iteration,
state_hash,
event_hash,
txroot,
hash: [0; 32],
cert: Default::default(),
Expand Down
5 changes: 3 additions & 2 deletions node-data/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -988,8 +988,9 @@ mod tests {
seed: ledger::Seed::from([2; 48]),
generator_bls_pubkey: bls::PublicKeyBytes([5; 96]),
state_hash: [4; 32],
hash: [5; 32],
txroot: [6; 32],
event_hash: [5; 32],
hash: [6; 32],
txroot: [7; 32],
cert: Certificate {
first_reduction: ledger::StepVotes::new([6; 48], 22222222),
second_reduction: ledger::StepVotes::new([7; 48], 3333333),
Expand Down
11 changes: 9 additions & 2 deletions node/src/chain/acceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,19 @@ impl<DB: database::DB, VM: vm::VMExecution, N: Network> Acceptor<N, DB, VM> {
{
let vm = self.vm.write().await;
let txs = self.db.read().await.update(|t| {
let (txs, state_hash) = match blk.header.iteration {
let (txs, verification_output) = match blk.header.iteration {
1 => vm.finalize(blk)?,
_ => vm.accept(blk)?,
};

assert_eq!(blk.header.state_hash, state_hash);
assert_eq!(
blk.header.state_hash,
verification_output.state_root
);
assert_eq!(
blk.header.event_hash,
verification_output.event_hash
);

// Store block with updated transactions with Error and GasSpent
t.store_block(&blk.header, &txs)?;
Expand Down
8 changes: 4 additions & 4 deletions node/src/chain/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use async_trait::async_trait;
use dusk_consensus::commons::{ConsensusError, Database, RoundUpdate};
use dusk_consensus::consensus::Consensus;
use dusk_consensus::contract_state::{
CallParams, Error, Operations, Output, StateRoot,
CallParams, Error, Operations, Output, StateRoot, VerificationOutput,
};
use dusk_consensus::user::provisioners::Provisioners;
use node_data::ledger::{Block, Hash, Transaction};
Expand Down Expand Up @@ -253,7 +253,7 @@ impl<DB: database::DB, VM: vm::VMExecution> Operations for Executor<DB, VM> {
&self,
params: CallParams,
txs: Vec<Transaction>,
) -> Result<StateRoot, dusk_consensus::contract_state::Error> {
) -> Result<VerificationOutput, dusk_consensus::contract_state::Error> {
tracing::info!("verifying state");

let vm = self.vm.read().await;
Expand All @@ -272,7 +272,7 @@ impl<DB: database::DB, VM: vm::VMExecution> Operations for Executor<DB, VM> {
let vm = self.vm.read().await;

let db = self.db.read().await;
let (executed_txs, discarded_txs, state_root) = db
let (executed_txs, discarded_txs, verification_output) = db
.view(|view| {
let txs = view.get_txs_sorted_by_fee().map_err(|err| {
anyhow::anyhow!("failed to get mempool txs: {}", err)
Expand All @@ -289,7 +289,7 @@ impl<DB: database::DB, VM: vm::VMExecution> Operations for Executor<DB, VM> {

Ok(Output {
txs: executed_txs,
state_root,
verification_output,
discarded_txs,
provisioners: Provisioners::default(),
})
Expand Down
6 changes: 4 additions & 2 deletions node/src/network/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use node_data::message::Message;
use node_data::Serializable;
use std::io::{self, Read, Write};

const RROTOCOL_VERSION: [u8; 8] = [0, 0, 0, 0, 1, 0, 0, 0];
const PROTOCOL_VERSION: [u8; 8] = [0, 0, 0, 0, 1, 0, 0, 0];

/// Defines PDU (Protocol Data Unit) structure.
#[derive(Debug, Default)]
Expand All @@ -33,7 +33,7 @@ impl Pdu {
let mut header_buf = vec![];
Header {
checksum: calc_checksum(&payload_buf[..]),
version: RROTOCOL_VERSION,
version: PROTOCOL_VERSION,
reserved,
}
.write(&mut header_buf)?;
Expand Down Expand Up @@ -106,6 +106,8 @@ fn calc_checksum(buf: &[u8]) -> [u8; 4] {
#[cfg(test)]
mod tests {
use super::*;

#[ignore = "We are incompatible with `dusk-blockchain`'s protocol, which is what this was meant to test"]
#[test]
fn test_block() {
let hexdata = "6e0a00000000000000000000010000008c773cfffede68e79ebbe2670b00f6060000000000008424946400000000f0b411c188b40c1196fe3621c4793ee5164dc6c2e20ece8a8c6aa1dfe6678a0430910a12a8ba0eace1d12063b9dbfd5e18d78fcc06a0ed59b952ac143b29186b189e8d4bfc3dc0aa43a7522bc61cec5150b4b1edd86ef27da5a7215c2671022acb9284c2c81230625172513d8070d3df5baf66903d83ed01c6bb809c6255fdf806e21a44e11070dd90bffc32f30a9010616906260757181552d2cd1f317a9d6cc803ddf71c76fb8e1357b62b659a2bae5617daebae1f5bc467cb1e6c34496f8bfc839515cdd712bb83509d3b4ff821b9850b1098da050ad3eb61fd65384aadf17a8c511051b202d8aff24ede98d09a0d6b005ed0b2000000000130b7a60a49581b53ae17ef7adf5a06beb499e49f757ceaf1d172c6063ea9297361368ea3326df36eb09e85bab0a07083b530a03365463092c008e08929031b9f5c13309ce306f38d3cc93eda62af95aced173a6f352e258c54ff5a98be9df15345281d000000000000001d000000000000006538724fa461839a2b1a3570e8823cbe9fc57140a02af1b7921ca267cf87f90b010100000001000000af08000031858df61df8a7208b64540f1dafffcce0ec7613f38d6147ca4393c101d45e600200000000000000f1afb77f1551f559f1226f88b2efbbc37c811218cc50531f0a8a704c98c35a32e1b905bb45a09cbca4e003a9f9d2eb6c16adf6fa49ca8afd8dfdfca449f354700100000000000000017918bbfc50c9a07b4abf98e605085f543cca07ca802b94afe1d992995543335a2d6307d9dc46929cb072d09bc790b6214671fc55df8e8d7af1bb3ef33529d31dce2982d5fef7fd0f7e36ba3e88d119fb807a546f3e273d09380dbdf48d0c57f0513c03a5c1e98e40493acde840d384c965bfccdb26af78aec81333fe24028fc2ffffffffffffffffe2f34d13ef74e08d966ced4a75ea36af891247031f848b003755dff9e8060b01104e6237b437d401ba7ad37a2435fbcb39ad17e3308a0a80c97acbe336e68851d034589b1859998aeced6f060874daf17299ae5cba212020f6bb80701afb1f410065cd1d000000000100000000000000d870bd7510b7d51655ce1122829ec083b7d0a5a4db2ffe16589b3eabaec51d0f7a600e3dae06a4f740336cedd2b5bbeaf50428fbee075bd29cef630bab5f86a9001004000000000000a0f630636f64629f0a4422b00d5dbccb0405c4124603b4f00b29ef1ab49a617bacda7c6ea142a7ca80b1817f072a0c8491a6966f8b648c6e552b4afaa4fc5d1867448d1e3a1a360cccb68d54f100e47ab0a98464e8e8bbcca13c057ea89bb0f1b1aedd1ed10e18b5661f2dd029ecb7060110cd784837675c5588cbc5721b9075eb9b6c6a1dacff8fd9ae5e2587994f0e8b74ecc9cd9254916dcb7518d807d452ba551a5590d3045283739f8f954d3550ae08717f717bcff71a8c87d3725135abb0e1cf62b16d3e0185d589f2c84f04b577ec154ab770719eec1b3e935736021a49dbfdbd0fc76e12d33d516e3ab187b680b5a42b6f9d8104699a0e5d440db122698bbc0e7d7907d32d73664b88a4efe650bcd2cd8e17b6e1060fb99e0ba7cea790bae9e87f920bd37bb5d95946e679150560659f037cc148780745b21a8f8f726a82ec597f8195622fda20700cc38bdeb1d64eb47a240c3c72b4e1752677e39157764231ee2667ab36ccdbfba42457f8aa78190e9f349fdb0f39419a0118585b830e1f5384814e9656b8979aa59833641c241d35c05dc76d7e364aee2450106ab83406673fc18e931b92e5ccdb9c147b867649519adf577c562d87284c4674ee2b4300dc24d0f1a6dc1181b28b14322e7102cb0bf4959f2d49c55f76b438bb3b98b1ae81660da05395dd2780c2b7a57f91dfea8ab8e0ef39c6d3aa90b6a9c796dc7a5442582066d7eb35d61e41e26ad02c5bec835f0e56f87369a55eb8aa9267638b4cffbf8595a67158f55c8dc85e4c607c114f2d51f5bbd0424906bd3a49b3979ccc1fd3266c11b4f6fee01452a215c2537200e2f96527fbfb2a2525cf4a856a3d7ad224f90e77ebd1564d83a75c34e4bfbb3a2e9112af6d5d684c693079671817d04798e47a891313e74401893d3cbed23ffcba13c62a9815a2207d3b4791a77bcd52326a8acd57918a371552bb46e486f1a6217e10ae74f5f8e4c1984c28ef8ac960abeb001c26282439eae48249cce5272acaba1be1ce770cd90c68efbda84dd3ccf2f2ce51d9b7351703d7cb6d928f27d0a662c26e54a6342d509e877b8355a50c2fb23f8f680c063a49d6ab31a2b34a17038141b04c19221df2f229ce7ca70b837ebf0c3a030527fc7037172d0ddc595e1aaba4774c1746a83dff4867b5986c5afe399c93ead34e37aaa79e48def89950118f5ab0c7d66074dd680fbc7146c977135a6aef55617befeba25f269b606a21f8880ce2c30e0ce8b898643c08871773ac1e41f62d86c24060b1072418275ded45bb819939ca45d681878ec16257902ce4d4aebc709027d77f2c8c622ce7f1a7f79a2d5efd460266a059ad242ff7b64947f44d1b9bd8d29a633b9223fb75ce14deb158c81e9a1703395531d173bdd88b8df90bee088618e12b875e42f45ff5cc7159b136e05b2426628b0dafa076e5dcc223a37cf5f0df7e75607f040101000000000000000000000000000000000000000000000000000000000000000400000000000000726f6f747aaa96c657582d963de258f184da3d7c95042920db92a2b2591c181466ea5a5311b5ef84f135b3d567120eaae941f35f8d5d62a8f42c8c9dacd2c78cc6f02e558d0d18fc4e78997967851fef237755ee6ee490036925c7fb100eefdbec1c033b8332252314a8fd0c05a01f9a8b87372381ee179818e8ffff36dc94a411c0d75e9ded4fcdf533fd58fc80c8dae586d783ed32168744d0f952dee4f02ce4e25f552327ac75c4aba87513dc54e4a5c2e2e36835828113ef92fea59dbf2457575903bf3156016acac7a44a1d6b546f4199bba7b24966c739ddc433a521ee5a776148349a0a53a6cd16d1cd20e13120bd404fd23a752a8f3facd53b78d360d3f3a03e57bf726eed5f1d8d4c530cd187919796fbb4cdc4dceb809f3839bcb453ae7022ae10a0f7ee7f4355e9d74fbf55d3221bb0beb1bf9ae1f6927e9d3cce9f24581640d55c7bf2cd4b6f130ef439a20b990223bb9022446b7e02e502619b4dd3f80d31e6ca8a4c8785453c9a4886d5e9159bcd1974030e70d1cdd008f3408845871c4cbfb0554963f5f47b91a81a0d1f7370be7c072d77a9e03489921981f503ec2f29a07829b2b4f9f285e2ff0d50378d59b12ad2fb8386001e561c3c3c5e66df31256fac5c58b056a49ffe0c23e8e583944e0252529b1c8438fbd22be0d89d5838bc023097bb353188a830dc1a280a0d36ad045d0691354f4a3cdf06724101be6bc23a3f90ad62b7eb699b215644326e61c546068bb46871cc5007e81aa117c1538a9297e803ff05b1f631d15791d5f3e179718a3a752649ef7c13f4e03f0390117a7e8542930b0d81da721a28e246a451c995bcc2f6a1961b56c6e0c030563068b32b6a97b404c884d9430e60d070354accd59c9e4e01f816c149898241f7f42e8724c0af7e5e84b28c9d830add2ab94c78dc474e06ca84d444267d37c86697615396cd4c74e95815fafd25e0f96ea952a9d2de0fbb646e83bf25147ed597df42";
Expand Down
15 changes: 10 additions & 5 deletions node/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
use async_trait::async_trait;
use dusk_bls12_381_sign::PublicKey as BlsPublicKey;
use dusk_consensus::{
contract_state::CallParams, user::provisioners::Provisioners,
contract_state::CallParams, contract_state::VerificationOutput,
user::provisioners::Provisioners,
};
use node_data::ledger::{Block, SpentTransaction, Transaction};

Expand All @@ -19,23 +20,27 @@ pub trait VMExecution: Send + Sync + 'static {
&self,
params: CallParams,
txs: I,
) -> anyhow::Result<(Vec<SpentTransaction>, Vec<Transaction>, [u8; 32])>;
) -> anyhow::Result<(
Vec<SpentTransaction>,
Vec<Transaction>,
VerificationOutput,
)>;

fn verify_state_transition(
&self,
params: &CallParams,
txs: Vec<Transaction>,
) -> anyhow::Result<[u8; 32]>;
) -> anyhow::Result<VerificationOutput>;

fn accept(
&self,
blk: &Block,
) -> anyhow::Result<(Vec<SpentTransaction>, [u8; 32])>;
) -> anyhow::Result<(Vec<SpentTransaction>, VerificationOutput)>;

fn finalize(
&self,
blk: &Block,
) -> anyhow::Result<(Vec<SpentTransaction>, [u8; 32])>;
) -> anyhow::Result<(Vec<SpentTransaction>, VerificationOutput)>;

fn preverify(&self, tx: &Transaction) -> anyhow::Result<()>;

Expand Down
1 change: 1 addition & 0 deletions rusk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ dirs = "4"
dusk-schnorr = "0.13"
dusk-poseidon = "0.30"
poseidon-merkle = { version = "0.2.1-rc.0", features = ["rkyv-impl", "size_32"] }
sha3 = "0.10"
dusk-plonk = "0.14"
dusk-bls12_381 = "0.11"
dusk-bls12_381-sign = "0.4"
Expand Down
10 changes: 7 additions & 3 deletions rusk/src/lib/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use std::{fmt, io};

use dusk_bls12_381::BlsScalar;
use dusk_consensus::contract_state::VerificationOutput;
use rusk_abi::dusk::Dusk;

#[derive(Debug)]
Expand Down Expand Up @@ -44,7 +45,7 @@ pub enum Error {
/// Proof creation error
ProofCreation(rusk_prover::ProverError),
/// Failed to produce proper state
InconsistentState([u8; 32]),
InconsistentState(VerificationOutput),
/// Other
Other(Box<dyn std::error::Error>),
}
Expand Down Expand Up @@ -129,8 +130,11 @@ impl fmt::Display for Error {
Error::ProofCreation(e) => {
write!(f, "Proof creation error: {e}")
}
Error::InconsistentState(state_root) => {
write!(f, "Inconsistent state root {}", hex::encode(state_root))
Error::InconsistentState(verification_output) => {
write!(
f,
"Inconsistent state verification data {verification_output}",
)
}
}
}
Expand Down
Loading

0 comments on commit b3e849d

Please sign in to comment.