Skip to content

Commit

Permalink
Merge #4370
Browse files Browse the repository at this point in the history
4370: Contract level messages r=alsrdn a=alsrdn

Contract level messages are a facility that enable a smart contract to emit a message while executing, which eventually gets sent on the event stream and is visible from outside the network.

This PR introduces 2 new FFIs that allow contracts to manage message topics and emit messages.
Messages are sent out through `DeployProcessed` SSE events.

Co-authored-by: Alexandru Sardan <alexandru@casperlabs.io>
Co-authored-by: Joe Sacher <321623+sacherjj@users.noreply.github.com>
Co-authored-by: Luca B <93586856+bradjohnl@users.noreply.github.com>
  • Loading branch information
4 people authored Nov 3, 2023
2 parents 381ebcc + dbc56fe commit 390a56e
Show file tree
Hide file tree
Showing 84 changed files with 3,970 additions and 252 deletions.
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 73 additions & 16 deletions execution_engine/src/engine_state/execution_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::collections::VecDeque;

use casper_types::{
bytesrepr::FromBytes,
contract_messages::Messages,
execution::{Effects, ExecutionResultV2 as TypesExecutionResult, Transform, TransformKind},
CLTyped, CLValue, Gas, Key, Motes, StoredValue, TransferAddr,
};
Expand All @@ -25,6 +26,8 @@ pub enum ExecutionResult {
cost: Gas,
/// Execution effects.
effects: Effects,
/// Messages emitted during execution.
messages: Messages,
},
/// Execution was finished successfully
Success {
Expand All @@ -34,6 +37,8 @@ pub enum ExecutionResult {
cost: Gas,
/// Execution effects.
effects: Effects,
/// Messages emitted during execution.
messages: Messages,
},
}

Expand All @@ -60,6 +65,7 @@ impl ExecutionResult {
transfers: Vec::default(),
cost: Gas::default(),
effects: Effects::new(),
messages: Vec::default(),
}
}

Expand Down Expand Up @@ -127,19 +133,25 @@ impl ExecutionResult {
error,
transfers,
effects,
messages,
..
} => ExecutionResult::Failure {
error,
transfers,
cost,
effects,
messages,
},
ExecutionResult::Success {
transfers, effects, ..
transfers,
effects,
messages,
..
} => ExecutionResult::Success {
transfers,
cost,
effects,
messages,
},
}
}
Expand All @@ -154,17 +166,25 @@ impl ExecutionResult {
error,
cost,
effects,
messages,
..
} => ExecutionResult::Failure {
error,
transfers,
cost,
effects,
messages,
},
ExecutionResult::Success { cost, effects, .. } => ExecutionResult::Success {
ExecutionResult::Success {
cost,
effects,
messages,
..
} => ExecutionResult::Success {
transfers,
cost,
effects,
messages,
},
}
}
Expand All @@ -180,20 +200,24 @@ impl ExecutionResult {
transfers,
cost,
effects: _,
messages,
} => ExecutionResult::Failure {
error,
transfers,
cost,
effects,
messages,
},
ExecutionResult::Success {
transfers,
cost,
effects: _,
messages,
} => ExecutionResult::Success {
transfers,
cost,
effects,
messages,
},
}
}
Expand Down Expand Up @@ -291,6 +315,7 @@ impl ExecutionResult {
effects,
transfers,
cost: gas_cost,
messages: Vec::default(),
})
}

Expand All @@ -305,28 +330,44 @@ impl ExecutionResult {
}
}

impl From<ExecutionResult> for TypesExecutionResult {
/// A versioned execution result and the messages produced by that execution.
pub struct ExecutionResultAndMessages {
/// Execution result
pub execution_result: TypesExecutionResult,
/// Messages emitted during execution
pub messages: Messages,
}

impl From<ExecutionResult> for ExecutionResultAndMessages {
fn from(execution_result: ExecutionResult) -> Self {
match execution_result {
ExecutionResult::Success {
transfers,
cost,
effects,
} => TypesExecutionResult::Success {
effects,
transfers,
cost: cost.value(),
messages,
} => ExecutionResultAndMessages {
execution_result: TypesExecutionResult::Success {
effects,
transfers,
cost: cost.value(),
},
messages,
},
ExecutionResult::Failure {
error,
transfers,
cost,
effects,
} => TypesExecutionResult::Failure {
effects,
transfers,
cost: cost.value(),
error_message: error.to_string(),
messages,
} => ExecutionResultAndMessages {
execution_result: TypesExecutionResult::Failure {
effects,
transfers,
cost: cost.value(),
error_message: error.to_string(),
},
messages,
},
}
}
Expand Down Expand Up @@ -422,9 +463,11 @@ impl ExecutionResultBuilder {
let mut transfers = self.transfers();
let cost = self.total_cost();

let mut all_effects = match self.payment_execution_result {
let (mut all_effects, mut all_messages) = match self.payment_execution_result {
Some(result @ ExecutionResult::Failure { .. }) => return Ok(result),
Some(ExecutionResult::Success { effects, .. }) => effects,
Some(ExecutionResult::Success {
effects, messages, ..
}) => (effects, messages),
None => return Err(ExecutionResultBuilderError::MissingPaymentExecutionResult),
};

Expand All @@ -436,11 +479,18 @@ impl ExecutionResultBuilder {
transfers: session_transfers,
effects: _,
cost: _,
messages,
}) => {
error = Some(session_error);
transfers = session_transfers;
all_messages.extend(messages);
}
Some(ExecutionResult::Success {
effects, messages, ..
}) => {
all_effects.append(effects);
all_messages.extend(messages);
}
Some(ExecutionResult::Success { effects, .. }) => all_effects.append(effects),
None => return Err(ExecutionResultBuilderError::MissingSessionExecutionResult),
};

Expand All @@ -451,7 +501,12 @@ impl ExecutionResultBuilder {
error::Error::Finalization,
));
}
Some(ExecutionResult::Success { effects, .. }) => all_effects.append(effects),
Some(ExecutionResult::Success {
effects, messages, ..
}) => {
all_effects.append(effects);
all_messages.extend(messages);
}
None => return Err(ExecutionResultBuilderError::MissingFinalizeExecutionResult),
}

