Correct BABE randomness by calculating InOut bytes directly in pallet (#5876)

* vrf: remove Raw* types

* babe: remove Raw* types

* pallet-babe: switch representation of RawVRFOutput to Randomness

* pallet-babe: calculate inout within the pallet

* Remove make_transcript duplication

* Bump spec version

* Fix frame tests

* and_then -> map

* Always enable u64_backend

* Fix nostd compile

* fix import: should not use std

* Remove unused definition of RawVRFOutput

* Remove unused import of RuntimeDebug

Co-authored-by: Gavin Wood <gavin@parity.io>
This commit is contained in:
Wei Tang
2020-05-04 19:51:47 +02:00
committed by GitHub
parent 9c5536e01a
commit a00a4ca551
13 changed files with 146 additions and 241 deletions
@@ -13,7 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { version = "1.0.0", package = "parity-scale-codec", default-features = false }
schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated"], optional = true }
schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false }
sp-std = { version = "2.0.0-dev", path = "../../std", default-features = false }
sp-core = { version = "2.0.0-dev", path = "../../core", default-features = false }
sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" }
@@ -22,7 +22,7 @@ sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../ru
default = ["std"]
std = [
"codec/std",
"schnorrkel",
"schnorrkel/std",
"sp-std/std",
"sp-core/std",
"sp-runtime/std",
@@ -16,72 +16,38 @@
//! Schnorrkel-based VRF.
use codec::{Encode, Decode};
use sp_runtime::RuntimeDebug;
use sp_std::ops::{Deref, DerefMut};
#[cfg(feature = "std")]
use std::convert::TryFrom;
#[cfg(feature = "std")]
use codec::EncodeLike;
#[cfg(feature = "std")]
use schnorrkel::errors::MultiSignatureStage;
#[cfg(feature = "std")]
use codec::{Encode, Decode, EncodeLike};
use sp_std::{convert::TryFrom, prelude::*};
use sp_core::U512;
use sp_std::ops::{Deref, DerefMut};
use schnorrkel::errors::MultiSignatureStage;
#[cfg(feature = "std")]
pub use schnorrkel::{SignatureError, vrf::{VRF_PROOF_LENGTH, VRF_OUTPUT_LENGTH}};
/// The length of the VRF proof.
#[cfg(not(feature = "std"))]
pub const VRF_PROOF_LENGTH: usize = 64;
/// The length of the VRF output.
#[cfg(not(feature = "std"))]
pub const VRF_OUTPUT_LENGTH: usize = 32;
pub use schnorrkel::{SignatureError, PublicKey, vrf::{VRF_PROOF_LENGTH, VRF_OUTPUT_LENGTH}};
/// The length of the Randomness.
pub const RANDOMNESS_LENGTH: usize = VRF_OUTPUT_LENGTH;
/// Raw VRF output.
#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode)]
pub struct RawVRFOutput(pub [u8; VRF_OUTPUT_LENGTH]);
impl Deref for RawVRFOutput {
type Target = [u8; VRF_OUTPUT_LENGTH];
fn deref(&self) -> &Self::Target { &self.0 }
}
impl DerefMut for RawVRFOutput {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
/// VRF output type available for `std` environment, suitable for schnorrkel operations.
#[cfg(feature = "std")]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct VRFOutput(pub schnorrkel::vrf::VRFOutput);
#[cfg(feature = "std")]
impl Deref for VRFOutput {
type Target = schnorrkel::vrf::VRFOutput;
fn deref(&self) -> &Self::Target { &self.0 }
}
#[cfg(feature = "std")]
impl DerefMut for VRFOutput {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
#[cfg(feature = "std")]
impl Encode for VRFOutput {
fn encode(&self) -> Vec<u8> {
self.0.as_bytes().encode()
}
}
#[cfg(feature = "std")]
impl EncodeLike for VRFOutput { }
#[cfg(feature = "std")]
impl Decode for VRFOutput {
fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
let decoded = <[u8; VRF_OUTPUT_LENGTH]>::decode(i)?;
@@ -89,7 +55,6 @@ impl Decode for VRFOutput {
}
}
#[cfg(feature = "std")]
impl TryFrom<[u8; VRF_OUTPUT_LENGTH]> for VRFOutput {
type Error = SignatureError;
@@ -98,91 +63,39 @@ impl TryFrom<[u8; VRF_OUTPUT_LENGTH]> for VRFOutput {
}
}
#[cfg(feature = "std")]
impl TryFrom<RawVRFOutput> for VRFOutput {
type Error = SignatureError;
fn try_from(raw: RawVRFOutput) -> Result<VRFOutput, Self::Error> {
schnorrkel::vrf::VRFOutput::from_bytes(&raw.0).map(VRFOutput)
}
}
#[cfg(feature = "std")]
impl From<VRFOutput> for RawVRFOutput {
fn from(output: VRFOutput) -> RawVRFOutput {
RawVRFOutput(output.to_bytes())
}
}
/// Raw VRF proof.
#[derive(Clone, Copy, Encode, Decode)]
pub struct RawVRFProof(pub [u8; VRF_PROOF_LENGTH]);
impl Deref for RawVRFProof {
type Target = [u8; VRF_PROOF_LENGTH];
fn deref(&self) -> &Self::Target { &self.0 }
}
impl DerefMut for RawVRFProof {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
#[cfg(feature = "std")]
impl std::fmt::Debug for RawVRFProof {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", &self)
}
}
impl core::cmp::PartialEq for RawVRFProof {
fn eq(&self, other: &Self) -> bool {
self == other
}
}
impl core::cmp::Eq for RawVRFProof { }
/// VRF proof type available for `std` environment, suitable for schnorrkel operations.
#[cfg(feature = "std")]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct VRFProof(pub schnorrkel::vrf::VRFProof);
#[cfg(feature = "std")]
impl PartialOrd for VRFProof {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
#[cfg(feature = "std")]
impl Ord for VRFProof {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
U512::from(self.0.to_bytes()).cmp(&U512::from(other.0.to_bytes()))
}
}
#[cfg(feature = "std")]
impl Deref for VRFProof {
type Target = schnorrkel::vrf::VRFProof;
fn deref(&self) -> &Self::Target { &self.0 }
}
#[cfg(feature = "std")]
impl DerefMut for VRFProof {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
#[cfg(feature = "std")]
impl Encode for VRFProof {
fn encode(&self) -> Vec<u8> {
self.0.to_bytes().encode()
}
}
#[cfg(feature = "std")]
impl EncodeLike for VRFProof { }
#[cfg(feature = "std")]
impl Decode for VRFProof {
fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
let decoded = <[u8; VRF_PROOF_LENGTH]>::decode(i)?;
@@ -190,7 +103,6 @@ impl Decode for VRFProof {
}
}
#[cfg(feature = "std")]
impl TryFrom<[u8; VRF_PROOF_LENGTH]> for VRFProof {
type Error = SignatureError;
@@ -199,23 +111,6 @@ impl TryFrom<[u8; VRF_PROOF_LENGTH]> for VRFProof {
}
}
#[cfg(feature = "std")]
impl TryFrom<RawVRFProof> for VRFProof {
type Error = SignatureError;
fn try_from(raw: RawVRFProof) -> Result<VRFProof, Self::Error> {
schnorrkel::vrf::VRFProof::from_bytes(&raw.0).map(VRFProof)
}
}
#[cfg(feature = "std")]
impl From<VRFProof> for RawVRFProof {
fn from(output: VRFProof) -> RawVRFProof {
RawVRFProof(output.to_bytes())
}
}
#[cfg(feature = "std")]
fn convert_error(e: SignatureError) -> codec::Error {
use SignatureError::*;
use MultiSignatureStage::*;