Skip to content

Commit

Permalink
Backport SignextLowering #1189 + #1280 (#1286)
Browse files Browse the repository at this point in the history
* Add `SignextLowering` pass to `wasm-opt` (#1280)

* Add `SignextLowering` pass to `wasm-opt`

* Remove check for Rust version

(cherry picked from commit 756aa38)

* Update wasm-opt

* Cargo.lock

* Enable Wasm sign_ext (#1189)

* Enable Wasm sign_ext

* Bump substrate crates

* Add warning when building with new rustc

* Stable toolchain

* Revert "Stable toolchain"

This reverts commit aa2a2e6.

---------

Co-authored-by: Andrew Jones <ascjones@gmail.com>

* Cargo.lock

* Remove version check

* WIP updating subxt

* Updating subxt

---------

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
  • Loading branch information
ascjones and athei authored Aug 22, 2023
1 parent c746b0d commit 8a8f0cb
Show file tree
Hide file tree
Showing 14 changed files with 1,038 additions and 330 deletions.
1,210 changes: 949 additions & 261 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions crates/build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ rustc_version = "0.4.0"
scale = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] }
toml = "0.7.3"
tracing = "0.1.37"
parity-wasm = "0.45.0"
parity-wasm = { version = "0.45.0", features = ["sign_ext"] }
semver = { version = "1.0.17", features = ["serde"] }
serde = { version = "1", default-features = false, features = ["derive"] }
serde_json = "1.0.96"
tempfile = "3.5.0"
term_size = "0.3.2"
url = { version = "2.3.1", features = ["serde"] }
wasm-opt = "0.112.0"
wasm-opt = "0.113.0"
which = "4.4.0"
zip = { version = "0.6.6", default-features = false }
strum = { version = "0.24", features = ["derive"] }
Expand Down
1 change: 1 addition & 0 deletions crates/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ fn exec_cargo_for_onchain_target(
// Allow nightly features on a stable toolchain
env.push(("RUSTC_BOOTSTRAP", Some("1".to_string())))
}

