Skip to content

feat: implement drand randomness precompile#2

Open
fine135 wants to merge 1 commit into
mainfrom
feat/drand-precompile
Open

feat: implement drand randomness precompile#2
fine135 wants to merge 1 commit into
mainfrom
feat/drand-precompile

Conversation

@fine135

@fine135 fine135 commented Mar 11, 2026

Copy link
Copy Markdown
Collaborator

Introduces a new EVM precompile for smart contracts to access the Substrate Drand randomness beacon state.

  • Added DrandPrecompile in drand.rs to expose pallet-drand storage to EVM
  • Added PrecompileHandleExtStorage trait to automate gas cost calculation on database reads based on SCALE-encoded size
  • Created Solidity interface and ABI in drand.sol and drand.abi, mapped to address 0x0811
  • Hooked the new precompile into the EVM environment in lib.rs
  • Added comprehensive TypeScript test suite in drand.precompile.test.ts covering edge cases, decoding, and gas metering
  • Updated related dependencies in Cargo.toml and yarn.lock

Description

This PR implements a new precompile mapped to address 0x0811 that bridges the Substrate pallet-drand state into the EVM environment. This allows Solidity smart contracts to perform read-only queries for verifiable randomness pulses, beacon configurations, and round information using native Ethereum types (like bytes32). It introduces the DrandPrecompile Rust implementation alongside an efficient PrecompileHandleExtStorage trait to cleanly calculate gas costs based on the SCALE-encoded size of DB reads. Additional exhaustive TypeScript tests ensure correct behavior, accurate ABI decoding, and precise gas metering.
Note on getPalletVersion():
As requested in the initial specification (opentensor/subtensor#2455), this precompile includes a getPalletVersion() function. Since the pallet-drand itself does not maintain its own explicit versioning in storage, this function is currently implemented to return a hardcoded placeholder version based on the requirements described in that issue.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Other (please describe):

Checklist

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have run ./scripts/fix_rust.sh to ensure my code is formatted and linted correctly
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Additional Notes

The implementation uses a 1-byte minimum gas charge rule for empty database reads to prevent spamming the RPC / node with arbitrary read attempts.

Introduces a new EVM precompile for smart contracts to access the Substrate Drand randomness beacon state.
- Added DrandPrecompile in drand.rs to expose pallet-drand storage to EVM
- Added PrecompileHandleExtStorage trait to automate gas cost calculation on database reads based on SCALE-encoded size
- Created Solidity interface and ABI in drand.sol and drand.abi, mapped to address 0x0811
- Hooked the new precompile into the EVM environment in lib.rs
- Added comprehensive TypeScript test suite in drand.precompile.test.ts covering edge cases, decoding, and gas metering
- Updated related dependencies in Cargo.toml and yarn.lock
Comment thread pallets/drand/src/lib.rs
Comment on lines +42 to +46
function getPulse(uint64 round) external view returns (DrandPulse memory);

/// @dev Returns the randomness from the latest stored round as bytes32.
/// Returns zero bytes32 if no pulse is stored.
function getCurrentRandomness() external view returns (bytes32);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We want the contracts to get the randomness for the current block regardless of whether it's drand-based or new-future-method-based, so I don't think it should use round numbers but block numbers which should then be, in subtensor, translated to the drand number or another-future-source randomness id.

Future proof it.

Comment thread precompiles/src/solidity/drand.sol
Comment thread precompiles/src/solidity/drand.sol
Comment thread precompiles/src/solidity/drand.sol
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants