mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-12 19:51:03 +00:00
add runner crate (#34)
Signed-off-by: xermicus <cyrill@parity.io> Co-authored-by: xermicus <cyrill@parity.io> Co-authored-by: pgherveou <pgherveou@gmail.com>
This commit is contained in:
Generated
+8097
-48
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,8 @@ env_logger = { version = "0.10.0", default-features = false }
|
|||||||
serde_stacker = "0.1"
|
serde_stacker = "0.1"
|
||||||
criterion = { version = "0.5", features = ["html_reports"] }
|
criterion = { version = "0.5", features = ["html_reports"] }
|
||||||
log = { version = "0.4" }
|
log = { version = "0.4" }
|
||||||
|
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
|
||||||
|
scale-info = { version = "2.11.1", default-features = false }
|
||||||
|
|
||||||
# Benchmarking against EVM
|
# Benchmarking against EVM
|
||||||
primitive-types = { version = "0.12", features = ["codec"] }
|
primitive-types = { version = "0.12", features = ["codec"] }
|
||||||
@@ -47,6 +49,10 @@ version = "0.5"
|
|||||||
default-features = false
|
default-features = false
|
||||||
features = ["serde", "llvm18-0", "no-libffi-linking", "target-riscv"]
|
features = ["serde", "llvm18-0", "no-libffi-linking", "target-riscv"]
|
||||||
|
|
||||||
|
[workspace.dependencies.polkadot-sdk]
|
||||||
|
git = "https://github.com/paritytech/polkadot-sdk"
|
||||||
|
rev = "559fa1db0594a81d5dbf343613ba2f3fc16708da"
|
||||||
|
|
||||||
[profile.benchmark]
|
[profile.benchmark]
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ alloy-sol-types = { workspace = true }
|
|||||||
hex = { workspace = true }
|
hex = { workspace = true }
|
||||||
env_logger = { workspace = true }
|
env_logger = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
|
||||||
|
|
||||||
revive-solidity = { path = "../solidity" }
|
revive-solidity = { path = "../solidity" }
|
||||||
revive-differential = { path = "../differential" }
|
revive-differential = { path = "../differential" }
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use alloy_primitives::{Address, I256, U256};
|
use alloy_primitives::{Address, I256, U256};
|
||||||
use alloy_sol_types::{sol, SolCall, SolConstructor};
|
use alloy_sol_types::{sol, SolCall, SolConstructor};
|
||||||
|
|
||||||
|
use revive_solidity::test_utils::*;
|
||||||
|
|
||||||
use crate::mock_runtime::{CallOutput, State};
|
use crate::mock_runtime::{CallOutput, State};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -193,8 +195,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Baseline::baselineCall::new(()).abi_encode(),
|
calldata: Baseline::baselineCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,8 +207,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Computation::odd_productCall::new((n,)).abi_encode(),
|
calldata: Computation::odd_productCall::new((n,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,8 +219,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Computation::triangle_numberCall::new((n,)).abi_encode(),
|
calldata: Computation::triangle_numberCall::new((n,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,8 +231,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: FibonacciRecursive::fib3Call::new((U256::from(n),)).abi_encode(),
|
calldata: FibonacciRecursive::fib3Call::new((U256::from(n),)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -241,8 +243,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: FibonacciIterative::fib3Call::new((U256::from(n),)).abi_encode(),
|
calldata: FibonacciIterative::fib3Call::new((U256::from(n),)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,8 +255,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: FibonacciBinet::fib3Call::new((U256::from(n),)).abi_encode(),
|
calldata: FibonacciBinet::fib3Call::new((U256::from(n),)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,8 +267,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: SHA1::sha1Call::new((pre,)).abi_encode(),
|
calldata: SHA1::sha1Call::new((pre,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,8 +279,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Flipper::flipCall::new(()).abi_encode(),
|
calldata: Flipper::flipCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,8 +291,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Flipper::constructorCall::new((coin,)).abi_encode(),
|
calldata: Flipper::constructorCall::new((coin,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,8 +303,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: IERC20::totalSupplyCall::new(()).abi_encode(),
|
calldata: IERC20::totalSupplyCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,8 +315,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Block::numberCall::new(()).abi_encode(),
|
calldata: Block::numberCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,8 +327,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Block::timestampCall::new(()).abi_encode(),
|
calldata: Block::timestampCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,8 +339,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Context::address_thisCall::new(()).abi_encode(),
|
calldata: Context::address_thisCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,8 +351,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Context::callerCall::new(()).abi_encode(),
|
calldata: Context::callerCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,8 +363,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: DivisionArithmetics::divCall::new((n, d)).abi_encode(),
|
calldata: DivisionArithmetics::divCall::new((n, d)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,8 +375,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: DivisionArithmetics::sdivCall::new((n, d)).abi_encode(),
|
calldata: DivisionArithmetics::sdivCall::new((n, d)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,8 +387,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: DivisionArithmetics::modCall::new((n, d)).abi_encode(),
|
calldata: DivisionArithmetics::modCall::new((n, d)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,8 +399,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: DivisionArithmetics::smodCall::new((n, d)).abi_encode(),
|
calldata: DivisionArithmetics::smodCall::new((n, d)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -409,8 +411,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: MStore8::mStore8Call::new((value,)).abi_encode(),
|
calldata: MStore8::mStore8Call::new((value,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,8 +423,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Events::emitEventCall::new((topics,)).abi_encode(),
|
calldata: Events::emitEventCall::new((topics,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -433,8 +435,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: vec![0; 4],
|
calldata: vec![0; 4],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,8 +447,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: vec![0; 4],
|
calldata: vec![0; 4],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,8 +459,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: ExtCode::ExtCodeSizeCall::new((address,)).abi_encode(),
|
calldata: ExtCode::ExtCodeSizeCall::new((address,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,8 +471,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: ExtCode::CodeSizeCall::new(()).abi_encode(),
|
calldata: ExtCode::CodeSizeCall::new(()).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -481,8 +483,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: MCopy::memcpyCall::new((payload,)).abi_encode(),
|
calldata: MCopy::memcpyCall::new((payload,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,8 +495,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Call::value_transferCall::new((destination,)).abi_encode(),
|
calldata: Call::value_transferCall::new((destination,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,8 +507,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Call::callCall::new((callee, payload)).abi_encode(),
|
calldata: Call::callCall::new((callee, payload)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -517,8 +519,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Default::default(),
|
calldata: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,8 +531,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Value::balance_ofCall::new((address,)).abi_encode(),
|
calldata: Value::balance_ofCall::new((address,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,8 +543,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Bitwise::opByteCall::new((index, value)).abi_encode(),
|
calldata: Bitwise::opByteCall::new((index, value)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,8 +555,8 @@ impl Contract {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
evm_runtime: compile_evm_bin_runtime(name, code),
|
||||||
pvm_runtime: crate::compile_blob(name, code),
|
pvm_runtime: compile_blob(name, code),
|
||||||
calldata: Storage::transientCall::new((value,)).abi_encode(),
|
calldata: Storage::transientCall::new((value,)).abi_encode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,120 +4,12 @@ use mock_runtime::{CallOutput, State};
|
|||||||
|
|
||||||
use crate::mock_runtime::{Event, ReturnFlags};
|
use crate::mock_runtime::{Event, ReturnFlags};
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use std::{collections::HashMap, sync::Mutex};
|
|
||||||
|
|
||||||
pub mod cases;
|
pub mod cases;
|
||||||
pub mod mock_runtime;
|
pub mod mock_runtime;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub(crate) static PVM_BLOB_CACHE: Lazy<Mutex<HashMap<CompiledBlobId, Vec<u8>>>> =
|
|
||||||
Lazy::new(Default::default);
|
|
||||||
pub(crate) static EVM_BLOB_CACHE: Lazy<Mutex<HashMap<CompiledBlobId, Vec<u8>>>> =
|
|
||||||
Lazy::new(Default::default);
|
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq)]
|
|
||||||
struct CompiledBlobId {
|
|
||||||
contract_name: String,
|
|
||||||
solc_optimizer_enabled: bool,
|
|
||||||
pipeline: revive_solidity::SolcPipeline,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compile the blob of `contract_name` found in given `source_code`.
|
|
||||||
/// The `solc` optimizer will be enabled
|
|
||||||
pub fn compile_blob(contract_name: &str, source_code: &str) -> Vec<u8> {
|
|
||||||
compile_blob_with_options(
|
|
||||||
contract_name,
|
|
||||||
source_code,
|
|
||||||
true,
|
|
||||||
revive_solidity::SolcPipeline::Yul,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compile the EVM bin-runtime of `contract_name` found in given `source_code`.
|
|
||||||
/// The `solc` optimizer will be enabled
|
|
||||||
pub fn compile_evm_bin_runtime(contract_name: &str, source_code: &str) -> Vec<u8> {
|
|
||||||
let pipeline = revive_solidity::SolcPipeline::Yul;
|
|
||||||
let solc_optimizer_enabled = true;
|
|
||||||
let id = CompiledBlobId {
|
|
||||||
contract_name: contract_name.to_owned(),
|
|
||||||
pipeline,
|
|
||||||
solc_optimizer_enabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(blob) = EVM_BLOB_CACHE.lock().unwrap().get(&id) {
|
|
||||||
return blob.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_name = "contract.sol";
|
|
||||||
let contracts = revive_solidity::test_utils::build_solidity_with_options_evm(
|
|
||||||
[(file_name.into(), source_code.into())].into(),
|
|
||||||
Default::default(),
|
|
||||||
None,
|
|
||||||
pipeline,
|
|
||||||
solc_optimizer_enabled,
|
|
||||||
)
|
|
||||||
.expect("source should compile");
|
|
||||||
let bin_runtime = &contracts
|
|
||||||
.get(contract_name)
|
|
||||||
.unwrap_or_else(|| panic!("contract '{}' didn't produce bin-runtime", contract_name))
|
|
||||||
.object;
|
|
||||||
|
|
||||||
let blob = hex::decode(bin_runtime).expect("bin-runtime shold be hex encoded");
|
|
||||||
|
|
||||||
EVM_BLOB_CACHE.lock().unwrap().insert(id, blob.clone());
|
|
||||||
|
|
||||||
blob
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compile the blob of `contract_name` found in given `source_code`.
|
|
||||||
pub fn compile_blob_with_options(
|
|
||||||
contract_name: &str,
|
|
||||||
source_code: &str,
|
|
||||||
solc_optimizer_enabled: bool,
|
|
||||||
pipeline: revive_solidity::SolcPipeline,
|
|
||||||
) -> Vec<u8> {
|
|
||||||
let id = CompiledBlobId {
|
|
||||||
contract_name: contract_name.to_owned(),
|
|
||||||
solc_optimizer_enabled,
|
|
||||||
pipeline,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(blob) = PVM_BLOB_CACHE.lock().unwrap().get(&id) {
|
|
||||||
return blob.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_name = "contract.sol";
|
|
||||||
let contracts = revive_solidity::test_utils::build_solidity_with_options(
|
|
||||||
[(file_name.into(), source_code.into())].into(),
|
|
||||||
Default::default(),
|
|
||||||
None,
|
|
||||||
pipeline,
|
|
||||||
revive_llvm_context::OptimizerSettings::cycles(),
|
|
||||||
solc_optimizer_enabled,
|
|
||||||
)
|
|
||||||
.expect("source should compile")
|
|
||||||
.contracts
|
|
||||||
.expect("source should contain at least one contract");
|
|
||||||
|
|
||||||
let bytecode = contracts[file_name][contract_name]
|
|
||||||
.evm
|
|
||||||
.as_ref()
|
|
||||||
.expect("source should produce EVM output")
|
|
||||||
.bytecode
|
|
||||||
.as_ref()
|
|
||||||
.expect("source should produce assembly text")
|
|
||||||
.object
|
|
||||||
.as_str();
|
|
||||||
let blob = hex::decode(bytecode).expect("hex encoding should always be valid");
|
|
||||||
|
|
||||||
PVM_BLOB_CACHE.lock().unwrap().insert(id, blob.clone());
|
|
||||||
|
|
||||||
blob
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assert_success(contract: &Contract, differential: bool) -> (State, CallOutput) {
|
pub fn assert_success(contract: &Contract, differential: bool) -> (State, CallOutput) {
|
||||||
let (state, output) = contract.execute();
|
let (state, output) = contract.execute();
|
||||||
assert_eq!(output.flags, ReturnFlags::Success);
|
assert_eq!(output.flags, ReturnFlags::Success);
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ use alloy_sol_types::{sol, SolCall, SolValue};
|
|||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
use sha1::Digest;
|
use sha1::Digest;
|
||||||
|
|
||||||
|
use revive_solidity::test_utils::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assert_success,
|
assert_success,
|
||||||
cases::Contract,
|
cases::Contract,
|
||||||
@@ -62,7 +64,7 @@ fn hash_keccak_256() {
|
|||||||
hash = keccak256(bytes(_pre));
|
hash = keccak256(bytes(_pre));
|
||||||
}
|
}
|
||||||
}"#;
|
}"#;
|
||||||
let code = crate::compile_blob("TestSha3", source);
|
let code = compile_blob("TestSha3", source);
|
||||||
|
|
||||||
let param = "hello";
|
let param = "hello";
|
||||||
let input = TestSha3::testCall::new((param.to_string(),)).abi_encode();
|
let input = TestSha3::testCall::new((param.to_string(),)).abi_encode();
|
||||||
@@ -82,7 +84,7 @@ fn hash_keccak_256() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn erc20() {
|
fn erc20() {
|
||||||
let _ = crate::compile_blob("ERC20", include_str!("../contracts/ERC20.sol"));
|
let _ = compile_blob("ERC20", include_str!("../contracts/ERC20.sol"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -109,7 +111,7 @@ fn msize_plain() {
|
|||||||
function mSize() public pure returns (uint);
|
function mSize() public pure returns (uint);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
let code = crate::compile_blob_with_options(
|
let code = compile_blob_with_options(
|
||||||
"MSize",
|
"MSize",
|
||||||
include_str!("../contracts/MSize.sol"),
|
include_str!("../contracts/MSize.sol"),
|
||||||
false,
|
false,
|
||||||
@@ -138,7 +140,7 @@ fn transferred_value() {
|
|||||||
function value() public payable returns (uint);
|
function value() public payable returns (uint);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
let code = crate::compile_blob("Value", include_str!("../contracts/Value.sol"));
|
let code = compile_blob("Value", include_str!("../contracts/Value.sol"));
|
||||||
|
|
||||||
let (_, output) = State::default()
|
let (_, output) = State::default()
|
||||||
.transaction()
|
.transaction()
|
||||||
@@ -162,7 +164,7 @@ fn msize_non_word_sized_access() {
|
|||||||
function mStore100() public pure returns (uint);
|
function mStore100() public pure returns (uint);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
let code = crate::compile_blob_with_options(
|
let code = compile_blob_with_options(
|
||||||
"MSize",
|
"MSize",
|
||||||
include_str!("../contracts/MSize.sol"),
|
include_str!("../contracts/MSize.sol"),
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "revive-runner"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { workspace = true }
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
codec = { workspace = true, default-features = false }
|
||||||
|
scale-info = { workspace = true, default-features = false }
|
||||||
|
polkadot-sdk = { workspace = true, features = ["experimental", "runtime"] }
|
||||||
|
|
||||||
|
revive-solidity = { path = "../solidity" }
|
||||||
Binary file not shown.
@@ -0,0 +1,393 @@
|
|||||||
|
//! Experimental test runner for testing [pallet-revive](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/revive) contracts.
|
||||||
|
//! The crate exposes a single function [`run_tests`] that takes a [`Specs`] that defines in a declarative way:
|
||||||
|
//! - The Genesis configuration
|
||||||
|
//! - A list of [`SpecsAction`] that will be executed in order.
|
||||||
|
//!
|
||||||
|
//! ## Example
|
||||||
|
//! ```rust
|
||||||
|
//! use revive_runner::*;
|
||||||
|
//! use SpecsAction::*;
|
||||||
|
//! run_test(Specs {
|
||||||
|
//! balances: vec![(ALICE, 1_000_000_000)],
|
||||||
|
//! actions: vec![Instantiate {
|
||||||
|
//! origin: ALICE,
|
||||||
|
//! value: 0,
|
||||||
|
//! gas_limit: Some(GAS_LIMIT),
|
||||||
|
//! storage_deposit_limit: Some(DEPOSIT_LIMIT),
|
||||||
|
//! code: Code::Bytes(include_bytes!("../fixtures/Baseline.pvm").to_vec()),
|
||||||
|
//! data: vec![],
|
||||||
|
//! salt: vec![],
|
||||||
|
//! }],
|
||||||
|
//! })
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use polkadot_sdk::*;
|
||||||
|
use polkadot_sdk::{
|
||||||
|
pallet_revive::{CollectEvents, ContractExecResult, ContractInstantiateResult, DebugInfo},
|
||||||
|
polkadot_runtime_common::BuildStorage,
|
||||||
|
polkadot_sdk_frame::testing_prelude::*,
|
||||||
|
sp_keystore::{testing::MemoryKeystore, KeystoreExt},
|
||||||
|
sp_runtime::AccountId32,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
mod runtime;
|
||||||
|
use crate::runtime::*;
|
||||||
|
|
||||||
|
pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
|
||||||
|
pub const BOB: AccountId32 = AccountId32::new([2u8; 32]);
|
||||||
|
pub const CHARLIE: AccountId32 = AccountId32::new([3u8; 32]);
|
||||||
|
|
||||||
|
/// Externalities builder
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ExtBuilder {
|
||||||
|
/// List of endowments at genesis
|
||||||
|
balance_genesis_config: Vec<(AccountId, Balance)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtBuilder {
|
||||||
|
/// Set the balance of an account at genesis
|
||||||
|
fn balance_genesis_config(mut self, value: Vec<(AccountId, Balance)>) -> Self {
|
||||||
|
self.balance_genesis_config = value;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build the externalities
|
||||||
|
pub fn build(self) -> sp_io::TestExternalities {
|
||||||
|
sp_tracing::try_init_simple();
|
||||||
|
let mut t = frame_system::GenesisConfig::<Runtime>::default()
|
||||||
|
.build_storage()
|
||||||
|
.unwrap();
|
||||||
|
pallet_balances::GenesisConfig::<Runtime> {
|
||||||
|
balances: self.balance_genesis_config,
|
||||||
|
}
|
||||||
|
.assimilate_storage(&mut t)
|
||||||
|
.unwrap();
|
||||||
|
let mut ext = sp_io::TestExternalities::new(t);
|
||||||
|
ext.register_extension(KeystoreExt::new(MemoryKeystore::new()));
|
||||||
|
ext.execute_with(|| System::set_block_number(1));
|
||||||
|
|
||||||
|
ext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default gas limit
|
||||||
|
pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024);
|
||||||
|
|
||||||
|
/// Default deposit limit
|
||||||
|
pub const DEPOSIT_LIMIT: Balance = 10_000_000;
|
||||||
|
|
||||||
|
/// Expectation for a call
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct VerifyCallExpectation {
|
||||||
|
/// When provided, the expected gas consumed
|
||||||
|
gas_consumed: Option<Weight>,
|
||||||
|
/// When provided, the expected output
|
||||||
|
output: Option<Vec<u8>>,
|
||||||
|
///Expected call result
|
||||||
|
success: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for VerifyCallExpectation {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
gas_consumed: None,
|
||||||
|
output: None,
|
||||||
|
success: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VerifyCallExpectation {
|
||||||
|
/// Verify that the expectations are met
|
||||||
|
fn verify(self, result: CallResult) {
|
||||||
|
dbg!(&result);
|
||||||
|
assert_eq!(self.success, result.is_ok());
|
||||||
|
if let Some(gas_consumed) = self.gas_consumed {
|
||||||
|
assert_eq!(gas_consumed, result.gas_consumed());
|
||||||
|
}
|
||||||
|
if let Some(output) = self.output {
|
||||||
|
assert_eq!(output, result.output());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Result of a call
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum CallResult {
|
||||||
|
Exec(ContractExecResult<Balance, EventRecord>),
|
||||||
|
Instantiate(ContractInstantiateResult<AccountId, Balance, EventRecord>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CallResult {
|
||||||
|
/// Check if the call was successful
|
||||||
|
fn is_ok(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Exec(res) => res.result.is_ok(),
|
||||||
|
Self::Instantiate(res) => res.result.is_ok(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Get the output of the call
|
||||||
|
fn output(&self) -> Vec<u8> {
|
||||||
|
match self {
|
||||||
|
Self::Exec(res) => res
|
||||||
|
.result
|
||||||
|
.as_ref()
|
||||||
|
.map(|r| r.data.clone())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
Self::Instantiate(res) => res
|
||||||
|
.result
|
||||||
|
.as_ref()
|
||||||
|
.map(|r| r.result.data.clone())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Get the gas consumed by the call
|
||||||
|
fn gas_consumed(&self) -> Weight {
|
||||||
|
match self {
|
||||||
|
Self::Exec(res) => res.gas_consumed,
|
||||||
|
Self::Instantiate(res) => res.gas_consumed,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum Code {
|
||||||
|
/// Compile a single solidity source and use the blob of `contract`
|
||||||
|
Solidity {
|
||||||
|
path: std::path::PathBuf,
|
||||||
|
contract: String,
|
||||||
|
},
|
||||||
|
/// Read the contract blob from disk
|
||||||
|
Path(std::path::PathBuf),
|
||||||
|
/// A contract blob
|
||||||
|
Bytes(Vec<u8>),
|
||||||
|
/// Pre-existing contract hash
|
||||||
|
Hash(Hash),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Code> for pallet_revive::Code<Hash> {
|
||||||
|
fn from(val: Code) -> Self {
|
||||||
|
match val {
|
||||||
|
Code::Solidity { path, contract } => {
|
||||||
|
pallet_revive::Code::Upload(revive_solidity::test_utils::compile_blob(
|
||||||
|
contract.as_str(),
|
||||||
|
std::fs::read_to_string(path).unwrap().as_str(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Code::Path(path) => pallet_revive::Code::Upload(std::fs::read(path).unwrap()),
|
||||||
|
Code::Bytes(bytes) => pallet_revive::Code::Upload(bytes),
|
||||||
|
Code::Hash(hash) => pallet_revive::Code::Existing(hash),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An action to perform in a contract test
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum SpecsAction {
|
||||||
|
/// Instantiate a contract
|
||||||
|
Instantiate {
|
||||||
|
origin: AccountId,
|
||||||
|
#[serde(default)]
|
||||||
|
value: Balance,
|
||||||
|
#[serde(default)]
|
||||||
|
gas_limit: Option<Weight>,
|
||||||
|
#[serde(default)]
|
||||||
|
storage_deposit_limit: Option<Balance>,
|
||||||
|
code: Code,
|
||||||
|
#[serde(default)]
|
||||||
|
data: Vec<u8>,
|
||||||
|
#[serde(default)]
|
||||||
|
salt: Vec<u8>,
|
||||||
|
},
|
||||||
|
/// Call a contract
|
||||||
|
Call {
|
||||||
|
origin: AccountId,
|
||||||
|
dest: AccountId,
|
||||||
|
#[serde(default)]
|
||||||
|
value: Balance,
|
||||||
|
#[serde(default)]
|
||||||
|
gas_limit: Option<Weight>,
|
||||||
|
#[serde(default)]
|
||||||
|
storage_deposit_limit: Option<Balance>,
|
||||||
|
#[serde(default)]
|
||||||
|
data: Vec<u8>,
|
||||||
|
},
|
||||||
|
/// Verify the result of the last call, omitting this will simply ensure the last call was successful
|
||||||
|
VerifyCall(VerifyCallExpectation),
|
||||||
|
|
||||||
|
/// Verify the balance of an account
|
||||||
|
VerifyBalance {
|
||||||
|
origin: AccountId,
|
||||||
|
expected: Balance,
|
||||||
|
},
|
||||||
|
/// Verify the storage of a contract
|
||||||
|
VerifyStorage {
|
||||||
|
contract: AccountId,
|
||||||
|
key: Vec<u8>,
|
||||||
|
expected: Option<Vec<u8>>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specs for a contract test
|
||||||
|
#[derive(Default, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct Specs {
|
||||||
|
/// List of endowments at genesis
|
||||||
|
pub balances: Vec<(AccountId, Balance)>,
|
||||||
|
/// List of actions to perform
|
||||||
|
pub actions: Vec<SpecsAction>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Specs {
|
||||||
|
/// Get the list of actions to perform
|
||||||
|
/// A default [`SpecAction::VerifyCall`] is injected after each Instantiate or Call action when
|
||||||
|
/// missing
|
||||||
|
fn actions(&self) -> Vec<SpecsAction> {
|
||||||
|
self.actions
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(index, item)| {
|
||||||
|
let next_item = self.actions.get(index + 1);
|
||||||
|
if matches!(
|
||||||
|
item,
|
||||||
|
SpecsAction::Instantiate { .. } | SpecsAction::Call { .. }
|
||||||
|
) && !matches!(next_item, Some(SpecsAction::VerifyCall(_)))
|
||||||
|
{
|
||||||
|
return vec![
|
||||||
|
item.clone(),
|
||||||
|
SpecsAction::VerifyCall(VerifyCallExpectation::default()),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
vec![item.clone()]
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run a contract test
|
||||||
|
/// The test takes a [`Specs`] and executes the actions in order
|
||||||
|
pub fn run_test(specs: Specs) {
|
||||||
|
ExtBuilder::default()
|
||||||
|
.balance_genesis_config(specs.balances.clone())
|
||||||
|
.build()
|
||||||
|
.execute_with(|| {
|
||||||
|
use SpecsAction::*;
|
||||||
|
|
||||||
|
let mut res: Option<CallResult> = None;
|
||||||
|
let actions = specs.actions();
|
||||||
|
|
||||||
|
for action in actions {
|
||||||
|
match action {
|
||||||
|
Instantiate {
|
||||||
|
origin,
|
||||||
|
value,
|
||||||
|
gas_limit,
|
||||||
|
storage_deposit_limit,
|
||||||
|
code,
|
||||||
|
data,
|
||||||
|
salt,
|
||||||
|
} => {
|
||||||
|
res = Some(CallResult::Instantiate(Contracts::bare_instantiate(
|
||||||
|
RuntimeOrigin::signed(origin),
|
||||||
|
value,
|
||||||
|
gas_limit.unwrap_or(GAS_LIMIT),
|
||||||
|
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT),
|
||||||
|
code.into(),
|
||||||
|
data,
|
||||||
|
salt,
|
||||||
|
DebugInfo::Skip,
|
||||||
|
CollectEvents::Skip,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Call {
|
||||||
|
origin,
|
||||||
|
dest,
|
||||||
|
value,
|
||||||
|
gas_limit,
|
||||||
|
storage_deposit_limit,
|
||||||
|
data,
|
||||||
|
} => {
|
||||||
|
res = Some(CallResult::Exec(Contracts::bare_call(
|
||||||
|
RuntimeOrigin::signed(origin),
|
||||||
|
dest,
|
||||||
|
value,
|
||||||
|
gas_limit.unwrap_or(GAS_LIMIT),
|
||||||
|
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT),
|
||||||
|
data,
|
||||||
|
DebugInfo::Skip,
|
||||||
|
CollectEvents::Skip,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
VerifyCall(expectation) => {
|
||||||
|
if let Some(res) = res.take() {
|
||||||
|
expectation.verify(res);
|
||||||
|
} else {
|
||||||
|
panic!("No call to verify");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VerifyBalance { origin, expected } => {
|
||||||
|
assert_eq!(Balances::free_balance(&origin), expected);
|
||||||
|
}
|
||||||
|
VerifyStorage {
|
||||||
|
contract,
|
||||||
|
key,
|
||||||
|
expected,
|
||||||
|
} => {
|
||||||
|
let Ok(storage) = Contracts::get_storage(contract, key) else {
|
||||||
|
panic!("Error reading storage");
|
||||||
|
};
|
||||||
|
assert_eq!(storage, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn instantiate_works() {
|
||||||
|
use SpecsAction::*;
|
||||||
|
run_test(Specs {
|
||||||
|
balances: vec![(ALICE, 1_000_000_000)],
|
||||||
|
actions: vec![Instantiate {
|
||||||
|
origin: ALICE,
|
||||||
|
value: 0,
|
||||||
|
gas_limit: Some(GAS_LIMIT),
|
||||||
|
storage_deposit_limit: Some(DEPOSIT_LIMIT),
|
||||||
|
code: Code::Bytes(include_bytes!("../fixtures/Baseline.pvm").to_vec()),
|
||||||
|
data: vec![],
|
||||||
|
salt: vec![],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn instantiate_with_json() {
|
||||||
|
let specs = serde_json::from_str::<Specs>(
|
||||||
|
r#"
|
||||||
|
{
|
||||||
|
"balances": [
|
||||||
|
[ "5C62Ck4UrFPiBtoCmeSrgF7x9yv9mn38446dhCpsi2mLHiFT", 1000000000 ]
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"Instantiate": {
|
||||||
|
"origin": "5C62Ck4UrFPiBtoCmeSrgF7x9yv9mn38446dhCpsi2mLHiFT",
|
||||||
|
"value": 0,
|
||||||
|
"code": {
|
||||||
|
"Path": "fixtures/Baseline.pvm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
run_test(specs);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
use frame_support::runtime;
|
||||||
|
|
||||||
|
use polkadot_sdk::*;
|
||||||
|
use polkadot_sdk::{
|
||||||
|
polkadot_sdk_frame::{log, runtime::prelude::*},
|
||||||
|
sp_runtime::{AccountId32, Perbill},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub type Balance = u128;
|
||||||
|
pub type AccountId = AccountId32;
|
||||||
|
pub type Block = frame_system::mocking::MockBlock<Runtime>;
|
||||||
|
pub type Hash = <Runtime as frame_system::Config>::Hash;
|
||||||
|
pub type EventRecord =
|
||||||
|
frame_system::EventRecord<<Runtime as frame_system::Config>::RuntimeEvent, Hash>;
|
||||||
|
|
||||||
|
#[runtime]
|
||||||
|
mod runtime {
|
||||||
|
#[runtime::runtime]
|
||||||
|
#[runtime::derive(
|
||||||
|
RuntimeCall,
|
||||||
|
RuntimeEvent,
|
||||||
|
RuntimeError,
|
||||||
|
RuntimeOrigin,
|
||||||
|
RuntimeFreezeReason,
|
||||||
|
RuntimeHoldReason,
|
||||||
|
RuntimeSlashReason,
|
||||||
|
RuntimeLockId,
|
||||||
|
RuntimeTask
|
||||||
|
)]
|
||||||
|
pub struct Runtime;
|
||||||
|
|
||||||
|
#[runtime::pallet_index(0)]
|
||||||
|
pub type System = frame_system;
|
||||||
|
|
||||||
|
#[runtime::pallet_index(1)]
|
||||||
|
pub type Timestamp = pallet_timestamp;
|
||||||
|
|
||||||
|
#[runtime::pallet_index(2)]
|
||||||
|
pub type Balances = pallet_balances;
|
||||||
|
|
||||||
|
#[runtime::pallet_index(3)]
|
||||||
|
pub type Contracts = pallet_revive;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
|
||||||
|
impl frame_system::Config for Runtime {
|
||||||
|
type Block = Block;
|
||||||
|
type AccountId = AccountId;
|
||||||
|
type AccountData = pallet_balances::AccountData<<Runtime as pallet_balances::Config>::Balance>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
|
||||||
|
impl pallet_balances::Config for Runtime {
|
||||||
|
type AccountStore = System;
|
||||||
|
type Balance = Balance;
|
||||||
|
type ExistentialDeposit = ConstU128<1_000>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
|
||||||
|
impl pallet_timestamp::Config for Runtime {}
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
pub const UnstableInterface: bool = true;
|
||||||
|
pub const DepositPerByte: Balance = 1;
|
||||||
|
pub const DepositPerItem: Balance = 2;
|
||||||
|
pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_impl(pallet_revive::config_preludes::TestDefaultConfig)]
|
||||||
|
impl pallet_revive::Config for Runtime {
|
||||||
|
type Time = Timestamp;
|
||||||
|
type Currency = Balances;
|
||||||
|
type CallFilter = ();
|
||||||
|
type ChainExtension = ();
|
||||||
|
type DepositPerByte = DepositPerByte;
|
||||||
|
type DepositPerItem = DepositPerItem;
|
||||||
|
type AddressGenerator = pallet_revive::DefaultAddressGenerator;
|
||||||
|
type UnsafeUnstableInterface = UnstableInterface;
|
||||||
|
type UploadOrigin = EnsureSigned<AccountId>;
|
||||||
|
type InstantiateOrigin = EnsureSigned<AccountId>;
|
||||||
|
type Migrations = ();
|
||||||
|
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
|
||||||
|
type Debug = ();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user