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

Staking Precompiles #358

Merged
merged 102 commits into from
May 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
832726b
init
4meta5 Apr 8, 2021
f179e91
Merge branch 'master' into amar-int-tests
4meta5 Apr 12, 2021
737c0fd
save
4meta5 Apr 13, 2021
cf4e42d
Initial pass at Sacrifice precompile
notlesh Apr 13, 2021
9efad64
Add gas-related tests for Sacrifice precompile
notlesh Apr 13, 2021
69a32b7
import pallet instances from runtime and start evm transfer to stake …
4meta5 Apr 14, 2021
71d5660
transfer to stake without evm transfer
4meta5 Apr 14, 2021
1f10d75
rename carl to charlie
4meta5 Apr 14, 2021
97fc054
push failed test to show how evm call works
4meta5 Apr 15, 2021
688a324
set gas price and limit to make test pass
JoshOrndorff Apr 15, 2021
b3abf42
test still fails, push to show that transfer through EVM does not suc…
4meta5 Apr 15, 2021
f154f50
test passes
4meta5 Apr 15, 2021
270ea2d
save unfinished pay block authors todo
4meta5 Apr 15, 2021
ad59685
Sketched idea, mostly right (I think), doesn't compile because of .di…
JoshOrndorff Apr 15, 2021
0d2a184
holy shit it compiles!
JoshOrndorff Apr 15, 2021
a539aaa
ditch BigUint
JoshOrndorff Apr 15, 2021
1e5f8d1
don't need to name phantom field
JoshOrndorff Apr 15, 2021
28a7e50
BalanceOf<Runtime>
JoshOrndorff Apr 15, 2021
ab7fea5
Don't need temp buffers for inputs
JoshOrndorff Apr 15, 2021
026d4c9
no_std
JoshOrndorff Apr 15, 2021
fbb9852
reward block authors runtime integration test
4meta5 Apr 16, 2021
15aae62
improve readability
4meta5 Apr 18, 2021
a46d404
increase test inflation config to see test balances go up more
4meta5 Apr 18, 2021
106beec
move to own file, and rename for pallet-specific precompile
JoshOrndorff Apr 20, 2021
17ebf9b
Try (and fail) to install in Runtime
JoshOrndorff Apr 20, 2021
93b197c
Add proper trait bounds so it compiles
JoshOrndorff Apr 20, 2021
4d8838e
Better constant use
JoshOrndorff Apr 20, 2021
5f9a279
Prep work for ABI stuff
JoshOrndorff Apr 20, 2021
e543abb
oops
JoshOrndorff Apr 20, 2021
6c5b3b3
Try some logging - Can't figure out why calls are failing
JoshOrndorff Apr 20, 2021
d5c24c7
Merge branch 'master' into joshy-staking-precompiles
JoshOrndorff Apr 20, 2021
481f43d
address most review comments
4meta5 Apr 21, 2021
84789de
Idea: don't be generic?
JoshOrndorff Apr 21, 2021
3ff424f
Merge branch 'master' into joshy-staking-precompiles
JoshOrndorff Apr 21, 2021
f2660f3
Merge branch 'amar-int-tests' into joshy-staking-precompiles
JoshOrndorff Apr 21, 2021
883a892
Another cleanup idea.
JoshOrndorff Apr 21, 2021
ca44e43
Merge branch 'master' into amar-int-tests
JoshOrndorff Apr 21, 2021
9e6c7f8
Fix test for root origin
JoshOrndorff Apr 21, 2021
eba6070
Merge branch 'amar-int-tests' into joshy-staking-precompiles
JoshOrndorff Apr 21, 2021
b12d12e
Slightly clean the logging even though it isn't working
JoshOrndorff Apr 21, 2021
78e46ab
sketch a test
JoshOrndorff Apr 21, 2021
d0d988e
idea about how to get big endial nomination amount vec
JoshOrndorff Apr 21, 2021
d4ec7ee
Print events more nicely
JoshOrndorff Apr 21, 2021
0f08b90
Seemed to work
JoshOrndorff Apr 21, 2021
821988e
Clean up address
JoshOrndorff Apr 21, 2021
6b2da9b
Cleanup test init
JoshOrndorff Apr 21, 2021
6fc8583
Cleanup test init
JoshOrndorff Apr 21, 2021
3c1ca8a
Nicer balances format
JoshOrndorff Apr 21, 2021
ee0cd4c
remove prints
JoshOrndorff Apr 21, 2021
4367b09
Start sketching toward a second wrapped extrinsic
JoshOrndorff Apr 21, 2021
6a61969
Fix test
JoshOrndorff Apr 21, 2021
189a204
matching on selector is working
JoshOrndorff Apr 22, 2021
5e0c1ee
precompile and test for join candidates
JoshOrndorff Apr 22, 2021
0e69a5e
finish precompiles
4meta5 Apr 22, 2021
0ac505c
fmt
4meta5 Apr 22, 2021
9f151cf
fmt
4meta5 Apr 22, 2021
d184ab9
green
4meta5 Apr 22, 2021
e9c6bd0
more tests
4meta5 Apr 22, 2021
11a3d68
finish tests
4meta5 Apr 22, 2021
810de06
better
4meta5 Apr 22, 2021
e0f0eef
sketch example contract
JoshOrndorff Apr 22, 2021
eff5128
Fill in precompile calls. Untested, but solc accepts them :)
JoshOrndorff Apr 22, 2021
140dbbd
accessor selector
JoshOrndorff Apr 22, 2021
5461907
attempt at integration test
JoshOrndorff Apr 22, 2021
8cdd26e
better logging
JoshOrndorff Apr 23, 2021
28fbe48
switch to interface
JoshOrndorff Apr 23, 2021
fa41eb3
Reminder stopped vs returned
JoshOrndorff Apr 23, 2021
a39da02
enable receive function
JoshOrndorff Apr 23, 2021
5e8374c
More logging
JoshOrndorff Apr 23, 2021
d8da583
Simpler test contract
JoshOrndorff Apr 23, 2021
1f3bedb
skip tests so docker image builds
JoshOrndorff Apr 23, 2021
32bb16f
added test for staking precompile
joelamouche Apr 23, 2021
e7eed6e
More logging, notes, and cleanup from learning session
JoshOrndorff Apr 23, 2021
8197789
Add some bogus code predoplyed under precompile
JoshOrndorff Apr 23, 2021
083a1c3
Merge branch 'master' into joshy-staking-precompiles
4meta5 Apr 24, 2021
262aef0
Slightly nicer predeploy
JoshOrndorff Apr 26, 2021
0a216c2
sketch idea to fetch addresses from moonbeam precompile struct
JoshOrndorff Apr 26, 2021
f44f96b
accessor attempt compiles
JoshOrndorff Apr 26, 2021
68eb3db
First access test passes
JoshOrndorff Apr 26, 2021
20e951d
Consider 12 mystery bytes when calling accessor + test
JoshOrndorff Apr 27, 2021
c109b36
Narrower generic params
JoshOrndorff Apr 27, 2021
2da7a9d
helper method
JoshOrndorff Apr 27, 2021
009d688
cleaner matching
JoshOrndorff Apr 27, 2021
24da4bf
More complete interface including accessor methods
JoshOrndorff Apr 27, 2021
cedc825
compare gases instead of weights
JoshOrndorff Apr 27, 2021
c3fc676
moar logging
JoshOrndorff Apr 27, 2021
06b2fdd
💡 EVERYTHING is padded to 256 bits
JoshOrndorff Apr 27, 2021
89675f1
strip too-verbose logging from precompile set
JoshOrndorff Apr 27, 2021
49bb673
properly parse account in recoke_nomination
JoshOrndorff Apr 27, 2021
fd8c7bc
Basic nomination dao is working
JoshOrndorff Apr 27, 2021
898f02c
More polishing on Nomination DAO
JoshOrndorff Apr 27, 2021
ff4e4c9
remove sacrifice precompile stuff and make all integration tests pass…
4meta5 Apr 28, 2021
91b4dfb
clean and move unfinished tests to jira moonbeam 495
4meta5 Apr 28, 2021
b8842b2
green
4meta5 Apr 28, 2021
ec9ca76
Merge branch 'master' into joshy-staking-precompiles
4meta5 Apr 29, 2021
dd33e71
add is candidate with rust runtime integration test
4meta5 Apr 29, 2021
f2d6443
clean and bump spec version
4meta5 Apr 29, 2021
d116efb
address some review comments
4meta5 Apr 29, 2021
97c9436
min nomination test commented out but fails
4meta5 Apr 30, 2021
cb0addd
add some comments requested in review
4meta5 Apr 30, 2021
9557521
fix min nomination test as per joshy comment
4meta5 Apr 30, 2021
b8f3122
fix precompile addresses in dead code
4meta5 Apr 30, 2021
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
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 31 additions & 2 deletions node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

