Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes needed to support the modified speculative execution in the sidecar #16

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1624b7a
Update `SpeculativeExecutionResult` type
Mar 25, 2024
45ae400
Merge remote-tracking branch 'ed/feat-2.0-spicy-wip-merge' into sidec…
Mar 25, 2024
93993af
Speculative execution result now contains the block hash
Mar 26, 2024
8ea2ba0
Reenable serialization roundtrip test for 'SpeculativeExecutionResult'
Mar 26, 2024
d08823d
Merge remote-tracking branch 'ed/feat-2.0-spicy-wip-merge' into sidec…
Mar 26, 2024
59d50b9
Remove unused imports
Mar 26, 2024
c3df04c
Delay 'version' read until the value is necessary
Mar 27, 2024
3b1841e
Add 'testing' feature flag to binary port to enable sidecar testing
Mar 27, 2024
1b12c76
Merge remote-tracking branch 'ed/feat-2.0-spicy-wip-merge' into sidec…
Mar 28, 2024
ff0512f
Fixes after the merge
Mar 28, 2024
c5725cb
Update comment
Mar 28, 2024
dd2ef57
Fix feature flags
Mar 28, 2024
bdab634
Return None in case of an error in get_addressable_entity
jacek-casper Mar 28, 2024
09a5dbd
Merge remote-tracking branch 'ed/feat-2.0-integration-pr' into sideca…
Mar 29, 2024
7f694da
Update comment
Mar 29, 2024
cb09194
Expose 'Pointer' which is currently used in 'casper-test'
Mar 29, 2024
c4e0a96
Merge #4636
casperlabs-bors-ng[bot] Apr 2, 2024
9873c9c
Merge remote-tracking branch 'ed/feat-2.0-integration-pr' into sideca…
Apr 3, 2024
90cd6cf
Merge pull request #4635 from EdHastingsCasperAssociation/feat-2.0-in…
EdHastingsCasperAssociation Apr 4, 2024
74d9802
Merge remote-tracking branch 'ed/feat-2.0-integration-pr' into sideca…
Apr 4, 2024
17df109
Merge remote-tracking branch 'upstream/feat-2.0' into sidecar_related…
Apr 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions binary_port/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@ casper-types = { version = "3.0.0", path = "../types", features = ["datasize", "
serde = { version = "1.0.183", features = ["derive"] }
thiserror = "1.0.45"
serde-map-to-array = "1.1.0"
once_cell = { version = "1.5.2", optional = true }
once_cell = { version = "1.5.2" }
schemars = { version = "0.8.16", features = ["preserve_order", "impl_json_schema"] }
bincode = "1.3.3"
rand = "0.8.3"

[dev-dependencies]
casper-types = { path = "../types", features = ["datasize", "json-schema", "std", "testing"] }
rand = "0.8.3"
serde_json = "1"
serde_test = "1"

[package.metadata.docs.rs]
all-features = true
rustc-args = ["--cfg", "docsrs"]

[features]
testing = ["rand/default"]
8 changes: 4 additions & 4 deletions binary_port/src/error_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pub enum ErrorCode {
/// Root not found.
#[error("root not found")]
RootNotFound = 3,
/// Invalid deploy item variant.
#[error("invalid deploy item variant")]
/// Invalid item variant.
#[error("invalid item variant")]
InvalidItemVariant = 4,
/// Wasm preprocessing.
#[error("wasm preprocessing")]
Expand All @@ -33,8 +33,8 @@ pub enum ErrorCode {
/// Internal error.
#[error("internal error")]
InternalError = 8,
/// The query to global state failed.
#[error("the query to global state failed")]
/// The query failed.
#[error("the query failed")]
FailedQuery = 9,
/// Bad request.
#[error("bad request")]
Expand Down
99 changes: 81 additions & 18 deletions binary_port/src/speculative_execution_result.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
use once_cell::sync::Lazy;
#[cfg(any(feature = "testing", test))]
use rand::Rng;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

#[cfg(any(feature = "testing", test))]
use rand::distributions::{Alphanumeric, DistString};

#[cfg(any(feature = "testing", test))]
use casper_types::testing::TestRng;
use casper_types::{
bytesrepr::{self, FromBytes, ToBytes},
contract_messages::Messages,
execution::Effects,
Gas, InvalidTransaction, Transfer,
BlockHash, Digest, Gas, InvalidTransaction, Transfer,
};

#[derive(Debug)]
static SPECULATIVE_EXECUTION_RESULT: Lazy<SpeculativeExecutionResult> = Lazy::new(|| {
SpeculativeExecutionResult::new(
BlockHash::new(Digest::from([0; Digest::LENGTH])),
vec![],
Gas::zero(),
Gas::zero(),
Effects::new(),
Messages::new(),
None,
)
});
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, JsonSchema)]
pub struct SpeculativeExecutionResult {
/// Block hash against which the execution was performed.
block_hash: BlockHash,
/// List of transfers that happened during execution.
transfers: Vec<Transfer>,
/// Gas limit.
Expand All @@ -23,6 +47,7 @@ pub struct SpeculativeExecutionResult {

impl SpeculativeExecutionResult {
pub fn new(
block_hash: BlockHash,
transfers: Vec<Transfer>,
limit: Gas,
consumed: Gas,
Expand All @@ -37,6 +62,40 @@ impl SpeculativeExecutionResult {
effects,
messages,
error,
block_hash,
}
}

// This method is not intended to be used by third party crates.
#[doc(hidden)]
pub fn example() -> &'static Self {
&SPECULATIVE_EXECUTION_RESULT
}

#[cfg(any(feature = "testing", test))]
pub fn random(rng: &mut TestRng) -> Self {
use casper_types::contract_messages::Message;

let random_messages = |rng: &mut TestRng| -> Messages {
let count = rng.gen_range(16..128);
std::iter::repeat_with(|| Message::random(rng))
.take(count)
.collect()
};

SpeculativeExecutionResult {
block_hash: BlockHash::new(rng.gen()),
transfers: vec![Transfer::random(rng)],
limit: Gas::random(rng),
consumed: Gas::random(rng),
effects: Effects::random(rng),
messages: random_messages(rng),
error: if rng.gen() {
None
} else {
let count = rng.gen_range(16..128);
Some(Alphanumeric.sample_string(rng, count))
},
}
}
}
Expand All @@ -50,6 +109,7 @@ impl From<InvalidTransaction> for SpeculativeExecutionResult {
effects: Default::default(),
messages: Default::default(),
error: Some(format!("{}", invalid_transaction)),
block_hash: Default::default(),
}
}
}
Expand All @@ -68,6 +128,7 @@ impl ToBytes for SpeculativeExecutionResult {
+ ToBytes::serialized_length(&self.effects)
+ ToBytes::serialized_length(&self.messages)
+ ToBytes::serialized_length(&self.error)
+ ToBytes::serialized_length(&self.block_hash)
}

fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
Expand All @@ -76,7 +137,8 @@ impl ToBytes for SpeculativeExecutionResult {
self.consumed.write_bytes(writer)?;
self.effects.write_bytes(writer)?;
self.messages.write_bytes(writer)?;
self.error.write_bytes(writer)
self.error.write_bytes(writer)?;
self.block_hash.write_bytes(writer)
}
}