Expand All @@ -460,12 +515,14 @@ impl ExecutionResultBuilder {
transfers,
cost,
effects: all_effects,
messages: all_messages,
}),
Some(error) => Ok(ExecutionResult::Failure {
error,
transfers,
cost,
effects: all_effects,
messages: all_messages,
}),
}
}
Expand Down
3 changes: 2 additions & 1 deletion execution_engine/src/engine_state/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize};

use casper_storage::global_state::state::StateProvider;
use casper_types::{
addressable_entity::{ActionThresholds, NamedKeys},
addressable_entity::{ActionThresholds, MessageTopics, NamedKeys},
execution::Effects,
package::{EntityVersions, Groups, PackageKind, PackageStatus},
system::{
Expand Down Expand Up @@ -1152,6 +1152,7 @@ where
main_purse,
associated_keys,
ActionThresholds::default(),
MessageTopics::default(),
);

let access_key = self
Expand Down
12 changes: 10 additions & 2 deletions execution_engine/src/engine_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use casper_storage::{

use casper_types::{
account::{Account, AccountHash},
addressable_entity::{AssociatedKeys, NamedKeys},
addressable_entity::{AssociatedKeys, MessageTopics, NamedKeys},
bytesrepr::ToBytes,
execution::Effects,
package::{EntityVersions, Groups, PackageKind, PackageKindTag, PackageStatus},
Expand Down Expand Up @@ -822,6 +822,7 @@ where
account.main_purse(),
associated_keys,
account.action_thresholds().clone().into(),
MessageTopics::default(),
);

let access_key = generator.new_uref(AccessRights::READ_ADD_WRITE);
Expand Down Expand Up @@ -2630,11 +2631,13 @@ fn log_execution_result(preamble: &'static str, result: &ExecutionResult) {
transfers,
cost,
effects,
messages,
} => {
debug!(
%cost,
transfer_count = %transfers.len(),
transforms_count = %effects.len(),
messages_count = %messages.len(),
"{}: execution success",
preamble
);
Expand All @@ -2644,12 +2647,14 @@ fn log_execution_result(preamble: &'static str, result: &ExecutionResult) {
transfers,
cost,
effects,
messages,
} => {
debug!(
%error,
%cost,
transfer_count = %transfers.len(),
transforms_count = %effects.len(),
messages_count = %messages.len(),
"{}: execution failure",
preamble
);
Expand All @@ -2664,6 +2669,7 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool
transfers: _,
cost: _,
effects: _,
messages: _,
} => match error {
Error::Exec(err) => match err {
ExecError::WasmPreprocessing(_) | ExecError::UnsupportedWasmStart => true,
Expand Down Expand Up @@ -2718,7 +2724,9 @@ fn should_charge_for_errors_in_wasm(execution_result: &ExecutionResult) -> bool
| ExecError::UnexpectedKeyVariant(_)
| ExecError::InvalidPackageKind(_)
| ExecError::Transform(_)
| ExecError::InvalidEntryPointType => false,
| ExecError::InvalidEntryPointType
| ExecError::InvalidMessageTopicOperation
| ExecError::InvalidUtf8Encoding(_) => false,
ExecError::DisabledUnrestrictedTransfers => false,
},
Error::WasmPreprocessing(_) => true,
Expand Down
4 changes: 3 additions & 1 deletion execution_engine/src/engine_state/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use thiserror::Error;

use casper_storage::global_state::state::StateProvider;
use casper_types::{
addressable_entity::{ActionThresholds, AssociatedKeys, NamedKeys, Weight},
addressable_entity::{ActionThresholds, AssociatedKeys, MessageTopics, NamedKeys, Weight},
bytesrepr::{self, ToBytes},
execution::Effects,
package::{EntityVersions, Groups, PackageKind, PackageKindTag, PackageStatus},
Expand Down Expand Up @@ -151,6 +151,7 @@ where
URef::default(),
AssociatedKeys::default(),
ActionThresholds::default(),
MessageTopics::default(),
);

let byte_code_key =
Expand Down Expand Up @@ -297,6 +298,7 @@ where
main_purse,
associated_keys,
ActionThresholds::default(),
MessageTopics::default(),
);

let access_key = address_generator.new_uref(AccessRights::READ_ADD_WRITE);
Expand Down
Loading

0 comments on commit 390a56e

Please sign in to comment.