From d1ab7890b6fa583d79902131f0315549e203184c Mon Sep 17 00:00:00 2001 From: Stefan Date: Mon, 9 Oct 2023 16:07:12 +0700 Subject: [PATCH] Stefan/documentation (#355) * oracle randomness doc * slippy --- .github/workflows/check.yml | 6 +- Cargo.toml | 2 +- game/offchain-worker-randomness/src/lib.rs | 6 +- game/offchain-worker-randomness/src/mock.rs | 4 +- game/oracle-randomness/README.md | 71 +++++++++++++++++- game/oracle-randomness/src/lib.rs | 81 +++++++++++++++------ game/oracle-randomness/src/mock.rs | 2 +- runtime/devnet/src/lib.rs | 2 +- runtime/testnet/src/lib.rs | 2 +- support/src/game/types.rs | 6 +- 10 files changed, 144 insertions(+), 38 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index c15aaf26..7c3d93de 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -35,7 +35,9 @@ jobs: - name: Check Build for Benchmarking run: | - mkdir node # Create the "node" directory + if [ ! -d "node" ]; then + mkdir node # Create the "node" directory + fi pushd node make check-benchmark - popd # Return to the previous directory + popd # Return to the previous directory \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 1f40e60f..6d9201ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -182,7 +182,7 @@ cumulus-relay-chain-rpc-interface = { git = "https://github.com/paritytech/cumul [features] -default = [] +# default = [] devnet-native = ["gafi-cli/devnet-native"] testnet-native = ["gafi-cli/testnet-native"] runtime-benchmarks= [ "gafi-cli/runtime-benchmarks" ] diff --git a/game/offchain-worker-randomness/src/lib.rs b/game/offchain-worker-randomness/src/lib.rs index e69f466a..6b367d1c 100644 --- a/game/offchain-worker-randomness/src/lib.rs +++ b/game/offchain-worker-randomness/src/lib.rs @@ -100,7 +100,7 @@ pub mod pallet { /// Number of attempts to re-randomize in order to reduce modulus bias. #[pallet::constant] - type RandomAttemps: Get; + type RandomAttempts: Get; } /// Defines the block when next unsigned transaction will be accepted. @@ -177,7 +177,7 @@ pub mod pallet { impl GameRandomness for Pallet { /// Generates a random number between 1 and `total` (inclusive). - /// This function repeats the process up to `RandomAttemps` times if + /// This function repeats the process up to `RandomAttempts` times if /// the number falls within the overflow range of the modulo operation to mitigate modulo /// bias. /// @@ -189,7 +189,7 @@ pub mod pallet { return None } let mut random_number = Self::generate_random_number(random); - for _ in 1..T::RandomAttemps::get() { + for _ in 1..T::RandomAttempts::get() { if random_number < u32::MAX.saturating_sub(u32::MAX.wrapping_rem(total)) { break } diff --git a/game/offchain-worker-randomness/src/mock.rs b/game/offchain-worker-randomness/src/mock.rs index b2565bb9..278e0b43 100644 --- a/game/offchain-worker-randomness/src/mock.rs +++ b/game/offchain-worker-randomness/src/mock.rs @@ -55,7 +55,7 @@ impl pallet_insecure_randomness_collective_flip::Config for Test {} parameter_types! { pub PalletGameId: PalletId = PalletId(*b"gamegame"); pub const UnsignedPriority: u64 = 100; - pub const RandomAttemps: u32 = 10; + pub const RandomAttempts: u32 = 10; pub const UnsignedInterval: u32 = 1; } @@ -64,7 +64,7 @@ impl offchain_worker_randomness::Config for Test { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); type Randomness = RandomnessCollectiveFlip; - type RandomAttemps = RandomAttemps; + type RandomAttempts = RandomAttempts; type UnsignedPriority = UnsignedPriority; type UnsignedInterval = UnsignedInterval; } diff --git a/game/oracle-randomness/README.md b/game/oracle-randomness/README.md index d0d59537..aa688c5b 100644 --- a/game/oracle-randomness/README.md +++ b/game/oracle-randomness/README.md @@ -1 +1,70 @@ -License: MIT-0 \ No newline at end of file +# Title: Oracle Randomness Pallet + +## Introduction +The Oracle Randomness Pallet is a module that provides a secure and decentralized source of randomness on the blockchain. It allows users to generate random numbers that are verifiably fair and unbiased, making it suitable for various applications such as gaming, lotteries, and random selection processes. + +## Features +- Generation of random numbers using a decentralized oracle network +- Verifiable fairness and transparency of the generated random numbers +- Integration with other modules and smart contracts on the blockchain +- Configurable parameters for randomness generation + +## Usage +To use the Oracle Randomness Pallet in your runtime or application, follow these steps: + +1. Add the pallet as a dependency in your `Cargo.toml` file: + ```toml + [dependencies] + oracle-randomness = { version = "x.x.x", default-features = false } + ``` + +2. Import the pallet into your runtime: + ```rust + use oracle_randomness; + ``` + +3. Configure the pallet by setting the desired parameters in your runtime's `construct_runtime!` macro: + ```rust + construct_runtime!( + ... + OracleRandomness: oracle_randomness::{Pallet, Call, Storage, Event}, + ... + ); + ``` + +4. Implement the necessary traits for the Oracle Randomness Pallet in your runtime: + ```rust + impl oracle_randomness::Config for Runtime { + type Event = Event; + } + ``` + +5. Use the provided dispatchable functions or methods to interact with the Oracle Randomness Pallet. + +## Terminology +- Oracle: A trusted entity that provides random number generation services on the blockchain. +- Randomness: A sequence of unpredictable and unbiased numbers generated by the Oracle Randomness Pallet. + +## Goals +The Oracle Randomness Pallet aims to achieve the following goals: +- Provide a secure and decentralized source of randomness on the blockchain. +- Ensure verifiable fairness and transparency of the generated random numbers. +- Enable integration with other modules and smart contracts for various applications. + +## Interface +The Oracle Randomness Pallet provides the following dispatchable functions or methods: + +### Permissionless Functions +- `request_randomness(seed: T::Hash) -> DispatchResult`: Requests the generation of a random number using the specified seed. + +### Permissioned Functions +- `submit_random_seed_unsigned(block_number: BlockNumberFor, seed: Vec) -> DispatchResult`: Submits the a oracle's seed from offchain worker. + +- `set_new_random_urls(urls: Vec>) -> DispatchResult`: Root set new oracle source urls. + +### Metadata Functions +- `random_number(total: u32, adjust: u32) -> Option`: Retrieves the latest generated random number. + + +## License +Apache License 2.0. \ No newline at end of file diff --git a/game/oracle-randomness/src/lib.rs b/game/oracle-randomness/src/lib.rs index c82858d7..c67d0240 100644 --- a/game/oracle-randomness/src/lib.rs +++ b/game/oracle-randomness/src/lib.rs @@ -42,15 +42,19 @@ pub mod pallet { /// Type representing the weight of this pallet type WeightInfo: WeightInfo; + /// Maximum number of attempts. #[pallet::constant] - type RandomAttemps: Get; + type RandomAttempts: Get; + /// Seed's Length #[pallet::constant] type SeedLength: Get; + /// Maximum number of URLs #[pallet::constant] type MaxRandomURL: Get; + /// Maximum URL length #[pallet::constant] type RandomURLLength: Get; @@ -69,11 +73,12 @@ pub mod pallet { type UnsignedInterval: Get>; } - /// Storing random seed generated. + /// Storing randomly generated seed. #[pallet::storage] pub(crate) type RandomSeed = StorageValue<_, SeedPayload, BoundedVec>, OptionQuery>; + /// Storing URLs to get randomness. #[pallet::storage] #[pallet::getter(fn urls)] pub type RandomnessURLs = StorageValue< @@ -82,29 +87,17 @@ pub mod pallet { ValueQuery, >; - // #[pallet::type_value] - // pub fn DefaultURLIndexing() -> u32 { - // 0u32 - // } - - // #[pallet::storage] - // #[pallet::getter(fn url_indexing)] - // pub type URLIndexing = StorageValue< - // _, - // u32, - // ValueQuery, - // DefaultURLIndexing, - // >; - + /// Storing the next unsigned block. #[pallet::storage] #[pallet::getter(fn next_unsigned_at)] pub(super) type NextUnsignedAt = StorageValue<_, BlockNumberFor, ValueQuery>; + /// Currently selected URL for URL switching. #[pallet::storage] #[pallet::getter(fn next_randomness_url)] pub(super) type SelectedRandomnessURL = StorageValue<_, BoundedVec, OptionQuery>; - + #[pallet::genesis_config] #[derive(frame_support::DefaultNoBound)] pub struct GenesisConfig { @@ -156,6 +149,19 @@ pub mod pallet { #[pallet::call] impl Pallet { + /// Set new random URLs for the oracle. + /// + /// This function allows the privileged origin to set new random URLs for the oracle. The + /// origin must be signed by a privileged account. + /// + /// Parameters: + /// - `origin`: The origin of the call, which must be a privileged account. + /// - `urls`: A vector of vectors of bytes representing the new random URLs to be set. + /// + /// Events: + /// - Emits a `NewOracleRandomnessURL` event when the new random URLs are successfully set. + /// + /// Weight: `O(1)` #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::set_new_random_urls())] pub fn set_new_random_urls(origin: OriginFor, urls: Vec>) -> DispatchResult { @@ -192,6 +198,21 @@ pub mod pallet { Ok(()) } + /// Submit a random seed from an unsigned source. + /// + /// This function allows an unsigned source to submit a random seed for the oracle. The + /// origin must be none (unsigned). + /// + /// Parameters: + /// - `origin`: The origin of the call, which must be none (unsigned). + /// - `block_number`: The block number associated with the random seed. + /// - `seed`: A vector of bytes representing the random seed to be submitted. + /// + /// Events: + /// - Emits a `NewOracleRandomnessSeed` event when the random seed is successfully + /// submitted. + /// + /// Weight: `O(1)` #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::submit_random_seed_unsigned())] pub fn submit_random_seed_unsigned( @@ -232,6 +253,14 @@ pub mod pallet { } impl Pallet { + /// Get the next URL from a list of URLs. + /// + /// Parameters: + /// - `urls`: A vector of vectors of bytes representing the list of URLs. + /// - `maybe_current_url`: An optional vector of bytes representing the current URL. + /// + /// Returns: + /// - An optional vector of bytes representing the next URL. pub fn get_next_url( urls: Vec>, maybe_current_url: Option>, @@ -275,12 +304,18 @@ pub mod pallet { } impl GameRandomness for Pallet { - /// Generates a random number between 1 and `total` (inclusive). - /// This function repeats the process up to `RandomAttemps` times if - /// the number falls within the overflow range of the modulo operation to mitigate modulo - /// bias. + /// Generate a random number. + /// + /// This function generates a random number from 1 to `total` based on the provided + /// parameters. It uses the current random seed stored in the storage to generate the random + /// number. + /// + /// Parameters: + /// - `total`: The total number of possible outcomes. + /// - `adjust`: An adjustment value to add to the seed before generating the random number. /// - /// Returns `None` if `total` is 0. + /// Returns: + /// - An optional random number. fn random_number(total: u32, adjust: u32) -> Option { if total == 0 { return None @@ -290,7 +325,7 @@ pub mod pallet { let mut extended_seed = payload.seed.to_vec(); extended_seed.extend_from_slice(&adjust.to_le_bytes()); let seed_hash = blake2_256(&extended_seed); - return Self::random_bias(&seed_hash, total, T::RandomAttemps::get()) + return Self::random_bias(&seed_hash, total, T::RandomAttempts::get()) } None } diff --git a/game/oracle-randomness/src/mock.rs b/game/oracle-randomness/src/mock.rs index 55e295a9..2999dd56 100644 --- a/game/oracle-randomness/src/mock.rs +++ b/game/oracle-randomness/src/mock.rs @@ -58,7 +58,7 @@ parameter_types! { impl oracle_randomness::Config for Test { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type RandomAttemps = ConstU32<5>; + type RandomAttempts = ConstU32<5>; type SeedLength = SeedLength; type MaxRandomURL = ConstU32; type RandomURLLength = ConstU32; diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 1eaf8758..c6caed27 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -465,7 +465,7 @@ parameter_types! { impl oracle_randomness::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = OracleRandomnessWeight; - type RandomAttemps = OracleRandomAttemps; + type RandomAttempts = OracleRandomAttemps; type SeedLength = SeedLength; type MaxRandomURL = MaxRandomURL; type RandomURLLength = RandomURLLength; diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 3b969acd..77c34cbc 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -461,7 +461,7 @@ parameter_types! { impl oracle_randomness::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = OracleRandomnessWeight; - type RandomAttemps = OracleRandomAttemps; + type RandomAttempts = OracleRandomAttemps; type SeedLength = SeedLength; type MaxRandomURL = MaxRandomURL; type RandomURLLength = RandomURLLength; diff --git a/support/src/game/types.rs b/support/src/game/types.rs index 88395efd..5f325316 100644 --- a/support/src/game/types.rs +++ b/support/src/game/types.rs @@ -111,11 +111,11 @@ where Seed: Debug + AsRef<[u8]>, { fn fmt(&self, f: &mut Formatter<'_>) -> sp_std::fmt::Result { - write!(f, " block_number: {:?},\n", self.block_number)?; + writeln!(f, " block_number: {:?}", self.block_number)?; if let Ok(seed) = sp_std::str::from_utf8(self.seed.as_ref()) { - write!(f, " seed: {:?}\n", seed)?; + writeln!(f, " seed: {:?}", seed)?; } else { - write!(f, " seed: {:?}\n", self.seed)?; + writeln!(f, " seed: {:?}", self.seed)?; } Ok(()) }