contracts: Add RPC that allows instantiating of a contract (#8451)

* contracts: Add RPC that allows instantiating of a contract

* Encode `debug_message` as bytes because usage of `String` is forbidden

* Remove erroneous derive attribute

* Fix rpc tests for new `debug_message` encoding

* Fix typo

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

Co-authored-by: Andrew Jones <ascjones@gmail.com>
This commit is contained in:
Alexander Theißen
2021-04-13 13:26:52 +02:00
committed by GitHub
parent 24311eee3e
commit f854194139
16 changed files with 471 additions and 191 deletions
+36 -16
View File
@@ -27,14 +27,13 @@ mod runtime;
use crate::{
CodeHash, Schedule, Config,
wasm::env_def::FunctionImplProvider,
exec::{Ext, Executable, ExportedFunction},
exec::{Ext, Executable, ExportedFunction, ExecResult},
gas::GasMeter,
};
use sp_std::prelude::*;
use sp_core::crypto::UncheckedFrom;
use codec::{Encode, Decode};
use frame_support::dispatch::DispatchError;
use pallet_contracts_primitives::ExecResult;
pub use self::runtime::{ReturnCode, Runtime, RuntimeToken};
#[cfg(feature = "runtime-benchmarks")]
pub use self::code_cache::reinstrument;
@@ -246,17 +245,20 @@ mod tests {
use super::*;
use crate::{
CodeHash, BalanceOf, Error, Pallet as Contracts,
exec::{Ext, StorageKey, AccountIdOf, Executable, SeedOf, BlockNumberOf, RentParams},
exec::{
Ext, StorageKey, AccountIdOf, Executable, SeedOf, BlockNumberOf,
RentParams, ExecError, ErrorOrigin,
},
gas::GasMeter,
tests::{Test, Call, ALICE, BOB},
};
use std::collections::HashMap;
use sp_core::H256;
use sp_core::{Bytes, H256};
use hex_literal::hex;
use sp_runtime::DispatchError;
use frame_support::{assert_ok, dispatch::DispatchResult, weights::Weight};
use assert_matches::assert_matches;
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags, ExecError, ErrorOrigin};
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
use pretty_assertions::assert_eq;
const GAS_LIMIT: Weight = 10_000_000_000;
@@ -336,7 +338,7 @@ mod tests {
Contracts::<Test>::contract_address(&ALICE, &code_hash, salt),
ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
data: Bytes(Vec::new()),
},
0,
))
@@ -367,7 +369,7 @@ mod tests {
});
// Assume for now that it was just a plain transfer.
// TODO: Add tests for different call outcomes.
Ok((ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }, 0))
Ok((ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) }, 0))
}
fn terminate(
&mut self,
@@ -946,7 +948,10 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: [0x22; 32].to_vec() });
assert_eq!(output, ExecReturnValue {
flags: ReturnFlags::empty(),
data: Bytes([0x22; 32].to_vec())
});
}
/// calls `seal_caller` and compares the result with the constant 42.
@@ -1209,7 +1214,7 @@ mod tests {
&mut gas_meter,
).unwrap();
let gas_left = Weight::decode(&mut output.data.as_slice()).unwrap();
let gas_left = Weight::decode(&mut &*output.data).unwrap();
assert!(gas_left < GAS_LIMIT, "gas_left must be less than initial");
assert!(gas_left > gas_meter.gas_left(), "gas_left must be greater than final");
}
@@ -1299,7 +1304,13 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: vec![1, 2, 3, 4] });
assert_eq!(
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: Bytes(vec![1, 2, 3, 4])
}
);
}
const CODE_TIMESTAMP_NOW: &str = r#"
@@ -1526,7 +1537,10 @@ mod tests {
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F").to_vec(),
data: Bytes(
hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F")
.to_vec()
),
},
);
}
@@ -1601,10 +1615,10 @@ mod tests {
output,
ExecReturnValue {
flags: ReturnFlags::empty(),
data: (
data: Bytes((
hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"),
42u64,
).encode(),
).encode()),
},
);
}
@@ -1837,7 +1851,10 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: hex!("445566778899").to_vec() });
assert_eq!(output, ExecReturnValue {
flags: ReturnFlags::empty(),
data: Bytes(hex!("445566778899").to_vec()),
});
assert!(output.is_success());
}
@@ -1850,7 +1867,10 @@ mod tests {
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::REVERT, data: hex!("5566778899").to_vec() });
assert_eq!(output, ExecReturnValue {
flags: ReturnFlags::REVERT,
data: Bytes(hex!("5566778899").to_vec()),
});
assert!(!output.is_success());
}
@@ -1962,7 +1982,7 @@ mod tests {
MockExt::default(),
&mut GasMeter::new(GAS_LIMIT),
).unwrap();
let rent_params = <RentParams<Test>>::default().encode();
let rent_params = Bytes(<RentParams<Test>>::default().encode());
assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: rent_params });
}
}
@@ -19,7 +19,7 @@
use crate::{
Config, CodeHash, BalanceOf, Error,
exec::{Ext, StorageKey, TopicOf},
exec::{Ext, StorageKey, TopicOf, ExecResult, ExecError},
gas::{GasMeter, Token, ChargedAmount},
wasm::env_def::ConvertibleToWasm,
schedule::HostFnWeights,
@@ -29,14 +29,14 @@ use frame_support::{dispatch::DispatchError, ensure, traits::Get, weights::Weigh
use sp_std::prelude::*;
use codec::{Decode, DecodeAll, Encode};
use sp_runtime::traits::SaturatedConversion;
use sp_core::crypto::UncheckedFrom;
use sp_core::{Bytes, crypto::UncheckedFrom};
use sp_io::hashing::{
keccak_256,
blake2_256,
blake2_128,
sha2_256,
};
use pallet_contracts_primitives::{ExecResult, ExecReturnValue, ReturnFlags, ExecError};
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
/// Every error that can be returned to a contract when it calls any of the host functions.
///
@@ -347,19 +347,19 @@ where
)?;
Ok(ExecReturnValue {
flags,
data,
data: Bytes(data),
})
},
TrapReason::Termination => {
Ok(ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
data: Bytes(Vec::new()),
})
},
TrapReason::Restoration => {
Ok(ExecReturnValue {
flags: ReturnFlags::empty(),
data: Vec::new(),
data: Bytes(Vec::new()),
})
},
TrapReason::SupervisorError(error) => Err(error)?,
@@ -370,7 +370,7 @@ where
match sandbox_result {
// No traps were generated. Proceed normally.
Ok(_) => {
Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() })
Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Bytes(Vec::new()) })
}
// `Error::Module` is returned only if instantiation or linking failed (i.e.
// wasm binary tried to import a function that is not provided by the host).
@@ -596,7 +596,7 @@ where
/// Fallible conversion of a `ExecResult` to `ReturnCode`.
fn exec_into_return_code(from: ExecResult) -> Result<ReturnCode, DispatchError> {
use pallet_contracts_primitives::ErrorOrigin::Callee;
use crate::exec::ErrorOrigin::Callee;
let ExecError { error, origin } = match from {
Ok(retval) => return Ok(retval.into()),