// the linker needs our linker script as file
let rustflags = target.rustflags();
if matches!(target, Target::RiscV) {
Expand Down
16 changes: 12 additions & 4 deletions crates/build/src/wasm_opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

use anyhow::Result;
use wasm_opt::OptimizationOptions;
use wasm_opt::{
Feature,
OptimizationOptions,
Pass,
};

use std::{
fmt,
Expand Down Expand Up @@ -65,10 +69,14 @@ impl WasmOptHandler {
);

OptimizationOptions::from(self.optimization_level)
// Binaryen (and wasm-opt) now enables the `SignExt` and `MutableGlobals`
// features by default, so we want to disable those for now since
// `pallet-contracts` still needs to enable these.
.mvp_features_only()
// Since rustc 1.70 `SignExt` can't be disabled anymore. Hence we have to allow it,
// in order that the Wasm binary containing these instructions can be loaded.
.enable_feature(Feature::SignExt)
// This pass will then remove any `signext` instructions in order that the resulting
// Wasm binary is compatible with older versions of `pallet-contracts` which do not
// support the `signext` instruction.
.add_pass(Pass::SignextLowering)
// the memory in our module is imported, `wasm-opt` needs to be told that
// the memory is initialized to zeroes, otherwise it won't run the
// memory-packing pre-pass.
Expand Down
11 changes: 6 additions & 5 deletions crates/cargo-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ rust_decimal = "1.29"

# dependencies for extrinsics (deploying and calling a contract)
async-std = { version = "1.12.0", features = ["attributes", "tokio1"] }
sp-core = "20.0.0"
sp-runtime = "23.0.0"
sp-weights = "19.0.0"
pallet-contracts-primitives = "23.0.0"
sp-core = "21.0.0"
sp-runtime = "24.0.0"
sp-weights = "20.0.0"
pallet-contracts-primitives = "24.0.0"
scale-info = "2.7.0"
subxt = "0.28.0"
subxt = "0.30.1"
subxt-signer = { version = "0.30.1", features = ["subxt", "sr25519"] }
hex = "0.4.3"
jsonrpsee = { version = "0.18.2", features = ["ws-client"] }

Expand Down
15 changes: 8 additions & 7 deletions crates/cargo-contract/src/cmd/extrinsics/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

use super::{
account_id,
display_contract_exec_result,
prompt_confirm_tx,
state_call,
Expand All @@ -24,7 +25,6 @@ use super::{
ContractMessageTranscoder,
DefaultConfig,
ExtrinsicOpts,
PairSigner,
StorageDeposit,
TokenMetadata,
MAX_KEY_COL_WIDTH,
Expand Down Expand Up @@ -61,6 +61,7 @@ use subxt::{
Config,
OnlineClient,
};
use subxt_signer::sr25519::Keypair;

#[derive(Debug, clap::Args)]
#[clap(name = "call", about = "Call a contract")]
Expand Down Expand Up @@ -106,7 +107,7 @@ impl CallCommand {
let call_data = transcoder.encode(&self.message, &self.args)?;
tracing::debug!("Message data: {:?}", hex::encode(&call_data));

let signer = super::pair_signer(self.extrinsic_opts.signer()?);
let signer = self.extrinsic_opts.signer()?;

async_std::task::block_on(async {
let url = self.extrinsic_opts.url_to_string();
Expand Down Expand Up @@ -168,8 +169,8 @@ impl CallCommand {
&self,
input_data: Vec<u8>,
client: &Client,
signer: &PairSigner,
) -> Result<ContractExecResult<Balance>> {
signer: &Keypair,
) -> Result<ContractExecResult<Balance, ()>> {
let url = self.extrinsic_opts.url_to_string();
let token_metadata = TokenMetadata::query(client).await?;
let storage_deposit_limit = self
Expand All @@ -179,7 +180,7 @@ impl CallCommand {
.map(|bv| bv.denominate_balance(&token_metadata))
.transpose()?;
let call_request = CallRequest {
origin: signer.account_id().clone(),
origin: account_id(signer),
dest: self.contract.clone(),
value: self.value.denominate_balance(&token_metadata)?,
gas_limit: None,
Expand All @@ -193,7 +194,7 @@ impl CallCommand {
&self,
client: &Client,
data: Vec<u8>,
signer: &PairSigner,
signer: &Keypair,
transcoder: &ContractMessageTranscoder,
) -> Result<(), ErrorVariant> {
tracing::debug!("calling contract {:?}", self.contract);
Expand Down Expand Up @@ -245,7 +246,7 @@ impl CallCommand {
&self,
client: &Client,
data: Vec<u8>,
signer: &PairSigner,
signer: &Keypair,
) -> Result<Weight> {
if self.extrinsic_opts.skip_dry_run {
return match (self.gas_limit, self.proof_size) {
Expand Down
18 changes: 11 additions & 7 deletions crates/cargo-contract/src/cmd/extrinsics/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ impl From<subxt::Error> for ErrorVariant {
.details()
.map(|details| {
ErrorVariant::Module(ModuleError {
pallet: details.pallet().to_string(),
error: details.error().to_string(),
docs: details.docs().to_vec(),
pallet: details.pallet.name().to_string(),
error: details.variant.name.to_string(),
docs: details.variant.docs.clone(),
})
})
.unwrap_or_else(|err| {
Expand Down Expand Up @@ -91,11 +91,15 @@ impl ErrorVariant {
) -> anyhow::Result<ErrorVariant> {
match error {
DispatchError::Module(err) => {
let details = metadata.error(err.index, err.error[0])?;
let pallet = metadata.pallet_by_index_err(err.index)?;
let variant =
pallet.error_variant_by_index(err.error[0]).ok_or_else(|| {
anyhow::anyhow!("Error variant {} not found", err.error[0])
})?;
Ok(ErrorVariant::Module(ModuleError {
pallet: details.pallet().to_owned(),
error: details.error().to_owned(),
docs: details.docs().to_owned(),
pallet: pallet.name().to_string(),
error: variant.name.to_owned(),
docs: variant.docs.to_owned(),
}))
}
err => {
Expand Down
16 changes: 9 additions & 7 deletions crates/cargo-contract/src/cmd/extrinsics/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,20 @@ impl DisplayEvents {
) -> Result<DisplayEvents> {
let mut events: Vec<Event> = vec![];

let runtime_metadata = subxt_metadata.runtime_metadata();
let events_transcoder = TranscoderBuilder::new(&runtime_metadata.types)
let events_transcoder = TranscoderBuilder::new(subxt_metadata.types())
.with_default_custom_type_transcoders()
.done();

for event in result.iter() {
let event = event?;
tracing::debug!("displaying event {:?}", event);
tracing::debug!(
"displaying event {}:{}",
event.pallet_name(),
event.variant_name()
);

let event_metadata =
subxt_metadata.event(event.pallet_index(), event.variant_index())?;
let event_fields = event_metadata.fields();
let event_metadata = event.event_metadata();
let event_fields = &event_metadata.variant.fields;

let mut event_entry = Event {
pallet: event.pallet_name().to_string(),
Expand Down Expand Up @@ -136,7 +138,7 @@ impl DisplayEvents {
});

let decoded_field = events_transcoder.decode(
&runtime_metadata.types,
subxt_metadata.types(),
field_metadata.ty.id,
event_data,
)?;
Expand Down
14 changes: 8 additions & 6 deletions crates/cargo-contract/src/cmd/extrinsics/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

use super::{
account_id,
display_contract_exec_result,
prompt_confirm_tx,
state_call,
Expand All @@ -24,7 +25,6 @@ use super::{
ContractMessageTranscoder,
DefaultConfig,
ExtrinsicOpts,
PairSigner,
StorageDeposit,
MAX_KEY_COL_WIDTH,
};
Expand Down Expand Up @@ -63,6 +63,7 @@ use subxt::{
Config,
OnlineClient,
};
use subxt_signer::sr25519::Keypair;

#[derive(Debug, clap::Args)]
pub struct InstantiateCommand {
Expand Down Expand Up @@ -114,7 +115,7 @@ impl InstantiateCommand {
let artifacts = self.extrinsic_opts.contract_artifacts()?;
let transcoder = artifacts.contract_transcoder()?;
let data = transcoder.encode(&self.constructor, &self.args)?;
let signer = super::pair_signer(self.extrinsic_opts.signer()?);
let signer = self.extrinsic_opts.signer()?;
let url = self.extrinsic_opts.url_to_string();
let verbosity = self.extrinsic_opts.verbosity()?;
let code = if let Some(code) = artifacts.code {
Expand Down Expand Up @@ -187,7 +188,7 @@ pub struct Exec {
verbosity: Verbosity,
url: String,
client: Client,
signer: PairSigner,
signer: Keypair,
transcoder: ContractMessageTranscoder,
output_json: bool,
}
Expand Down Expand Up @@ -353,11 +354,12 @@ impl Exec {

async fn instantiate_dry_run(
&self,
) -> Result<ContractInstantiateResult<<DefaultConfig as Config>::AccountId, Balance>>
{
) -> Result<
ContractInstantiateResult<<DefaultConfig as Config>::AccountId, Balance, ()>,
> {
let storage_deposit_limit = self.args.storage_deposit_limit;
let call_request = InstantiateRequest {
origin: self.signer.account_id().clone(),
origin: account_id(&self.signer),
value: self.args.value,
gas_limit: None,
storage_deposit_limit,
Expand Down
40 changes: 20 additions & 20 deletions crates/cargo-contract/src/cmd/extrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,20 @@ use scale::{
Decode,
Encode,
};
use sp_core::{
crypto::Pair,
sr25519,
Bytes,
};
use sp_core::Bytes;
use sp_weights::Weight;
use subxt::{
blocks,
config,
tx,
utils::AccountId32,
Config,
OnlineClient,
};
use subxt_signer::{
sr25519::Keypair,
SecretUri,
};

use std::{
option::Option,
Expand All @@ -97,8 +98,6 @@ pub use remove::RemoveCommand;
pub use subxt::PolkadotConfig as DefaultConfig;
pub use upload::UploadCommand;

type PairSigner = tx::PairSigner<DefaultConfig, sr25519::Pair>;

/// Arguments required for creating and sending an extrinsic to a substrate node.
#[derive(Clone, Debug, clap::Args)]
pub struct ExtrinsicOpts {
Expand All @@ -118,11 +117,12 @@ pub struct ExtrinsicOpts {
)]
url: url::Url,
/// Secret key URI for the account deploying the contract.
///
/// e.g.
/// - for a dev account "//Alice"
/// - with a password "//Alice///SECRET_PASSWORD"
#[clap(name = "suri", long, short)]
suri: String,
/// Password for the secret key.
#[clap(name = "password", long, short)]
password: Option<String>,
#[clap(flatten)]
verbosity: VerbosityFlags,
/// Submit the extrinsic for on-chain execution.
Expand Down Expand Up @@ -150,9 +150,10 @@ impl ExtrinsicOpts {
}

/// Returns the signer for contract extrinsics.
pub fn signer(&self) -> Result<sr25519::Pair> {
Pair::from_string(&self.suri, self.password.as_ref().map(String::as_ref))
.map_err(|_| anyhow::anyhow!("Secret string error"))
pub fn signer(&self) -> Result<Keypair> {
let uri = <SecretUri as std::str::FromStr>::from_str(&self.suri)?;
let keypair = Keypair::from_uri(&uri)?;
Ok(keypair)
}

/// Returns the verbosity
Expand Down Expand Up @@ -317,17 +318,17 @@ impl WasmCode {
}
}

/// Create a new [`PairSigner`] from the given [`sr25519::Pair`].
pub fn pair_signer(pair: sr25519::Pair) -> PairSigner {
PairSigner::new(pair)
/// Get the account id from the Keypair
pub fn account_id(keypair: &Keypair) -> AccountId32 {
subxt::tx::Signer::<DefaultConfig>::account_id(keypair)
}

const STORAGE_DEPOSIT_KEY: &str = "Storage Deposit";
pub const MAX_KEY_COL_WIDTH: usize = STORAGE_DEPOSIT_KEY.len() + 1;

/// Print to stdout the fields of the result of a `instantiate` or `call` dry-run via RPC.
pub fn display_contract_exec_result<R, const WIDTH: usize>(
result: &ContractResult<R, Balance>,
result: &ContractResult<R, Balance, ()>,
) -> Result<()> {
let mut debug_message_lines = std::str::from_utf8(&result.debug_message)
.context("Error decoding UTF8 debug message bytes")?
Expand All @@ -352,7 +353,7 @@ pub fn display_contract_exec_result<R, const WIDTH: usize>(
}

pub fn display_contract_exec_result_debug<R, const WIDTH: usize>(
result: &ContractResult<R, Balance>,
result: &ContractResult<R, Balance, ()>,
) -> Result<()> {
let mut debug_message_lines = std::str::from_utf8(&result.debug_message)
.context("Error decoding UTF8 debug message bytes")?
Expand Down Expand Up @@ -396,8 +397,7 @@ where
T: Config,
Call: tx::TxPayload,
Signer: tx::Signer<T>,
<T::ExtrinsicParams as config::ExtrinsicParams<T::Index, T::Hash>>::OtherParams:
Default,
<T::ExtrinsicParams as config::ExtrinsicParams<T::Hash>>::OtherParams: Default,
{
client
.tx()
Expand Down
Loading

0 comments on commit 8a8f0cb

Please sign in to comment.