feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
[package]
|
||||
name = "pezsp-consensus-sassafras"
|
||||
version = "0.3.4-dev"
|
||||
authors.workspace = true
|
||||
description = "Primitives for Sassafras consensus"
|
||||
edition.workspace = true
|
||||
license = "Apache-2.0"
|
||||
homepage.workspace = true
|
||||
repository = "https://github.com/pezkuwichain/pezkuwi-sdk/"
|
||||
documentation = "https://docs.rs/pezsp-consensus-sassafras"
|
||||
readme = "README.md"
|
||||
publish = false
|
||||
|
||||
[package.metadata.pezkuwi-sdk]
|
||||
exclude-from-umbrella = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { workspace = true }
|
||||
scale-info = { features = ["derive"], workspace = true }
|
||||
serde = { features = ["derive"], optional = true, workspace = true }
|
||||
pezsp-api = { workspace = true }
|
||||
pezsp-application-crypto = { features = [
|
||||
"bandersnatch-experimental",
|
||||
], workspace = true }
|
||||
pezsp-consensus-slots = { workspace = true }
|
||||
pezsp-core = { features = ["bandersnatch-experimental"], workspace = true }
|
||||
pezsp-runtime = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"codec/std",
|
||||
"scale-info/std",
|
||||
"serde/std",
|
||||
"pezsp-api/std",
|
||||
"pezsp-application-crypto/std",
|
||||
"pezsp-consensus-slots/std",
|
||||
"pezsp-core/std",
|
||||
"pezsp-runtime/std",
|
||||
]
|
||||
|
||||
# Serde support without relying on std features.
|
||||
serde = [
|
||||
"dep:serde",
|
||||
"scale-info/serde",
|
||||
"pezsp-application-crypto/serde",
|
||||
"pezsp-consensus-slots/serde",
|
||||
"pezsp-core/serde",
|
||||
"pezsp-runtime/serde",
|
||||
]
|
||||
runtime-benchmarks = [
|
||||
"pezsp-api/runtime-benchmarks",
|
||||
"pezsp-consensus-slots/runtime-benchmarks",
|
||||
"pezsp-runtime/runtime-benchmarks",
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
Primitives for SASSAFRAS.
|
||||
|
||||
- Tracking issue: https://github.com/pezkuwichain/pezkuwi-sdk/issues/95
|
||||
- RFC proposal: https://github.com/polkadot-fellows/RFCs/pull/26
|
||||
|
||||
Depends on `pezsp-core` feature: `bandersnatch-experimental`.
|
||||
@@ -0,0 +1,99 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Sassafras digests structures and helpers.
|
||||
|
||||
use crate::{
|
||||
ticket::TicketClaim, vrf::VrfSignature, AuthorityId, AuthorityIndex, AuthoritySignature,
|
||||
EpochConfiguration, Randomness, Slot, SASSAFRAS_ENGINE_ID,
|
||||
};
|
||||
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
use pezsp_runtime::{DigestItem, RuntimeDebug};
|
||||
|
||||
/// Epoch slot claim digest entry.
|
||||
///
|
||||
/// This is mandatory for each block.
|
||||
#[derive(Clone, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||
pub struct SlotClaim {
|
||||
/// Authority index that claimed the slot.
|
||||
pub authority_idx: AuthorityIndex,
|
||||
/// Corresponding slot number.
|
||||
pub slot: Slot,
|
||||
/// Slot claim VRF signature.
|
||||
pub vrf_signature: VrfSignature,
|
||||
/// Ticket auxiliary information for claim check.
|
||||
pub ticket_claim: Option<TicketClaim>,
|
||||
}
|
||||
|
||||
/// Information about the next epoch.
|
||||
///
|
||||
/// This is mandatory in the first block of each epoch.
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)]
|
||||
pub struct NextEpochDescriptor {
|
||||
/// Randomness value.
|
||||
pub randomness: Randomness,
|
||||
/// Authorities list.
|
||||
pub authorities: Vec<AuthorityId>,
|
||||
/// Epoch configuration.
|
||||
///
|
||||
/// If not present previous epoch parameters are used.
|
||||
pub config: Option<EpochConfiguration>,
|
||||
}
|
||||
|
||||
/// Runtime digest entries.
|
||||
///
|
||||
/// Entries which may be generated by on-chain code.
|
||||
#[derive(Decode, Encode, Clone, PartialEq, Eq)]
|
||||
pub enum ConsensusLog {
|
||||
/// Provides information about the next epoch parameters.
|
||||
#[codec(index = 1)]
|
||||
NextEpochData(NextEpochDescriptor),
|
||||
/// Disable the authority with given index.
|
||||
#[codec(index = 2)]
|
||||
OnDisabled(AuthorityIndex),
|
||||
}
|
||||
|
||||
impl TryFrom<&DigestItem> for SlotClaim {
|
||||
type Error = ();
|
||||
fn try_from(item: &DigestItem) -> Result<Self, Self::Error> {
|
||||
item.pre_runtime_try_to(&SASSAFRAS_ENGINE_ID).ok_or(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&SlotClaim> for DigestItem {
|
||||
fn from(claim: &SlotClaim) -> Self {
|
||||
DigestItem::PreRuntime(SASSAFRAS_ENGINE_ID, claim.encode())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&DigestItem> for AuthoritySignature {
|
||||
type Error = ();
|
||||
fn try_from(item: &DigestItem) -> Result<Self, Self::Error> {
|
||||
item.seal_try_to(&SASSAFRAS_ENGINE_ID).ok_or(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&AuthoritySignature> for DigestItem {
|
||||
fn from(signature: &AuthoritySignature) -> Self {
|
||||
DigestItem::Seal(SASSAFRAS_ENGINE_ID, signature.encode())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Primitives for Sassafras consensus.
|
||||
|
||||
#![deny(warnings)]
|
||||
#![forbid(unsafe_code, missing_docs, unused_variables, unused_imports)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_core::crypto::KeyTypeId;
|
||||
use pezsp_runtime::{ConsensusEngineId, RuntimeDebug};
|
||||
|
||||
pub use pezsp_consensus_slots::{Slot, SlotDuration};
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod digests;
|
||||
pub mod ticket;
|
||||
pub mod vrf;
|
||||
|
||||
pub use ticket::{
|
||||
ticket_id_threshold, EphemeralPublic, EphemeralSignature, TicketBody, TicketClaim,
|
||||
TicketEnvelope, TicketId,
|
||||
};
|
||||
|
||||
mod app {
|
||||
use pezsp_application_crypto::{app_crypto, bandersnatch, key_types::SASSAFRAS};
|
||||
app_crypto!(bandersnatch, SASSAFRAS);
|
||||
}
|
||||
|
||||
/// Key type identifier.
|
||||
pub const KEY_TYPE: KeyTypeId = pezsp_application_crypto::key_types::SASSAFRAS;
|
||||
|
||||
/// Consensus engine identifier.
|
||||
pub const SASSAFRAS_ENGINE_ID: ConsensusEngineId = *b"SASS";
|
||||
|
||||
/// VRF output length for per-slot randomness.
|
||||
pub const RANDOMNESS_LENGTH: usize = 32;
|
||||
|
||||
/// Index of an authority.
|
||||
pub type AuthorityIndex = u32;
|
||||
|
||||
/// Sassafras authority keypair. Necessarily equivalent to the schnorrkel public key used in
|
||||
/// the main Sassafras module. If that ever changes, then this must, too.
|
||||
#[cfg(feature = "std")]
|
||||
pub type AuthorityPair = app::Pair;
|
||||
|
||||
/// Sassafras authority signature.
|
||||
pub type AuthoritySignature = app::Signature;
|
||||
|
||||
/// Sassafras authority identifier. Necessarily equivalent to the schnorrkel public key used in
|
||||
/// the main Sassafras module. If that ever changes, then this must, too.
|
||||
pub type AuthorityId = app::Public;
|
||||
|
||||
/// Weight of a Sassafras block.
|
||||
/// Primary blocks have a weight of 1 whereas secondary blocks have a weight of 0.
|
||||
pub type SassafrasBlockWeight = u32;
|
||||
|
||||
/// An equivocation proof for multiple block authorships on the same slot (i.e. double vote).
|
||||
pub type EquivocationProof<H> = pezsp_consensus_slots::EquivocationProof<H, AuthorityId>;
|
||||
|
||||
/// Randomness required by some protocol's operations.
|
||||
pub type Randomness = [u8; RANDOMNESS_LENGTH];
|
||||
|
||||
/// Protocol configuration that can be modified on epoch change.
|
||||
///
|
||||
/// Mostly tweaks to the ticketing system parameters.
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Encode,
|
||||
Decode,
|
||||
DecodeWithMemTracking,
|
||||
RuntimeDebug,
|
||||
MaxEncodedLen,
|
||||
TypeInfo,
|
||||
Default,
|
||||
)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct EpochConfiguration {
|
||||
/// Tickets redundancy factor.
|
||||
///
|
||||
/// Expected ratio between epoch's slots and the cumulative number of tickets which can
|
||||
/// be submitted by the set of epoch validators.
|
||||
pub redundancy_factor: u32,
|
||||
/// Tickets max attempts for each validator.
|
||||
///
|
||||
/// Influences the anonymity of block producers. As all published tickets have a public
|
||||
/// attempt number less than `attempts_number` if two tickets share an attempt number
|
||||
/// then they must belong to two different validators, which reduces anonymity late as
|
||||
/// we approach the epoch tail.
|
||||
///
|
||||
/// This anonymity loss already becomes small when `attempts_number = 64` or `128`.
|
||||
pub attempts_number: u32,
|
||||
}
|
||||
|
||||
/// Sassafras epoch information
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, TypeInfo)]
|
||||
pub struct Epoch {
|
||||
/// Epoch index.
|
||||
pub index: u64,
|
||||
/// Starting slot of the epoch.
|
||||
pub start: Slot,
|
||||
/// Number of slots in the epoch.
|
||||
pub length: u32,
|
||||
/// Randomness value.
|
||||
pub randomness: Randomness,
|
||||
/// Authorities list.
|
||||
pub authorities: Vec<AuthorityId>,
|
||||
/// Epoch configuration.
|
||||
pub config: EpochConfiguration,
|
||||
}
|
||||
|
||||
/// An opaque type used to represent the key ownership proof at the runtime API boundary.
|
||||
///
|
||||
/// The inner value is an encoded representation of the actual key ownership proof which will be
|
||||
/// parameterized when defining the runtime. At the runtime API boundary this type is unknown and
|
||||
/// as such we keep this opaque representation, implementors of the runtime API will have to make
|
||||
/// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type.
|
||||
#[derive(Decode, Encode, PartialEq, TypeInfo)]
|
||||
#[repr(transparent)]
|
||||
pub struct OpaqueKeyOwnershipProof(Vec<u8>);
|
||||
|
||||
// Runtime API.
|
||||
pezsp_api::decl_runtime_apis! {
|
||||
/// API necessary for block authorship with Sassafras.
|
||||
pub trait SassafrasApi {
|
||||
/// Get ring context to be used for ticket construction and verification.
|
||||
fn ring_context() -> Option<vrf::RingContext>;
|
||||
|
||||
/// Submit next epoch validator tickets via an unsigned extrinsic.
|
||||
/// This method returns `false` when creation of the extrinsics fails.
|
||||
fn submit_tickets_unsigned_extrinsic(tickets: Vec<TicketEnvelope>) -> bool;
|
||||
|
||||
/// Get ticket id associated to the given slot.
|
||||
fn slot_ticket_id(slot: Slot) -> Option<TicketId>;
|
||||
|
||||
/// Get ticket id and data associated to the given slot.
|
||||
fn slot_ticket(slot: Slot) -> Option<(TicketId, TicketBody)>;
|
||||
|
||||
/// Current epoch information.
|
||||
fn current_epoch() -> Epoch;
|
||||
|
||||
/// Next epoch information.
|
||||
fn next_epoch() -> Epoch;
|
||||
|
||||
/// Generates a proof of key ownership for the given authority in the current epoch.
|
||||
///
|
||||
/// An example usage of this module is coupled with the session historical module to prove
|
||||
/// that a given authority key is tied to a given staking identity during a specific
|
||||
/// session.
|
||||
///
|
||||
/// Proofs of key ownership are necessary for submitting equivocation reports.
|
||||
fn generate_key_ownership_proof(authority_id: AuthorityId) -> Option<OpaqueKeyOwnershipProof>;
|
||||
|
||||
/// Submits an unsigned extrinsic to report an equivocation.
|
||||
///
|
||||
/// The caller must provide the equivocation proof and a key ownership proof (should be
|
||||
/// obtained using `generate_key_ownership_proof`). The extrinsic will be unsigned and
|
||||
/// should only be accepted for local authorship (not to be broadcast to the network). This
|
||||
/// method returns `false` when creation of the extrinsic fails.
|
||||
///
|
||||
/// Only useful in an offchain context.
|
||||
fn submit_report_equivocation_unsigned_extrinsic(
|
||||
equivocation_proof: EquivocationProof<Block::Header>,
|
||||
key_owner_proof: OpaqueKeyOwnershipProof,
|
||||
) -> bool;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Primitives related to tickets.
|
||||
|
||||
use crate::vrf::RingVrfSignature;
|
||||
use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
pub use pezsp_core::ed25519::{Public as EphemeralPublic, Signature as EphemeralSignature};
|
||||
|
||||
/// Ticket identifier.
|
||||
///
|
||||
/// Its value is the output of a VRF whose inputs cannot be controlled by the
|
||||
/// ticket's creator (refer to [`crate::vrf::ticket_id_input`] parameters).
|
||||
/// Because of this, it is also used as the ticket score to compare against
|
||||
/// the epoch ticket's threshold to decide if the ticket is worth being considered
|
||||
/// for slot assignment (refer to [`ticket_id_threshold`]).
|
||||
pub type TicketId = u128;
|
||||
|
||||
/// Ticket data persisted on-chain.
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo,
|
||||
)]
|
||||
pub struct TicketBody {
|
||||
/// Attempt index.
|
||||
pub attempt_idx: u32,
|
||||
/// Ephemeral public key which gets erased when the ticket is claimed.
|
||||
pub erased_public: EphemeralPublic,
|
||||
/// Ephemeral public key which gets exposed when the ticket is claimed.
|
||||
pub revealed_public: EphemeralPublic,
|
||||
}
|
||||
|
||||
/// Ticket ring vrf signature.
|
||||
pub type TicketSignature = RingVrfSignature;
|
||||
|
||||
/// Ticket envelope used on during submission.
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo,
|
||||
)]
|
||||
pub struct TicketEnvelope {
|
||||
/// Ticket body.
|
||||
pub body: TicketBody,
|
||||
/// Ring signature.
|
||||
pub signature: TicketSignature,
|
||||
}
|
||||
|
||||
/// Ticket claim information filled by the block author.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||
pub struct TicketClaim {
|
||||
/// Signature verified via `TicketBody::erased_public`.
|
||||
pub erased_signature: EphemeralSignature,
|
||||
}
|
||||
|
||||
/// Computes a boundary for [`TicketId`] maximum allowed value for a given epoch.
|
||||
///
|
||||
/// Only ticket identifiers below this threshold should be considered as candidates
|
||||
/// for slot assignment.
|
||||
///
|
||||
/// The value is computed as `TicketId::MAX*(redundancy*slots)/(attempts*validators)`
|
||||
///
|
||||
/// Where:
|
||||
/// - `redundancy`: redundancy factor;
|
||||
/// - `slots`: number of slots in epoch;
|
||||
/// - `attempts`: max number of tickets attempts per validator;
|
||||
/// - `validators`: number of validators in epoch.
|
||||
///
|
||||
/// If `attempts * validators = 0` then we return 0.
|
||||
///
|
||||
/// For details about the formula and implications refer to
|
||||
/// [*probabilities an parameters*](https://research.web3.foundation/Polkadot/protocols/block-production/SASSAFRAS#probabilities-and-parameters)
|
||||
/// paragraph of the w3f introduction to the protocol.
|
||||
// TODO: replace with [RFC-26](https://github.com/polkadot-fellows/RFCs/pull/26)
|
||||
// "Tickets Threshold" paragraph once is merged
|
||||
pub fn ticket_id_threshold(
|
||||
redundancy: u32,
|
||||
slots: u32,
|
||||
attempts: u32,
|
||||
validators: u32,
|
||||
) -> TicketId {
|
||||
let num = redundancy as u64 * slots as u64;
|
||||
let den = attempts as u64 * validators as u64;
|
||||
TicketId::max_value()
|
||||
.checked_div(den.into())
|
||||
.unwrap_or_default()
|
||||
.saturating_mul(num.into())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// This is a trivial example/check which just better explain explains the rationale
|
||||
// behind the threshold.
|
||||
//
|
||||
// After this reading the formula should become obvious.
|
||||
#[test]
|
||||
fn ticket_id_threshold_trivial_check() {
|
||||
// For an epoch with `s` slots we want to accept a number of tickets equal to ~s·r
|
||||
let redundancy = 2;
|
||||
let slots = 1000;
|
||||
let attempts = 100;
|
||||
let validators = 500;
|
||||
|
||||
let threshold = ticket_id_threshold(redundancy, slots, attempts, validators);
|
||||
let threshold = threshold as f64 / TicketId::MAX as f64;
|
||||
|
||||
// We expect that the total number of tickets allowed to be submitted
|
||||
// is slots*redundancy
|
||||
let avt = ((attempts * validators) as f64 * threshold) as u32;
|
||||
assert_eq!(avt, slots * redundancy);
|
||||
|
||||
println!("threshold: {}", threshold);
|
||||
println!("avt = {}", avt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Utilities related to VRF input, pre-output and signatures.
|
||||
|
||||
use crate::{Randomness, TicketBody, TicketId};
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
use codec::Encode;
|
||||
use pezsp_consensus_slots::Slot;
|
||||
|
||||
pub use pezsp_core::bandersnatch::{
|
||||
ring_vrf::{RingProver, RingVerifier, RingVerifierKey, RingVrfSignature},
|
||||
vrf::{VrfInput, VrfPreOutput, VrfSignData, VrfSignature},
|
||||
};
|
||||
|
||||
/// Ring size (aka authorities count) for Sassafras consensus.
|
||||
pub const RING_SIZE: usize = 1024;
|
||||
|
||||
/// Bandersnatch VRF [`RingContext`] specialization for Sassafras using [`RING_SIZE`].
|
||||
pub type RingContext = pezsp_core::bandersnatch::ring_vrf::RingContext<RING_SIZE>;
|
||||
|
||||
/// Input for slot claim
|
||||
pub fn slot_claim_input(randomness: &Randomness, slot: Slot, epoch: u64) -> VrfInput {
|
||||
let v = [b"sassafras-ticket", randomness.as_slice(), &slot.to_le_bytes(), &epoch.to_le_bytes()]
|
||||
.concat();
|
||||
VrfInput::new(&v[..])
|
||||
}
|
||||
|
||||
/// Signing-data to claim slot ownership during block production.
|
||||
pub fn slot_claim_sign_data(randomness: &Randomness, slot: Slot, epoch: u64) -> VrfSignData {
|
||||
let v = [b"sassafras-ticket", randomness.as_slice(), &slot.to_le_bytes(), &epoch.to_le_bytes()]
|
||||
.concat();
|
||||
VrfSignData::new(&v[..], &[])
|
||||
}
|
||||
|
||||
/// VRF input to generate the ticket id.
|
||||
pub fn ticket_id_input(randomness: &Randomness, attempt: u32, epoch: u64) -> VrfInput {
|
||||
let v =
|
||||
[b"sassafras-ticket", randomness.as_slice(), &attempt.to_le_bytes(), &epoch.to_le_bytes()]
|
||||
.concat();
|
||||
VrfInput::new(&v[..])
|
||||
}
|
||||
|
||||
/// Data to be signed via ring-vrf.
|
||||
pub fn ticket_body_sign_data(ticket_body: &TicketBody, ticket_id_input: VrfInput) -> VrfSignData {
|
||||
VrfSignData { vrf_input: ticket_id_input, aux_data: ticket_body.encode() }
|
||||
}
|
||||
|
||||
/// Make ticket-id from the given VRF pre-output.
|
||||
///
|
||||
/// Pre-output should have been obtained from the input directly using the vrf
|
||||
/// secret key or from the vrf signature pre-output.
|
||||
pub fn make_ticket_id(preout: &VrfPreOutput) -> TicketId {
|
||||
let bytes: [u8; 16] = preout.make_bytes()[..16].try_into().unwrap();
|
||||
u128::from_le_bytes(bytes)
|
||||
}
|
||||
Reference in New Issue
Block a user