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

Decode new ink! events with signature topic #1184

Merged
merged 15 commits into from
Sep 11, 2023
620 changes: 194 additions & 426 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions crates/build/templates/new/_Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@ authors = ["[your_name] <[your_email]>"]
edition = "2021"

[dependencies]
ink = { version = "4.3.0", default-features = false }
ink = { version = "5.0.0-alpha", default-features = false }

scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true }

[dev-dependencies]
ink_e2e = "4.3.0"

[lib]
path = "lib.rs"

Expand Down
7 changes: 4 additions & 3 deletions crates/cargo-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ contract-metadata = { version = "4.0.0-alpha", path = "../metadata" }

anyhow = "1.0.75"
clap = { version = "4.4.2", features = ["derive", "env"] }
primitive-types = { version = "0.12.1", default-features = false, features = ["codec", "scale-info", "serde"] }
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
which = "4.4.2"
Expand All @@ -39,9 +40,9 @@ semver = "1.0"
# dependencies for extrinsics (deploying and calling a contract)
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
subxt = "0.31.0"
sp-core = "21.0.0"
sp-weights = "20.0.0"
pallet-contracts-primitives = "24.0.0"
sp-core = "22.0.0"
sp-weights = "21.0.0"
pallet-contracts-primitives = "25.0.0"
hex = "0.4.3"

[build-dependencies]
Expand Down
71 changes: 51 additions & 20 deletions crates/cargo-contract/src/cmd/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,58 @@ use anyhow::{
Context,
Result,
};
use clap::{
Args,
Subcommand,
};
use colored::Colorize as _;
use contract_build::{
util,
CrateMetadata,
};
use contract_transcode::ContractMessageTranscoder;

#[derive(Debug, Clone, clap::Args)]
#[clap(
name = "decode",
about = "Decodes the input or output data of a contract"
)]
#[derive(Debug, Args)]
pub struct DecodeCommand {
/// The type of data to encode.
#[clap(value_enum, short, long)]
r#type: DataType,
#[clap(subcommand)]
commands: DecodeCommands,
}

#[derive(Debug, Subcommand)]
pub enum DecodeCommands {
#[clap(name = "message")]
Message(DecodeMessage),
/// Upload contract code
#[clap(name = "constructor")]
Constructor(DecodeConstructor),
/// Instantiate a contract
#[clap(name = "event")]
Event(DecodeEvent),
}

#[derive(Debug, Clone, Args)]
pub struct DecodeMessage {
/// The data to decode; this has to be a hex value starting with `0x`.
#[clap(short, long)]
data: String,
}

