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

Backport SignextLowering #1189 + #1280 #1286

Merged
merged 8 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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