Skip to content

Commit

Permalink
Stefan/documentation (#355)
Browse files Browse the repository at this point in the history
* oracle randomness doc

* slippy
  • Loading branch information
mutobui authored Oct 9, 2023
1 parent 1e2516b commit d1ab789
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 38 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
Expand Down
6 changes: 3 additions & 3 deletions game/offchain-worker-randomness/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub mod pallet {

/// Number of attempts to re-randomize in order to reduce modulus bias.
#[pallet::constant]
type RandomAttemps: Get<u32>;
type RandomAttempts: Get<u32>;
}

/// Defines the block when next unsigned transaction will be accepted.
Expand Down Expand Up @@ -177,7 +177,7 @@ pub mod pallet {

impl<T: Config> GameRandomness for Pallet<T> {
/// 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.
///
Expand All @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions game/offchain-worker-randomness/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand Down
71 changes: 70 additions & 1 deletion game/oracle-randomness/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,70 @@
License: MIT-0
# 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<T>},
...
);
```

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<T>, seed: Vec<u8>) -> DispatchResult`: Submits the a oracle's seed from offchain worker.

- `set_new_random_urls(urls: Vec<Vec<u8>>) -> DispatchResult`: Root set new oracle source urls.

### Metadata Functions
- `random_number(total: u32, adjust: u32) -> Option<T::u32>`: Retrieves the latest generated random number.


## License
Apache License 2.0.
81 changes: 58 additions & 23 deletions game/oracle-randomness/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>;
type RandomAttempts: Get<u32>;

/// Seed's Length
#[pallet::constant]
type SeedLength: Get<u32>;

/// Maximum number of URLs
#[pallet::constant]
type MaxRandomURL: Get<u32>;

/// Maximum URL length
#[pallet::constant]
type RandomURLLength: Get<u32>;

Expand All @@ -69,11 +73,12 @@ pub mod pallet {
type UnsignedInterval: Get<BlockNumberFor<Self>>;
}

/// Storing random seed generated.
/// Storing randomly generated seed.
#[pallet::storage]
pub(crate) type RandomSeed<T: Config> =
StorageValue<_, SeedPayload<BlockNumberFor<T>, BoundedVec<u8, T::SeedLength>>, OptionQuery>;

/// Storing URLs to get randomness.
#[pallet::storage]
#[pallet::getter(fn urls)]
pub type RandomnessURLs<T: Config> = StorageValue<
Expand All @@ -82,29 +87,17 @@ pub mod pallet {
ValueQuery,
>;

// #[pallet::type_value]
// pub fn DefaultURLIndexing<T: Config>() -> u32 {
// 0u32
// }

// #[pallet::storage]
// #[pallet::getter(fn url_indexing)]
// pub type URLIndexing<T: Config> = StorageValue<
// _,
// u32,
// ValueQuery,
// DefaultURLIndexing<T>,
// >;

/// Storing the next unsigned block.
#[pallet::storage]
#[pallet::getter(fn next_unsigned_at)]
pub(super) type NextUnsignedAt<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;

/// Currently selected URL for URL switching.
#[pallet::storage]
#[pallet::getter(fn next_randomness_url)]
pub(super) type SelectedRandomnessURL<T: Config> =
StorageValue<_, BoundedVec<u8, T::RandomURLLength>, OptionQuery>;

#[pallet::genesis_config]
#[derive(frame_support::DefaultNoBound)]
pub struct GenesisConfig<T> {
Expand Down Expand Up @@ -156,6 +149,19 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
/// 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<T>, urls: Vec<Vec<u8>>) -> DispatchResult {
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -232,6 +253,14 @@ pub mod pallet {
}

impl<T: Config> Pallet<T> {
/// 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<Vec<u8>>,
maybe_current_url: Option<Vec<u8>>,
Expand Down Expand Up @@ -275,12 +304,18 @@ pub mod pallet {
}

impl<T: Config> GameRandomness for Pallet<T> {
/// 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<u32> {
if total == 0 {
return None
Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion game/oracle-randomness/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<MAX_RANDOM_URL>;
type RandomURLLength = ConstU32<URL_LENGTH>;
Expand Down
2 changes: 1 addition & 1 deletion runtime/devnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ parameter_types! {
impl oracle_randomness::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = OracleRandomnessWeight<Runtime>;
type RandomAttemps = OracleRandomAttemps;
type RandomAttempts = OracleRandomAttemps;
type SeedLength = SeedLength;
type MaxRandomURL = MaxRandomURL;
type RandomURLLength = RandomURLLength;
Expand Down
2 changes: 1 addition & 1 deletion runtime/testnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ parameter_types! {
impl oracle_randomness::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = OracleRandomnessWeight<Runtime>;
type RandomAttemps = OracleRandomAttemps;
type RandomAttempts = OracleRandomAttemps;
type SeedLength = SeedLength;
type MaxRandomURL = MaxRandomURL;
type RandomURLLength = RandomURLLength;
Expand Down
6 changes: 3 additions & 3 deletions support/src/game/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down

0 comments on commit d1ab789

Please sign in to comment.