Expand All @@ -88,6 +150,7 @@ impl FromBytes for SpeculativeExecutionResult {
let (effects, bytes) = Effects::from_bytes(bytes)?;
let (messages, bytes) = Messages::from_bytes(bytes)?;
let (error, bytes) = Option::<String>::from_bytes(bytes)?;
let (block_hash, bytes) = BlockHash::from_bytes(bytes)?;
Ok((
SpeculativeExecutionResult {
transfers,
Expand All @@ -96,23 +159,23 @@ impl FromBytes for SpeculativeExecutionResult {
effects,
messages,
error,
block_hash,
},
bytes,
))
}
}
//
// #[cfg(test)]
// mod tests {
// // use super::*;
// // use casper_types::testing::TestRng;
//
// #[test]
// fn bytesrepr_roundtrip() {
// todo!();
// let rng = &mut TestRng::new();
//
// let val = SpeculativeExecutionResult::random(rng);
// bytesrepr::test_serialization_roundtrip(&val);
// }
// }

#[cfg(test)]
mod tests {
use super::*;
use casper_types::testing::TestRng;

#[test]
fn bytesrepr_roundtrip() {
let rng = &mut TestRng::new();

let val = SpeculativeExecutionResult::random(rng);
bytesrepr::test_serialization_roundtrip(&val);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ where
Key::addressable_entity_key(EntityKindTag::System, entity_hash),
&[],
)
.expect("must have value"),
.ok()?,
};

