Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions crates/pallet-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(unused_must_use, unsafe_code, unused_variables, unused_must_use)]

extern crate alloc;

mod default_weights;
pub mod equivocation;

Expand All @@ -26,6 +28,7 @@ mod mock;
#[cfg(all(feature = "std", test))]
mod tests;

use alloc::string::String;
use codec::{Decode, Encode, MaxEncodedLen};
use core::num::NonZeroU64;
use equivocation::{HandleEquivocation, SubspaceEquivocationOffence};
Expand All @@ -38,6 +41,7 @@ pub use pallet::*;
use scale_info::TypeInfo;
use schnorrkel::SignatureError;
use sp_consensus_slots::Slot;
use sp_consensus_subspace::consensus::verify_solution;
use sp_consensus_subspace::digests::CompatibleDigestItem;
use sp_consensus_subspace::offence::{OffenceDetails, OffenceError, OnOffenceHandler};
use sp_consensus_subspace::{
Expand All @@ -52,16 +56,14 @@ use sp_runtime::transaction_validity::{
use sp_runtime::DispatchError;
use sp_std::collections::btree_map::BTreeMap;
use sp_std::prelude::*;
use subspace_core_primitives::crypto::kzg;
use subspace_core_primitives::crypto::kzg::Kzg;
use subspace_core_primitives::{
PublicKey, Randomness, RewardSignature, RootBlock, SectorId, SectorIndex, SegmentIndex,
SolutionRange, PIECES_IN_SEGMENT, PIECE_SIZE, RECORDED_HISTORY_SEGMENT_SIZE, RECORD_SIZE,
};
use subspace_solving::REWARD_SIGNING_CONTEXT;
use subspace_verification::{
check_reward_signature, derive_next_solution_range, derive_randomness, verify_solution,
Error as VerificationError, PieceCheckParams, VerifySolutionParams,
check_reward_signature, derive_next_solution_range, derive_randomness, PieceCheckParams,
VerifySolutionParams,
};

pub trait WeightInfo {
Expand Down Expand Up @@ -1197,7 +1199,7 @@ enum CheckVoteError {
SlotInThePast,
BadRewardSignature(SignatureError),
UnknownRecordsRoot,
InvalidSolution(VerificationError),
InvalidSolution(String),
DuplicateVote,
Equivocated(SubspaceEquivocationOffence<FarmerPublicKey>),
}
Expand Down Expand Up @@ -1358,20 +1360,18 @@ fn check_vote<T: Config>(
return Err(CheckVoteError::UnknownRecordsRoot);
};

let kzg = Kzg::new(kzg::test_public_parameters());

if let Err(error) = verify_solution::<FarmerPublicKey, T::AccountId>(
solution,
if let Err(error) = verify_solution(
solution.into(),
slot.into(),
VerifySolutionParams {
global_randomness: &vote_verification_data.global_randomness,
(&VerifySolutionParams {
global_randomness: vote_verification_data.global_randomness,
solution_range: vote_verification_data.solution_range,
piece_check_params: Some(PieceCheckParams {
records_root: &records_root,
records_root,
pieces_in_segment,
}),
},
Some(&kzg),
})
.into(),
) {
debug!(
target: "runtime::subspace",
Expand Down
22 changes: 15 additions & 7 deletions crates/pallet-subspace/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,17 @@ use rand::Rng;
use schnorrkel::Keypair;
use sp_consensus_slots::Slot;
use sp_consensus_subspace::digests::{CompatibleDigestItem, PreDigest};
use sp_consensus_subspace::{FarmerSignature, SignedVote, Vote};
use sp_consensus_subspace::{FarmerSignature, KzgExtension, SignedVote, Vote};
use sp_core::crypto::UncheckedFrom;
use sp_core::H256;
use sp_io::TestExternalities;
use sp_runtime::testing::{Digest, DigestItem, Header, TestXt};
use sp_runtime::traits::{Block as BlockT, Header as _, IdentityLookup};
use sp_runtime::Perbill;
use std::num::NonZeroU64;
use std::sync::Once;
use subspace_archiving::archiver::{ArchivedSegment, Archiver};
use subspace_core_primitives::crypto::kzg::{Kzg, Witness};
use subspace_core_primitives::crypto::kzg::{test_public_parameters, Kzg, Witness};
use subspace_core_primitives::crypto::{blake2b_256_254_hash, kzg};
use subspace_core_primitives::{
ArchivedBlockProgress, Blake2b256Hash, LastArchivedBlock, Piece, Randomness, RecordsRoot,
Expand Down Expand Up @@ -230,20 +231,27 @@ pub fn make_pre_digest(
Digest { logs: vec![log] }
}

pub fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> TestExternalities {
static INITIALIZE_LOGGER: Once = Once::new();
INITIALIZE_LOGGER.call_once(|| {
let _ = env_logger::try_init_from_env(env_logger::Env::new().default_filter_or("error"));
});

let mut t = frame_system::GenesisConfig::default()
let mut storage = frame_system::GenesisConfig::default()
.build_storage::<Test>()
.unwrap();

GenesisBuild::<Test>::assimilate_storage(&pallet_subspace::GenesisConfig::default(), &mut t)
.unwrap();
GenesisBuild::<Test>::assimilate_storage(
&pallet_subspace::GenesisConfig::default(),
&mut storage,
)
.unwrap();

let mut ext = TestExternalities::from(storage);

ext.register_extension(KzgExtension::new(Kzg::new(test_public_parameters())));

t.into()
ext
}

/// Creates an equivocation at the current block, by generating two headers.
Expand Down
11 changes: 6 additions & 5 deletions crates/pallet-subspace/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use frame_support::dispatch::{GetDispatchInfo, Pays};
use frame_support::weights::Weight;
use frame_support::{assert_err, assert_ok};
use frame_system::{EventRecord, Phase};
use schnorrkel::Keypair;
use schnorrkel::{Keypair, SignatureError};
use sp_consensus_slots::Slot;
use sp_consensus_subspace::{
FarmerPublicKey, FarmerSignature, GlobalRandomnesses, SolutionRanges, Vote,
Expand Down Expand Up @@ -1003,10 +1003,10 @@ fn vote_outside_of_solution_range() {
1,
);

assert_matches!(
assert_eq!(
super::check_vote::<Test>(&signed_vote, false),
Err(CheckVoteError::InvalidSolution(
VerificationError::OutsideSolutionRange
VerificationError::OutsideSolutionRange.to_string()
))
);
});
Expand Down Expand Up @@ -1055,10 +1055,11 @@ fn vote_invalid_solution_signature() {
.to_bytes(),
);

assert_matches!(
assert_eq!(
super::check_vote::<Test>(&signed_vote, false),
Err(CheckVoteError::InvalidSolution(
VerificationError::InvalidSolutionSignature(_)
VerificationError::InvalidSolutionSignature(SignatureError::ScalarFormatError)
.to_string()
))
);
});
Expand Down
4 changes: 2 additions & 2 deletions crates/sc-consensus-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,8 @@ where
VerificationParams {
header: block.header.clone(),
slot_now: slot_now + 1,
verify_solution_params: VerifySolutionParams {
global_randomness: &subspace_digest_items.global_randomness,
verify_solution_params: &VerifySolutionParams {
global_randomness: subspace_digest_items.global_randomness,
solution_range: subspace_digest_items.solution_range,
piece_check_params: None,
},
Expand Down
6 changes: 3 additions & 3 deletions crates/sc-consensus-subspace/src/slot_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,11 @@ where
let solution_verification_result = verify_solution(
&solution,
slot.into(),
VerifySolutionParams {
global_randomness: &global_randomness,
&VerifySolutionParams {
global_randomness,
solution_range: voting_solution_range,
piece_check_params: Some(PieceCheckParams {
records_root: &records_root,
records_root,

pieces_in_segment: PIECES_IN_SEGMENT,
}),
Expand Down
8 changes: 4 additions & 4 deletions crates/sp-consensus-subspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ scale-info = { version = "2.3.1", default-features = false, features = ["derive"
schnorrkel = { version = "0.9.1", default-features = false, features = ["u64_backend"] }
sp-api = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-application-crypto = { version = "7.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-arithmetic = { version = "6.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-consensus = { version = "0.10.0-dev", optional = true, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-core = { version = "7.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-externalities = { version = "0.13.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-inherents = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-io = { version = "7.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-runtime = { version = "7.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-runtime-interface = { version = "7.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-std = { version = "5.0.0", default-features = false, git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232" }
sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "456cfad45a178617f6886ec400c312f2fea59232", default-features = false }
subspace-archiving = { version = "0.1.0", path = "../subspace-archiving", default-features = false }
Expand All @@ -45,13 +45,13 @@ std = [
"schnorrkel/std",
"sp-api/std",
"sp-application-crypto/std",
"sp-arithmetic/std",
"sp-consensus",
"sp-consensus-slots/std",
"sp-core/std",
"sp-externalities/std",
"sp-inherents/std",
"sp-io/std",
"sp-runtime/std",
"sp-runtime-interface/std",
"sp-std/std",
"sp-timestamp/std",
"subspace-archiving/std",
Expand Down
83 changes: 81 additions & 2 deletions crates/sp-consensus-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#![forbid(unsafe_code, missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate core;
extern crate alloc;

pub mod digests;
pub mod inherents;
Expand All @@ -28,6 +28,8 @@ pub mod offence;
mod tests;

use crate::digests::{CompatibleDigestItem, PreDigest};
use alloc::borrow::Cow;
use alloc::string::String;
use codec::{Decode, Encode, MaxEncodedLen};
use core::num::NonZeroU64;
use core::time::Duration;
Expand All @@ -39,6 +41,8 @@ use sp_core::crypto::KeyTypeId;
use sp_core::H256;
use sp_io::hashing;
use sp_runtime::{ConsensusEngineId, DigestItem};
use sp_runtime_interface::pass_by::PassBy;
use sp_runtime_interface::{pass_by, runtime_interface};
use sp_std::vec::Vec;
use subspace_core_primitives::crypto::kzg::Kzg;
use subspace_core_primitives::{
Expand Down Expand Up @@ -335,6 +339,81 @@ impl ChainConstants {
}
}

/// Wrapped solution for the purposes of runtime interface.
#[derive(Debug, Encode, Decode)]
pub struct WrappedSolution(Solution<FarmerPublicKey, ()>);

impl<RewardAddress> From<&Solution<FarmerPublicKey, RewardAddress>> for WrappedSolution {
fn from(solution: &Solution<FarmerPublicKey, RewardAddress>) -> Self {
Self(Solution {
public_key: solution.public_key.clone(),
reward_address: (),
sector_index: solution.sector_index,
total_pieces: solution.total_pieces,
piece_offset: solution.piece_offset,
piece_record_hash: solution.piece_record_hash,
piece_witness: solution.piece_witness,
chunk_offset: solution.chunk_offset,
chunk: solution.chunk,
chunk_signature: solution.chunk_signature,
})
}
}

impl PassBy for WrappedSolution {
type PassBy = pass_by::Codec<Self>;
}

/// Wrapped solution verification parameters for the purposes of runtime interface.
#[derive(Debug, Encode, Decode)]
pub struct WrappedVerifySolutionParams<'a>(Cow<'a, VerifySolutionParams>);

impl<'a> From<&'a VerifySolutionParams> for WrappedVerifySolutionParams<'a> {
fn from(value: &'a VerifySolutionParams) -> Self {
Self(Cow::Borrowed(value))
}
}

impl<'a> PassBy for WrappedVerifySolutionParams<'a> {
type PassBy = pass_by::Codec<Self>;
}

#[cfg(feature = "std")]
sp_externalities::decl_extension! {
/// A KZG extension.
pub struct KzgExtension(Kzg);
}

#[cfg(feature = "std")]
impl KzgExtension {
/// Create new instance.
pub fn new(kzg: Kzg) -> Self {
Self(kzg)
}
}

/// Consensus-related runtime interface
#[runtime_interface]
pub trait Consensus {
/// Verify whether solution is valid.
fn verify_solution(
&mut self,
solution: WrappedSolution,
slot: u64,
params: WrappedVerifySolutionParams<'_>,
) -> Result<(), String> {
use sp_externalities::ExternalitiesExt;

let kzg = &self
.extension::<KzgExtension>()
.expect("No `KzgExtension` associated for the current context!")
.0;

subspace_verification::verify_solution(&solution.0, slot, &params.0, Some(kzg))
.map_err(|error| error.to_string())
}
}

sp_api::decl_runtime_apis! {
/// API necessary for block authorship with Subspace.
pub trait SubspaceApi<RewardAddress: Encode + Decode> {
Expand Down Expand Up @@ -436,7 +515,7 @@ where
/// The slot number of the current time.
pub slot_now: Slot,
/// Parameters for solution verification
pub verify_solution_params: VerifySolutionParams<'a>,
pub verify_solution_params: &'a VerifySolutionParams,
/// Signing context for reward signature
pub reward_signing_context: &'a SigningContext,
}
Expand Down
Loading