Skip to content

Commit

Permalink
Decode new ink! events with signature topic (#1184)
Browse files Browse the repository at this point in the history
* Cargo.lock

* Decode contract event based on signature topic

* Fmt

* Cargo.lock

* Cargo.lock

* Update decode command to accept event signature

* Update substrate deps to fix conflict with `subtle`

* Fix transcode tests compilation

* Fix up decode integration test

* Use ink deps release

* Cargo.lock

* Cargo.lock

* reorder
  • Loading branch information
ascjones committed Sep 11, 2023
1 parent a0c063b commit 9a67ad4
Show file tree
Hide file tree
Showing 9 changed files with 324 additions and 494 deletions.
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

0 comments on commit 9a67ad4

Please sign in to comment.