if let StoredValue::AddressableEntity(entity) = value {
Expand Down
2 changes: 1 addition & 1 deletion node/src/components/binary_port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,6 @@ where
+ From<ChainspecRawBytesRequest>
+ Send,
{
let version = effect_builder.get_protocol_version().await;
loop {
let Some(incoming_request) = server.next_request().await? else {
debug!("remote party closed the connection");
Expand All @@ -732,6 +731,7 @@ where
return Err(Error::NoPayload);
};

let version = effect_builder.get_protocol_version().await;
let resp = handle_payload(effect_builder, payload, version).await;
let resp_and_payload = BinaryResponseAndRequest::new(resp, payload);
incoming_request.respond(Some(Bytes::from(ToBytes::to_bytes(&resp_and_payload)?)))
Expand Down
5 changes: 4 additions & 1 deletion node/src/components/contract_runtime/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,10 @@ where
Ok(wasm_v1_request) => execution_engine_v1.execute(state_provider, wasm_v1_request),
Err(error) => WasmV1Result::invalid_executable_item(gas_limit, error),
};
SpeculativeExecutionResult::WasmV1(utils::spec_exec_from_wasm_v1_result(wasm_v1_result))
SpeculativeExecutionResult::WasmV1(utils::spec_exec_from_wasm_v1_result(
wasm_v1_result,
block_header.block_hash(),
))
}

#[allow(clippy::too_many_arguments)]
Expand Down
7 changes: 5 additions & 2 deletions node/src/components/contract_runtime/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use casper_execution_engine::engine_state::{ExecutionEngineV1, WasmV1Result};
use casper_storage::{
data_access_layer::DataAccessLayer, global_state::state::lmdb::LmdbGlobalState,
};
use casper_types::{Chainspec, EraId, Key};
use casper_types::{BlockHash, Chainspec, EraId, Key};
use once_cell::sync::Lazy;
use std::{
cmp,
Expand Down Expand Up @@ -387,6 +387,7 @@ pub(super) fn calculate_prune_eras(

pub(crate) fn spec_exec_from_wasm_v1_result(
wasm_v1_result: WasmV1Result,
block_hash: BlockHash,
) -> SpeculativeExecutionResult {
let transfers = wasm_v1_result.transfers().to_owned();
let limit = wasm_v1_result.limit().to_owned();
Expand All @@ -398,7 +399,9 @@ pub(crate) fn spec_exec_from_wasm_v1_result(
.to_owned()
.map(|err| format!("{:?}", err));

SpeculativeExecutionResult::new(transfers, limit, consumed, effects, messages, error_msg)
SpeculativeExecutionResult::new(
block_hash, transfers, limit, consumed, effects, messages, error_msg,
)
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion types/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub use block_body::{BlockBody, BlockBodyV1, BlockBodyV2};
pub use block_hash::BlockHash;
pub use block_hash_and_height::BlockHashAndHeight;
pub use block_header::{BlockHeader, BlockHeaderV1, BlockHeaderV2};
pub use block_identifier::{BlockIdentifier, ParseBlockIdentifierError};
pub use block_identifier::BlockIdentifier;
pub use block_signatures::{
BlockSignatures, BlockSignaturesMergeError, BlockSignaturesV1, BlockSignaturesV2,
};
Expand Down
60 changes: 42 additions & 18 deletions types/src/contract_messages/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ use rand::{
use schemars::JsonSchema;
use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer};

#[cfg(any(feature = "testing", test))]
use crate::testing::TestRng;

use super::{FromStrError, TopicNameHash};

/// Collection of multiple messages.
Expand Down Expand Up @@ -128,6 +131,24 @@ pub enum MessagePayload {
Bytes(Bytes),
}

impl MessagePayload {
#[cfg(any(feature = "testing", test))]
/// Returns a random `MessagePayload`.
pub fn random(rng: &mut TestRng) -> Self {
let count = rng.gen_range(16..128);
if rng.gen() {
MessagePayload::String(Alphanumeric.sample_string(rng, count))
} else {
MessagePayload::Bytes(
std::iter::repeat_with(|| rng.gen())
.take(count)
.collect::<Vec<u8>>()
.into(),
)
}
}
}

impl<T> From<T> for MessagePayload
where
T: Into<String>,
Expand Down Expand Up @@ -274,6 +295,20 @@ impl Message {

Ok(MessageChecksum(checksum))
}

/// Returns a random `Message`.
#[cfg(any(feature = "testing", test))]
pub fn random(rng: &mut TestRng) -> Self {
let count = rng.gen_range(16..128);
Self {
entity_hash: rng.gen(),
message: MessagePayload::random(rng),
topic_name: Alphanumeric.sample_string(rng, count),
topic_name_hash: rng.gen(),
topic_index: rng.gen(),
block_index: rng.gen(),
}
}
}

impl ToBytes for Message {
Expand Down Expand Up @@ -340,40 +375,29 @@ impl Distribution<Message> for Standard {

#[cfg(test)]
mod tests {
use crate::{bytesrepr, contract_messages::topics::TOPIC_NAME_HASH_LENGTH, KEY_HASH_LENGTH};
use crate::bytesrepr;

use super::*;

#[test]
fn serialization_roundtrip() {
let rng = &mut TestRng::new();

let message_checksum = MessageChecksum([1; MESSAGE_CHECKSUM_LENGTH]);
bytesrepr::test_serialization_roundtrip(&message_checksum);

let message_payload: MessagePayload = "message payload".into();
let message_payload = MessagePayload::random(rng);
bytesrepr::test_serialization_roundtrip(&message_payload);

let message_payload = MessagePayload::Bytes(vec![5u8; 128].into());
bytesrepr::test_serialization_roundtrip(&message_payload);

let message = Message::new(
EntityAddr::new_smart_contract([1; KEY_HASH_LENGTH]),
message_payload,
"test_topic".to_string(),
TopicNameHash::new([0x4du8; TOPIC_NAME_HASH_LENGTH]),
10,
111,
);
let message = Message::random(rng);
bytesrepr::test_serialization_roundtrip(&message);
}

#[test]
fn json_roundtrip() {
let message_payload: MessagePayload = "message payload".into();
let json_string = serde_json::to_string_pretty(&message_payload).unwrap();
let decoded: MessagePayload = serde_json::from_str(&json_string).unwrap();
assert_eq!(decoded, message_payload);
let rng = &mut TestRng::new();

let message_payload = MessagePayload::Bytes(vec![255u8; 32].into());
let message_payload = MessagePayload::random(rng);
let json_string = serde_json::to_string_pretty(&message_payload).unwrap();
let decoded: MessagePayload = serde_json::from_str(&json_string).unwrap();
assert_eq!(decoded, message_payload);
Expand Down
2 changes: 1 addition & 1 deletion types/src/execution/execution_result_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl FromBytes for PaymentInfo {
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[serde(deny_unknown_fields)]
pub struct ExecutionResultV2 {
/// Who initiatied this transaction.
/// Who initiated this transaction.
pub initiator: InitiatorAddr,
/// If there is no error message, this execution was processed successfully.
/// If there is an error message, this execution failed to fully process for the stated reason.
Expand Down
Loading
Loading