#[derive(Debug, Clone, Args)]
pub struct DecodeConstructor {
/// The data to decode; this has to be a hex value starting with `0x`.
#[clap(short, long)]
data: String,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
enum DataType {
Event,
Message,
Constructor,
#[derive(Debug, Clone, Args)]
pub struct DecodeEvent {
/// The signature topic of the event to be decoded; this has to be a hex value
/// starting with `0x`.
#[clap(short, long)]
signature_topic: String,
/// The data to decode; this has to be a hex value starting with `0x`.
#[clap(short, long)]
data: String,
}

impl DecodeCommand {
Expand All @@ -54,20 +80,25 @@ impl DecodeCommand {
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;

const ERR_MSG: &str = "Failed to decode specified data as a hex value";
let decoded_data = match self.r#type {
DataType::Event => {
let decoded_data = match &self.commands {
DecodeCommands::Event(event) => {
let signature_topic_data =
util::decode_hex(&event.signature_topic).context(ERR_MSG)?;
let signature_topic =
primitive_types::H256::from_slice(&signature_topic_data);
transcoder.decode_contract_event(
&mut &util::decode_hex(&self.data).context(ERR_MSG)?[..],
&signature_topic,
&mut &util::decode_hex(&event.data).context(ERR_MSG)?[..],
)?
}
DataType::Message => {
DecodeCommands::Message(message) => {
transcoder.decode_contract_message(
&mut &util::decode_hex(&self.data).context(ERR_MSG)?[..],
&mut &util::decode_hex(&message.data).context(ERR_MSG)?[..],
)?
}
DataType::Constructor => {
DecodeCommands::Constructor(constructor) => {
transcoder.decode_contract_constructor(
&mut &util::decode_hex(&self.data).context(ERR_MSG)?[..],
&mut &util::decode_hex(&constructor.data).context(ERR_MSG)?[..],
)?
}
};
Expand Down
28 changes: 14 additions & 14 deletions crates/cargo-contract/tests/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,9 @@ fn decode_works() {
// message data is being decoded properly
cargo_contract(&project_dir)
.arg("decode")
.arg("message")
.arg("--data")
.arg(msg_data)
.arg("-t")
.arg("message")
.assert()
.success()
.stdout(predicates::str::contains(msg_decoded));
Expand All @@ -98,42 +97,45 @@ fn decode_works() {
// wrong message data is being handled properly
cargo_contract(&project_dir)
.arg("decode")
.arg("message")
.arg("--data")
.arg(wrong_msg_data)
.arg("-t")
.arg("message")
.assert()
.failure()
.stderr(predicates::str::contains(error_msg));

// when
let event_data: &str = "080001";
let signature_topic =
"325c98ff66bd0d9d1c10789ae1f2a17bdfb2dcf6aa3d8092669afafdef1cb72d";
let event_data: &str = "0001";
let event_decoded: &str = r#"Switched { new_value: true }"#;

// then
// event data is being decoded properly
cargo_contract(&project_dir)
.arg("decode")
.arg("event")
.arg("--signature-topic")
.arg(signature_topic)
.arg("--data")
.arg(event_data)
.arg("-t")
.arg("event")
.assert()
.success()
.stdout(predicates::str::contains(event_decoded));

// and when
let wrong_event_data: &str = "0800010C";
let wrong_event_data: &str = "00010C";
let error_msg: &str = "input length was longer than expected by 1 byte(s).\nManaged to decode `Switched`, `new_value` but `0C` bytes were left unread";

// then
// wrong event data is being handled properly
cargo_contract(&project_dir)
.arg("decode")
.arg("event")
.arg("--signature-topic")
.arg(signature_topic)
.arg("--data")
.arg(wrong_event_data)
.arg("-t")
.arg("event")
.assert()
.failure()
.stderr(predicates::str::contains(error_msg));
Expand All @@ -146,10 +148,9 @@ fn decode_works() {
// constructor data is being decoded properly
cargo_contract(&project_dir)
.arg("decode")
.arg("constructor")
.arg("-d")
.arg(constructor_data)
.arg("-t")
.arg("constructor")
.assert()
.success()
.stdout(predicates::str::contains(constructor_decoded));
Expand All @@ -162,10 +163,9 @@ fn decode_works() {
// wrong constructor data is being handled properly
cargo_contract(&project_dir)
.arg("decode")
.arg("constructor")
.arg("-d")
.arg(wrong_constructor_data)
.arg("-t")
.arg("constructor")
.assert()
.failure()
.stderr(predicates::str::contains(error_msg));
Expand Down
8 changes: 4 additions & 4 deletions crates/extrinsics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ serde_json = "1.0.105"
url = { version = "2.4.1", features = ["serde"] }
rust_decimal = "1.32"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
sp-core = "21.0.0"
sp-runtime = "24.0.0"
sp-weights = "20.0.0"
pallet-contracts-primitives = "24.0.0"
sp-core = "22.0.0"
sp-runtime = "25.0.0"
sp-weights = "21.0.0"
pallet-contracts-primitives = "25.0.0"
scale-info = "2.8.0"
subxt = "0.31.0"
subxt-signer = { version = "0.31.0", features = ["subxt", "sr25519"] }
Expand Down
24 changes: 16 additions & 8 deletions crates/extrinsics/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ impl DisplayEvents {
};

let event_data = &mut event.field_bytes();
let event_sig_topic = event.topics().iter().next();
let mut unnamed_field_name = 0;
for field_metadata in event_fields {
if <ContractEmitted as StaticEvent>::is_event(
Expand All @@ -121,6 +122,7 @@ impl DisplayEvents {
let field = contract_event_data_field(
transcoder,
field_metadata,
event_sig_topic,
event_data,
)?;
event_entry.fields.push(field);
Expand Down Expand Up @@ -212,18 +214,24 @@ impl DisplayEvents {
fn contract_event_data_field(
transcoder: Option<&ContractMessageTranscoder>,
field_metadata: &scale_info::Field<PortableForm>,
event_sig_topic: Option<&sp_core::H256>,
event_data: &mut &[u8],
) -> Result<Field> {
let event_value = if let Some(transcoder) = transcoder {
match transcoder.decode_contract_event(event_data) {
Ok(contract_event) => contract_event,
Err(err) => {
tracing::warn!(
"Decoding contract event failed: {:?}. It might have come from another contract.",
err
);
Value::Hex(Hex::from_str(&hex::encode(&event_data))?)
if let Some(event_sig_topic) = event_sig_topic {
match transcoder.decode_contract_event(event_sig_topic, event_data) {
Ok(contract_event) => contract_event,
Err(err) => {
tracing::warn!(
"Decoding contract event failed: {:?}. It might have come from another contract.",
err
);
Value::Hex(Hex::from_str(&hex::encode(&event_data))?)
}
}
} else {
tracing::info!("Anonymous event not decoded. Data displayed as raw hex.");
Value::Hex(Hex::from_str(&hex::encode(event_data))?)
}
} else {
Value::Hex(Hex::from_str(&hex::encode(event_data))?)
Expand Down
6 changes: 3 additions & 3 deletions crates/transcode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ contract-metadata = { version = "4.0.0-alpha", path = "../metadata" }
escape8259 = "0.5.2"
hex = "0.4.3"
indexmap = "2.0.0"
ink_env = "4.3.0"
ink_metadata = "4.3.0"
ink_env = "5.0.0-alpha"
ink_metadata = "5.0.0-alpha"
itertools = "0.11.0"
tracing = "0.1.37"
nom = "7.1.3"
Expand All @@ -40,7 +40,7 @@ strsim = "0.10.0"

[dev-dependencies]
assert_matches = "1.5.0"
ink = "4.3.0"
ink = "5.0.0-alpha"
sp-core = "22.0.0"
sp-keyring = "25.0.0"

Expand Down
Loading
Loading