use bip39::{Language, Mnemonic, Seed};
use cumulus_primitives_core::ParaId;
use evm::GenesisAccount;
use log::debug;
use moonbeam_runtime::{
AccountId, Balance, BalancesConfig, CouncilCollectiveConfig, DemocracyConfig, EVMConfig,
Expand All @@ -39,7 +40,7 @@ use sp_runtime::{
Perbill,
};
use std::convert::TryInto;
use std::{collections::BTreeMap, str::FromStr};
use std::str::FromStr;
use tiny_hderive::bip32::ExtendedPrivKey;

/// Helper function to derive `num_accounts` child pairs from mnemonics
Expand Down Expand Up @@ -232,6 +233,15 @@ pub fn testnet_genesis(
para_id: ParaId,
chain_id: u64,
) -> GenesisConfig {
// This is supposed the be the simplest bytecode to revert without returning any data.
// We will pre-deploy it under all of our precompiles to ensure they can be called from
// within contracts. TODO We should have a test to ensure this is the right bytecode.
// (PUSH1 0x00 PUSH1 0x00 REVERT)
4meta5 marked this conversation as resolved.
Show resolved Hide resolved
let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
// TODO consider whether this should be imported from moonbeam precompiles
let precompile_addresses = vec![1, 2, 3, 4, 5, 6, 7, 8, 1024, 1025, 2048]
.into_iter()
.map(H160::from_low_u64_be);
GenesisConfig {
frame_system: SystemConfig {
code: WASM_BINARY
Expand All @@ -252,7 +262,26 @@ pub fn testnet_genesis(
},
pallet_ethereum_chain_id: EthereumChainIdConfig { chain_id },
pallet_evm: EVMConfig {
accounts: BTreeMap::new(),
// We need _some_ code inserted at the precompile address so that
// the evm will actually call the address.
// TODO Cleanly fetch the addresses from
// the runtime/moonbeam precompiles and systematically fill them with code
// that will revert if it is called by accident (it shouldn't be because
// it is shadowed by the precompile).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite following this TODO... is it still relevant / should it be done before merging?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we'll do it in a follow-up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a followup makes more sense. There is a design decision to be made. Basically the dilemna is this.

We need to get bogus code under every precompile address. The precompile addresses are codified in the precompiles crate, but the genesis config (which includes the pre-deployed bogus code) is set up here.

So the decision is whether we have the list of addresses in both places (as we do now), or do we call into the precompiles crate to get them somehow. I started sketching that also, but still didn't like it because even the way I sketched it the addresses were still in two places (although at least they were in the same file).

// This one is for the parachain staking precompile wrappers
accounts: precompile_addresses
.map(|a| {
(
a,
GenesisAccount {
nonce: Default::default(),
balance: Default::default(),
storage: Default::default(),
code: revert_bytecode.clone(),
},
)
})
.collect(),
},
pallet_ethereum: EthereumConfig {},
pallet_democracy: DemocracyConfig {},
Expand Down
22 changes: 9 additions & 13 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,21 @@ moonbeam-rpc-primitives-debug = { path = "../primitives/rpc/debug", default-feat
moonbeam-rpc-primitives-txpool = { path = "../primitives/rpc/txpool", default-features = false }

# Cumulus dependencies
cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
parachain-info = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
parachain-info = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }

[dev-dependencies]
cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }
evm = { version = "0.26.0", default-features = false, features = ["with-codec"] }

[build-dependencies]
substrate-wasm-builder = { version = "4.0.0", git = "https://github.com/paritytech/substrate", branch = "rococo-v1" }

[features]
# By default, we build the parachain runtime
default = [
"std"
# parachain-only dependencies can't be conditionally included here.
# Default feature dependencies must not be optional (aparently)
"std",
]
std = [
"parity-scale-codec/std",
Expand Down Expand Up @@ -125,12 +123,10 @@ std = [

# Will be enabled by the `wasm-builder` when building the runtime for WASM.
runtime-wasm = [
# "cumulus-upward-message/runtime-wasm",
# "cumulus-upward-message/runtime-wasm",
]

# A feature that should be enabled when the runtime should be build for on-chain
# deployment. This will disable stuff that shouldn't be part of the on-chain wasm
# to make it smaller like logging for example.
on-chain-release-build = [
"sp-api/disable-logging",
]
on-chain-release-build = ["sp-api/disable-logging"]
10 changes: 9 additions & 1 deletion runtime/precompiles/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ frame-support = { git = "https://github.com/paritytech/substrate", branch = "roc
evm = { version = "0.26.0", default-features = false, features = ["with-codec"] }
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }
pallet-evm = { git = "https://github.com/purestake/frontier", default-features = false, branch = "notlesh-moonbeam-v0.7" }
pallet-evm-precompile-bn128 = { git = "https://github.com/purestake/frontier", default-features = false, branch = "notlesh-moonbeam-v0.7" }
pallet-evm-precompile-dispatch = { git = "https://github.com/purestake/frontier", default-features = false, branch = "notlesh-moonbeam-v0.7" }
pallet-evm-precompile-modexp = { git = "https://github.com/purestake/frontier", default-features = false, branch = "notlesh-moonbeam-v0.7" }
pallet-evm-precompile-simple = { git = "https://github.com/purestake/frontier", default-features = false, branch = "notlesh-moonbeam-v0.7" }
pallet-evm-precompile-sha3fips = { git = "https://github.com/purestake/frontier", default-features = false, branch = "notlesh-moonbeam-v0.7" }
parachain-staking = { path = "../../pallets/parachain-staking", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }

[dev-dependencies]
hex = "0.4"

[features]
default = [ "std" ]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
Expand All @@ -36,5 +42,7 @@ std = [
"pallet-evm-precompile-dispatch/std",
"pallet-evm-precompile-modexp/std",
"pallet-evm-precompile-simple/std",
"parachain-staking/std",
"frame-system/std",
"pallet-evm-precompile-sha3fips/std",
]
76 changes: 76 additions & 0 deletions runtime/precompiles/src/StakingInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;

/// The interface through which solidity contracts will interact with Parachain Staking
/// We follow this same interface including four-byte function selectors, in the precompile that
/// wraps the pallet
interface ParachainStaking {
// First some simple accessors

/// Check whether the specified address is currently a staking nominator
function is_nominator(address nominator) external view returns (bool);

/// Check whether the specified addess is currently a collator candidate
function is_candidate(address collator) external view returns (bool);

/// Get the minimum nomination amount
function min_nomination() external view returns (uint256);

// Now the dispatchables

/// Join the set of collator candidates
function join_candidates(uint256 amount) external;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice to document what this amount is (is it 10^-18 units?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like it's used below as well, so maybe a comment at the top of the contract...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better variable name would go a long way. maybe bond_amount. Good news the names don't affect the signatures so we wouldn't have to regenerate them. Agree about the units. Luckily solidity makes this nice with keywords like ether, wei, etc.


/// Request to leave the set of candidates. If successful, the account is immediately
/// removed from the candidate pool to prevent selection as a collator, but unbonding is
/// executed with a delay of `BondDuration` rounds.
function leave_candidates() external;

/// Temporarily leave the set of collator candidates without unbonding
function go_offline() external;

/// Rejoin the set of collator candidates if previously had called `go_offline`
function go_online() external;

/// Bond more for collator candidates
function candidate_bond_more(uint256 more) external;

/// Bond less for collator candidates
function candidate_bond_less(uint256 less) external;

/// If caller is not a nominator, then join the set of nominators
/// If caller is a nominator, then makes nomination to change their nomination state
function nominate(address collator, uint256 amount) external;

/// Leave the set of nominators and, by implication, revoke all ongoing nominations
function leave_nominators() external;

/// Revoke an existing nomination
function revoke_nomination(address collator) external;

/// Bond more for nominators with respect to a specific collator candidate
function nominator_bond_more(address candidate, uint256 more) external;

/// Bond less for nominators with respect to a specific nominator candidate
function nominator_bond_less(address candidate, uint256 less) external;
}

// These are the selectors generated by remix following this advice
// https://ethereum.stackexchange.com/a/73405/9963
// Eventually we will probably want a better way of generating these and copying them to Rust
// {
// "289b6ba7": "candidate_bond_less(uint256)",
// "c57bd3a8": "candidate_bond_more(uint256)",
// "767e0450": "go_offline()",
// "d2f73ceb": "go_online()",
// "8545c833": "is_candidate(address)",
// "8e5080e7": "is_nominator(address)",
// "ad76ed5a": "join_candidates(uint256)",
// "b7694219": "leave_candidates()",
// "e8d68a37": "leave_nominators()",
// "c9f593b2": "min_nomination()",
// "82f2c8df": "nominate(address,uint256)",
// "f6a52569": "nominator_bond_less(address,uint256)",
// "971d44c8": "nominator_bond_more(address,uint256)",
// "4b65c34b": "revoke_nomination(address)"
// }
43 changes: 39 additions & 4 deletions runtime/precompiles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,66 @@

#![cfg_attr(not(feature = "std"), no_std)]

mod staking;
use codec::Decode;
use evm::{Context, ExitError, ExitSucceed};
use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo};
use pallet_evm::{Config, Precompile, PrecompileSet};
use pallet_evm::{Precompile, PrecompileSet};
use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing};
use pallet_evm_precompile_dispatch::Dispatch;
use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
use pallet_evm_precompile_simple::{ECRecover, Identity, Ripemd160, Sha256};
use sp_core::H160;
use sp_std::convert::TryFrom;
use sp_std::fmt::Debug;
use sp_std::{marker::PhantomData, vec::Vec};
use staking::ParachainStakingWrapper;

use frame_support::traits::Currency;
type BalanceOf<Runtime> = <<Runtime as parachain_staking::Config>::Currency as Currency<
<Runtime as frame_system::Config>::AccountId,
>>::Balance;

//TODO Maybe we don't need to / shouldn't be generic over the runtime.
// Pros: Would simplify trait bounds and speed up compile time (maybe not noticeably).
// Cons: Would proclude using this precompile set in mocked Runtimes.
/// The PrecompileSet installed in the Moonbeam runtime.
/// We include the nine Istanbul precompiles
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
/// as well as a special precompile for dispatching Substrate extrinsics
#[derive(Debug, Clone, Copy)]
pub struct MoonbeamPrecompiles<R>(PhantomData<R>);

// The idea here is that we won't have to list the addresses in this file and the chain spec.
// Unfortunately we still have to type it twice in this file.
impl<R: frame_system::Config> MoonbeamPrecompiles<R>
where
R::AccountId: From<H160>,
{
/// Return all addresses that contain precompiles. This can be used to populate dummy code
/// under the precompile, and potentially in the future to prevent using accounts that have
/// precompiles at their addresses explicitly using something like SignedExtra.
#[allow(dead_code)]
fn used_addresses() -> impl Iterator<Item = R::AccountId> {
sp_std::vec![1, 2, 3, 4, 5, 6, 7, 8, 1024, 1025, 2048]
.into_iter()
.map(|x| hash(x).into())
}
}

/// The following distribution has been decided for the precompiles
/// 0-1023: Ethereum Mainnet Precompiles
/// 1024-2047 Precompiles that are not in Ethereum Mainnet but are neither Moonbeam specific
/// 2048-4095 Moonbeam specific prerecompiles

/// 2048-4095 Moonbeam specific precompiles
impl<R> PrecompileSet for MoonbeamPrecompiles<R>
where
R: Config,
R::Call: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo + Decode,
<R::Call as Dispatchable>::Origin: From<Option<R::AccountId>>,
R: parachain_staking::Config + pallet_evm::Config,
R::AccountId: From<H160>,
BalanceOf<R>: TryFrom<sp_core::U256> + Debug,
R::Call: From<parachain_staking::Call<R>>,
{
fn execute(
address: H160,
Expand All @@ -65,6 +96,10 @@ where
// Non-Moonbeam specific nor Ethereum precompiles :
a if a == hash(1024) => Some(Dispatch::<R>::execute(input, target_gas, context)),
a if a == hash(1025) => Some(Sha3FIPS256::execute(input, target_gas, context)),
// Moonbeam specific precompiles :
a if a == hash(2048) => Some(ParachainStakingWrapper::<R>::execute(
input, target_gas, context,
)),
_ => None,
}
}
Expand Down
Loading