mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 09:50:01 +00:00
feat: ✨ Add Moonbeam EVM Precompile Registry (#137)
## Summary This PR implements a comprehensive EVM precompile registry system for DataHaven, following Moonbeam's exact architecture and patterns. The implementation includes: - **Registry Precompile**: A new precompile at address `0x0815` (2069) that manages and queries available precompiles - **Core Ethereum Precompiles**: Standard Ethereum precompiles (ECRecover, SHA256, RIPEMD160, Identity, ModExp, BN128Add, BN128Mul, BN128Pairing, Blake2F, SHA3FIPS) - **Modular Architecture**: Clean separation following Moonbeam's structure with dedicated precompile modules per runtime ## Key Features ### Registry Precompile Functions - `isPrecompile(address)`: Check if an address corresponds to any precompile (active or inactive) - `isActivePrecompile(address)`: Check if a precompile is currently active in the runtime - `updateAccountCode(address)`: Insert dummy EVM bytecode for Solidity compatibility ### Runtime Integration - Integrated across all three runtimes (testnet, stagenet, mainnet) - Uses Moonbeam's `PrecompileSetBuilder` pattern for composable precompile management - Proper gas accounting with database read/write operations - Access control through `CallableByContract` and `CallableByPrecompile` traits --------- Co-authored-by: undercover-cactus <lola@moonsonglabs.com>
This commit is contained in:
parent
ee7969b540
commit
6886bcbdde
19 changed files with 1093 additions and 63 deletions
232
operator/Cargo.lock
generated
232
operator/Cargo.lock
generated
|
|
@ -1309,6 +1309,17 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"regex-automata 0.4.9",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "build-helper"
|
||||
version = "0.1.1"
|
||||
|
|
@ -1409,6 +1420,12 @@ dependencies = [
|
|||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "case"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6c0e7b807d60291f42f33f58480c0bfafe28ed08286446f45e463728cf9c1c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.22"
|
||||
|
|
@ -2355,6 +2372,7 @@ dependencies = [
|
|||
"hex-literal 0.3.4",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"num_enum",
|
||||
"pallet-authorship",
|
||||
"pallet-babe",
|
||||
"pallet-balances",
|
||||
|
|
@ -2368,6 +2386,12 @@ dependencies = [
|
|||
"pallet-ethereum",
|
||||
"pallet-evm",
|
||||
"pallet-evm-chain-id",
|
||||
"pallet-evm-precompile-blake2",
|
||||
"pallet-evm-precompile-bn128",
|
||||
"pallet-evm-precompile-modexp",
|
||||
"pallet-evm-precompile-registry",
|
||||
"pallet-evm-precompile-sha3fips",
|
||||
"pallet-evm-precompile-simple",
|
||||
"pallet-external-validators",
|
||||
"pallet-external-validators-rewards",
|
||||
"pallet-external-validators-rewards-runtime-api",
|
||||
|
|
@ -2405,6 +2429,7 @@ dependencies = [
|
|||
"parity-scale-codec",
|
||||
"polkadot-primitives",
|
||||
"polkadot-runtime-common",
|
||||
"precompile-utils",
|
||||
"scale-info",
|
||||
"serde_json",
|
||||
"shp-constants",
|
||||
|
|
@ -2579,6 +2604,7 @@ dependencies = [
|
|||
"hex-literal 0.3.4",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"num_enum",
|
||||
"pallet-authorship",
|
||||
"pallet-babe",
|
||||
"pallet-balances",
|
||||
|
|
@ -2592,6 +2618,12 @@ dependencies = [
|
|||
"pallet-ethereum",
|
||||
"pallet-evm",
|
||||
"pallet-evm-chain-id",
|
||||
"pallet-evm-precompile-blake2",
|
||||
"pallet-evm-precompile-bn128",
|
||||
"pallet-evm-precompile-modexp",
|
||||
"pallet-evm-precompile-registry",
|
||||
"pallet-evm-precompile-sha3fips",
|
||||
"pallet-evm-precompile-simple",
|
||||
"pallet-external-validators",
|
||||
"pallet-external-validators-rewards",
|
||||
"pallet-external-validators-rewards-runtime-api",
|
||||
|
|
@ -2629,6 +2661,7 @@ dependencies = [
|
|||
"parity-scale-codec",
|
||||
"polkadot-primitives",
|
||||
"polkadot-runtime-common",
|
||||
"precompile-utils",
|
||||
"scale-info",
|
||||
"serde_json",
|
||||
"shp-constants",
|
||||
|
|
@ -2704,6 +2737,7 @@ dependencies = [
|
|||
"hex-literal 0.3.4",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"num_enum",
|
||||
"pallet-authorship",
|
||||
"pallet-babe",
|
||||
"pallet-balances",
|
||||
|
|
@ -2717,6 +2751,12 @@ dependencies = [
|
|||
"pallet-ethereum",
|
||||
"pallet-evm",
|
||||
"pallet-evm-chain-id",
|
||||
"pallet-evm-precompile-blake2",
|
||||
"pallet-evm-precompile-bn128",
|
||||
"pallet-evm-precompile-modexp",
|
||||
"pallet-evm-precompile-registry",
|
||||
"pallet-evm-precompile-sha3fips",
|
||||
"pallet-evm-precompile-simple",
|
||||
"pallet-external-validators",
|
||||
"pallet-external-validators-rewards",
|
||||
"pallet-external-validators-rewards-runtime-api",
|
||||
|
|
@ -2754,6 +2794,7 @@ dependencies = [
|
|||
"parity-scale-codec",
|
||||
"polkadot-primitives",
|
||||
"polkadot-runtime-common",
|
||||
"precompile-utils",
|
||||
"scale-info",
|
||||
"serde_json",
|
||||
"shp-constants",
|
||||
|
|
@ -2925,6 +2966,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3841,12 +3883,6 @@ version = "0.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
|
|
@ -5989,6 +6025,9 @@ name = "lazy_static"
|
|||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
|
|
@ -7347,6 +7386,20 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
|
|
@ -7391,6 +7444,17 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
|
|
@ -7599,7 +7663,7 @@ dependencies = [
|
|||
"expander",
|
||||
"indexmap 2.9.0",
|
||||
"itertools 0.11.0",
|
||||
"petgraph 0.6.5",
|
||||
"petgraph",
|
||||
"proc-macro-crate 3.3.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -7961,6 +8025,70 @@ dependencies = [
|
|||
"scale-info",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-evm-precompile-blake2"
|
||||
version = "2.0.0-dev"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"fp-evm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-evm-precompile-bn128"
|
||||
version = "2.0.0-dev"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"fp-evm",
|
||||
"sp-core",
|
||||
"substrate-bn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-evm-precompile-modexp"
|
||||
version = "2.0.0-dev"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"fp-evm",
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-evm-precompile-registry"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fp-evm",
|
||||
"frame-support",
|
||||
"frame-system",
|
||||
"pallet-balances",
|
||||
"pallet-evm",
|
||||
"pallet-timestamp",
|
||||
"parity-scale-codec",
|
||||
"precompile-utils",
|
||||
"scale-info",
|
||||
"sp-core",
|
||||
"sp-io",
|
||||
"sp-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-evm-precompile-sha3fips"
|
||||
version = "2.0.0-dev"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"fp-evm",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-evm-precompile-simple"
|
||||
version = "2.0.0-dev"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"fp-evm",
|
||||
"ripemd",
|
||||
"sp-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-external-validators"
|
||||
version = "0.1.0"
|
||||
|
|
@ -8871,17 +8999,7 @@ version = "0.6.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||
dependencies = [
|
||||
"fixedbitset 0.4.2",
|
||||
"indexmap 2.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
|
||||
dependencies = [
|
||||
"fixedbitset 0.5.7",
|
||||
"fixedbitset",
|
||||
"indexmap 2.9.0",
|
||||
]
|
||||
|
||||
|
|
@ -9438,6 +9556,49 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "precompile-utils"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"derive_more 1.0.0",
|
||||
"environmental",
|
||||
"evm",
|
||||
"fp-evm",
|
||||
"frame-support",
|
||||
"frame-system",
|
||||
"hex",
|
||||
"hex-literal 0.4.1",
|
||||
"impl-trait-for-tuples",
|
||||
"log",
|
||||
"num_enum",
|
||||
"pallet-evm",
|
||||
"parity-scale-codec",
|
||||
"precompile-utils-macro",
|
||||
"scale-info",
|
||||
"serde",
|
||||
"similar-asserts",
|
||||
"sp-core",
|
||||
"sp-io",
|
||||
"sp-runtime",
|
||||
"sp-weights",
|
||||
"staging-xcm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "precompile-utils-macro"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/polkadot-evm/frontier?rev=75329a2df49e2cc7981485392c31160929d1bd48#75329a2df49e2cc7981485392c31160929d1bd48"
|
||||
dependencies = [
|
||||
"case",
|
||||
"num_enum",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-stable2412-6)",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "2.1.5"
|
||||
|
|
@ -9726,7 +9887,7 @@ dependencies = [
|
|||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
"petgraph 0.7.1",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost 0.13.5",
|
||||
"prost-types",
|
||||
|
|
@ -12448,6 +12609,26 @@ dependencies = [
|
|||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar-asserts"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a"
|
||||
dependencies = [
|
||||
"console",
|
||||
"similar",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple-dns"
|
||||
version = "0.9.3"
|
||||
|
|
@ -14280,6 +14461,19 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-bn"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crunchy",
|
||||
"lazy_static",
|
||||
"rand 0.8.5",
|
||||
"rustc-hex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-build-script-utils"
|
||||
version = "11.0.0"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ members = [
|
|||
"node",
|
||||
"pallets/outbound-commitment-store",
|
||||
"pallets/*",
|
||||
"precompiles/*",
|
||||
"primitives/bridge",
|
||||
"runtime/*",
|
||||
]
|
||||
|
|
@ -29,6 +30,7 @@ pallet-external-validators-rewards = { path = "./pallets/external-validators-rew
|
|||
pallet-external-validators-rewards-runtime-api = { path = "./pallets/external-validators-rewards/runtime-api", default-features = false }
|
||||
pallet-outbound-commitment-store = { path = "./pallets/outbound-commitment-store", default-features = false }
|
||||
pallet-datahaven-native-transfer = { path = "./pallets/datahaven-native-transfer", default-features = false }
|
||||
pallet-evm-precompile-registry = { path = "./precompiles/precompile-registry", default-features = false }
|
||||
|
||||
# Crates.io (wasm)
|
||||
alloy-core = { version = "0.8.15", default-features = false }
|
||||
|
|
@ -54,6 +56,7 @@ libsecp256k1 = { version = "0.7", default-features = false }
|
|||
log = { version = "0.4.25" }
|
||||
milagro-bls = { version = "1.5.4", default-features = false, package = "snowbridge-milagro-bls" }
|
||||
num-bigint = { version = "0.4.3", default-features = false }
|
||||
num_enum = { version = "0.7.3", default-features = false }
|
||||
openssl-sys = { version = "0.9", features = [
|
||||
"vendored",
|
||||
] } # This is just to set the "vendored" feature required for the crossbuild, so that OpenSSL builds from source
|
||||
|
|
@ -211,10 +214,14 @@ pallet-dynamic-fee = { git = "https://github.com/polkadot-evm/frontier", rev="75
|
|||
pallet-ethereum = { git = "https://github.com/polkadot-evm/frontier/", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm = { git = "https://github.com/polkadot-evm/frontier/", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm-chain-id = { git = "https://github.com/polkadot-evm/frontier/", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm-precompile-blake2 = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm-precompile-bn128 = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm-precompile-modexp = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm-precompile-sha3fips = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-evm-precompile-simple = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
pallet-hotfix-sufficients = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
precompile-utils = { git = "https://github.com/polkadot-evm/frontier/", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
precompile-utils-macro = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
|
||||
# Frontier (client)
|
||||
fc-api = { git = "https://github.com/polkadot-evm/frontier", rev="75329a2df49e2cc7981485392c31160929d1bd48", default-features = false }
|
||||
|
|
|
|||
42
operator/precompiles/precompile-registry/Cargo.toml
Normal file
42
operator/precompiles/precompile-registry/Cargo.toml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
[package]
|
||||
name = "pallet-evm-precompile-registry"
|
||||
authors = ["The DataHaven Team"]
|
||||
description = "Registry of active precompiles"
|
||||
edition = "2021"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
# Substrate
|
||||
frame-support = { workspace = true }
|
||||
frame-system = { workspace = true }
|
||||
sp-core = { workspace = true }
|
||||
sp-io = { workspace = true }
|
||||
|
||||
# Frontier
|
||||
fp-evm = { workspace = true }
|
||||
pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
precompile-utils = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# Precompile utils for testing
|
||||
precompile-utils = { workspace = true, features = ["std", "testing"] }
|
||||
|
||||
# Substrate
|
||||
pallet-balances = { workspace = true, features = ["insecure_zero_ed", "std"] }
|
||||
pallet-timestamp = { workspace = true, features = ["std"] }
|
||||
parity-scale-codec = { workspace = true, features = ["max-encoded-len", "std"] }
|
||||
scale-info = { workspace = true, features = ["derive", "std"] }
|
||||
sp-runtime = { workspace = true, features = ["std"] }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"fp-evm/std",
|
||||
"frame-support/std",
|
||||
"frame-system/std",
|
||||
"pallet-evm/std",
|
||||
"parity-scale-codec/std",
|
||||
"precompile-utils/std",
|
||||
"sp-core/std",
|
||||
"sp-io/std",
|
||||
]
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
pragma solidity >=0.8.3;
|
||||
|
||||
/// @dev The PrecompileRegistry contract's address.
|
||||
address constant PRECOMPILE_REGISTRY_ADDRESS = 0x0000000000000000000000000000000000000815;
|
||||
|
||||
/// @dev The PrecompileRegistry contract's instance.
|
||||
PrecompileRegistry constant PRECOMPILE_REGISTRY_CONTRACT = PrecompileRegistry(
|
||||
PRECOMPILE_REGISTRY_ADDRESS
|
||||
);
|
||||
|
||||
/// @author The Moonbeam Team
|
||||
/// @title Precompile Registry
|
||||
/// @dev Interface to the set of available precompiles.
|
||||
/// @custom:address 0x0000000000000000000000000000000000000815
|
||||
interface PrecompileRegistry {
|
||||
/// @dev Query if the given address is a precompile. Note that deactivated precompiles
|
||||
/// are still considered precompiles and will return `true`.
|
||||
/// @param a: Address to query
|
||||
/// @return output Is this address a precompile?
|
||||
/// @custom:selector 446b450e
|
||||
function isPrecompile(address a) external view returns (bool);
|
||||
|
||||
/// @dev Query if the given address is an active precompile. Will return false if the
|
||||
/// address is not a precompile or if this precompile is deactivated.
|
||||
/// @param a: Address to query
|
||||
/// @return output Is this address an active precompile?
|
||||
/// @custom:selector 6f5e23cf
|
||||
function isActivePrecompile(address a) external view returns (bool);
|
||||
|
||||
/// @dev Update the account code of a precompile address.
|
||||
/// As precompiles are implemented inside the Runtime, they don't have a bytecode, and
|
||||
/// their account code is empty by default. However in Solidity calling a function of a
|
||||
/// contract often automatically adds a check that the contract bytecode is non-empty.
|
||||
/// For that reason a dummy code (0x60006000fd) can be inserted at the precompile address
|
||||
/// to pass that check. This function allows any user to insert that code to precompile address
|
||||
/// if they need it.
|
||||
/// @param a: Address of the precompile.
|
||||
/// @custom:selector 48ceb1b4
|
||||
function updateAccountCode(address a) external;
|
||||
}
|
||||
99
operator/precompiles/precompile-registry/src/lib.rs
Normal file
99
operator/precompiles/precompile-registry/src/lib.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright 2019-2025 PureStake Inc.
|
||||
// This file is part of Moonbeam.
|
||||
|
||||
// Moonbeam is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Moonbeam is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use core::marker::PhantomData;
|
||||
use fp_evm::{ExitError, IsPrecompileResult, PrecompileFailure};
|
||||
use precompile_utils::{
|
||||
precompile_set::{is_precompile_or_fail, IsActivePrecompile},
|
||||
prelude::*,
|
||||
};
|
||||
use sp_core::Get;
|
||||
|
||||
const DUMMY_CODE: [u8; 5] = [0x60, 0x00, 0x60, 0x00, 0xfd];
|
||||
|
||||
pub struct PrecompileRegistry<Runtime>(PhantomData<Runtime>);
|
||||
|
||||
#[precompile_utils::precompile]
|
||||
impl<Runtime> PrecompileRegistry<Runtime>
|
||||
where
|
||||
Runtime: pallet_evm::Config,
|
||||
Runtime::PrecompilesType: IsActivePrecompile,
|
||||
{
|
||||
#[precompile::public("isPrecompile(address)")]
|
||||
#[precompile::view]
|
||||
fn is_precompile(handle: &mut impl PrecompileHandle, address: Address) -> EvmResult<bool> {
|
||||
// We consider the precompile set is optimized to do at most one storage read.
|
||||
// In the case of moonbeam, the storage item that can be read is pallet_asset::Asset
|
||||
// (TODO make it more generic, maybe add a const generic on PrecompileRegistry type)
|
||||
// Storage item: Asset:
|
||||
// Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15)
|
||||
handle.record_db_read::<Runtime>(175)?;
|
||||
is_precompile_or_fail::<Runtime>(address.0, handle.remaining_gas())
|
||||
}
|
||||
|
||||
#[precompile::public("isActivePrecompile(address)")]
|
||||
#[precompile::view]
|
||||
fn is_active_precompile(
|
||||
handle: &mut impl PrecompileHandle,
|
||||
address: Address,
|
||||
) -> EvmResult<bool> {
|
||||
// We consider the precompile set is optimized to do at most one storage read.
|
||||
// In the case of moonbeam, the storage item that can be read is pallet_asset::Asset
|
||||
// (TODO make it more generic, maybe add a const generic on PrecompileRegistry type)
|
||||
// Storage item: Asset:
|
||||
// Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15)
|
||||
handle.record_db_read::<Runtime>(175)?;
|
||||
match <Runtime::PrecompilesValue>::get()
|
||||
.is_active_precompile(address.0, handle.remaining_gas())
|
||||
{
|
||||
IsPrecompileResult::Answer { is_precompile, .. } => Ok(is_precompile),
|
||||
IsPrecompileResult::OutOfGas => Err(PrecompileFailure::Error {
|
||||
exit_status: ExitError::OutOfGas,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
#[precompile::public("updateAccountCode(address)")]
|
||||
fn update_account_code(handle: &mut impl PrecompileHandle, address: Address) -> EvmResult<()> {
|
||||
// Prevent touching addresses that are not precompiles.
|
||||
//
|
||||
// We consider the precompile set is optimized to do at most one storage read.
|
||||
// In the case of moonbeam, the storage item that can be read is pallet_asset::Asset
|
||||
// (TODO make it more generic, maybe add a const generic on PrecompileRegistry type)
|
||||
// Storage item: Asset:
|
||||
// Blake2_128(16) + AssetId(16) + AssetDetails((4 * AccountId(20)) + (3 * Balance(16)) + 15)
|
||||
handle.record_db_read::<Runtime>(175)?;
|
||||
if !is_precompile_or_fail::<Runtime>(address.0, handle.remaining_gas())? {
|
||||
return Err(revert("provided address is not a precompile"));
|
||||
}
|
||||
|
||||
// pallet_evm::create_account read storage item pallet_evm::AccountCodes
|
||||
//
|
||||
// AccountCodes: Blake2128(16) + H160(20) + Vec(5)
|
||||
// We asume an existing precompile can hold at most 5 bytes worth of dummy code.
|
||||
handle.record_db_read::<Runtime>(41)?;
|
||||
pallet_evm::Pallet::<Runtime>::create_account(address.0, DUMMY_CODE.to_vec());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
198
operator/precompiles/precompile-registry/src/mock.rs
Normal file
198
operator/precompiles/precompile-registry/src/mock.rs
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
// Copyright 2019-2025 PureStake Inc.
|
||||
// This file is part of Moonbeam.
|
||||
|
||||
// Moonbeam is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Moonbeam is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::*;
|
||||
|
||||
use frame_support::traits::Everything;
|
||||
use frame_support::{construct_runtime, pallet_prelude::*, parameter_types};
|
||||
use pallet_evm::{EnsureAddressNever, EnsureAddressRoot, FrameSystemAccountProvider};
|
||||
use precompile_utils::{mock_account, precompile_set::*, testing::MockAccount};
|
||||
use sp_core::H256;
|
||||
use sp_runtime::BuildStorage;
|
||||
use sp_runtime::{
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
Perbill,
|
||||
};
|
||||
|
||||
pub type AccountId = MockAccount;
|
||||
pub type Balance = u128;
|
||||
|
||||
type Block = frame_system::mocking::MockBlockU32<Runtime>;
|
||||
|
||||
construct_runtime!(
|
||||
pub enum Runtime {
|
||||
System: frame_system,
|
||||
Balances: pallet_balances,
|
||||
Evm: pallet_evm,
|
||||
Timestamp: pallet_timestamp,
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u32 = 250;
|
||||
pub const MaximumBlockWeight: Weight = Weight::from_parts(1024, 1);
|
||||
pub const MaximumBlockLength: u32 = 2 * 1024;
|
||||
pub const AvailableBlockRatio: Perbill = Perbill::one();
|
||||
pub const SS58Prefix: u8 = 42;
|
||||
}
|
||||
|
||||
impl frame_system::Config for Runtime {
|
||||
type BaseCallFilter = Everything;
|
||||
type DbWeight = ();
|
||||
type RuntimeOrigin = RuntimeOrigin;
|
||||
type RuntimeTask = RuntimeTask;
|
||||
type Nonce = u64;
|
||||
type Block = Block;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = AccountId;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = pallet_balances::AccountData<Balance>;
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type BlockWeights = ();
|
||||
type BlockLength = ();
|
||||
type SS58Prefix = SS58Prefix;
|
||||
type OnSetCode = ();
|
||||
type MaxConsumers = frame_support::traits::ConstU32<16>;
|
||||
type SingleBlockMigrations = ();
|
||||
type MultiBlockMigrator = ();
|
||||
type PreInherents = ();
|
||||
type PostInherents = ();
|
||||
type PostTransactions = ();
|
||||
type ExtensionsWeightInfo = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: u128 = 0;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
type MaxReserves = ();
|
||||
type ReserveIdentifier = [u8; 4];
|
||||
type MaxLocks = ();
|
||||
type Balance = Balance;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
type WeightInfo = ();
|
||||
type RuntimeHoldReason = ();
|
||||
type FreezeIdentifier = ();
|
||||
type MaxFreezes = ();
|
||||
type RuntimeFreezeReason = ();
|
||||
type DoneSlashHandler = ();
|
||||
}
|
||||
|
||||
mock_account!(Registry, |_| MockAccount::from_u64(1));
|
||||
mock_account!(Removed, |_| MockAccount::from_u64(2));
|
||||
mock_account!(SmartContract, |_| MockAccount::from_u64(3));
|
||||
|
||||
pub type Precompiles<R> = PrecompileSetBuilder<
|
||||
R,
|
||||
(
|
||||
PrecompileAt<AddressU64<1>, PrecompileRegistry<R>>,
|
||||
RemovedPrecompileAt<AddressU64<2>>,
|
||||
),
|
||||
>;
|
||||
|
||||
pub type PCall = PrecompileRegistryCall<Runtime>;
|
||||
|
||||
parameter_types! {
|
||||
pub PrecompilesValue: Precompiles<Runtime> = Precompiles::new();
|
||||
pub const WeightPerGas: Weight = Weight::from_parts(1, 0);
|
||||
}
|
||||
|
||||
impl pallet_evm::Config for Runtime {
|
||||
type FeeCalculator = ();
|
||||
type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
|
||||
type WeightPerGas = WeightPerGas;
|
||||
type CallOrigin = EnsureAddressRoot<AccountId>;
|
||||
type WithdrawOrigin = EnsureAddressNever<AccountId>;
|
||||
type AddressMapping = AccountId;
|
||||
type Currency = Balances;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Runner = pallet_evm::runner::stack::Runner<Self>;
|
||||
type PrecompilesType = Precompiles<Runtime>;
|
||||
type PrecompilesValue = PrecompilesValue;
|
||||
type ChainId = ();
|
||||
type OnChargeTransaction = ();
|
||||
type BlockGasLimit = ();
|
||||
type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping<Self>;
|
||||
type FindAuthor = ();
|
||||
type OnCreate = ();
|
||||
type GasLimitPovSizeRatio = ();
|
||||
type GasLimitStorageGrowthRatio = ();
|
||||
type Timestamp = Timestamp;
|
||||
type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
|
||||
type AccountProvider = FrameSystemAccountProvider<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MinimumPeriod: u64 = 5;
|
||||
}
|
||||
impl pallet_timestamp::Config for Runtime {
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = ();
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
pub(crate) struct ExtBuilder {
|
||||
// endowed accounts with balances
|
||||
balances: Vec<(AccountId, Balance)>,
|
||||
}
|
||||
|
||||
impl Default for ExtBuilder {
|
||||
fn default() -> ExtBuilder {
|
||||
ExtBuilder { balances: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtBuilder {
|
||||
pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
|
||||
self.balances = balances;
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn build(self) -> sp_io::TestExternalities {
|
||||
let mut t = frame_system::GenesisConfig::<Runtime>::default()
|
||||
.build_storage()
|
||||
.expect("Frame system builds valid default genesis config");
|
||||
|
||||
pallet_balances::GenesisConfig::<Runtime> {
|
||||
balances: self.balances,
|
||||
}
|
||||
.assimilate_storage(&mut t)
|
||||
.expect("Pallet balances storage can be assimilated");
|
||||
|
||||
let mut ext = sp_io::TestExternalities::new(t);
|
||||
ext.execute_with(|| {
|
||||
System::set_block_number(1);
|
||||
pallet_evm::Pallet::<Runtime>::create_account(
|
||||
SmartContract.into(),
|
||||
b"SmartContract".to_vec(),
|
||||
);
|
||||
});
|
||||
ext
|
||||
}
|
||||
}
|
||||
202
operator/precompiles/precompile-registry/src/tests.rs
Normal file
202
operator/precompiles/precompile-registry/src/tests.rs
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
// Copyright 2019-2025 PureStake Inc.
|
||||
// This file is part of Moonbeam.
|
||||
|
||||
// Moonbeam is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Moonbeam is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::mock::{
|
||||
ExtBuilder, PCall, Precompiles, PrecompilesValue, Registry, Removed, Runtime, SmartContract,
|
||||
};
|
||||
use precompile_utils::{prelude::*, testing::*};
|
||||
use sp_core::H160;
|
||||
|
||||
fn precompiles() -> Precompiles<Runtime> {
|
||||
PrecompilesValue::get()
|
||||
}
|
||||
|
||||
mod selectors {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn selectors() {
|
||||
assert!(PCall::is_precompile_selectors().contains(&0x446b450e));
|
||||
assert!(PCall::is_active_precompile_selectors().contains(&0x6f5e23cf));
|
||||
assert!(PCall::update_account_code_selectors().contains(&0x48ceb1b4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modifiers() {
|
||||
ExtBuilder::default()
|
||||
.with_balances(vec![(CryptoAlith.into(), 1000)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let mut tester =
|
||||
PrecompilesModifierTester::new(precompiles(), CryptoAlith, Registry);
|
||||
|
||||
tester.test_view_modifier(PCall::is_precompile_selectors());
|
||||
tester.test_view_modifier(PCall::is_active_precompile_selectors());
|
||||
tester.test_default_modifier(PCall::update_account_code_selectors());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
mod is_precompile {
|
||||
|
||||
use super::*;
|
||||
|
||||
fn call(target_address: impl Into<H160>, output: bool) {
|
||||
ExtBuilder::default()
|
||||
.with_balances(vec![(CryptoAlith.into(), 1000)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
precompiles()
|
||||
.prepare_test(
|
||||
Alice, // can be anyone
|
||||
Registry,
|
||||
PCall::is_precompile {
|
||||
address: Address(target_address.into()),
|
||||
},
|
||||
)
|
||||
.expect_no_logs()
|
||||
.execute_returns(output);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_precompile() {
|
||||
call(Registry, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_removed_precompile() {
|
||||
call(Removed, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_eoa() {
|
||||
call(CryptoAlith, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_smart_contract() {
|
||||
call(SmartContract, false);
|
||||
}
|
||||
}
|
||||
|
||||
mod is_active_precompile {
|
||||
|
||||
use super::*;
|
||||
|
||||
fn call(target_address: impl Into<H160>, output: bool) {
|
||||
ExtBuilder::default()
|
||||
.with_balances(vec![(CryptoAlith.into(), 1000)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
precompiles()
|
||||
.prepare_test(
|
||||
Alice, // can be anyone
|
||||
Registry,
|
||||
PCall::is_active_precompile {
|
||||
address: Address(target_address.into()),
|
||||
},
|
||||
)
|
||||
.expect_no_logs()
|
||||
.execute_returns(output);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_precompile() {
|
||||
call(Registry, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_removed_precompile() {
|
||||
call(Removed, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_eoa() {
|
||||
call(CryptoAlith, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_smart_contract() {
|
||||
call(SmartContract, false);
|
||||
}
|
||||
}
|
||||
|
||||
mod update_account_code {
|
||||
use super::*;
|
||||
|
||||
fn call(target_address: impl Into<H160>, expect_changes: bool) {
|
||||
ExtBuilder::default()
|
||||
.with_balances(vec![(CryptoAlith.into(), 1000)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let target_address = target_address.into();
|
||||
|
||||
let precompiles = precompiles();
|
||||
let tester = precompiles.prepare_test(
|
||||
Alice, // can be anyone
|
||||
Registry,
|
||||
PCall::update_account_code {
|
||||
address: Address(target_address),
|
||||
},
|
||||
);
|
||||
|
||||
if expect_changes {
|
||||
tester.execute_returns(());
|
||||
let new_code = pallet_evm::AccountCodes::<Runtime>::get(target_address);
|
||||
assert_eq!(&new_code, &[0x60, 0x00, 0x60, 0x00, 0xfd]);
|
||||
} else {
|
||||
let current_code = pallet_evm::AccountCodes::<Runtime>::get(target_address);
|
||||
|
||||
tester.execute_reverts(|revert| {
|
||||
revert == b"provided address is not a precompile"
|
||||
});
|
||||
|
||||
let new_code = pallet_evm::AccountCodes::<Runtime>::get(target_address);
|
||||
assert_eq!(current_code, new_code);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_precompile() {
|
||||
call(Registry, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_removed_precompile() {
|
||||
call(Removed, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_eoa() {
|
||||
call(CryptoAlith, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn works_on_smart_contract() {
|
||||
call(SmartContract, false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_solidity_interface() {
|
||||
check_precompile_implements_solidity_interfaces(
|
||||
&["PrecompileRegistry.sol"],
|
||||
PCall::supports_selector,
|
||||
)
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ hex = { workspace = true }
|
|||
hex-literal = { workspace = true }
|
||||
log = { workspace = true }
|
||||
num-bigint = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
pallet-authorship = { workspace = true }
|
||||
pallet-babe = { workspace = true }
|
||||
pallet-balances = { workspace = true, features = ["insecure_zero_ed"] }
|
||||
|
|
@ -40,10 +41,14 @@ pallet-beefy = { workspace = true }
|
|||
pallet-beefy-mmr = { workspace = true }
|
||||
pallet-collective = { workspace = true }
|
||||
pallet-conviction-voting = { workspace = true }
|
||||
pallet-ethereum = { workspace = true }
|
||||
pallet-referenda = { workspace = true }
|
||||
pallet-evm = { workspace = true }
|
||||
pallet-ethereum = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
pallet-evm-chain-id = { workspace = true }
|
||||
pallet-evm-precompile-blake2 = { workspace = true }
|
||||
pallet-evm-precompile-bn128 = { workspace = true }
|
||||
pallet-evm-precompile-modexp = { workspace = true }
|
||||
pallet-evm-precompile-sha3fips = { workspace = true }
|
||||
pallet-evm-precompile-simple = { workspace = true }
|
||||
pallet-external-validators = { workspace = true }
|
||||
pallet-external-validators-rewards = { workspace = true }
|
||||
pallet-external-validators-rewards-runtime-api = { workspace = true }
|
||||
|
|
@ -59,17 +64,19 @@ pallet-datahaven-native-transfer = { workspace = true }
|
|||
pallet-parameters = { workspace = true }
|
||||
pallet-preimage = { workspace = true }
|
||||
pallet-proxy = { workspace = true }
|
||||
pallet-referenda = { workspace = true }
|
||||
pallet-scheduler = { workspace = true }
|
||||
pallet-session = { workspace = true }
|
||||
pallet-sudo = { workspace = true }
|
||||
pallet-timestamp = { workspace = true }
|
||||
pallet-transaction-payment = { workspace = true }
|
||||
pallet-transaction-payment = { workspace = true }
|
||||
pallet-transaction-payment-rpc-runtime-api = { workspace = true }
|
||||
pallet-treasury = { workspace = true }
|
||||
pallet-utility = { workspace = true }
|
||||
pallet-whitelist = { workspace = true }
|
||||
polkadot-primitives = { workspace = true }
|
||||
polkadot-runtime-common = { workspace = true }
|
||||
precompile-utils = { workspace = true }
|
||||
scale-info = { workspace = true, features = ["derive", "serde"] }
|
||||
serde_json = { workspace = true, default-features = false, features = [
|
||||
"alloc",
|
||||
|
|
@ -112,6 +119,8 @@ xcm-executor = { workspace = true }
|
|||
strum = { workspace = true }
|
||||
strum_macros = { workspace = true }
|
||||
|
||||
# DataHaven precompiles
|
||||
pallet-evm-precompile-registry = { workspace = true }
|
||||
|
||||
# StorageHub
|
||||
pallet-bucket-nfts = { workspace = true }
|
||||
|
|
@ -135,7 +144,6 @@ shp-file-key-verifier = { workspace = true }
|
|||
shp-data-price-updater = { workspace = true }
|
||||
sp-trie = { workspace = true }
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { workspace = true, optional = true, default-features = true }
|
||||
|
||||
|
|
@ -145,6 +153,8 @@ frame-support-test = { workspace = true }
|
|||
sp-io = { workspace = true }
|
||||
sp-tracing = { workspace = true }
|
||||
|
||||
precompile-utils = { workspace = true, features = ["std", "testing"] }
|
||||
|
||||
# Snowbridge testing
|
||||
snowbridge-core = { workspace = true }
|
||||
snowbridge-pallet-system = { workspace = true }
|
||||
|
|
@ -157,6 +167,7 @@ std = [
|
|||
"codec/std",
|
||||
"datahaven-runtime-common/std",
|
||||
"fp-account/std",
|
||||
"fp-evm/std",
|
||||
"frame-benchmarking?/std",
|
||||
"frame-executive/std",
|
||||
"frame-metadata-hash-extension/std",
|
||||
|
|
@ -175,6 +186,7 @@ std = [
|
|||
"pallet-ethereum/std",
|
||||
"pallet-evm-chain-id/std",
|
||||
"pallet-evm/std",
|
||||
"pallet-evm-precompile-registry/std",
|
||||
"pallet-external-validators/std",
|
||||
"pallet-external-validators-rewards/std",
|
||||
"pallet-external-validators-rewards-runtime-api/std",
|
||||
|
|
@ -200,6 +212,7 @@ std = [
|
|||
"pallet-whitelist/std",
|
||||
"polkadot-primitives/std",
|
||||
"polkadot-runtime-common/std",
|
||||
"precompile-utils/std",
|
||||
"scale-info/std",
|
||||
"serde_json/std",
|
||||
"snowbridge-beacon-primitives/std",
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ pub mod runtime_params;
|
|||
mod storagehub;
|
||||
|
||||
use super::{
|
||||
currency::*, AccountId, Babe, Balance, Balances, BeefyMmrLeaf, Block, BlockNumber,
|
||||
EthereumBeaconClient, EthereumOutboundQueueV2, EvmChainId, ExistentialDeposit,
|
||||
ExternalValidators, ExternalValidatorsRewards, Hash, Historical, ImOnline, MessageQueue, Nonce,
|
||||
Offences, OriginCaller, OutboundCommitmentStore, PalletInfo, Preimage, Referenda, Runtime,
|
||||
RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason, RuntimeOrigin, RuntimeTask,
|
||||
Scheduler, Session, SessionKeys, Signature, System, Timestamp, Treasury, BLOCK_HASH_COUNT,
|
||||
EXTRINSIC_BASE_WEIGHT, MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
|
||||
SLOT_DURATION, VERSION,
|
||||
currency::*, precompiles::DataHavenPrecompiles, AccountId, Babe, Balance, Balances,
|
||||
BeefyMmrLeaf, Block, BlockNumber, EthereumBeaconClient, EthereumOutboundQueueV2, EvmChainId,
|
||||
ExistentialDeposit, ExternalValidators, ExternalValidatorsRewards, Hash, Historical, ImOnline,
|
||||
MessageQueue, Nonce, Offences, OriginCaller, OutboundCommitmentStore, PalletInfo, Preimage,
|
||||
Referenda, Runtime, RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason,
|
||||
RuntimeOrigin, RuntimeTask, Scheduler, Session, SessionKeys, Signature, System, Timestamp,
|
||||
Treasury, BLOCK_HASH_COUNT, EXTRINSIC_BASE_WEIGHT, MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT,
|
||||
NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use datahaven_runtime_common::{
|
||||
|
|
@ -774,7 +774,7 @@ datahaven_runtime_common::impl_on_charge_evm_transaction!();
|
|||
parameter_types! {
|
||||
pub BlockGasLimit: U256
|
||||
= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
|
||||
// pub PrecompilesValue: TemplatePrecompiles<Runtime> = TemplatePrecompiles::<_>::new();
|
||||
pub PrecompilesValue: DataHavenPrecompiles<Runtime> = DataHavenPrecompiles::<_>::new();
|
||||
pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
|
||||
pub SuicideQuickClearLimit: u32 = 0;
|
||||
/// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare
|
||||
|
|
@ -800,8 +800,8 @@ impl pallet_evm::Config for Runtime {
|
|||
type AddressMapping = IdentityAddressMapping;
|
||||
type Currency = Balances;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type PrecompilesType = ();
|
||||
type PrecompilesValue = ();
|
||||
type PrecompilesType = DataHavenPrecompiles<Self>;
|
||||
type PrecompilesValue = PrecompilesValue;
|
||||
type ChainId = EvmChainId;
|
||||
type BlockGasLimit = BlockGasLimit;
|
||||
type Runner = pallet_evm::runner::stack::Runner<Self>;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
|||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarks;
|
||||
pub mod configs;
|
||||
pub mod precompiles;
|
||||
pub mod weights;
|
||||
|
||||
// Re-export governance for tests
|
||||
|
|
|
|||
67
operator/runtime/mainnet/src/precompiles.rs
Normal file
67
operator/runtime/mainnet/src/precompiles.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2019-2025 The DataHaven Team
|
||||
// This file is part of DataHaven.
|
||||
|
||||
// DataHaven is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// DataHaven is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with DataHaven. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use pallet_evm_precompile_blake2::Blake2F;
|
||||
use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing};
|
||||
use pallet_evm_precompile_modexp::Modexp;
|
||||
use pallet_evm_precompile_registry::PrecompileRegistry;
|
||||
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
|
||||
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
|
||||
use precompile_utils::precompile_set::*;
|
||||
|
||||
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
|
||||
|
||||
/// EVM precompiles available in the DataHaven Mainnet runtime.
|
||||
#[precompile_utils::precompile_name_from_address]
|
||||
type DataHavenPrecompilesAt<R> = (
|
||||
// Ethereum precompiles:
|
||||
// We allow DELEGATECALL to stay compliant with Ethereum behavior.
|
||||
PrecompileAt<AddressU64<1>, ECRecover, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<2>, Sha256, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<3>, Ripemd160, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<4>, Identity, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<5>, Modexp, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<6>, Bn128Add, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<7>, Bn128Mul, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<8>, Bn128Pairing, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<9>, Blake2F, EthereumPrecompilesChecks>,
|
||||
// Non-DataHaven specific nor Ethereum precompiles :
|
||||
PrecompileAt<AddressU64<1024>, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>,
|
||||
RemovedPrecompileAt<AddressU64<1025>>,
|
||||
PrecompileAt<AddressU64<1026>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
|
||||
RemovedPrecompileAt<AddressU64<1027>>,
|
||||
// DataHaven specific precompiles:
|
||||
PrecompileAt<
|
||||
AddressU64<2069>,
|
||||
PrecompileRegistry<R>,
|
||||
(CallableByContract, CallableByPrecompile),
|
||||
>,
|
||||
);
|
||||
|
||||
/// The PrecompileSet installed in the DataHaven runtime.
|
||||
/// We include the nine Istanbul precompiles
|
||||
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
|
||||
/// 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 DataHaven specific
|
||||
/// 2048-4095 DataHaven specific precompiles
|
||||
pub type DataHavenPrecompiles<R> = PrecompileSetBuilder<
|
||||
R,
|
||||
(
|
||||
// Skip precompiles if out of range.
|
||||
PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), DataHavenPrecompilesAt<R>>,
|
||||
),
|
||||
>;
|
||||
|
|
@ -33,6 +33,7 @@ hex = { workspace = true }
|
|||
hex-literal = { workspace = true }
|
||||
log = { workspace = true }
|
||||
num-bigint = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
pallet-authorship = { workspace = true }
|
||||
pallet-babe = { workspace = true }
|
||||
pallet-balances = { workspace = true, features = ["insecure_zero_ed"]}
|
||||
|
|
@ -40,10 +41,14 @@ pallet-beefy = { workspace = true }
|
|||
pallet-beefy-mmr = { workspace = true }
|
||||
pallet-collective = { workspace = true }
|
||||
pallet-conviction-voting = { workspace = true }
|
||||
pallet-ethereum = { workspace = true }
|
||||
pallet-referenda = { workspace = true }
|
||||
pallet-evm = { workspace = true }
|
||||
pallet-ethereum = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
pallet-evm-chain-id = { workspace = true }
|
||||
pallet-evm-precompile-blake2 = { workspace = true }
|
||||
pallet-evm-precompile-bn128 = { workspace = true }
|
||||
pallet-evm-precompile-modexp = { workspace = true }
|
||||
pallet-evm-precompile-sha3fips = { workspace = true }
|
||||
pallet-evm-precompile-simple = { workspace = true }
|
||||
pallet-external-validators = { workspace = true }
|
||||
pallet-external-validators-rewards = { workspace = true }
|
||||
pallet-external-validators-rewards-runtime-api = { workspace = true }
|
||||
|
|
@ -59,6 +64,7 @@ pallet-datahaven-native-transfer = { workspace = true }
|
|||
pallet-parameters = { workspace = true }
|
||||
pallet-preimage = { workspace = true }
|
||||
pallet-proxy = { workspace = true }
|
||||
pallet-referenda = { workspace = true }
|
||||
pallet-scheduler = { workspace = true }
|
||||
pallet-session = { workspace = true }
|
||||
pallet-sudo = { workspace = true }
|
||||
|
|
@ -70,6 +76,7 @@ pallet-utility = { workspace = true }
|
|||
pallet-whitelist = { workspace = true }
|
||||
polkadot-primitives = { workspace = true }
|
||||
polkadot-runtime-common = { workspace = true }
|
||||
precompile-utils = { workspace = true }
|
||||
scale-info = { workspace = true, features = ["derive", "serde"] }
|
||||
serde_json = { workspace = true, default-features = false, features = [
|
||||
"alloc",
|
||||
|
|
@ -112,6 +119,9 @@ xcm = { workspace = true }
|
|||
xcm-builder = { workspace = true }
|
||||
xcm-executor = { workspace = true }
|
||||
|
||||
# DataHaven precompiles
|
||||
pallet-evm-precompile-registry = { workspace = true }
|
||||
|
||||
# StorageHub
|
||||
pallet-bucket-nfts = { workspace = true }
|
||||
pallet-nfts = { workspace = true }
|
||||
|
|
@ -143,6 +153,8 @@ frame-support-test = { workspace = true }
|
|||
sp-io = { workspace = true }
|
||||
sp-tracing = { workspace = true }
|
||||
|
||||
precompile-utils = { workspace = true, features = ["std", "testing"] }
|
||||
|
||||
# Snowbridge testing
|
||||
snowbridge-core = { workspace = true }
|
||||
snowbridge-pallet-system = { workspace = true }
|
||||
|
|
@ -155,6 +167,7 @@ std = [
|
|||
"codec/std",
|
||||
"datahaven-runtime-common/std",
|
||||
"fp-account/std",
|
||||
"fp-evm/std",
|
||||
"frame-benchmarking?/std",
|
||||
"frame-executive/std",
|
||||
"frame-metadata-hash-extension/std",
|
||||
|
|
@ -173,6 +186,7 @@ std = [
|
|||
"pallet-ethereum/std",
|
||||
"pallet-evm-chain-id/std",
|
||||
"pallet-evm/std",
|
||||
"pallet-evm-precompile-registry/std",
|
||||
"pallet-external-validators/std",
|
||||
"pallet-external-validators-rewards/std",
|
||||
"pallet-external-validators-rewards-runtime-api/std",
|
||||
|
|
@ -198,6 +212,7 @@ std = [
|
|||
"pallet-whitelist/std",
|
||||
"polkadot-primitives/std",
|
||||
"polkadot-runtime-common/std",
|
||||
"precompile-utils/std",
|
||||
"scale-info/std",
|
||||
"serde_json/std",
|
||||
"snowbridge-beacon-primitives/std",
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ pub mod runtime_params;
|
|||
mod storagehub;
|
||||
|
||||
use super::{
|
||||
currency::*, AccountId, Babe, Balance, Balances, BeefyMmrLeaf, Block, BlockNumber,
|
||||
EthereumBeaconClient, EthereumOutboundQueueV2, EvmChainId, ExistentialDeposit,
|
||||
ExternalValidators, ExternalValidatorsRewards, Hash, Historical, ImOnline, MessageQueue, Nonce,
|
||||
Offences, OriginCaller, OutboundCommitmentStore, PalletInfo, Preimage, Referenda, Runtime,
|
||||
RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason, RuntimeOrigin, RuntimeTask,
|
||||
Scheduler, Session, SessionKeys, Signature, System, Timestamp, Treasury, BLOCK_HASH_COUNT,
|
||||
EXTRINSIC_BASE_WEIGHT, MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
|
||||
SLOT_DURATION, VERSION,
|
||||
currency::*, precompiles::DataHavenPrecompiles, AccountId, Babe, Balance, Balances,
|
||||
BeefyMmrLeaf, Block, BlockNumber, EthereumBeaconClient, EthereumOutboundQueueV2, EvmChainId,
|
||||
ExistentialDeposit, ExternalValidators, ExternalValidatorsRewards, Hash, Historical, ImOnline,
|
||||
MessageQueue, Nonce, Offences, OriginCaller, OutboundCommitmentStore, PalletInfo, Preimage,
|
||||
Referenda, Runtime, RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason,
|
||||
RuntimeOrigin, RuntimeTask, Scheduler, Session, SessionKeys, Signature, System, Timestamp,
|
||||
Treasury, BLOCK_HASH_COUNT, EXTRINSIC_BASE_WEIGHT, MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT,
|
||||
NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use datahaven_runtime_common::{
|
||||
|
|
@ -773,7 +773,7 @@ datahaven_runtime_common::impl_on_charge_evm_transaction!();
|
|||
parameter_types! {
|
||||
pub BlockGasLimit: U256
|
||||
= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
|
||||
// pub PrecompilesValue: TemplatePrecompiles<Runtime> = TemplatePrecompiles::<_>::new();
|
||||
pub PrecompilesValue: DataHavenPrecompiles<Runtime> = DataHavenPrecompiles::<_>::new();
|
||||
pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
|
||||
pub SuicideQuickClearLimit: u32 = 0;
|
||||
/// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare
|
||||
|
|
@ -799,8 +799,8 @@ impl pallet_evm::Config for Runtime {
|
|||
type AddressMapping = IdentityAddressMapping;
|
||||
type Currency = Balances;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type PrecompilesType = ();
|
||||
type PrecompilesValue = ();
|
||||
type PrecompilesType = DataHavenPrecompiles<Self>;
|
||||
type PrecompilesValue = PrecompilesValue;
|
||||
type ChainId = EvmChainId;
|
||||
type BlockGasLimit = BlockGasLimit;
|
||||
type Runner = pallet_evm::runner::stack::Runner<Self>;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
|||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarks;
|
||||
pub mod configs;
|
||||
pub mod precompiles;
|
||||
pub mod weights;
|
||||
|
||||
// Re-export governance for tests
|
||||
|
|
|
|||
67
operator/runtime/stagenet/src/precompiles.rs
Normal file
67
operator/runtime/stagenet/src/precompiles.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2019-2025 The DataHaven Team
|
||||
// This file is part of DataHaven.
|
||||
|
||||
// DataHaven is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// DataHaven is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with DataHaven. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use pallet_evm_precompile_blake2::Blake2F;
|
||||
use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing};
|
||||
use pallet_evm_precompile_modexp::Modexp;
|
||||
use pallet_evm_precompile_registry::PrecompileRegistry;
|
||||
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
|
||||
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
|
||||
use precompile_utils::precompile_set::*;
|
||||
|
||||
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
|
||||
|
||||
/// EVM precompiles available in the DataHaven Stagenet runtime.
|
||||
#[precompile_utils::precompile_name_from_address]
|
||||
type DataHavenPrecompilesAt<R> = (
|
||||
// Ethereum precompiles:
|
||||
// We allow DELEGATECALL to stay compliant with Ethereum behavior.
|
||||
PrecompileAt<AddressU64<1>, ECRecover, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<2>, Sha256, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<3>, Ripemd160, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<4>, Identity, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<5>, Modexp, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<6>, Bn128Add, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<7>, Bn128Mul, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<8>, Bn128Pairing, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<9>, Blake2F, EthereumPrecompilesChecks>,
|
||||
// Non-DataHaven specific nor Ethereum precompiles :
|
||||
PrecompileAt<AddressU64<1024>, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>,
|
||||
RemovedPrecompileAt<AddressU64<1025>>,
|
||||
PrecompileAt<AddressU64<1026>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
|
||||
RemovedPrecompileAt<AddressU64<1027>>,
|
||||
// DataHaven specific precompiles:
|
||||
PrecompileAt<
|
||||
AddressU64<2069>,
|
||||
PrecompileRegistry<R>,
|
||||
(CallableByContract, CallableByPrecompile),
|
||||
>,
|
||||
);
|
||||
|
||||
/// The PrecompileSet installed in the DataHaven runtime.
|
||||
/// We include the nine Istanbul precompiles
|
||||
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
|
||||
/// 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 DataHaven specific
|
||||
/// 2048-4095 DataHaven specific precompiles
|
||||
pub type DataHavenPrecompiles<R> = PrecompileSetBuilder<
|
||||
R,
|
||||
(
|
||||
// Skip precompiles if out of range.
|
||||
PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), DataHavenPrecompilesAt<R>>,
|
||||
),
|
||||
>;
|
||||
|
|
@ -33,6 +33,7 @@ hex = { workspace = true }
|
|||
hex-literal = { workspace = true }
|
||||
log = { workspace = true }
|
||||
num-bigint = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
pallet-authorship = { workspace = true }
|
||||
pallet-babe = { workspace = true }
|
||||
pallet-balances = { workspace = true, features = ["insecure_zero_ed"] }
|
||||
|
|
@ -41,10 +42,14 @@ pallet-beefy-mmr = { workspace = true }
|
|||
pallet-collective = { workspace = true }
|
||||
pallet-conviction-voting = { workspace = true }
|
||||
pallet-datahaven-native-transfer = { workspace = true }
|
||||
pallet-referenda = { workspace = true }
|
||||
pallet-ethereum = { workspace = true }
|
||||
pallet-evm = { workspace = true }
|
||||
pallet-ethereum = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] }
|
||||
pallet-evm-chain-id = { workspace = true }
|
||||
pallet-evm-precompile-blake2 = { workspace = true }
|
||||
pallet-evm-precompile-bn128 = { workspace = true }
|
||||
pallet-evm-precompile-modexp = { workspace = true }
|
||||
pallet-evm-precompile-sha3fips = { workspace = true }
|
||||
pallet-evm-precompile-simple = { workspace = true }
|
||||
pallet-external-validators = { workspace = true }
|
||||
pallet-external-validators-rewards = { workspace = true }
|
||||
pallet-external-validators-rewards-runtime-api = { workspace = true }
|
||||
|
|
@ -59,6 +64,7 @@ pallet-outbound-commitment-store = { workspace = true }
|
|||
pallet-parameters = { workspace = true }
|
||||
pallet-preimage = { workspace = true }
|
||||
pallet-proxy = { workspace = true }
|
||||
pallet-referenda = { workspace = true }
|
||||
pallet-scheduler = { workspace = true }
|
||||
pallet-session = { workspace = true }
|
||||
pallet-sudo = { workspace = true }
|
||||
|
|
@ -70,6 +76,7 @@ pallet-utility = { workspace = true }
|
|||
pallet-whitelist = { workspace = true }
|
||||
polkadot-primitives = { workspace = true }
|
||||
polkadot-runtime-common = { workspace = true }
|
||||
precompile-utils = { workspace = true }
|
||||
scale-info = { workspace = true, features = ["derive", "serde"] }
|
||||
serde_json = { workspace = true, default-features = false, features = [
|
||||
"alloc",
|
||||
|
|
@ -112,6 +119,9 @@ xcm-executor = { workspace = true }
|
|||
strum = { workspace = true }
|
||||
strum_macros = { workspace = true }
|
||||
|
||||
# DataHaven precompiles
|
||||
pallet-evm-precompile-registry = { workspace = true }
|
||||
|
||||
# StorageHub
|
||||
pallet-bucket-nfts = { workspace = true }
|
||||
pallet-nfts = { workspace = true }
|
||||
|
|
@ -143,6 +153,8 @@ frame-support-test = { workspace = true }
|
|||
sp-io = { workspace = true }
|
||||
sp-tracing = { workspace = true }
|
||||
|
||||
precompile-utils = { workspace = true, features = ["std", "testing"] }
|
||||
|
||||
# Snowbridge testing
|
||||
snowbridge-core = { workspace = true }
|
||||
snowbridge-outbound-queue-primitives = { workspace = true }
|
||||
|
|
@ -155,6 +167,7 @@ std = [
|
|||
"codec/std",
|
||||
"datahaven-runtime-common/std",
|
||||
"fp-account/std",
|
||||
"fp-evm/std",
|
||||
"frame-benchmarking?/std",
|
||||
"frame-executive/std",
|
||||
"frame-metadata-hash-extension/std",
|
||||
|
|
@ -173,6 +186,7 @@ std = [
|
|||
"pallet-ethereum/std",
|
||||
"pallet-evm-chain-id/std",
|
||||
"pallet-evm/std",
|
||||
"pallet-evm-precompile-registry/std",
|
||||
"pallet-grandpa/std",
|
||||
"pallet-identity/std",
|
||||
"pallet-im-online/std",
|
||||
|
|
@ -195,6 +209,7 @@ std = [
|
|||
"pallet-whitelist/std",
|
||||
"polkadot-primitives/std",
|
||||
"polkadot-runtime-common/std",
|
||||
"precompile-utils/std",
|
||||
"scale-info/std",
|
||||
"serde_json/std",
|
||||
"snowbridge-beacon-primitives/std",
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ pub mod runtime_params;
|
|||
mod storagehub;
|
||||
|
||||
use super::{
|
||||
currency::*, AccountId, Babe, Balance, Balances, BeefyMmrLeaf, Block, BlockNumber,
|
||||
EthereumBeaconClient, EthereumOutboundQueueV2, EvmChainId, ExistentialDeposit,
|
||||
ExternalValidators, ExternalValidatorsRewards, Hash, Historical, ImOnline, MessageQueue, Nonce,
|
||||
Offences, OriginCaller, OutboundCommitmentStore, PalletInfo, Preimage, Referenda, Runtime,
|
||||
RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason, RuntimeOrigin, RuntimeTask,
|
||||
Scheduler, Session, SessionKeys, Signature, System, Timestamp, Treasury, BLOCK_HASH_COUNT,
|
||||
EXTRINSIC_BASE_WEIGHT, MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
|
||||
SLOT_DURATION, VERSION,
|
||||
currency::*, precompiles::DataHavenPrecompiles, AccountId, Babe, Balance, Balances,
|
||||
BeefyMmrLeaf, Block, BlockNumber, EthereumBeaconClient, EthereumOutboundQueueV2, EvmChainId,
|
||||
ExistentialDeposit, ExternalValidators, ExternalValidatorsRewards, Hash, Historical, ImOnline,
|
||||
MessageQueue, Nonce, Offences, OriginCaller, OutboundCommitmentStore, PalletInfo, Preimage,
|
||||
Referenda, Runtime, RuntimeCall, RuntimeEvent, RuntimeFreezeReason, RuntimeHoldReason,
|
||||
RuntimeOrigin, RuntimeTask, Scheduler, Session, SessionKeys, Signature, System, Timestamp,
|
||||
Treasury, BLOCK_HASH_COUNT, EXTRINSIC_BASE_WEIGHT, MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT,
|
||||
NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use datahaven_runtime_common::{
|
||||
|
|
@ -773,7 +773,7 @@ datahaven_runtime_common::impl_on_charge_evm_transaction!();
|
|||
parameter_types! {
|
||||
pub BlockGasLimit: U256
|
||||
= U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS);
|
||||
// pub PrecompilesValue: TemplatePrecompiles<Runtime> = TemplatePrecompiles::<_>::new();
|
||||
pub PrecompilesValue: DataHavenPrecompiles<Runtime> = DataHavenPrecompiles::<_>::new();
|
||||
pub WeightPerGas: Weight = Weight::from_parts(WEIGHT_PER_GAS, 0);
|
||||
pub SuicideQuickClearLimit: u32 = 0;
|
||||
/// The amount of gas per pov. A ratio of 16 if we convert ref_time to gas and we compare
|
||||
|
|
@ -799,8 +799,8 @@ impl pallet_evm::Config for Runtime {
|
|||
type AddressMapping = IdentityAddressMapping;
|
||||
type Currency = Balances;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type PrecompilesType = ();
|
||||
type PrecompilesValue = ();
|
||||
type PrecompilesType = DataHavenPrecompiles<Self>;
|
||||
type PrecompilesValue = PrecompilesValue;
|
||||
type ChainId = EvmChainId;
|
||||
type BlockGasLimit = BlockGasLimit;
|
||||
type Runner = pallet_evm::runner::stack::Runner<Self>;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
|||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarks;
|
||||
pub mod configs;
|
||||
pub mod precompiles;
|
||||
pub mod weights;
|
||||
// Re-export governance for tests
|
||||
pub use configs::governance;
|
||||
|
|
|
|||
67
operator/runtime/testnet/src/precompiles.rs
Normal file
67
operator/runtime/testnet/src/precompiles.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2019-2025 The DataHaven Team
|
||||
// This file is part of DataHaven.
|
||||
|
||||
// DataHaven is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// DataHaven is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with DataHaven. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use pallet_evm_precompile_blake2::Blake2F;
|
||||
use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing};
|
||||
use pallet_evm_precompile_modexp::Modexp;
|
||||
use pallet_evm_precompile_registry::PrecompileRegistry;
|
||||
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
|
||||
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
|
||||
use precompile_utils::precompile_set::*;
|
||||
|
||||
type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, CallableByPrecompile);
|
||||
|
||||
/// EVM precompiles available in the DataHaven Testnet runtime.
|
||||
#[precompile_utils::precompile_name_from_address]
|
||||
type DataHavenPrecompilesAt<R> = (
|
||||
// Ethereum precompiles:
|
||||
// We allow DELEGATECALL to stay compliant with Ethereum behavior.
|
||||
PrecompileAt<AddressU64<1>, ECRecover, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<2>, Sha256, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<3>, Ripemd160, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<4>, Identity, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<5>, Modexp, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<6>, Bn128Add, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<7>, Bn128Mul, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<8>, Bn128Pairing, EthereumPrecompilesChecks>,
|
||||
PrecompileAt<AddressU64<9>, Blake2F, EthereumPrecompilesChecks>,
|
||||
// Non-DataHaven specific nor Ethereum precompiles :
|
||||
PrecompileAt<AddressU64<1024>, Sha3FIPS256, (CallableByContract, CallableByPrecompile)>,
|
||||
RemovedPrecompileAt<AddressU64<1025>>,
|
||||
PrecompileAt<AddressU64<1026>, ECRecoverPublicKey, (CallableByContract, CallableByPrecompile)>,
|
||||
RemovedPrecompileAt<AddressU64<1027>>,
|
||||
// DataHaven specific precompiles:
|
||||
PrecompileAt<
|
||||
AddressU64<2069>,
|
||||
PrecompileRegistry<R>,
|
||||
(CallableByContract, CallableByPrecompile),
|
||||
>,
|
||||
);
|
||||
|
||||
/// The PrecompileSet installed in the DataHaven runtime.
|
||||
/// We include the nine Istanbul precompiles
|
||||
/// (https://github.com/ethereum/go-ethereum/blob/3c46f557/core/vm/contracts.go#L69)
|
||||
/// 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 DataHaven specific
|
||||
/// 2048-4095 DataHaven specific precompiles
|
||||
pub type DataHavenPrecompiles<R> = PrecompileSetBuilder<
|
||||
R,
|
||||
(
|
||||
// Skip precompiles if out of range.
|
||||
PrecompilesInRangeInclusive<(AddressU64<1>, AddressU64<4095>), DataHavenPrecompilesAt<R>>,
|
||||
),
|
||||
>;
|
||||
Loading…
Reference in a new issue