From bfd40d397ea9a3076afca13f1985d440cc0d50b5 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 23 Mar 2026 19:03:16 +0800 Subject: [PATCH 1/3] revert pr 2445 --- Cargo.lock | 1 - contract-tests/src/contracts/drand.ts | 37 -------- contract-tests/test/drand.precompile.test.ts | 98 -------------------- pallets/admin-utils/src/lib.rs | 2 - precompiles/Cargo.toml | 2 - precompiles/src/drand.rs | 57 ------------ precompiles/src/lib.rs | 11 +-- runtime/tests/precompiles.rs | 97 ------------------- 8 files changed, 1 insertion(+), 304 deletions(-) delete mode 100644 contract-tests/src/contracts/drand.ts delete mode 100644 contract-tests/test/drand.precompile.test.ts delete mode 100644 precompiles/src/drand.rs diff --git a/Cargo.lock b/Cargo.lock index ef764199aa..4b29e9c313 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18227,7 +18227,6 @@ dependencies = [ "pallet-admin-utils", "pallet-balances", "pallet-crowdloan", - "pallet-drand", "pallet-evm", "pallet-evm-precompile-bn128", "pallet-evm-precompile-dispatch", diff --git a/contract-tests/src/contracts/drand.ts b/contract-tests/src/contracts/drand.ts deleted file mode 100644 index 32a0c5c9c0..0000000000 --- a/contract-tests/src/contracts/drand.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Drand precompile address: 0x80e = 2062 -export const IDRAND_ADDRESS = "0x000000000000000000000000000000000000080e"; - -export const IDrandABI = [ - { - inputs: [ - { - internalType: "uint64", - name: "round", - type: "uint64", - }, - ], - name: "getRandomness", - outputs: [ - { - internalType: "bytes32", - name: "", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "getLastStoredRound", - outputs: [ - { - internalType: "uint64", - name: "", - type: "uint64", - }, - ], - stateMutability: "view", - type: "function", - }, -] as const; diff --git a/contract-tests/test/drand.precompile.test.ts b/contract-tests/test/drand.precompile.test.ts deleted file mode 100644 index 76612012f7..0000000000 --- a/contract-tests/test/drand.precompile.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as assert from "assert"; - -import { getDevnetApi } from "../src/substrate"; -import { getPublicClient } from "../src/utils"; -import { ETH_LOCAL_URL } from "../src/config"; -import { devnet } from "@polkadot-api/descriptors"; -import { PublicClient } from "viem"; -import { TypedApi } from "polkadot-api"; -import { toViemAddress } from "../src/address-utils"; -import { IDrandABI, IDRAND_ADDRESS } from "../src/contracts/drand"; - -describe("Test Drand Precompile", () => { - let publicClient: PublicClient; - let api: TypedApi; - - before(async () => { - publicClient = await getPublicClient(ETH_LOCAL_URL); - api = await getDevnetApi(); - }); - - describe("Drand Randomness Functions", () => { - it("getLastStoredRound returns a value", async () => { - const lastRound = await publicClient.readContract({ - abi: IDrandABI, - address: toViemAddress(IDRAND_ADDRESS), - functionName: "getLastStoredRound", - args: [], - }); - - const lastRoundFromApi = await api.query.Drand.LastStoredRound.getValue({ at: "best" }); - - assert.ok(lastRound !== undefined, "getLastStoredRound should return a value"); - assert.strictEqual( - typeof lastRound, - "bigint", - "getLastStoredRound should return a bigint" - ); - assert.ok(lastRound === lastRoundFromApi, "Last stored round should match the value from the API"); - }); - - it("getRandomness returns bytes32 for a round", async () => { - const lastRound = await publicClient.readContract({ - abi: IDrandABI, - address: toViemAddress(IDRAND_ADDRESS), - functionName: "getLastStoredRound", - args: [], - }); - - const randomness = await publicClient.readContract({ - abi: IDrandABI, - address: toViemAddress(IDRAND_ADDRESS), - functionName: "getRandomness", - args: [lastRound], - }); - - const pulseFromApi = await api.query.Drand.Pulses.getValue(lastRound, { at: "best" }); - const randomnessFromApi = pulseFromApi?.randomness.asHex(); - - assert.ok(randomness !== undefined, "getRandomness should return a value"); - assert.strictEqual( - typeof randomness, - "string", - "getRandomness should return a hex string (bytes32)" - ); - assert.strictEqual( - randomness.length, - 66, - "bytes32 should be 0x + 64 hex chars" - ); - assert.strictEqual( - randomness, - randomnessFromApi, - "Randomness should match the value from the API" - ); - }); - - it("getRandomness for non-existent round returns zero bytes", async () => { - // Use a very high round number that will not have a stored pulse - const nonExistentRound = BigInt(999999999); - const randomness = await publicClient.readContract({ - abi: IDrandABI, - address: toViemAddress(IDRAND_ADDRESS), - functionName: "getRandomness", - args: [nonExistentRound], - }); - - console.log("randomness", randomness); - - assert.ok(randomness !== undefined, "getRandomness should return a value"); - const zeroBytes32 = "0x" + "0".repeat(64); - assert.strictEqual( - randomness.toLowerCase(), - zeroBytes32, - "getRandomness for non-existent round should return zero bytes32" - ); - }); - }); -}); diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 972efa9d2a..a0c094e564 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -147,8 +147,6 @@ pub mod pallet { AddressMapping, /// Voting power precompile VotingPower, - /// Drand randomness precompile - Drand, } #[pallet::type_value] diff --git a/precompiles/Cargo.toml b/precompiles/Cargo.toml index 8bf412c503..be1824cf91 100644 --- a/precompiles/Cargo.toml +++ b/precompiles/Cargo.toml @@ -39,7 +39,6 @@ pallet-admin-utils.workspace = true subtensor-swap-interface.workspace = true pallet-crowdloan.workspace = true pallet-shield.workspace = true -pallet-drand.workspace = true [lints] workspace = true @@ -66,7 +65,6 @@ std = [ "pallet-subtensor-swap/std", "pallet-subtensor/std", "pallet-shield/std", - "pallet-drand/std", "precompile-utils/std", "scale-info/std", "sp-core/std", diff --git a/precompiles/src/drand.rs b/precompiles/src/drand.rs deleted file mode 100644 index 3a1449afba..0000000000 --- a/precompiles/src/drand.rs +++ /dev/null @@ -1,57 +0,0 @@ -use core::marker::PhantomData; - -use fp_evm::PrecompileHandle; -use precompile_utils::EvmResult; -use sp_core::H256; - -use crate::PrecompileExt; - -/// Drand precompile for smart contract access to Drand beacon randomness. -/// -/// This precompile allows smart contracts to read verifiable randomness from the -/// Drand Quicknet beacon that is bridged on-chain by the Drand pallet. -pub struct DrandPrecompile(PhantomData); - -impl PrecompileExt for DrandPrecompile -where - R: frame_system::Config + pallet_drand::Config, - R::AccountId: From<[u8; 32]>, -{ - const INDEX: u64 = 2062; -} - -#[precompile_utils::precompile] -impl DrandPrecompile -where - R: frame_system::Config + pallet_drand::Config, - R::AccountId: From<[u8; 32]>, -{ - /// Get the 32-byte randomness for a specific Drand round. - /// - /// Returns the SHA256 hash of the BLS signature for the given round. - /// Returns 32 zero bytes if no pulse exists for the round. - /// - /// # Arguments - /// * `round` - The Drand round number (u64) - /// - /// # Returns - /// * `bytes32` - The 32-byte randomness, or zeros if round not stored - #[precompile::public("getRandomness(uint64)")] - #[precompile::view] - fn get_randomness(_: &mut impl PrecompileHandle, round: u64) -> EvmResult { - let randomness = pallet_drand::Pallet::::random_at(round); - Ok(H256::from(randomness)) - } - - /// Get the last Drand round that has been stored on-chain. - /// - /// Returns 0 if no pulses have been stored yet. - /// - /// # Returns - /// * `uint64` - The last stored round number - #[precompile::public("getLastStoredRound()")] - #[precompile::view] - fn get_last_stored_round(_: &mut impl PrecompileHandle) -> EvmResult { - Ok(pallet_drand::LastStoredRound::::get()) - } -} diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs index 2a4c4e42f3..a824ac39d4 100644 --- a/precompiles/src/lib.rs +++ b/precompiles/src/lib.rs @@ -31,7 +31,6 @@ pub use address_mapping::AddressMappingPrecompile; pub use alpha::AlphaPrecompile; pub use balance_transfer::BalanceTransferPrecompile; pub use crowdloan::CrowdloanPrecompile; -pub use drand::DrandPrecompile; pub use ed25519::Ed25519Verify; pub use extensions::PrecompileExt; pub use leasing::LeasingPrecompile; @@ -49,7 +48,6 @@ mod address_mapping; mod alpha; mod balance_transfer; mod crowdloan; -mod drand; mod ed25519; mod extensions; mod leasing; @@ -77,7 +75,6 @@ where + pallet_crowdloan::Config + pallet_shield::Config + pallet_subtensor_proxy::Config - + pallet_drand::Config + Send + Sync + scale_info::TypeInfo, @@ -115,7 +112,6 @@ where + pallet_crowdloan::Config + pallet_shield::Config + pallet_subtensor_proxy::Config - + pallet_drand::Config + Send + Sync + scale_info::TypeInfo, @@ -140,7 +136,7 @@ where Self(Default::default()) } - pub fn used_addresses() -> [H160; 28] { + pub fn used_addresses() -> [H160; 27] { [ hash(1), hash(2), @@ -169,7 +165,6 @@ where hash(VotingPowerPrecompile::::INDEX), hash(ProxyPrecompile::::INDEX), hash(AddressMappingPrecompile::::INDEX), - hash(DrandPrecompile::::INDEX), ] } } @@ -185,7 +180,6 @@ where + pallet_crowdloan::Config + pallet_shield::Config + pallet_subtensor_proxy::Config - + pallet_drand::Config + Send + Sync + scale_info::TypeInfo, @@ -279,9 +273,6 @@ where PrecompileEnum::AddressMapping, ) } - a if a == hash(DrandPrecompile::::INDEX) => { - DrandPrecompile::::try_execute::(handle, PrecompileEnum::Drand) - } _ => None, } } diff --git a/runtime/tests/precompiles.rs b/runtime/tests/precompiles.rs index a9fc7a222f..d5daf5cf8a 100644 --- a/runtime/tests/precompiles.rs +++ b/runtime/tests/precompiles.rs @@ -7,7 +7,6 @@ use std::collections::BTreeSet; use fp_evm::{Context, ExitError, PrecompileFailure, PrecompileResult}; use frame_support::BoundedVec; use node_subtensor_runtime::{BuildStorage, Runtime, RuntimeGenesisConfig, System}; -use pallet_drand::{LastStoredRound, Pulses, types::Pulse}; use pallet_evm::{AddressMapping, BalanceConverter, PrecompileSet}; use precompile_utils::testing::{MockHandle, PrecompileTesterExt}; use sp_core::{H160, H256, U256}; @@ -220,99 +219,3 @@ mod balance_transfer { }); } } - -mod drand { - use super::*; - - fn get_last_stored_round_call_data() -> Vec { - let selector = sp_io::hashing::keccak_256(b"getLastStoredRound()"); - selector[..4].to_vec() - } - - fn get_randomness_call_data(round: u64) -> Vec { - let selector = sp_io::hashing::keccak_256(b"getRandomness(uint64)"); - let mut input = Vec::with_capacity(4 + 32); - input.extend_from_slice(&selector[..4]); - input.extend_from_slice(&[0u8; 24]); - input.extend_from_slice(&round.to_be_bytes()); - input - } - - #[test] - fn drand_precompile_get_last_stored_round_returns_value() { - new_test_ext().execute_with(|| { - let round = 1000; - LastStoredRound::::put(round); - let precompiles = Precompiles::::new(); - let caller = addr_from_index(1); - let precompile_addr = addr_from_index(DrandPrecompile::::INDEX); - let input = get_last_stored_round_call_data(); - - let result = - execute_precompile(&precompiles, precompile_addr, caller, input, U256::zero()); - let precompile_result = - result.expect("expected precompile call to be routed to drand precompile"); - let output = precompile_result - .expect("expected successful getLastStoredRound call") - .output; - - assert_eq!( - output.len(), - 32, - "getLastStoredRound should return 32 bytes (uint64 ABI)" - ); - #[allow(clippy::indexing_slicing)] - let output_u64 = u64::from_be_bytes(output[24..32].try_into().unwrap()); - assert_eq!(output_u64, round); - }); - } - - #[test] - fn drand_precompile_get_randomness_returns_bytes32() { - new_test_ext().execute_with(|| { - let round = 1000; - let value = 1u8; - Pulses::::insert( - round, - Pulse { - round: 1000, - randomness: BoundedVec::truncate_from(vec![value; 32]), - signature: BoundedVec::truncate_from(vec![0u8; 96]), - }, - ); - let precompiles = Precompiles::::new(); - let caller = addr_from_index(1); - let precompile_addr = addr_from_index(DrandPrecompile::::INDEX); - let input = get_randomness_call_data(round); - - let result = - execute_precompile(&precompiles, precompile_addr, caller, input, U256::zero()); - let precompile_result = - result.expect("expected precompile call to be routed to drand precompile"); - let output = precompile_result - .expect("expected successful getRandomness call") - .output; - - assert_eq!( - output.len(), - 32, - "getRandomness should return 32 bytes (bytes32)" - ); - assert!( - output.iter().all(|&b| b == value), - "getRandomness for round 1000 should return the inserted randomness (32 bytes of 1s)" - ); - - let non_existent_round = 999_999_999u64; - let input = get_randomness_call_data(non_existent_round); - let result = - execute_precompile(&precompiles, precompile_addr, caller, input, U256::zero()); - let precompile_result = - result.expect("expected precompile call to be routed to drand precompile"); - let output = precompile_result - .expect("expected successful getRandomness call") - .output; - assert!(output.iter().all(|&b| b == 0), "getRandomness for non-existent round should return 32 bytes of 0s"); - }); - } -} From 01ec40eca29bb00a60915e0126af466cf678c131 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 23 Mar 2026 19:05:31 +0800 Subject: [PATCH 2/3] commit Cargo.lock --- runtime/tests/precompiles.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/runtime/tests/precompiles.rs b/runtime/tests/precompiles.rs index d5daf5cf8a..815d055ab7 100644 --- a/runtime/tests/precompiles.rs +++ b/runtime/tests/precompiles.rs @@ -5,15 +5,13 @@ use core::iter::IntoIterator; use std::collections::BTreeSet; use fp_evm::{Context, ExitError, PrecompileFailure, PrecompileResult}; -use frame_support::BoundedVec; use node_subtensor_runtime::{BuildStorage, Runtime, RuntimeGenesisConfig, System}; use pallet_evm::{AddressMapping, BalanceConverter, PrecompileSet}; use precompile_utils::testing::{MockHandle, PrecompileTesterExt}; use sp_core::{H160, H256, U256}; use sp_runtime::traits::Hash; use subtensor_precompiles::{ - AddressMappingPrecompile, BalanceTransferPrecompile, DrandPrecompile, PrecompileExt, - Precompiles, + AddressMappingPrecompile, BalanceTransferPrecompile, PrecompileExt, Precompiles, }; type AccountId = ::AccountId; From d383748d30fcddf3d335af674babedae966f47d8 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 23 Mar 2026 19:07:01 +0800 Subject: [PATCH 3/3] bump version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5fd4e5b401..ecb8944aa9 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -268,7 +268,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 393, + spec_version: 394, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,