diff --git a/Cargo.lock b/Cargo.lock index c4a5362600..53afbe1bff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7870,6 +7870,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "subspace-core-primitives", ] [[package]] @@ -7957,7 +7958,6 @@ dependencies = [ "serde", "sp-consensus-slots", "sp-consensus-subspace", - "sp-core", "sp-io", "sp-runtime", "sp-std", @@ -10095,7 +10095,6 @@ dependencies = [ "futures", "futures-timer", "jsonrpsee 0.23.2", - "parity-scale-codec", "parking_lot 0.12.3", "sc-client-api", "sc-consensus-subspace", @@ -10732,6 +10731,7 @@ dependencies = [ "sp-consensus-subspace", "sp-runtime", "strum_macros 0.26.4", + "subspace-core-primitives", "substrate-prometheus-endpoint", "thiserror", "tracing", @@ -13200,7 +13200,6 @@ dependencies = [ "sc-transaction-pool-api", "sc-utils", "sp-api", - "sp-application-crypto", "sp-blockchain", "sp-consensus", "sp-consensus-slots", diff --git a/crates/pallet-offences-subspace/Cargo.toml b/crates/pallet-offences-subspace/Cargo.toml index 06db1f72c9..d9cd6a5c95 100644 --- a/crates/pallet-offences-subspace/Cargo.toml +++ b/crates/pallet-offences-subspace/Cargo.toml @@ -20,6 +20,7 @@ scale-info = { version = "2.11.2", default-features = false, features = ["derive sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } sp-runtime = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-std = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } +subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } [dev-dependencies] sp-io = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } @@ -36,5 +37,6 @@ std = [ "sp-consensus-subspace/std", "sp-runtime/std", "sp-std/std", + "subspace-core-primitives/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/crates/pallet-offences-subspace/src/lib.rs b/crates/pallet-offences-subspace/src/lib.rs index a4eab6d98c..1b2222bd07 100644 --- a/crates/pallet-offences-subspace/src/lib.rs +++ b/crates/pallet-offences-subspace/src/lib.rs @@ -29,9 +29,9 @@ pub use pallet::*; use sp_consensus_subspace::offence::{ Offence, OffenceDetails, OffenceError, OnOffenceHandler, ReportOffence, }; -use sp_consensus_subspace::FarmerPublicKey; use sp_runtime::traits::Hash; use sp_std::prelude::*; +use subspace_core_primitives::PublicKey; /// A binary blob which represents a SCALE codec-encoded `O::TimeSlot`. type OpaqueTimeSlot = Vec; @@ -44,8 +44,8 @@ mod pallet { use super::{OpaqueTimeSlot, ReportIdOf}; use frame_support::pallet_prelude::*; use sp_consensus_subspace::offence::{Kind, OffenceDetails, OnOffenceHandler}; - use sp_consensus_subspace::FarmerPublicKey; use sp_std::prelude::*; + use subspace_core_primitives::PublicKey; #[pallet::pallet] #[pallet::without_storage_info] @@ -57,14 +57,14 @@ mod pallet { /// The overarching event type. type RuntimeEvent: From + IsType<::RuntimeEvent>; /// A handler called for every offence report. - type OnOffenceHandler: OnOffenceHandler; + type OnOffenceHandler: OnOffenceHandler; } /// The primary structure that holds all offence records keyed by report identifiers. #[pallet::storage] #[pallet::getter(fn reports)] pub type Reports = - StorageMap<_, Twox64Concat, ReportIdOf, OffenceDetails>; + StorageMap<_, Twox64Concat, ReportIdOf, OffenceDetails>; /// A vector of reports of the same kind that happened at the same time slot. #[pallet::storage] @@ -107,7 +107,7 @@ mod pallet { } } -impl> ReportOffence for Pallet { +impl> ReportOffence for Pallet { fn report_offence(offence: O) -> Result<(), OffenceError> { let offenders = offence.offenders(); let time_slot = offence.time_slot(); @@ -133,7 +133,7 @@ impl> ReportOffence f Ok(()) } - fn is_known_offence(offenders: &[FarmerPublicKey], time_slot: &O::TimeSlot) -> bool { + fn is_known_offence(offenders: &[PublicKey], time_slot: &O::TimeSlot) -> bool { let any_unknown = offenders.iter().any(|offender| { let report_id = Self::report_id::(time_slot, offender); !>::contains_key(report_id) @@ -147,18 +147,18 @@ impl Pallet { /// Compute the ID for the given report properties. /// /// The report id depends on the offence kind, time slot and the id of offender. - fn report_id>( + fn report_id>( time_slot: &O::TimeSlot, - offender: &FarmerPublicKey, + offender: &PublicKey, ) -> ReportIdOf { (O::ID, time_slot.encode(), offender).using_encoded(T::Hashing::hash) } /// Triages the offence report and returns the set of offenders that was involved in unique /// reports along with the list of the concurrent offences. - fn triage_offence_report>( + fn triage_offence_report>( time_slot: &O::TimeSlot, - offenders: Vec, + offenders: Vec, ) -> Option { let mut storage = ReportIndexStorage::::load(time_slot); @@ -195,7 +195,7 @@ impl Pallet { struct TriageOutcome { /// Other reports for the same report kinds. - concurrent_offenders: Vec>, + concurrent_offenders: Vec>, } /// An auxiliary struct for working with storage of indexes localized for a specific offence @@ -204,13 +204,13 @@ struct TriageOutcome { /// This struct is responsible for aggregating storage writes and the underlying storage should not /// accessed directly meanwhile. #[must_use = "The changes are not saved without called `save`"] -struct ReportIndexStorage> { +struct ReportIndexStorage> { opaque_time_slot: OpaqueTimeSlot, concurrent_reports: Vec>, same_kind_reports: Vec<(O::TimeSlot, ReportIdOf)>, } -impl> ReportIndexStorage { +impl> ReportIndexStorage { /// Preload indexes from the storage for the specific `time_slot` and the kind of the offence. fn load(time_slot: &O::TimeSlot) -> Self { let opaque_time_slot = time_slot.encode(); diff --git a/crates/pallet-offences-subspace/src/mock.rs b/crates/pallet-offences-subspace/src/mock.rs index 6700c4f098..dc2e8305f9 100644 --- a/crates/pallet-offences-subspace/src/mock.rs +++ b/crates/pallet-offences-subspace/src/mock.rs @@ -25,10 +25,10 @@ use frame_support::derive_impl; use frame_support::weights::constants::ParityDbWeight; use frame_support::weights::Weight; use sp_consensus_subspace::offence::{self, Kind, OffenceDetails}; -use sp_consensus_subspace::FarmerPublicKey; use sp_core::H256; use sp_runtime::{BuildStorage, Perbill}; use std::cell::RefCell; +use subspace_core_primitives::PublicKey; pub struct OnOffenceHandler; @@ -81,7 +81,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pub const KIND: [u8; 16] = *b"test_report_1234"; /// Returns all offence details for the specific `kind` happened at the specific time slot. -pub fn offence_reports(kind: Kind, time_slot: u128) -> Vec> { +pub fn offence_reports(kind: Kind, time_slot: u128) -> Vec> { >::get(kind, time_slot.encode()) .into_iter() .map(|report_id| { @@ -111,6 +111,6 @@ impl offence::Offence for Offence { } /// Create the report id for the given `offender` and `time_slot` combination. -pub fn report_id(time_slot: u128, offender: FarmerPublicKey) -> H256 { - OffencesSubspace::report_id::>(&time_slot, &offender) +pub fn report_id(time_slot: u128, offender: PublicKey) -> H256 { + OffencesSubspace::report_id::>(&time_slot, &offender) } diff --git a/crates/pallet-offences-subspace/src/tests.rs b/crates/pallet-offences-subspace/src/tests.rs index 34c3d3ee6b..214379bf6b 100644 --- a/crates/pallet-offences-subspace/src/tests.rs +++ b/crates/pallet-offences-subspace/src/tests.rs @@ -26,13 +26,12 @@ use codec::{Decode, Encode}; use frame_system::{EventRecord, Phase}; use schnorrkel::Keypair; use sp_consensus_subspace::offence::{OffenceDetails, OffenceError, ReportOffence}; -use sp_consensus_subspace::FarmerPublicKey; -use sp_core::crypto::UncheckedFrom; use sp_runtime::Perbill; +use subspace_core_primitives::PublicKey; -fn generate_farmer_public_key() -> FarmerPublicKey { +fn generate_farmer_public_key() -> PublicKey { let keypair = Keypair::generate(); - FarmerPublicKey::unchecked_from(keypair.public.to_bytes()) + PublicKey::from(keypair.public.to_bytes()) } #[test] @@ -189,7 +188,7 @@ fn doesnt_deposit_event_for_dups() { #[test] fn reports_if_an_offence_is_dup() { - type TestOffence = Offence; + type TestOffence = Offence; new_test_ext().execute_with(|| { let time_slot = 42; @@ -203,7 +202,7 @@ fn reports_if_an_offence_is_dup() { offenders, }; - let mut test_offence = offence(time_slot, vec![farmer_0.clone()]); + let mut test_offence = offence(time_slot, vec![farmer_0]); // the report for farmer 0 at time slot 42 should not be a known // offence @@ -232,7 +231,7 @@ fn reports_if_an_offence_is_dup() { ); // after adding a new offender to the offence report - test_offence.offenders.push(farmer_1.clone()); + test_offence.offenders.push(farmer_1); // it should not be a known offence anymore assert!( @@ -274,11 +273,11 @@ fn should_properly_count_offences() { let offence1 = Offence { time_slot, - offenders: vec![farmer_1.clone()], + offenders: vec![farmer_1], }; let offence2 = Offence { time_slot, - offenders: vec![farmer_2.clone()], + offenders: vec![farmer_2], }; OffencesSubspace::report_offence(offence1).unwrap(); with_on_offence_fractions(|f| { @@ -319,19 +318,19 @@ fn should_properly_sort_offences() { let offence1 = Offence { time_slot, - offenders: vec![farmer_5.clone()], + offenders: vec![farmer_5], }; let offence2 = Offence { time_slot, - offenders: vec![farmer_4.clone()], + offenders: vec![farmer_4], }; let offence3 = Offence { time_slot: time_slot + 1, - offenders: vec![farmer_6.clone(), farmer_7.clone()], + offenders: vec![farmer_6, farmer_7], }; let offence4 = Offence { time_slot: time_slot - 1, - offenders: vec![farmer_3.clone()], + offenders: vec![farmer_3], }; OffencesSubspace::report_offence(offence1).unwrap(); with_on_offence_fractions(|f| { diff --git a/crates/pallet-subspace/Cargo.toml b/crates/pallet-subspace/Cargo.toml index 32d7a7e701..407c3b5b60 100644 --- a/crates/pallet-subspace/Cargo.toml +++ b/crates/pallet-subspace/Cargo.toml @@ -20,10 +20,9 @@ frame-system = { default-features = false, git = "https://github.com/subspace/po log = { version = "0.4.22", default-features = false } scale-info = { version = "2.11.2", default-features = false, features = ["derive"] } schnorrkel = { version = "0.11.4", default-features = false } -serde = { version = "1.0.206", optional = true, default-features = false, features = ["derive"] } +serde = { version = "1.0.206", optional = true, default-features = false, features = ["alloc", "derive"] } sp-consensus-subspace = { version = "0.1.0", default-features = false, path = "../sp-consensus-subspace" } sp-consensus-slots = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } -sp-core = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631", optional = true } sp-runtime = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-std = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } subspace-core-primitives = { version = "0.1.0", default-features = false, path = "../subspace-core-primitives" } @@ -36,7 +35,6 @@ futures = "0.3.29" pallet-balances = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } pallet-offences-subspace = { version = "0.1.0", path = "../pallet-offences-subspace" } rand = { version = "0.8.5", features = ["min_const_gen"] } -sp-core = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-io = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } subspace-archiving = { version = "0.1.0", path = "../subspace-archiving" } subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } @@ -46,6 +44,10 @@ subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-spac [features] default = ["std"] +serde = [ + "dep:serde", + "subspace-core-primitives/serde", +] std = [ "codec/std", "frame-benchmarking?/std", @@ -54,11 +56,9 @@ std = [ "log/std", "scale-info/std", "schnorrkel/std", - "serde", - "serde/std", + "serde?/std", "sp-consensus-subspace/std", "sp-consensus-slots/std", - "sp-core?/std", "sp-io/std", "sp-runtime/std", "sp-std/std", @@ -70,5 +70,4 @@ try-runtime = ["frame-support/try-runtime"] runtime-benchmarks = [ "frame-benchmarking", "frame-benchmarking/runtime-benchmarks", - "sp-core", ] diff --git a/crates/pallet-subspace/src/benchmarking.rs b/crates/pallet-subspace/src/benchmarking.rs index ff243998df..bf283ba05d 100644 --- a/crates/pallet-subspace/src/benchmarking.rs +++ b/crates/pallet-subspace/src/benchmarking.rs @@ -15,19 +15,16 @@ mod benchmarks { #[cfg(not(feature = "std"))] use alloc::vec::Vec; use frame_benchmarking::v2::*; + use frame_support::traits::Get; use frame_system::pallet_prelude::*; use frame_system::{Pallet as System, RawOrigin}; - use sp_consensus_subspace::{ - EquivocationProof, FarmerPublicKey, FarmerSignature, SignedVote, Vote, - }; - use sp_core::crypto::UncheckedFrom; - use sp_core::Get; + use sp_consensus_subspace::{EquivocationProof, SignedVote, Vote}; use sp_runtime::traits::{Block, Header}; use sp_std::boxed::Box; use sp_std::num::NonZeroU32; use subspace_core_primitives::{ - ArchivedBlockProgress, Blake3Hash, LastArchivedBlock, PotCheckpoints, PotOutput, - SegmentHeader, SegmentIndex, Solution, SolutionRange, + ArchivedBlockProgress, Blake3Hash, LastArchivedBlock, PotCheckpoints, PotOutput, PublicKey, + RewardSignature, SegmentHeader, SegmentIndex, Solution, SolutionRange, }; const SEED: u32 = 0; @@ -36,7 +33,7 @@ mod benchmarks { fn report_equivocation() { // Construct a dummy equivocation proof which is invalid but it is okay because the // proof is not validate during the call - let offender = FarmerPublicKey::unchecked_from([0u8; 32]); + let offender = PublicKey::from([0u8; 32]); let header = ::Header::new( System::::block_number(), Default::default(), @@ -110,13 +107,13 @@ mod benchmarks { parent_hash: System::::parent_hash(), slot: Pallet::::current_slot(), solution: Solution::genesis_solution( - FarmerPublicKey::unchecked_from([1u8; 32]), + PublicKey::from([1u8; 32]), account("user1", 1, SEED), ), proof_of_time: PotOutput::default(), future_proof_of_time: PotOutput::default(), }; - let signature = FarmerSignature::unchecked_from([2u8; 64]); + let signature = RewardSignature::from([2u8; 64]); let signed_vote = SignedVote { vote: unsigned_vote, signature, diff --git a/crates/pallet-subspace/src/equivocation.rs b/crates/pallet-subspace/src/equivocation.rs index 07c9c30ca9..b027df546b 100644 --- a/crates/pallet-subspace/src/equivocation.rs +++ b/crates/pallet-subspace/src/equivocation.rs @@ -37,13 +37,14 @@ use frame_system::offchain::SubmitTransaction; use frame_system::pallet_prelude::*; use sp_consensus_slots::Slot; use sp_consensus_subspace::offence::{Kind, Offence, OffenceError, ReportOffence}; -use sp_consensus_subspace::{EquivocationProof, FarmerPublicKey}; +use sp_consensus_subspace::EquivocationProof; use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, }; use sp_runtime::DispatchResult; use sp_std::prelude::*; +use subspace_core_primitives::PublicKey; use crate::{Call, Config, Pallet}; @@ -57,12 +58,10 @@ pub trait HandleEquivocation { type ReportLongevity: Get; /// Report an offence proved by the given reporters. - fn report_offence( - offence: SubspaceEquivocationOffence, - ) -> Result<(), OffenceError>; + fn report_offence(offence: SubspaceEquivocationOffence) -> Result<(), OffenceError>; /// Returns true if all of the offenders at the given time slot have already been reported. - fn is_known_offence(offenders: &[FarmerPublicKey], time_slot: &Slot) -> bool; + fn is_known_offence(offenders: &[PublicKey], time_slot: &Slot) -> bool; /// Create and dispatch an equivocation report extrinsic. fn submit_equivocation_report( @@ -73,13 +72,11 @@ pub trait HandleEquivocation { impl HandleEquivocation for () { type ReportLongevity = (); - fn report_offence( - _offence: SubspaceEquivocationOffence, - ) -> Result<(), OffenceError> { + fn report_offence(_offence: SubspaceEquivocationOffence) -> Result<(), OffenceError> { Ok(()) } - fn is_known_offence(_offenders: &[FarmerPublicKey], _time_slot: &Slot) -> bool { + fn is_known_offence(_offenders: &[PublicKey], _time_slot: &Slot) -> bool { true } @@ -112,20 +109,18 @@ where T: Config + frame_system::offchain::SendTransactionTypes>, // A system for reporting offences after valid equivocation reports are // processed. - R: ReportOffence>, + R: ReportOffence, // The longevity (in blocks) that the equivocation report is valid for. When using the staking // pallet this should be the bonding duration. L: Get, { type ReportLongevity = L; - fn report_offence( - offence: SubspaceEquivocationOffence, - ) -> Result<(), OffenceError> { + fn report_offence(offence: SubspaceEquivocationOffence) -> Result<(), OffenceError> { R::report_offence(offence) } - fn is_known_offence(offenders: &[FarmerPublicKey], time_slot: &Slot) -> bool { + fn is_known_offence(offenders: &[PublicKey], time_slot: &Slot) -> bool { R::is_known_offence(offenders, time_slot) } @@ -189,10 +184,7 @@ impl Pallet { // We assign the maximum priority for any equivocation report. .priority(TransactionPriority::MAX) // Only one equivocation report for the same offender at the same slot. - .and_provides(( - equivocation_proof.offender.clone(), - *equivocation_proof.slot, - )) + .and_provides((equivocation_proof.offender, *equivocation_proof.slot)) .longevity(longevity) // We don't propagate this. This can never be included on a remote node. .propagate(false) @@ -221,7 +213,7 @@ fn is_known_offence( ) -> Result<(), TransactionValidityError> { // Check if the offence has already been reported, and if so then we can discard the report. if T::HandleEquivocation::is_known_offence( - &[equivocation_proof.offender.clone()], + &[equivocation_proof.offender], &equivocation_proof.slot, ) { Err(InvalidTransaction::Stale.into()) @@ -234,19 +226,19 @@ fn is_known_offence( /// /// When a farmer released two or more solutions at the same slot. #[derive(Debug, Eq, PartialEq)] -pub struct SubspaceEquivocationOffence { +pub struct SubspaceEquivocationOffence { /// A Subspace slot in which this incident happened. pub slot: Slot, /// Identity of the farmer that produced the equivocation. pub offender: PublicKey, } -impl Offence for SubspaceEquivocationOffence { +impl Offence for SubspaceEquivocationOffence { const ID: Kind = *b"sub:equivocation"; type TimeSlot = Slot; fn offenders(&self) -> Vec { - vec![self.offender.clone()] + vec![self.offender] } fn time_slot(&self) -> Self::TimeSlot { diff --git a/crates/pallet-subspace/src/lib.rs b/crates/pallet-subspace/src/lib.rs index 286bea42c2..947062da25 100644 --- a/crates/pallet-subspace/src/lib.rs +++ b/crates/pallet-subspace/src/lib.rs @@ -51,8 +51,7 @@ use sp_consensus_subspace::consensus::{is_proof_of_time_valid, verify_solution}; use sp_consensus_subspace::digests::CompatibleDigestItem; use sp_consensus_subspace::offence::{OffenceDetails, OffenceError, OnOffenceHandler}; use sp_consensus_subspace::{ - EquivocationProof, FarmerPublicKey, FarmerSignature, PotParameters, PotParametersChange, - SignedVote, Vote, WrappedPotOutput, + EquivocationProof, PotParameters, PotParametersChange, SignedVote, Vote, WrappedPotOutput, }; use sp_runtime::generic::DigestItem; use sp_runtime::traits::{BlockNumberProvider, CheckedSub, Hash, One, Zero}; @@ -111,15 +110,15 @@ pub mod pallet { use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::CompatibleDigestItem; use sp_consensus_subspace::inherents::{InherentError, InherentType, INHERENT_IDENTIFIER}; - use sp_consensus_subspace::{EquivocationProof, FarmerPublicKey, FarmerSignature, SignedVote}; + use sp_consensus_subspace::{EquivocationProof, SignedVote}; use sp_runtime::DigestItem; use sp_std::collections::btree_map::BTreeMap; use sp_std::num::NonZeroU32; use sp_std::prelude::*; use subspace_core_primitives::crypto::Scalar; use subspace_core_primitives::{ - Blake3Hash, HistorySize, PieceOffset, PotCheckpoints, Randomness, SectorIndex, - SegmentHeader, SegmentIndex, SolutionRange, + Blake3Hash, HistorySize, PieceOffset, PotCheckpoints, PublicKey, Randomness, + RewardSignature, SectorIndex, SegmentHeader, SegmentIndex, SolutionRange, }; pub(super) struct InitialSolutionRanges { @@ -259,7 +258,7 @@ pub mod pallet { /// for everyone. FirstFarmer, /// Specified root farmer is allowed to author blocks unless unlocked for everyone. - RootFarmer(FarmerPublicKey), + RootFarmer(PublicKey), } #[derive(Debug, Copy, Clone, Encode, Decode, TypeInfo)] @@ -353,7 +352,7 @@ pub mod pallet { } AllowAuthoringBy::RootFarmer(root_farmer) => { AllowAuthoringByAnyone::::put(false); - RootPlotPublicKey::::put(root_farmer.clone()); + RootPlotPublicKey::::put(root_farmer); } } PotSlotIterations::::put(PotSlotIterationsValue { @@ -371,7 +370,7 @@ pub mod pallet { SegmentHeaderStored { segment_header: SegmentHeader }, /// Farmer vote. FarmerVote { - public_key: FarmerPublicKey, + public_key: PublicKey, reward_address: T::AccountId, height: BlockNumberFor, parent_hash: T::Hash, @@ -426,7 +425,7 @@ pub mod pallet { /// A set of blocked farmers keyed by their public key. #[pallet::storage] - pub(super) type BlockList = StorageMap<_, Twox64Concat, FarmerPublicKey, ()>; + pub(super) type BlockList = StorageMap<_, Twox64Concat, PublicKey, ()>; /// Mapping from segment index to corresponding segment commitment of contained records. #[pallet::storage] @@ -452,7 +451,7 @@ pub mod pallet { /// Parent block author information. #[pallet::storage] pub(super) type ParentBlockAuthorInfo = - StorageValue<_, (FarmerPublicKey, SectorIndex, PieceOffset, Scalar, Slot)>; + StorageValue<_, (PublicKey, SectorIndex, PieceOffset, Scalar, Slot)>; /// Enable rewards since specified block number. #[pallet::storage] @@ -467,7 +466,7 @@ pub mod pallet { pub(super) type CurrentBlockAuthorInfo = StorageValue< _, ( - FarmerPublicKey, + PublicKey, SectorIndex, PieceOffset, Scalar, @@ -481,8 +480,8 @@ pub mod pallet { pub(super) type ParentBlockVoters = StorageValue< _, BTreeMap< - (FarmerPublicKey, SectorIndex, PieceOffset, Scalar, Slot), - (T::AccountId, FarmerSignature), + (PublicKey, SectorIndex, PieceOffset, Scalar, Slot), + (T::AccountId, RewardSignature), >, ValueQuery, >; @@ -492,8 +491,8 @@ pub mod pallet { pub(super) type CurrentBlockVoters = StorageValue< _, BTreeMap< - (FarmerPublicKey, SectorIndex, PieceOffset, Scalar, Slot), - (T::AccountId, FarmerSignature), + (PublicKey, SectorIndex, PieceOffset, Scalar, Slot), + (T::AccountId, RewardSignature), >, >; @@ -521,7 +520,7 @@ pub mod pallet { /// Set just once to make sure no one else can author blocks until allowed for anyone. #[pallet::storage] #[pallet::getter(fn root_plot_public_key)] - pub(super) type RootPlotPublicKey = StorageValue<_, FarmerPublicKey>; + pub(super) type RootPlotPublicKey = StorageValue<_, PublicKey>; #[pallet::hooks] impl Hooks> for Pallet { @@ -846,7 +845,7 @@ impl Pallet { { // Remove old value CurrentBlockAuthorInfo::::take(); - let farmer_public_key = pre_digest.solution().public_key.clone(); + let farmer_public_key = pre_digest.solution().public_key; // Optional restriction for block authoring to the root user if !AllowAuthoringByAnyone::::get() { @@ -856,13 +855,11 @@ impl Pallet { panic!("Client bug, authoring must be only done by the root user"); } } else { - maybe_root_plot_public_key.replace(farmer_public_key.clone()); + maybe_root_plot_public_key.replace(farmer_public_key); // Deposit root plot public key update such that light client can validate // blocks later. frame_system::Pallet::::deposit_log( - DigestItem::root_plot_public_key_update(Some( - farmer_public_key.clone(), - )), + DigestItem::root_plot_public_key_update(Some(farmer_public_key)), ); } }); @@ -906,8 +903,8 @@ impl Pallet { } } CurrentBlockVoters::::put(BTreeMap::< - (FarmerPublicKey, SectorIndex, PieceOffset, Scalar, Slot), - (T::AccountId, FarmerSignature), + (PublicKey, SectorIndex, PieceOffset, Scalar, Slot), + (T::AccountId, RewardSignature), >::default()); // If solution range was updated in previous block, set it as current. @@ -1096,7 +1093,7 @@ impl Pallet { fn do_report_equivocation( equivocation_proof: EquivocationProof>, ) -> DispatchResultWithPostInfo { - let offender = equivocation_proof.offender.clone(); + let offender = equivocation_proof.offender; let slot = equivocation_proof.slot; let offence = SubspaceEquivocationOffence { slot, offender }; @@ -1180,7 +1177,7 @@ impl Pallet { .. } = signed_vote.vote; - if BlockList::::contains_key(&solution.public_key) { + if BlockList::::contains_key(solution.public_key) { Err(DispatchError::Other("Equivocated")) } else { Self::deposit_event(Event::FarmerVote { @@ -1301,7 +1298,7 @@ impl Pallet { } /// Check if `farmer_public_key` is in block list (due to equivocation) - pub fn is_in_block_list(farmer_public_key: &FarmerPublicKey) -> bool { + pub fn is_in_block_list(farmer_public_key: &PublicKey) -> bool { BlockList::::contains_key(farmer_public_key) } @@ -1386,7 +1383,7 @@ impl Pallet { .priority(TransactionPriority::MAX) // Should be included in the next block or block after that, but not later .longevity(2) - .and_provides(&signed_vote.signature) + .and_provides(signed_vote.signature) .build() } @@ -1463,7 +1460,7 @@ enum CheckVoteError { InvalidProofOfTime, InvalidFutureProofOfTime, DuplicateVote, - Equivocated(SubspaceEquivocationOffence), + Equivocated(SubspaceEquivocationOffence), } impl From for TransactionValidityError { @@ -1505,7 +1502,7 @@ fn check_vote( let height = *height; let slot = *slot; - if BlockList::::contains_key(&solution.public_key) { + if BlockList::::contains_key(solution.public_key) { return Err(CheckVoteError::BlockListed); } @@ -1596,8 +1593,8 @@ fn check_vote( if let Err(error) = check_reward_signature( signed_vote.vote.hash().as_bytes(), - &RewardSignature::from(&signed_vote.signature), - &PublicKey::from(&solution.public_key), + &signed_vote.signature, + &solution.public_key, &schnorrkel::signing_context(REWARD_SIGNING_CONTEXT), ) { debug!( @@ -1613,10 +1610,7 @@ fn check_vote( parent_vote_verification_data }; - let sector_id = SectorId::new( - PublicKey::from(&solution.public_key).hash(), - solution.sector_index, - ); + let sector_id = SectorId::new(solution.public_key.hash(), solution.sector_index); let recent_segments = T::RecentSegments::get(); let recent_history_fraction = ( @@ -1720,7 +1714,7 @@ fn check_vote( } let key = ( - solution.public_key.clone(), + solution.public_key, solution.sector_index, solution.piece_offset, solution.chunk, @@ -1789,10 +1783,7 @@ fn check_vote( .expect("Always set during block initialization") .insert( key, - ( - solution.reward_address.clone(), - signed_vote.signature.clone(), - ), + (solution.reward_address.clone(), signed_vote.signature), ); }); } @@ -1925,10 +1916,10 @@ impl frame_support::traits::Randomness> fo } } -impl OnOffenceHandler for Pallet { - fn on_offence(offenders: &[OffenceDetails]) { +impl OnOffenceHandler for Pallet { + fn on_offence(offenders: &[OffenceDetails]) { for offender in offenders { - BlockList::::insert(offender.offender.clone(), ()); + BlockList::::insert(offender.offender, ()); } } } diff --git a/crates/pallet-subspace/src/mock.rs b/crates/pallet-subspace/src/mock.rs index 918d25208b..1b15d15f7a 100644 --- a/crates/pallet-subspace/src/mock.rs +++ b/crates/pallet-subspace/src/mock.rs @@ -17,10 +17,7 @@ //! Test utilities use crate::equivocation::EquivocationHandler; -use crate::{ - self as pallet_subspace, AllowAuthoringBy, Config, EnableRewardsAt, FarmerPublicKey, - NormalEraChange, -}; +use crate::{self as pallet_subspace, AllowAuthoringBy, Config, EnableRewardsAt, NormalEraChange}; use frame_support::traits::{ConstU128, ConstU16, OnInitialize}; use frame_support::{derive_impl, parameter_types}; use futures::executor::block_on; @@ -28,10 +25,7 @@ use rand::Rng; use schnorrkel::Keypair; use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::{CompatibleDigestItem, PreDigest, PreDigestPotInfo}; -use sp_consensus_subspace::{ - FarmerSignature, KzgExtension, PosExtension, PotExtension, SignedVote, Vote, -}; -use sp_core::crypto::UncheckedFrom; +use sp_consensus_subspace::{KzgExtension, PosExtension, PotExtension, SignedVote, Vote}; use sp_io::TestExternalities; use sp_runtime::testing::{Digest, DigestItem, Header, TestXt}; use sp_runtime::traits::{Block as BlockT, Header as _}; @@ -47,8 +41,8 @@ use subspace_core_primitives::crypto::Scalar; use subspace_core_primitives::{ ArchivedBlockProgress, ArchivedHistorySegment, Blake3Hash, BlockNumber, HistorySize, LastArchivedBlock, Piece, PieceOffset, PosSeed, PotOutput, PublicKey, Record, - RecordedHistorySegment, SectorId, SegmentCommitment, SegmentHeader, SegmentIndex, SlotNumber, - Solution, SolutionRange, REWARD_SIGNING_CONTEXT, + RecordedHistorySegment, RewardSignature, SectorId, SegmentCommitment, SegmentHeader, + SegmentIndex, SlotNumber, Solution, SolutionRange, REWARD_SIGNING_CONTEXT, }; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::auditing::audit_sector_sync; @@ -197,7 +191,7 @@ pub fn go_to_block( let pre_digest = make_pre_digest( slot.into(), Solution { - public_key: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), + public_key: PublicKey::from(keypair.public.to_bytes()), reward_address, sector_index: 0, history_size: HistorySize::from(SegmentIndex::ZERO), @@ -231,7 +225,7 @@ pub fn progress_to_block( pub fn make_pre_digest( slot: Slot, - solution: Solution::AccountId>, + solution: Solution<::AccountId>, ) -> Digest { let log = DigestItem::subspace_pre_digest(&PreDigest::V0 { slot, @@ -295,14 +289,14 @@ pub fn generate_equivocation_proof( Scalar::from(&chunk_bytes) }; - let public_key = FarmerPublicKey::unchecked_from(keypair.public.to_bytes()); + let public_key = PublicKey::from(keypair.public.to_bytes()); let make_header = |piece_offset, reward_address: ::AccountId| { let parent_hash = System::parent_hash(); let pre_digest = make_pre_digest( slot, Solution { - public_key: public_key.clone(), + public_key, reward_address, sector_index: 0, history_size: HistorySize::from(SegmentIndex::ZERO), @@ -324,7 +318,7 @@ pub fn generate_equivocation_proof( // digest item let seal_header = |header: &mut Header| { let prehash = header.hash(); - let signature = FarmerSignature::unchecked_from( + let signature = RewardSignature::from( keypair .sign( schnorrkel::context::signing_context(REWARD_SIGNING_CONTEXT) @@ -495,7 +489,7 @@ pub fn create_signed_vote( parent_hash, slot, solution: Solution { - public_key: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), + public_key: PublicKey::from(keypair.public.to_bytes()), reward_address: solution.reward_address, sector_index: solution.sector_index, history_size: solution.history_size, @@ -510,7 +504,7 @@ pub fn create_signed_vote( future_proof_of_time, }; - let signature = FarmerSignature::unchecked_from( + let signature = RewardSignature::from( keypair .sign(reward_signing_context.bytes(vote.hash().as_ref())) .to_bytes(), diff --git a/crates/pallet-subspace/src/tests.rs b/crates/pallet-subspace/src/tests.rs index 5483dc4efa..36b2310294 100644 --- a/crates/pallet-subspace/src/tests.rs +++ b/crates/pallet-subspace/src/tests.rs @@ -35,8 +35,7 @@ use frame_system::{EventRecord, Phase}; use rand::prelude::*; use schnorrkel::Keypair; use sp_consensus_slots::Slot; -use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, PotExtension, SolutionRanges}; -use sp_core::crypto::UncheckedFrom; +use sp_consensus_subspace::{PotExtension, SolutionRanges}; use sp_runtime::traits::{BlockNumberProvider, Header}; use sp_runtime::transaction_validity::{ InvalidTransaction, TransactionPriority, TransactionSource, ValidTransaction, @@ -47,7 +46,9 @@ use std::collections::BTreeMap; use std::num::NonZeroU32; use std::sync::{Arc, Mutex}; use subspace_core_primitives::crypto::Scalar; -use subspace_core_primitives::{PieceOffset, PotOutput, SegmentIndex, SolutionRange}; +use subspace_core_primitives::{ + PieceOffset, PotOutput, PublicKey, RewardSignature, SegmentIndex, SolutionRange, +}; use subspace_runtime_primitives::{FindBlockRewardAddress, FindVotingRewardAddresses}; #[test] @@ -245,7 +246,7 @@ fn report_equivocation_current_session_works() { progress_to_block(&keypair, 1, 1); - let farmer_public_key = FarmerPublicKey::unchecked_from(keypair.public.to_bytes()); + let farmer_public_key = PublicKey::from(keypair.public.to_bytes()); // generate an equivocation proof. it creates two headers at the given // slot with different block hashes and signed by the given key @@ -270,7 +271,7 @@ fn report_equivocation_old_session_works() { progress_to_block(&keypair, 1, 1); - let farmer_public_key = FarmerPublicKey::unchecked_from(keypair.public.to_bytes()); + let farmer_public_key = PublicKey::from(keypair.public.to_bytes()); // generate an equivocation proof at the current slot let equivocation_proof = generate_equivocation_proof(&keypair, Subspace::current_slot()); @@ -368,7 +369,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() { progress_to_block(&keypair, 1, 1); - let farmer_public_key = FarmerPublicKey::unchecked_from(keypair.public.to_bytes()); + let farmer_public_key = PublicKey::from(keypair.public.to_bytes()); let equivocation_proof = generate_equivocation_proof(&keypair, Subspace::current_slot()); @@ -575,10 +576,7 @@ fn vote_block_listed() { let keypair = Keypair::generate(); let archived_segment = create_archived_segment(); - BlockList::::insert( - FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), - (), - ); + BlockList::::insert(PublicKey::from(keypair.public.to_bytes()), ()); // Vote author is in block list let signed_vote = create_signed_vote( @@ -916,7 +914,7 @@ fn vote_bad_reward_signature() { SolutionRange::MAX, ); - signed_vote.signature = FarmerSignature::unchecked_from(rand::random::<[u8; 64]>()); + signed_vote.signature = RewardSignature::from(rand::random::<[u8; 64]>()); assert_matches!( super::check_vote::(&signed_vote, false), @@ -1287,7 +1285,7 @@ fn vote_equivocation_current_block_plus_vote() { // Parent block author + sector index + chunk + slot matches that of the vote CurrentBlockAuthorInfo::::put(( - FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), + PublicKey::from(keypair.public.to_bytes()), signed_vote.vote.solution().sector_index, signed_vote.vote.solution().piece_offset, signed_vote.vote.solution().chunk, @@ -1299,7 +1297,7 @@ fn vote_equivocation_current_block_plus_vote() { super::check_vote::(&signed_vote, false), CheckVoteError::Equivocated(SubspaceEquivocationOffence { slot, - offender: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()) + offender: PublicKey::from(keypair.public.to_bytes()) }) ); }); @@ -1342,7 +1340,7 @@ fn vote_equivocation_parent_block_plus_vote() { // Parent block author + sector index + chunk + slot matches that of the vote ParentBlockAuthorInfo::::put(( - FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), + PublicKey::from(keypair.public.to_bytes()), signed_vote.vote.solution().sector_index, signed_vote.vote.solution().piece_offset, signed_vote.vote.solution().chunk, @@ -1353,7 +1351,7 @@ fn vote_equivocation_parent_block_plus_vote() { super::check_vote::(&signed_vote, true), CheckVoteError::Equivocated(SubspaceEquivocationOffence { slot, - offender: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()) + offender: PublicKey::from(keypair.public.to_bytes()) }) ); @@ -1409,13 +1407,13 @@ fn vote_equivocation_current_voters_duplicate() { let mut map = BTreeMap::new(); map.insert( ( - FarmerPublicKey::unchecked_from(voter_keypair.public.to_bytes()), + PublicKey::from(voter_keypair.public.to_bytes()), signed_vote.vote.solution().sector_index, signed_vote.vote.solution().piece_offset, signed_vote.vote.solution().chunk, slot, ), - (reward_address, signed_vote.signature.clone()), + (reward_address, signed_vote.signature), ); map }); @@ -1430,13 +1428,13 @@ fn vote_equivocation_current_voters_duplicate() { let mut map = BTreeMap::new(); map.insert( ( - FarmerPublicKey::unchecked_from(voter_keypair.public.to_bytes()), + PublicKey::from(voter_keypair.public.to_bytes()), signed_vote.vote.solution().sector_index, signed_vote.vote.solution().piece_offset, signed_vote.vote.solution().chunk, slot, ), - (reward_address, FarmerSignature::unchecked_from([0; 64])), + (reward_address, RewardSignature::from([0; 64])), ); map }); @@ -1493,13 +1491,13 @@ fn vote_equivocation_parent_voters_duplicate() { let mut map = BTreeMap::new(); map.insert( ( - FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), + PublicKey::from(keypair.public.to_bytes()), signed_vote.vote.solution().sector_index, signed_vote.vote.solution().piece_offset, signed_vote.vote.solution().chunk, slot, ), - (reward_address, signed_vote.signature.clone()), + (reward_address, signed_vote.signature), ); map }); @@ -1514,13 +1512,13 @@ fn vote_equivocation_parent_voters_duplicate() { let mut map = BTreeMap::new(); map.insert( ( - FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), + PublicKey::from(keypair.public.to_bytes()), signed_vote.vote.solution().sector_index, signed_vote.vote.solution().piece_offset, signed_vote.vote.solution().chunk, slot, ), - (reward_address, FarmerSignature::unchecked_from([0; 64])), + (reward_address, RewardSignature::from([0; 64])), ); map }); @@ -1530,7 +1528,7 @@ fn vote_equivocation_parent_voters_duplicate() { super::check_vote::(&signed_vote, false), CheckVoteError::Equivocated(SubspaceEquivocationOffence { slot, - offender: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()) + offender: PublicKey::from(keypair.public.to_bytes()) }) ); @@ -1545,7 +1543,7 @@ fn vote_equivocation_parent_voters_duplicate() { fn enabling_block_rewards_works() { fn set_block_rewards() { CurrentBlockAuthorInfo::::put(( - FarmerPublicKey::unchecked_from(Keypair::generate().public.to_bytes()), + PublicKey::from(Keypair::generate().public.to_bytes()), 0, PieceOffset::ZERO, Scalar::default(), @@ -1556,13 +1554,13 @@ fn enabling_block_rewards_works() { let mut map = BTreeMap::new(); map.insert( ( - FarmerPublicKey::unchecked_from(Keypair::generate().public.to_bytes()), + PublicKey::from(Keypair::generate().public.to_bytes()), 0, PieceOffset::ZERO, Scalar::default(), Subspace::current_slot(), ), - (2, FarmerSignature::unchecked_from([0; 64])), + (2, RewardSignature::from([0; 64])), ); map }); diff --git a/crates/sc-consensus-subspace-rpc/Cargo.toml b/crates/sc-consensus-subspace-rpc/Cargo.toml index 9ff6acf4e8..576a586403 100644 --- a/crates/sc-consensus-subspace-rpc/Cargo.toml +++ b/crates/sc-consensus-subspace-rpc/Cargo.toml @@ -17,7 +17,6 @@ async-oneshot = "0.5.9" futures = "0.3.29" futures-timer = "3.0.3" jsonrpsee = { version = "0.23.2", features = ["server", "macros"] } -parity-scale-codec = "3.6.12" parking_lot = "0.12.2" schnellru = "0.2.3" sc-client-api = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } diff --git a/crates/sc-consensus-subspace-rpc/src/lib.rs b/crates/sc-consensus-subspace-rpc/src/lib.rs index d2d0e548d0..57bf5ec17a 100644 --- a/crates/sc-consensus-subspace-rpc/src/lib.rs +++ b/crates/sc-consensus-subspace-rpc/src/lib.rs @@ -25,7 +25,6 @@ use jsonrpsee::core::async_trait; use jsonrpsee::proc_macros::rpc; use jsonrpsee::types::{ErrorObject, ErrorObjectOwned}; use jsonrpsee::PendingSubscriptionSink; -use parity_scale_codec::{Decode, Encode}; use parking_lot::Mutex; use sc_client_api::{AuxStore, BlockBackend}; use sc_consensus_subspace::archiver::{ @@ -43,10 +42,7 @@ use schnellru::{ByLength, LruMap}; use sp_api::{ApiError, ProvideRuntimeApi}; use sp_blockchain::HeaderBackend; use sp_consensus::SyncOracle; -use sp_consensus_subspace::{ - ChainConstants, FarmerPublicKey, FarmerSignature, SubspaceApi as SubspaceRuntimeApi, -}; -use sp_core::crypto::ByteArray; +use sp_consensus_subspace::{ChainConstants, SubspaceApi}; use sp_core::H256; use sp_objects::ObjectsApi; use sp_runtime::traits::Block as BlockT; @@ -263,8 +259,7 @@ where reward_signing_notification_stream: SubspaceNotificationStream, archived_segment_notification_stream: SubspaceNotificationStream, #[allow(clippy::type_complexity)] - solution_response_senders: - Arc>>>>, + solution_response_senders: Arc>>>>, reward_signature_senders: Arc>, dsn_bootstrap_nodes: Vec, segment_headers_store: SegmentHeadersStore, @@ -293,7 +288,7 @@ impl SubspaceRpc where Block: BlockT, Client: ProvideRuntimeApi + HeaderBackend, - Client::Api: SubspaceRuntimeApi, + Client::Api: SubspaceApi, SO: SyncOracle + Send + Sync + Clone + 'static, AS: AuxStore + Send + Sync + 'static, { @@ -441,18 +436,12 @@ where // into data structure `sc-consensus-subspace` expects let forward_solution_fut = async move { while let Some(solution) = response_receiver.next().await { - let public_key = - FarmerPublicKey::from_slice(solution.public_key.as_ref()) - .expect("Always correct length; qed"); - let reward_address = - FarmerPublicKey::from_slice(solution.reward_address.as_ref()) - .expect("Always correct length; qed"); - + let public_key = solution.public_key; let sector_index = solution.sector_index; let solution = Solution { - public_key: public_key.clone(), - reward_address, + public_key, + reward_address: solution.reward_address, sector_index, history_size: solution.history_size, piece_offset: solution.piece_offset, @@ -544,18 +533,7 @@ where let forward_signature_fut = async move { if let Ok(reward_signature) = response_receiver.await { if let Some(signature) = reward_signature.signature { - match FarmerSignature::decode(&mut signature.encode().as_ref()) { - Ok(signature) => { - let _ = signature_sender.unbounded_send(signature); - } - Err(error) => { - warn!( - "Failed to convert signature of length {}: {}", - signature.len(), - error - ); - } - } + let _ = signature_sender.unbounded_send(signature); } } }; @@ -575,10 +553,7 @@ where // This will be sent to the farmer RewardSigningInfo { hash: hash.into(), - public_key: public_key - .as_slice() - .try_into() - .expect("Public key is always 32 bytes; qed"), + public_key: *public_key, } }, ); diff --git a/crates/sc-consensus-subspace/src/archiver.rs b/crates/sc-consensus-subspace/src/archiver.rs index 5badb4ccbe..87eb830779 100644 --- a/crates/sc-consensus-subspace/src/archiver.rs +++ b/crates/sc-consensus-subspace/src/archiver.rs @@ -64,7 +64,7 @@ use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_consensus::SyncOracle; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi, SubspaceJustification}; +use sp_consensus_subspace::{SubspaceApi, SubspaceJustification}; use sp_objects::ObjectsApi; use sp_runtime::generic::SignedBlock; use sp_runtime::traits::{Block as BlockT, CheckedSub, Header, NumberFor, One, Zero}; @@ -78,7 +78,9 @@ use std::time::Duration; use subspace_archiving::archiver::{Archiver, NewArchivedSegment}; use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::objects::BlockObjectMapping; -use subspace_core_primitives::{BlockNumber, RecordedHistorySegment, SegmentHeader, SegmentIndex}; +use subspace_core_primitives::{ + BlockNumber, PublicKey, RecordedHistorySegment, SegmentHeader, SegmentIndex, +}; use subspace_erasure_coding::ErasureCoding; use tracing::{debug, info, trace, warn}; @@ -352,7 +354,7 @@ fn find_last_archived_block( where Block: BlockT, Client: ProvideRuntimeApi + BlockBackend + HeaderBackend, - Client::Api: SubspaceApi + ObjectsApi, + Client::Api: SubspaceApi + ObjectsApi, AS: AuxStore, { let Some(max_segment_index) = segment_headers_store.max_segment_index() else { @@ -526,7 +528,7 @@ fn initialize_archiver( where Block: BlockT, Client: ProvideRuntimeApi + BlockBackend + HeaderBackend + AuxStore, - Client::Api: SubspaceApi + ObjectsApi, + Client::Api: SubspaceApi + ObjectsApi, AS: AuxStore, { let client_info = client.info(); @@ -776,7 +778,7 @@ where + Send + Sync + 'static, - Client::Api: SubspaceApi + ObjectsApi, + Client::Api: SubspaceApi + ObjectsApi, AS: AuxStore + Send + Sync + 'static, SO: SyncOracle + Send + Sync + 'static, { @@ -934,7 +936,7 @@ where + Send + Sync + 'static, - Client::Api: SubspaceApi + ObjectsApi, + Client::Api: SubspaceApi + ObjectsApi, AS: AuxStore + Send + Sync + 'static, SO: SyncOracle + Send + Sync + 'static, { diff --git a/crates/sc-consensus-subspace/src/block_import.rs b/crates/sc-consensus-subspace/src/block_import.rs index 8bd9a70afe..afc67b69ec 100644 --- a/crates/sc-consensus-subspace/src/block_import.rs +++ b/crates/sc-consensus-subspace/src/block_import.rs @@ -46,9 +46,7 @@ use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::{ extract_pre_digest, extract_subspace_digest_items, SubspaceDigestItems, }; -use sp_consensus_subspace::{ - FarmerPublicKey, FarmerSignature, PotNextSlotInput, SubspaceApi, SubspaceJustification, -}; +use sp_consensus_subspace::{PotNextSlotInput, SubspaceApi, SubspaceJustification}; use sp_inherents::{CreateInherentDataProviders, InherentDataProvider}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor, One}; use sp_runtime::Justifications; @@ -170,7 +168,7 @@ pub enum Error { DifferentSegmentCommitment(SegmentIndex), /// Farmer in block list #[error("Farmer {0} is in block list")] - FarmerInBlockList(FarmerPublicKey), + FarmerInBlockList(PublicKey), /// Segment commitment not found #[error("Segment commitment for segment index {0} not found")] SegmentCommitmentNotFound(SegmentIndex), @@ -310,7 +308,7 @@ where PosTable: Table, Block: BlockT, Client: ProvideRuntimeApi + BlockBackend + HeaderBackend + AuxStore, - Client::Api: BlockBuilderApi + SubspaceApi + ApiExt, + Client::Api: BlockBuilderApi + SubspaceApi + ApiExt, CIDP: CreateInherentDataProviders + Send + Sync + 'static, AS: AuxStore + Send + Sync + 'static, BlockNumber: From<::Number>, @@ -340,12 +338,8 @@ where block_hash: Block::Hash, header: Block::Header, extrinsics: Option>, - root_plot_public_key: &Option, - subspace_digest_items: &SubspaceDigestItems< - FarmerPublicKey, - FarmerPublicKey, - FarmerSignature, - >, + root_plot_public_key: &Option, + subspace_digest_items: &SubspaceDigestItems, justifications: &Option, ) -> Result<(), Error> { let block_number = *header.number(); @@ -370,9 +364,7 @@ where "Ignoring block with solution provided by farmer in block list", ); - return Err(Error::FarmerInBlockList( - pre_digest.solution().public_key.clone(), - )); + return Err(Error::FarmerInBlockList(pre_digest.solution().public_key)); } let parent_header = self @@ -390,12 +382,9 @@ where let parent_subspace_digest_items = if block_number.is_one() { None } else { - Some(extract_subspace_digest_items::< - _, - FarmerPublicKey, - FarmerPublicKey, - FarmerSignature, - >(&parent_header)?) + Some(extract_subspace_digest_items::<_, PublicKey>( + &parent_header, + )?) }; let correct_solution_range = if block_number.is_one() { @@ -477,7 +466,7 @@ where } let sector_id = SectorId::new( - PublicKey::from(&pre_digest.solution().public_key).hash(), + pre_digest.solution().public_key.hash(), pre_digest.solution().sector_index, ); @@ -515,7 +504,7 @@ where // Piece is not checked during initial block verification because it requires access to // segment header and runtime, check it now. - subspace_verification::verify_solution::( + subspace_verification::verify_solution::( pre_digest.solution(), // Slot was already checked during initial block verification pre_digest.slot().into(), @@ -587,7 +576,7 @@ where + AuxStore + Send + Sync, - Client::Api: BlockBuilderApi + SubspaceApi + ApiExt, + Client::Api: BlockBuilderApi + SubspaceApi + ApiExt, CIDP: CreateInherentDataProviders + Send + Sync + 'static, AS: AuxStore + Send + Sync + 'static, BlockNumber: From<::Number>, diff --git a/crates/sc-consensus-subspace/src/slot_worker.rs b/crates/sc-consensus-subspace/src/slot_worker.rs index d1607b96af..5b1cccc287 100644 --- a/crates/sc-consensus-subspace/src/slot_worker.rs +++ b/crates/sc-consensus-subspace/src/slot_worker.rs @@ -55,10 +55,8 @@ use sp_consensus_subspace::digests::{ extract_pre_digest, CompatibleDigestItem, PreDigest, PreDigestPotInfo, }; use sp_consensus_subspace::{ - FarmerPublicKey, FarmerSignature, PotNextSlotInput, SignedVote, SubspaceApi, - SubspaceJustification, Vote, + PotNextSlotInput, SignedVote, SubspaceApi, SubspaceJustification, Vote, }; -use sp_core::crypto::ByteArray; use sp_core::H256; use sp_runtime::traits::{Block as BlockT, Header, NumberFor, One, Saturating, Zero}; use sp_runtime::{DigestItem, Justification, Justifications}; @@ -150,7 +148,7 @@ pub struct NewSlotNotification { /// New slot information. pub new_slot_info: NewSlotInfo, /// Sender that can be used to send solutions for the slot. - pub solution_sender: mpsc::Sender>, + pub solution_sender: mpsc::Sender>, } /// Notification with a hash that needs to be signed to receive reward and sender for signature. #[derive(Debug, Clone)] @@ -158,9 +156,9 @@ pub struct RewardSigningNotification { /// Hash to be signed. pub hash: H256, /// Public key of the plot identity that should create signature. - pub public_key: FarmerPublicKey, + pub public_key: PublicKey, /// Sender that can be used to send signature for the header. - pub signature_sender: TracingUnboundedSender, + pub signature_sender: TracingUnboundedSender, } /// Parameters for [`SubspaceSlotWorker`] @@ -230,7 +228,7 @@ where segment_headers_store: SegmentHeadersStore, /// Solution receivers for challenges that were sent to farmers and expected to be received /// eventually - pending_solutions: BTreeMap>>, + pending_solutions: BTreeMap>>, /// Collection of PoT slots that can be retrieved later if needed by block production pot_checkpoints: BTreeMap, pot_verifier: PotVerifier, @@ -242,7 +240,7 @@ impl PotSlotWorker where Block: BlockT, Client: HeaderBackend + ProvideRuntimeApi, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, SO: SyncOracle + Send + Sync, { fn on_proof(&mut self, slot: Slot, checkpoints: PotCheckpoints) { @@ -321,7 +319,7 @@ where + HeaderMetadata + AuxStore + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, E: Environment + Send + Sync, E::Proposer: Proposer, SO: SyncOracle + Send + Sync, @@ -337,10 +335,7 @@ where type CreateProposer = Pin> + Send + 'static>>; type Proposer = E::Proposer; - type Claim = ( - PreDigest, - SubspaceJustification, - ); + type Claim = (PreDigest, SubspaceJustification); type AuxData = (); fn logging_target(&self) -> &'static str { @@ -541,10 +536,7 @@ where continue; } - let sector_id = SectorId::new( - PublicKey::from(&solution.public_key).hash(), - solution.sector_index, - ); + let sector_id = SectorId::new(solution.public_key.hash(), solution.sector_index); let history_size = runtime_api.history_size(parent_hash).ok()?; let max_pieces_in_sector = runtime_api.max_pieces_in_sector(parent_hash).ok()?; @@ -587,7 +579,7 @@ where .segment_commitment(parent_hash, sector_expiration_check_segment_index) .ok()?; - let solution_verification_result = verify_solution::( + let solution_verification_result = verify_solution::( &solution, slot.into(), &VerifySolutionParams { @@ -698,7 +690,7 @@ where let signature = self .sign_reward( H256::from_slice(header_hash.as_ref()), - &pre_digest.solution().public_key, + pre_digest.solution().public_key, ) .await?; @@ -782,7 +774,7 @@ where + HeaderMetadata + AuxStore + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, E: Environment + Send + Sync, E::Proposer: Proposer, SO: SyncOracle + Send + Sync, @@ -837,7 +829,7 @@ where &self, parent_header: &Block::Header, slot: Slot, - solution: Solution, + solution: Solution, proof_of_time: PotOutput, future_proof_of_time: PotOutput, ) { @@ -863,7 +855,7 @@ where future_proof_of_time, }; - let signature = match self.sign_reward(vote.hash(), &solution.public_key).await { + let signature = match self.sign_reward(vote.hash(), solution.public_key).await { Ok(signature) => signature, Err(error) => { error!( @@ -889,8 +881,8 @@ where async fn sign_reward( &self, hash: H256, - public_key: &FarmerPublicKey, - ) -> Result { + public_key: PublicKey, + ) -> Result { let (signature_sender, mut signature_receiver) = tracing_unbounded("subspace_signature_signing_stream", 100); @@ -898,15 +890,15 @@ where .reward_signing_notification_sender .notify(|| RewardSigningNotification { hash, - public_key: public_key.clone(), + public_key, signature_sender, }); while let Some(signature) = signature_receiver.next().await { if check_reward_signature( hash.as_ref(), - &RewardSignature::from(&signature), - &subspace_core_primitives::PublicKey::from(public_key), + &signature, + &public_key, &self.reward_signing_context, ) .is_err() @@ -923,7 +915,7 @@ where Err(ConsensusError::CannotSign(format!( "Farmer didn't sign reward. Key: {:?}", - public_key.to_raw_vec() + public_key ))) } } @@ -937,7 +929,7 @@ pub(crate) fn extract_solution_ranges_for_block( where Block: BlockT, Client: ProvideRuntimeApi, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, { client .runtime_api() diff --git a/crates/sc-consensus-subspace/src/tests.rs b/crates/sc-consensus-subspace/src/tests.rs index bd09a10c99..a1f1695230 100644 --- a/crates/sc-consensus-subspace/src/tests.rs +++ b/crates/sc-consensus-subspace/src/tests.rs @@ -586,8 +586,8 @@ // // // // let _ = solution_sender // // .send(Solution { -// // public_key: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), -// // reward_address: FarmerPublicKey::unchecked_from( +// // public_key: FarmerPublicKey::from_bytes(keypair.public.to_bytes()), +// // reward_address: FarmerPublicKey::from_bytes( // // keypair.public.to_bytes(), // // ), // // piece_index, @@ -677,7 +677,7 @@ // #[test] // fn malformed_pre_digest_rejected() { // sp_tracing::try_init_simple(); -// let bad_seal = DigestItem::subspace_seal(FarmerSignature::unchecked_from([0u8; 64])); +// let bad_seal = DigestItem::subspace_seal(FarmerSignature::from_bytes([0u8; 64])); // assert!(CompatibleDigestItem::as_subspace_pre_digest::(&bad_seal).is_none()); // } // @@ -686,7 +686,7 @@ // sp_tracing::try_init_simple(); // let keypair = Keypair::generate(); // let ctx = schnorrkel::context::signing_context(REWARD_SIGNING_CONTEXT); -// let bad_seal = DigestItem::subspace_seal(FarmerSignature::unchecked_from( +// let bad_seal = DigestItem::subspace_seal(FarmerSignature::from_bytes( // keypair.sign(ctx.bytes(b"")).to_bytes(), // )); // assert!(CompatibleDigestItem::as_subspace_pre_digest::(&bad_seal).is_none()); @@ -700,8 +700,8 @@ // Some(( // PreDigest { // solution: Solution { -// public_key: FarmerPublicKey::unchecked_from([0u8; 32]), -// reward_address: FarmerPublicKey::unchecked_from([0u8; 32]), +// public_key: FarmerPublicKey::from_bytes([0u8; 32]), +// reward_address: FarmerPublicKey::from_bytes([0u8; 32]), // sector_index: 0, // history_size: HistorySize::from(NonZeroU64::new(1).unwrap()), // piece_offset: PieceOffset::default(), @@ -713,7 +713,7 @@ // }, // slot, // }, -// FarmerPublicKey::unchecked_from([0u8; 32]), +// FarmerPublicKey::from_bytes([0u8; 32]), // )) // } // @@ -762,8 +762,8 @@ // // logs: vec![DigestItem::subspace_pre_digest(&PreDigest { // // slot, // // solution: Solution { -// // public_key: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), -// // reward_address: FarmerPublicKey::unchecked_from(keypair.public.to_bytes()), +// // public_key: FarmerPublicKey::from_bytes(keypair.public.to_bytes()), +// // reward_address: FarmerPublicKey::from_bytes(keypair.public.to_bytes()), // // piece_index: 0, // // encoding, // // tag_signature: create_chunk_signature(&keypair, tag), diff --git a/crates/sc-consensus-subspace/src/verifier.rs b/crates/sc-consensus-subspace/src/verifier.rs index 9f0c642e55..f0371ba383 100644 --- a/crates/sc-consensus-subspace/src/verifier.rs +++ b/crates/sc-consensus-subspace/src/verifier.rs @@ -32,10 +32,7 @@ use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::{ extract_subspace_digest_items, CompatibleDigestItem, PreDigest, SubspaceDigestItems, }; -use sp_consensus_subspace::{ - ChainConstants, FarmerPublicKey, FarmerSignature, PotNextSlotInput, SubspaceApi, - SubspaceJustification, -}; +use sp_consensus_subspace::{ChainConstants, PotNextSlotInput, SubspaceApi, SubspaceJustification}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sp_runtime::{DigestItem, Justifications}; use std::iter; @@ -45,7 +42,7 @@ use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; use std::thread::available_parallelism; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::{BlockNumber, PublicKey, RewardSignature}; +use subspace_core_primitives::{BlockNumber, PublicKey}; use subspace_proof_of_space::Table; use subspace_verification::{check_reward_signature, verify_solution, VerifySolutionParams}; use tokio::sync::Semaphore; @@ -91,7 +88,7 @@ struct CheckedHeader { /// Includes the digest item that encoded the seal. pre_header: H, /// Pre-digest - pre_digest: PreDigest, + pre_digest: PreDigest, /// Seal (signature) seal: DigestItem, } @@ -163,7 +160,7 @@ where Block: BlockT, BlockNumber: From>, Client: AuxStore + HeaderBackend + ProvideRuntimeApi, - Client::Api: BlockBuilderApi + SubspaceApi, + Client::Api: BlockBuilderApi + SubspaceApi, SelectChain: sp_consensus::SelectChain, { /// Create new instance @@ -237,11 +234,7 @@ where async fn check_header( &self, params: VerificationParams<'_, Block::Header>, - subspace_digest_items: SubspaceDigestItems< - FarmerPublicKey, - FarmerPublicKey, - FarmerSignature, - >, + subspace_digest_items: SubspaceDigestItems, full_pot_verification: bool, justifications: &Option, ) -> Result, VerificationError> { @@ -367,8 +360,8 @@ where // Verify that block is signed properly if check_reward_signature( pre_hash.as_ref(), - &RewardSignature::from(&signature), - &PublicKey::from(&pre_digest.solution().public_key), + &signature, + &pre_digest.solution().public_key, &self.reward_signing_context, ) .is_err() @@ -377,7 +370,7 @@ where } // Verify that solution is valid - verify_solution::( + verify_solution::( pre_digest.solution(), slot.into(), verify_solution_params, @@ -397,7 +390,7 @@ where slot_now: Slot, slot: Slot, header: &Block::Header, - author: &FarmerPublicKey, + author: &PublicKey, origin: &BlockOrigin, ) -> Result<(), String> { // don't report any equivocations during initial sync @@ -464,7 +457,7 @@ where Block: BlockT, BlockNumber: From>, Client: HeaderBackend + ProvideRuntimeApi + Send + Sync + AuxStore, - Client::Api: BlockBuilderApi + SubspaceApi, + Client::Api: BlockBuilderApi + SubspaceApi, SelectChain: sp_consensus::SelectChain, { fn verification_concurrency(&self) -> NonZeroUsize { @@ -507,12 +500,8 @@ where block.header.digest().logs().len() ); - let subspace_digest_items = extract_subspace_digest_items::< - Block::Header, - FarmerPublicKey, - FarmerPublicKey, - FarmerSignature, - >(&block.header)?; + let subspace_digest_items = + extract_subspace_digest_items::(&block.header)?; // Check if farmer's plot is burned, ignore runtime API errors since this check will happen // during block import anyway diff --git a/crates/sc-proof-of-time/src/lib.rs b/crates/sc-proof-of-time/src/lib.rs index 679faf80e9..dfde337509 100644 --- a/crates/sc-proof-of-time/src/lib.rs +++ b/crates/sc-proof-of-time/src/lib.rs @@ -13,11 +13,11 @@ use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_consensus::{SelectChain, SyncOracle}; use sp_consensus_slots::{Slot, SlotDuration}; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi as SubspaceRuntimeApi}; +use sp_consensus_subspace::SubspaceApi; use sp_inherents::CreateInherentDataProviders; use sp_runtime::traits::Block as BlockT; use std::sync::Arc; -use subspace_core_primitives::PotCheckpoints; +use subspace_core_primitives::{PotCheckpoints, PublicKey}; use tokio::sync::broadcast::error::RecvError; use tracing::{debug, error, info, trace}; @@ -46,7 +46,7 @@ pub async fn start_slot_worker( ) where Block: BlockT, Client: ProvideRuntimeApi + HeaderBackend, - Client::Api: SubspaceRuntimeApi, + Client::Api: SubspaceApi, SC: SelectChain, Worker: PotSlotWorker + SimpleSlotWorker + Send + Sync, SO: SyncOracle + Send, diff --git a/crates/sc-proof-of-time/src/source.rs b/crates/sc-proof-of-time/src/source.rs index 09cf2bbbe3..0b6f922a04 100644 --- a/crates/sc-proof-of-time/src/source.rs +++ b/crates/sc-proof-of-time/src/source.rs @@ -18,16 +18,13 @@ use sp_blockchain::HeaderBackend; use sp_consensus::SyncOracle; use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::{extract_pre_digest, extract_subspace_digest_items}; -use sp_consensus_subspace::{ - ChainConstants, FarmerPublicKey, FarmerSignature, PotNextSlotInput, - SubspaceApi as SubspaceRuntimeApi, -}; +use sp_consensus_subspace::{ChainConstants, PotNextSlotInput, SubspaceApi}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Zero}; use std::collections::HashSet; use std::marker::PhantomData; use std::sync::Arc; use std::thread; -use subspace_core_primitives::PotCheckpoints; +use subspace_core_primitives::{PotCheckpoints, PublicKey}; use thread_priority::{set_current_thread_priority, ThreadPriority}; use tokio::sync::broadcast; use tracing::{debug, error, trace, warn}; @@ -73,7 +70,7 @@ impl PotSourceWorker where Block: BlockT, Client: BlockchainEvents + HeaderBackend + ProvideRuntimeApi, - Client::Api: SubspaceRuntimeApi, + Client::Api: SubspaceApi, SO: SyncOracle + Clone + Send + Sync + 'static, { // TODO: Struct for arguments @@ -339,24 +336,19 @@ where block_hash: Block::Hash, header: &Block::Header, ) { - let subspace_digest_items = match extract_subspace_digest_items::< - Block::Header, - FarmerPublicKey, - FarmerPublicKey, - FarmerSignature, - >(header) - { - Ok(pre_digest) => pre_digest, - Err(error) => { - error!( - %error, - block_number = %header.number(), - %block_hash, - "Failed to extract Subspace digest items from header" - ); - return; - } - }; + let subspace_digest_items = + match extract_subspace_digest_items::(header) { + Ok(pre_digest) => pre_digest, + Err(error) => { + error!( + %error, + block_number = %header.number(), + %block_hash, + "Failed to extract Subspace digest items from header" + ); + return; + } + }; let best_slot = subspace_digest_items.pre_digest.slot() + self.chain_constants.block_authoring_delay(); diff --git a/crates/sc-subspace-block-relay/Cargo.toml b/crates/sc-subspace-block-relay/Cargo.toml index ba090c034b..5d0dcafcbe 100644 --- a/crates/sc-subspace-block-relay/Cargo.toml +++ b/crates/sc-subspace-block-relay/Cargo.toml @@ -26,7 +26,7 @@ sp-consensus-subspace = { version = "0.1.0", path = "../sp-consensus-subspace" } sc-transaction-pool-api = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-runtime = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } strum_macros = "0.26.4" +subspace-core-primitives = { version = "0.1.0", path = "../subspace-core-primitives" } substrate-prometheus-endpoint = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } thiserror = "1.0.63" tracing = "0.1.40" - diff --git a/crates/sc-subspace-block-relay/src/consensus/relay.rs b/crates/sc-subspace-block-relay/src/consensus/relay.rs index 6a3af92aa2..cb31a2c018 100644 --- a/crates/sc-subspace-block-relay/src/consensus/relay.rs +++ b/crates/sc-subspace-block-relay/src/consensus/relay.rs @@ -28,12 +28,13 @@ use sc_network_sync::block_relay_protocol::{ }; use sc_transaction_pool_api::{InPoolTransaction, TransactionPool, TxHash}; use sp_api::ProvideRuntimeApi; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; +use sp_consensus_subspace::SubspaceApi; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header, One, Zero}; use std::num::{NonZeroU32, NonZeroUsize}; use std::sync::Arc; use std::time::{Duration, Instant}; +use subspace_core_primitives::PublicKey; use substrate_prometheus_endpoint::{PrometheusError, Registry}; use tracing::{debug, info, trace, warn}; @@ -295,7 +296,7 @@ impl ConsensusRelayServer where Block: BlockT, Client: HeaderBackend + BlockBackend + ProvideRuntimeApi, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, Pool: TransactionPool + 'static, { /// Creates the consensus relay server. @@ -553,7 +554,7 @@ impl BlockServer for ConsensusRelayServer + BlockBackend + ProvideRuntimeApi, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, Pool: TransactionPool + 'static, { async fn run(&mut self) { @@ -596,7 +597,7 @@ impl ServerBackend, TxHash, Extrinsi where Block: BlockT, Client: HeaderBackend + BlockBackend + ProvideRuntimeApi, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, Pool: TransactionPool + 'static, { fn download_unit_members( @@ -689,7 +690,7 @@ pub fn build_consensus_relay( where Block: BlockT, Client: HeaderBackend + BlockBackend + ProvideRuntimeApi + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, Pool: TransactionPool + 'static, { let (tx, request_receiver) = async_channel::bounded(NUM_PEER_HINT.get()); diff --git a/crates/sp-consensus-subspace/src/digests.rs b/crates/sp-consensus-subspace/src/digests.rs index 28492965d2..875528ea7c 100644 --- a/crates/sp-consensus-subspace/src/digests.rs +++ b/crates/sp-consensus-subspace/src/digests.rs @@ -16,39 +16,36 @@ //! Private implementation details of Subspace consensus digests. -use crate::{ - ConsensusLog, FarmerPublicKey, FarmerSignature, PotParametersChange, SUBSPACE_ENGINE_ID, -}; +use crate::{ConsensusLog, PotParametersChange, SUBSPACE_ENGINE_ID}; use codec::{Decode, Encode}; use log::trace; use sp_consensus_slots::Slot; -use sp_core::crypto::UncheckedFrom; use sp_runtime::traits::{Header as HeaderT, One, Zero}; use sp_runtime::DigestItem; use sp_std::collections::btree_map::{BTreeMap, Entry}; use sp_std::fmt; use sp_std::num::NonZeroU32; use subspace_core_primitives::{ - PotOutput, SegmentCommitment, SegmentIndex, Solution, SolutionRange, + PotOutput, PublicKey, RewardSignature, SegmentCommitment, SegmentIndex, Solution, SolutionRange, }; /// A Subspace pre-runtime digest. This contains all data required to validate a block and for the /// Subspace runtime module. #[derive(Debug, Clone, Encode, Decode)] -pub enum PreDigest { +pub enum PreDigest { /// Initial version of the pre-digest #[codec(index = 0)] V0 { /// Slot slot: Slot, /// Solution (includes PoR) - solution: Solution, + solution: Solution, /// Proof of time information pot_info: PreDigestPotInfo, }, } -impl PreDigest { +impl PreDigest { /// Slot #[inline] pub fn slot(&self) -> Slot { @@ -58,7 +55,7 @@ impl PreDigest { /// Solution (includes PoR) #[inline] - pub fn solution(&self) -> &Solution { + pub fn solution(&self) -> &Solution { let Self::V0 { solution, .. } = self; solution } @@ -106,20 +103,16 @@ impl PreDigestPotInfo { /// A digest item which is usable with Subspace consensus. pub trait CompatibleDigestItem: Sized { /// Construct a digest item which contains a Subspace pre-digest. - fn subspace_pre_digest( - pre_digest: &PreDigest, - ) -> Self; + fn subspace_pre_digest(pre_digest: &PreDigest) -> Self; /// If this item is an Subspace pre-digest, return it. - fn as_subspace_pre_digest( - &self, - ) -> Option>; + fn as_subspace_pre_digest(&self) -> Option>; /// Construct a digest item which contains a Subspace seal. - fn subspace_seal(signature: FarmerSignature) -> Self; + fn subspace_seal(signature: RewardSignature) -> Self; /// If this item is a Subspace signature, return the signature. - fn as_subspace_seal(&self) -> Option; + fn as_subspace_seal(&self) -> Option; /// Number of iterations for proof of time per slot, corresponds to slot that directly follows /// parent block's slot and can change before slot for which block is produced @@ -166,30 +159,26 @@ pub trait CompatibleDigestItem: Sized { fn as_enable_solution_range_adjustment_and_override(&self) -> Option>; /// Construct digest item that indicates update of root plot public key. - fn root_plot_public_key_update(root_plot_public_key: Option) -> Self; + fn root_plot_public_key_update(root_plot_public_key: Option) -> Self; /// If this item is a Subspace update of root plot public key, return it. - fn as_root_plot_public_key_update(&self) -> Option>; + fn as_root_plot_public_key_update(&self) -> Option>; } impl CompatibleDigestItem for DigestItem { - fn subspace_pre_digest( - pre_digest: &PreDigest, - ) -> Self { + fn subspace_pre_digest(pre_digest: &PreDigest) -> Self { Self::PreRuntime(SUBSPACE_ENGINE_ID, pre_digest.encode()) } - fn as_subspace_pre_digest( - &self, - ) -> Option> { + fn as_subspace_pre_digest(&self) -> Option> { self.pre_runtime_try_to(&SUBSPACE_ENGINE_ID) } - fn subspace_seal(signature: FarmerSignature) -> Self { + fn subspace_seal(signature: RewardSignature) -> Self { Self::Seal(SUBSPACE_ENGINE_ID, signature.encode()) } - fn as_subspace_seal(&self) -> Option { + fn as_subspace_seal(&self) -> Option { self.seal_try_to(&SUBSPACE_ENGINE_ID) } @@ -304,14 +293,14 @@ impl CompatibleDigestItem for DigestItem { }) } - fn root_plot_public_key_update(root_plot_public_key: Option) -> Self { + fn root_plot_public_key_update(root_plot_public_key: Option) -> Self { Self::Consensus( SUBSPACE_ENGINE_ID, ConsensusLog::RootPlotPublicKeyUpdate(root_plot_public_key).encode(), ) } - fn as_root_plot_public_key_update(&self) -> Option> { + fn as_root_plot_public_key_update(&self) -> Option> { self.consensus_try_to(&SUBSPACE_ENGINE_ID).and_then(|c| { if let ConsensusLog::RootPlotPublicKeyUpdate(root_plot_public_key) = c { Some(root_plot_public_key) @@ -429,11 +418,11 @@ impl From for String { /// Digest items extracted from a header into convenient form #[derive(Debug)] -pub struct SubspaceDigestItems { +pub struct SubspaceDigestItems { /// Pre-runtime digest - pub pre_digest: PreDigest, + pub pre_digest: PreDigest, /// Signature (seal) if present - pub signature: Option, + pub signature: Option, /// Number of iterations for proof of time per slot, corresponds to slot that directly follows /// parent block's slot and can change before slot for which block is produced pub pot_slot_iterations: NonZeroU32, @@ -448,18 +437,16 @@ pub struct SubspaceDigestItems { /// Enable solution range adjustment and Override solution range pub enable_solution_range_adjustment_and_override: Option>, /// Root plot public key was updated - pub root_plot_public_key_update: Option>, + pub root_plot_public_key_update: Option>, } /// Extract the Subspace global randomness from the given header. -pub fn extract_subspace_digest_items( +pub fn extract_subspace_digest_items( header: &Header, -) -> Result, Error> +) -> Result, Error> where Header: HeaderT, - PublicKey: Decode, RewardAddress: Decode, - Signature: Decode, { let mut maybe_pre_digest = None; let mut maybe_seal = None; @@ -478,10 +465,8 @@ where continue; } - let pre_digest = PreDigest::::decode( - &mut data.as_slice(), - ) - .map_err(|error| Error::FailedToDecode(ErrorDigestType::PreDigest, error))?; + let pre_digest = PreDigest::::decode(&mut data.as_slice()) + .map_err(|error| Error::FailedToDecode(ErrorDigestType::PreDigest, error))?; match maybe_pre_digest { Some(_) => { @@ -579,7 +564,7 @@ where continue; } - let seal = Signature::decode(&mut data.as_slice()) + let seal = RewardSignature::decode(&mut data.as_slice()) .map_err(|error| Error::FailedToDecode(ErrorDigestType::Seal, error))?; match maybe_seal { @@ -617,9 +602,7 @@ where /// Extract the Subspace pre digest from the given header. Pre-runtime digests are mandatory, the /// function will return `Err` if none is found. -pub fn extract_pre_digest
( - header: &Header, -) -> Result, Error> +pub fn extract_pre_digest
(header: &Header) -> Result, Error> where Header: HeaderT, { @@ -629,8 +612,8 @@ where return Ok(PreDigest::V0 { slot: Slot::from(0), solution: Solution::genesis_solution( - FarmerPublicKey::unchecked_from([0u8; 32]), - FarmerPublicKey::unchecked_from([0u8; 32]), + PublicKey::from([0u8; 32]), + PublicKey::from([0u8; 32]), ), pot_info: PreDigestPotInfo::V0 { proof_of_time: Default::default(), @@ -718,7 +701,7 @@ pub struct NextDigestsVerificationParams<'a, Header: HeaderT> { /// Header number for which we are verifying the digests. pub number: NumberOf
, /// Digests present in the header that corresponds to number above. - pub header_digests: &'a SubspaceDigestItems, + pub header_digests: &'a SubspaceDigestItems, /// Era duration at which solution range is updated. pub era_duration: NumberOf
, /// Slot probability. @@ -733,7 +716,7 @@ pub struct NextDigestsVerificationParams<'a, Header: HeaderT> { pub maybe_next_solution_range_override: &'a mut Option, /// Root plot public key. /// Value is updated when digest items contain an update. - pub maybe_root_plot_public_key: &'a mut Option, + pub maybe_root_plot_public_key: &'a mut Option, } /// Derives and verifies next digest items based on their respective intervals. @@ -793,15 +776,15 @@ pub fn verify_next_digests( )); } - if let Some(updated_root_plot_public_key) = &header_digests.root_plot_public_key_update { + if let Some(updated_root_plot_public_key) = header_digests.root_plot_public_key_update { match updated_root_plot_public_key { Some(updated_root_plot_public_key) => { if number.is_one() && root_plot_public_key.is_none() - && &header_digests.pre_digest.solution().public_key + && header_digests.pre_digest.solution().public_key == updated_root_plot_public_key { - root_plot_public_key.replace(updated_root_plot_public_key.clone()); + root_plot_public_key.replace(updated_root_plot_public_key); } else { return Err(Error::NextDigestVerificationError( ErrorDigestType::RootPlotPublicKeyUpdate, diff --git a/crates/sp-consensus-subspace/src/lib.rs b/crates/sp-consensus-subspace/src/lib.rs index fa1c79cd09..5fb1d531d1 100644 --- a/crates/sp-consensus-subspace/src/lib.rs +++ b/crates/sp-consensus-subspace/src/lib.rs @@ -37,7 +37,6 @@ use alloc::vec::Vec; use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_consensus_slots::{Slot, SlotDuration}; -use sp_core::crypto::KeyTypeId; use sp_core::H256; use sp_io::hashing; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; @@ -50,7 +49,7 @@ use subspace_core_primitives::crypto::kzg::Kzg; use subspace_core_primitives::{ Blake3Hash, BlockHash, BlockNumber, HistorySize, PotCheckpoints, PotOutput, PotSeed, PublicKey, RewardSignature, SegmentCommitment, SegmentHeader, SegmentIndex, SlotNumber, Solution, - SolutionRange, PUBLIC_KEY_LENGTH, REWARD_SIGNATURE_LENGTH, REWARD_SIGNING_CONTEXT, + SolutionRange, REWARD_SIGNING_CONTEXT, }; #[cfg(feature = "std")] use subspace_proof_of_space::chia::ChiaTable; @@ -62,44 +61,6 @@ use subspace_proof_of_space::PosTableType; use subspace_proof_of_space::Table; use subspace_verification::{check_reward_signature, VerifySolutionParams}; -/// Key type for Subspace pallet. -const KEY_TYPE: KeyTypeId = KeyTypeId(*b"sub_"); - -// TODO: Remove this and replace with simple encodable wrappers of Schnorrkel's types -mod app { - use super::KEY_TYPE; - use sp_application_crypto::{app_crypto, sr25519}; - - app_crypto!(sr25519, KEY_TYPE); -} - -/// A Subspace farmer signature. -pub type FarmerSignature = app::Signature; - -impl From<&FarmerSignature> for RewardSignature { - #[inline] - fn from(signature: &FarmerSignature) -> Self { - RewardSignature::from( - TryInto::<[u8; REWARD_SIGNATURE_LENGTH]>::try_into(AsRef::<[u8]>::as_ref(signature)) - .expect("Always correct length; qed"), - ) - } -} - -/// A Subspace farmer identifier. Necessarily equivalent to the schnorrkel public key used in -/// the main Subspace module. If that ever changes, then this must, too. -pub type FarmerPublicKey = app::Public; - -impl From<&FarmerPublicKey> for PublicKey { - #[inline] - fn from(pub_key: &FarmerPublicKey) -> Self { - PublicKey::from( - TryInto::<[u8; PUBLIC_KEY_LENGTH]>::try_into(AsRef::<[u8]>::as_ref(pub_key)) - .expect("Always correct length; qed"), - ) - } -} - /// The `ConsensusEngineId` of Subspace. const SUBSPACE_ENGINE_ID: ConsensusEngineId = *b"SUB_"; @@ -144,7 +105,7 @@ impl SubspaceJustification { } /// An equivocation proof for multiple block authorships on the same slot (i.e. double vote). -pub type EquivocationProof
= sp_consensus_slots::EquivocationProof; +pub type EquivocationProof
= sp_consensus_slots::EquivocationProof; /// Next slot input for proof of time evaluation #[derive(Debug, Copy, Clone, PartialEq, Eq, Decode, Encode, TypeInfo, MaxEncodedLen)] @@ -233,7 +194,7 @@ enum ConsensusLog { EnableSolutionRangeAdjustmentAndOverride(Option), /// Root plot public key was updated. #[codec(index = 6)] - RootPlotPublicKeyUpdate(Option), + RootPlotPublicKeyUpdate(Option), } /// Farmer vote. @@ -250,7 +211,7 @@ pub enum Vote { /// Slot at which vote was created. slot: Slot, /// Solution (includes PoR). - solution: Solution, + solution: Solution, /// Proof of time for this slot proof_of_time: PotOutput, /// Future proof of time @@ -265,7 +226,7 @@ where RewardAddress: Encode, { /// Solution contained within. - pub fn solution(&self) -> &Solution { + pub fn solution(&self) -> &Solution { let Self::V0 { solution, .. } = self; solution } @@ -288,12 +249,10 @@ pub struct SignedVote { /// Farmer vote. pub vote: Vote, /// Signature. - pub signature: FarmerSignature, + pub signature: RewardSignature, } -fn find_pre_digest( - header: &Header, -) -> Option> +fn find_pre_digest(header: &Header) -> Option> where Header: HeaderT, RewardAddress: Decode, @@ -305,7 +264,7 @@ where .find_map(|log| log.as_subspace_pre_digest()) } -fn is_seal_signature_valid
(mut header: Header, offender: &FarmerPublicKey) -> bool +fn is_seal_signature_valid
(mut header: Header, offender: &PublicKey) -> bool where Header: HeaderT, { @@ -325,8 +284,8 @@ where check_reward_signature( pre_hash.as_ref(), - &RewardSignature::from(&seal), - &PublicKey::from(offender), + &seal, + offender, &schnorrkel::signing_context(REWARD_SIGNING_CONTEXT), ) .is_ok() @@ -498,13 +457,13 @@ impl ChainConstants { /// Wrapped solution for the purposes of runtime interface. #[derive(Debug, Encode, Decode)] -pub struct WrappedSolution(Solution); +pub struct WrappedSolution(Solution<()>); -impl From<&Solution> for WrappedSolution { +impl From<&Solution> for WrappedSolution { #[inline] - fn from(solution: &Solution) -> Self { + fn from(solution: &Solution) -> Self { Self(Solution { - public_key: solution.public_key.clone(), + public_key: solution.public_key, reward_address: (), sector_index: solution.sector_index, history_size: solution.history_size, @@ -624,14 +583,14 @@ pub trait Consensus { .0; match pos_table_type { - PosTableType::Chia => subspace_verification::verify_solution::( + PosTableType::Chia => subspace_verification::verify_solution::( &solution.0, slot, ¶ms.0, kzg, ) .map_err(|error| error.to_string()), - PosTableType::Shim => subspace_verification::verify_solution::( + PosTableType::Shim => subspace_verification::verify_solution::( &solution.0, slot, ¶ms.0, @@ -723,7 +682,7 @@ sp_api::decl_runtime_apis! { ); /// Check if `farmer_public_key` is in block list (due to equivocation) - fn is_in_block_list(farmer_public_key: &FarmerPublicKey) -> bool; + fn is_in_block_list(farmer_public_key: &PublicKey) -> bool; /// Size of the blockchain history fn history_size() -> HistorySize; @@ -741,7 +700,7 @@ sp_api::decl_runtime_apis! { fn is_inherent(ext: &Block::Extrinsic) -> bool; /// Returns root plot public key in case block authoring is restricted. - fn root_plot_public_key() -> Option; + fn root_plot_public_key() -> Option; /// Whether solution range adjustment is enabled. fn should_adjust_solution_range() -> bool; diff --git a/crates/sp-consensus-subspace/src/tests.rs b/crates/sp-consensus-subspace/src/tests.rs index a73dabc448..9fbabf412c 100644 --- a/crates/sp-consensus-subspace/src/tests.rs +++ b/crates/sp-consensus-subspace/src/tests.rs @@ -1,26 +1,24 @@ use crate::digests::PreDigestPotInfo; -use crate::{ - is_equivocation_proof_valid, CompatibleDigestItem, EquivocationProof, FarmerPublicKey, - FarmerSignature, -}; +use crate::{is_equivocation_proof_valid, CompatibleDigestItem, EquivocationProof}; use schnorrkel::Keypair; use sp_consensus_slots::Slot; -use sp_core::crypto::UncheckedFrom; use sp_runtime::traits::BlakeTwo256; use sp_runtime::{Digest, DigestItem}; use std::num::NonZeroU64; -use subspace_core_primitives::{HistorySize, PieceOffset, Solution, REWARD_SIGNING_CONTEXT}; +use subspace_core_primitives::{ + HistorySize, PieceOffset, PublicKey, RewardSignature, Solution, REWARD_SIGNING_CONTEXT, +}; type Header = sp_runtime::generic::Header; -type PreDigest = crate::PreDigest; +type PreDigest = crate::PreDigest<()>; #[test] fn test_is_equivocation_proof_valid() { let keypair = Keypair::generate(); - let offender = FarmerPublicKey::unchecked_from(keypair.public.to_bytes()); + let offender = PublicKey::from(keypair.public.to_bytes()); let slot = Slot::from(1); let solution = Solution { - public_key: offender.clone(), + public_key: offender, reward_address: (), sector_index: 0, history_size: HistorySize::from(NonZeroU64::new(1).unwrap()), @@ -51,7 +49,7 @@ fn test_is_equivocation_proof_valid() { first_header .digest .logs - .push(DigestItem::subspace_seal(FarmerSignature::unchecked_from( + .push(DigestItem::subspace_seal(RewardSignature::from( keypair .sign( schnorrkel::context::signing_context(REWARD_SIGNING_CONTEXT) @@ -79,7 +77,7 @@ fn test_is_equivocation_proof_valid() { second_header .digest .logs - .push(DigestItem::subspace_seal(FarmerSignature::unchecked_from( + .push(DigestItem::subspace_seal(RewardSignature::from( keypair .sign( schnorrkel::context::signing_context(REWARD_SIGNING_CONTEXT) diff --git a/crates/subspace-core-primitives/Cargo.toml b/crates/subspace-core-primitives/Cargo.toml index c46f8a82d2..36341af5f7 100644 --- a/crates/subspace-core-primitives/Cargo.toml +++ b/crates/subspace-core-primitives/Cargo.toml @@ -27,7 +27,7 @@ parking_lot = { version = "0.12.2", optional = true } rayon = { version = "1.10.0", optional = true } rust-kzg-blst = { git = "https://github.com/grandinetech/rust-kzg", rev = "6c8fcc623df3d7e8c0f30951a49bfea764f90bf4", default-features = false } scale-info = { version = "2.11.2", default-features = false, features = ["derive"] } -serde = { version = "1.0.206", optional = true, features = ["alloc", "derive"] } +serde = { version = "1.0.206", optional = true, default-features = false, features = ["alloc", "derive"] } # Replacement for `parking_lot` in `no_std` environment spin = "0.9.7" static_assertions = "1.1.0" diff --git a/crates/subspace-core-primitives/src/lib.rs b/crates/subspace-core-primitives/src/lib.rs index 37100c3f83..191461e1d2 100644 --- a/crates/subspace-core-primitives/src/lib.rs +++ b/crates/subspace-core-primitives/src/lib.rs @@ -220,12 +220,6 @@ const_assert!( /// The closer solution's tag is to the target, the heavier it is. pub type BlockWeight = u128; -/// Length of public key in bytes. -pub const PUBLIC_KEY_LENGTH: usize = 32; - -/// Length of signature in bytes -pub const REWARD_SIGNATURE_LENGTH: usize = 64; - /// Proof of space seed. #[derive(Debug, Copy, Clone, Eq, PartialEq, Deref)] pub struct PosSeed([u8; Self::SIZE]); @@ -481,10 +475,9 @@ impl PotCheckpoints { TypeInfo, Deref, From, - Into, )] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct PublicKey(#[cfg_attr(feature = "serde", serde(with = "hex"))] [u8; PUBLIC_KEY_LENGTH]); +pub struct PublicKey(#[cfg_attr(feature = "serde", serde(with = "hex"))] [u8; Self::SIZE]); impl fmt::Display for PublicKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -492,6 +485,13 @@ impl fmt::Display for PublicKey { } } +impl From for [u8; PublicKey::SIZE] { + #[inline] + fn from(value: PublicKey) -> Self { + value.0 + } +} + impl AsRef<[u8]> for PublicKey { #[inline] fn as_ref(&self) -> &[u8] { @@ -500,6 +500,9 @@ impl AsRef<[u8]> for PublicKey { } impl PublicKey { + /// Public key size in bytes + pub const SIZE: usize = 32; + /// Public key hash. pub fn hash(&self) -> Blake3Hash { blake3_hash(&self.0) @@ -508,25 +511,17 @@ impl PublicKey { /// A Ristretto Schnorr signature as bytes produced by `schnorrkel` crate. #[derive( - Debug, - Copy, - Clone, - PartialEq, - Eq, - Ord, - PartialOrd, - Hash, - Encode, - Decode, - TypeInfo, - Deref, - From, - Into, + Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Encode, Decode, TypeInfo, Deref, From, )] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct RewardSignature( - #[cfg_attr(feature = "serde", serde(with = "hex"))] [u8; REWARD_SIGNATURE_LENGTH], -); +pub struct RewardSignature(#[cfg_attr(feature = "serde", serde(with = "hex"))] [u8; Self::SIZE]); + +impl From for [u8; RewardSignature::SIZE] { + #[inline] + fn from(value: RewardSignature) -> Self { + value.0 + } +} impl AsRef<[u8]> for RewardSignature { #[inline] @@ -535,6 +530,11 @@ impl AsRef<[u8]> for RewardSignature { } } +impl RewardSignature { + /// Reward signature size in bytes + pub const SIZE: usize = 64; +} + /// Progress of an archived block. #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Encode, Decode, TypeInfo)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -674,7 +674,7 @@ pub type SectorIndex = u16; #[derive(Clone, Debug, Eq, PartialEq, Encode, Decode, TypeInfo)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub struct Solution { +pub struct Solution { /// Public key of the farmer that created the solution pub public_key: PublicKey, /// Address for receiving block reward @@ -697,12 +697,10 @@ pub struct Solution { pub proof_of_space: PosProof, } -impl Solution { +impl Solution { /// Transform solution with one reward address type into solution with another compatible /// reward address type. - pub fn into_reward_address_format( - self, - ) -> Solution + pub fn into_reward_address_format(self) -> Solution where RewardAddressA: Into, T: Into, @@ -734,7 +732,7 @@ impl Solution { } } -impl Solution { +impl Solution { /// Dummy solution for the genesis block pub fn genesis_solution(public_key: PublicKey, reward_address: RewardAddress) -> Self { Self { diff --git a/crates/subspace-fake-runtime-api/src/lib.rs b/crates/subspace-fake-runtime-api/src/lib.rs index e6da2d07a5..2fe77e34be 100644 --- a/crates/subspace-fake-runtime-api/src/lib.rs +++ b/crates/subspace-fake-runtime-api/src/lib.rs @@ -20,7 +20,7 @@ use domain_runtime_primitives::opaque::Header as DomainHeader; use domain_runtime_primitives::{BlockNumber as DomainNumber, Hash as DomainHash}; use frame_support::weights::Weight; use sp_consensus_subspace::{ - ChainConstants, EquivocationProof, FarmerPublicKey, PotParameters, SignedVote, SolutionRanges, + ChainConstants, EquivocationProof, PotParameters, SignedVote, SolutionRanges, }; use sp_core::crypto::KeyTypeId; use sp_core::{OpaqueMetadata, H256}; @@ -43,7 +43,7 @@ use std::collections::btree_map::BTreeMap; use std::collections::btree_set::BTreeSet; use subspace_core_primitives::objects::BlockObjectMapping; use subspace_core_primitives::{ - HistorySize, Randomness, SegmentCommitment, SegmentHeader, SegmentIndex, U256, + HistorySize, PublicKey, Randomness, SegmentCommitment, SegmentHeader, SegmentIndex, U256, }; use subspace_runtime_primitives::opaque::Block; use subspace_runtime_primitives::{AccountId, Balance, BlockNumber, Moment, Nonce}; @@ -130,7 +130,7 @@ sp_api::impl_runtime_apis! { } } - impl sp_consensus_subspace::SubspaceApi for Runtime { + impl sp_consensus_subspace::SubspaceApi for Runtime { fn pot_parameters() -> PotParameters { unreachable!() } @@ -146,12 +146,12 @@ sp_api::impl_runtime_apis! { } fn submit_vote_extrinsic( - _signed_vote: SignedVote, ::Hash, FarmerPublicKey>, + _signed_vote: SignedVote, ::Hash, PublicKey>, ) { unreachable!() } - fn is_in_block_list(_farmer_public_key: &FarmerPublicKey) -> bool { + fn is_in_block_list(_farmer_public_key: &PublicKey) -> bool { unreachable!() } @@ -175,7 +175,7 @@ sp_api::impl_runtime_apis! { unreachable!() } - fn root_plot_public_key() -> Option { + fn root_plot_public_key() -> Option { unreachable!() } diff --git a/crates/subspace-farmer-components/src/proving.rs b/crates/subspace-farmer-components/src/proving.rs index c630719423..e82fe29000 100644 --- a/crates/subspace-farmer-components/src/proving.rs +++ b/crates/subspace-farmer-components/src/proving.rs @@ -188,7 +188,7 @@ where } } -type MaybeSolution = Result, ProvingError>; +type MaybeSolution = Result, ProvingError>; struct SolutionsIterator<'a, RewardAddress, PosTable, TableGenerator, Sector> where diff --git a/crates/subspace-farmer/src/single_disk_farm/farming.rs b/crates/subspace-farmer/src/single_disk_farm/farming.rs index 1da957fe45..c22f6f646a 100644 --- a/crates/subspace-farmer/src/single_disk_farm/farming.rs +++ b/crates/subspace-farmer/src/single_disk_farm/farming.rs @@ -130,7 +130,7 @@ where ) -> Result< Vec<( SectorIndex, - impl ProvableSolutions, ProvingError>> + 'a, + impl ProvableSolutions, ProvingError>> + 'a, )>, AuditingError, > diff --git a/crates/subspace-farmer/src/utils/ss58.rs b/crates/subspace-farmer/src/utils/ss58.rs index 0d9b8a15b1..6d532ad988 100644 --- a/crates/subspace-farmer/src/utils/ss58.rs +++ b/crates/subspace-farmer/src/utils/ss58.rs @@ -22,7 +22,7 @@ use blake2::digest::typenum::U64; use blake2::digest::FixedOutput; use blake2::{Blake2b, Digest}; use ss58_registry::Ss58AddressFormat; -use subspace_core_primitives::{PublicKey, PUBLIC_KEY_LENGTH}; +use subspace_core_primitives::PublicKey; use thiserror::Error; const PREFIX: &[u8] = b"SS58PRE"; @@ -68,7 +68,7 @@ pub fn parse_ss58_reward_address(s: &str) -> Result } _ => return Err(Ss58ParsingError::InvalidPrefix), }; - if data.len() != prefix_len + PUBLIC_KEY_LENGTH + CHECKSUM_LEN { + if data.len() != prefix_len + PublicKey::SIZE + CHECKSUM_LEN { return Err(Ss58ParsingError::BadLength); } let format: Ss58AddressFormat = ident.into(); @@ -76,16 +76,15 @@ pub fn parse_ss58_reward_address(s: &str) -> Result return Err(Ss58ParsingError::FormatNotAllowed); } - let hash = ss58hash(&data[0..PUBLIC_KEY_LENGTH + prefix_len]); + let hash = ss58hash(&data[0..PublicKey::SIZE + prefix_len]); let checksum = &hash[0..CHECKSUM_LEN]; - if data[PUBLIC_KEY_LENGTH + prefix_len..PUBLIC_KEY_LENGTH + prefix_len + CHECKSUM_LEN] - != *checksum + if data[PublicKey::SIZE + prefix_len..PublicKey::SIZE + prefix_len + CHECKSUM_LEN] != *checksum { // Invalid checksum. return Err(Ss58ParsingError::InvalidChecksum); } - let bytes: [u8; PUBLIC_KEY_LENGTH] = data[prefix_len..][..PUBLIC_KEY_LENGTH] + let bytes: [u8; PublicKey::SIZE] = data[prefix_len..][..PublicKey::SIZE] .try_into() .map_err(|_| Ss58ParsingError::BadLength)?; diff --git a/crates/subspace-malicious-operator/src/malicious_bundle_producer.rs b/crates/subspace-malicious-operator/src/malicious_bundle_producer.rs index ff1ccddf4a..d75953cbb5 100644 --- a/crates/subspace-malicious-operator/src/malicious_bundle_producer.rs +++ b/crates/subspace-malicious-operator/src/malicious_bundle_producer.rs @@ -16,7 +16,6 @@ use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::Info; use sp_consensus_slots::Slot; -use sp_consensus_subspace::FarmerPublicKey; use sp_core::crypto::UncheckedFrom; use sp_domains::core_api::DomainCoreApi; use sp_domains::{ @@ -458,7 +457,7 @@ pub fn construct_signed_extrinsic( raw_payload .using_encoded(|e| { consensus_keystore - .sr25519_sign(FarmerPublicKey::ID, &public_key, e) + .sr25519_sign(OperatorPublicKey::ID, &public_key, e) })? .ok_or(format!( "Failed to sign extrinsic, sudo key pair missing from keystore?, public_key {:?}", diff --git a/crates/subspace-node/src/chain_spec.rs b/crates/subspace-node/src/chain_spec.rs index 5ab64d0107..e5e7acc378 100644 --- a/crates/subspace-node/src/chain_spec.rs +++ b/crates/subspace-node/src/chain_spec.rs @@ -24,13 +24,12 @@ use sc_chain_spec::GenericChainSpec; use sc_service::ChainType; use sc_subspace_chain_specs::DEVNET_CHAIN_SPEC; use sc_telemetry::TelemetryEndpoints; -use sp_consensus_subspace::FarmerPublicKey; -use sp_core::crypto::{Ss58Codec, UncheckedFrom}; +use sp_core::crypto::Ss58Codec; use sp_domains::PermissionedActionAllowedBy; use sp_runtime::{BoundedVec, Percent}; use std::marker::PhantomData; use std::num::NonZeroU32; -use subspace_core_primitives::PotKey; +use subspace_core_primitives::{PotKey, PublicKey}; use subspace_runtime::{ AllowAuthoringBy, BalancesConfig, CouncilConfig, DemocracyConfig, DomainsConfig, EnableRewardsAt, HistorySeedingConfig, MaxDomainBlockSize, MaxDomainBlockWeight, RewardPoint, @@ -95,11 +94,11 @@ pub fn gemini_3h_compiled() -> Result { balances, GenesisParams { enable_rewards_at: EnableRewardsAt::Manually, - allow_authoring_by: AllowAuthoringBy::RootFarmer( - FarmerPublicKey::unchecked_from(hex_literal::hex!( + allow_authoring_by: AllowAuthoringBy::RootFarmer(PublicKey::from( + hex_literal::hex!( "8aecbcf0b404590ddddc01ebacb205a562d12fdb5c2aa6a4035c1a20f23c9515" - )), - ), + ), + )), // TODO: Adjust once we bench PoT on faster hardware // About 1s on 6.0 GHz Raptor Lake CPU (14900K) pot_slot_iterations: NonZeroU32::new(200_032_000).expect("Not zero; qed"), diff --git a/crates/subspace-rpc-primitives/src/lib.rs b/crates/subspace-rpc-primitives/src/lib.rs index 96c648fe33..7408a5867a 100644 --- a/crates/subspace-rpc-primitives/src/lib.rs +++ b/crates/subspace-rpc-primitives/src/lib.rs @@ -130,9 +130,10 @@ pub struct SolutionResponse { /// Solution farmer has for the challenge. /// /// Corresponds to `slot_number` above. - pub solution: Solution, + pub solution: Solution, } +// TODO: Use better types here /// Reward info that needs to be signed. #[derive(Clone, Copy, Debug, Encode, Decode, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index 3f4cdf83c8..3d68bb1045 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -61,10 +61,9 @@ use scale_info::TypeInfo; use sp_api::impl_runtime_apis; use sp_consensus_slots::{Slot, SlotDuration}; use sp_consensus_subspace::{ - ChainConstants, EquivocationProof, FarmerPublicKey, PotParameters, SignedVote, SolutionRanges, - Vote, + ChainConstants, EquivocationProof, PotParameters, SignedVote, SolutionRanges, Vote, }; -use sp_core::crypto::{ByteArray, KeyTypeId}; +use sp_core::crypto::KeyTypeId; use sp_core::{ConstBool, OpaqueMetadata, H256}; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::{ @@ -100,8 +99,8 @@ use sp_version::RuntimeVersion; use static_assertions::const_assert; use subspace_core_primitives::objects::BlockObjectMapping; use subspace_core_primitives::{ - sectors_to_solution_range, solution_range_to_sectors, HistorySize, Piece, Randomness, - SegmentCommitment, SegmentHeader, SegmentIndex, SlotNumber, SolutionRange, U256, + sectors_to_solution_range, solution_range_to_sectors, HistorySize, Piece, PublicKey, + Randomness, SegmentCommitment, SegmentHeader, SegmentIndex, SlotNumber, SolutionRange, U256, }; use subspace_runtime_primitives::{ maximum_normal_block_length, AccountId, Balance, BlockNumber, FindBlockRewardAddress, Hash, @@ -1032,15 +1031,10 @@ fn is_xdm_mmr_proof_valid(ext: &::Extrinsic) -> Option { struct RewardAddress([u8; 32]); -impl From for RewardAddress { +impl From for RewardAddress { #[inline] - fn from(farmer_public_key: FarmerPublicKey) -> Self { - Self( - farmer_public_key - .as_slice() - .try_into() - .expect("Public key is always of correct size; qed"), - ) + fn from(public_key: PublicKey) -> Self { + Self(*public_key) } } @@ -1183,7 +1177,7 @@ impl_runtime_apis! { } } - impl sp_consensus_subspace::SubspaceApi for Runtime { + impl sp_consensus_subspace::SubspaceApi for Runtime { fn pot_parameters() -> PotParameters { Subspace::pot_parameters() } @@ -1199,7 +1193,7 @@ impl_runtime_apis! { } fn submit_vote_extrinsic( - signed_vote: SignedVote, ::Hash, FarmerPublicKey>, + signed_vote: SignedVote, ::Hash, PublicKey>, ) { let SignedVote { vote, signature } = signed_vote; let Vote::V0 { @@ -1224,7 +1218,7 @@ impl_runtime_apis! { }) } - fn is_in_block_list(farmer_public_key: &FarmerPublicKey) -> bool { + fn is_in_block_list(farmer_public_key: &PublicKey) -> bool { // TODO: Either check tx pool too for pending equivocations or replace equivocation // mechanism with an alternative one, so that blocking happens faster Subspace::is_in_block_list(farmer_public_key) @@ -1254,7 +1248,7 @@ impl_runtime_apis! { } } - fn root_plot_public_key() -> Option { + fn root_plot_public_key() -> Option { Subspace::root_plot_public_key() } diff --git a/crates/subspace-service/src/lib.rs b/crates/subspace-service/src/lib.rs index bff7d6777f..015a650eb9 100644 --- a/crates/subspace-service/src/lib.rs +++ b/crates/subspace-service/src/lib.rs @@ -95,7 +95,7 @@ use sp_blockchain::HeaderMetadata; use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::extract_pre_digest; use sp_consensus_subspace::{ - FarmerPublicKey, KzgExtension, PosExtension, PotExtension, PotNextSlotInput, SubspaceApi, + KzgExtension, PosExtension, PotExtension, PotNextSlotInput, SubspaceApi, }; use sp_core::offchain::storage::OffchainDb; use sp_core::offchain::OffchainDbExt; @@ -119,7 +119,7 @@ use std::num::NonZeroUsize; use std::sync::Arc; use std::time::Duration; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; -use subspace_core_primitives::{BlockNumber, PotSeed, Record, REWARD_SIGNING_CONTEXT}; +use subspace_core_primitives::{BlockNumber, PotSeed, PublicKey, Record, REWARD_SIGNING_CONTEXT}; use subspace_erasure_coding::ErasureCoding; use subspace_networking::libp2p::multiaddr::Protocol; use subspace_networking::utils::piece_provider::PieceProvider; @@ -262,7 +262,7 @@ where + Send + Sync + 'static, - Client::Api: SubspaceApi + Client::Api: SubspaceApi + DomainsApi + BundleProducerElectionApi + MmrApi> @@ -482,7 +482,7 @@ where + OffchainWorkerApi + SessionKeys + TaggedTransactionQueue - + SubspaceApi + + SubspaceApi + DomainsApi + FraudProofApi + BundleProducerElectionApi @@ -679,7 +679,7 @@ where Client::Api: TaggedTransactionQueue + DomainsApi + FraudProofApi - + SubspaceApi + + SubspaceApi + MmrApi> + MessengerApi, ::Hash>, { @@ -739,7 +739,7 @@ where + SessionKeys + TaggedTransactionQueue + TransactionPaymentApi - + SubspaceApi + + SubspaceApi + DomainsApi + FraudProofApi + ObjectsApi diff --git a/crates/subspace-service/src/rpc.rs b/crates/subspace-service/src/rpc.rs index 6393182266..cf2ae496ab 100644 --- a/crates/subspace-service/src/rpc.rs +++ b/crates/subspace-service/src/rpc.rs @@ -39,11 +39,11 @@ use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; use sp_consensus::SyncOracle; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; +use sp_consensus_subspace::SubspaceApi; use sp_objects::ObjectsApi; use std::sync::Arc; use subspace_core_primitives::crypto::kzg::Kzg; -use subspace_core_primitives::BlockNumber; +use subspace_core_primitives::{BlockNumber, PublicKey}; use subspace_erasure_coding::ErasureCoding; use subspace_networking::libp2p::Multiaddr; use subspace_runtime_primitives::opaque::Block; @@ -102,7 +102,7 @@ where C::Api: substrate_frame_rpc_system::AccountNonceApi + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + BlockBuilder - + SubspaceApi + + SubspaceApi + mmr_rpc::MmrRuntimeApi::Hash, BlockNumber> + ObjectsApi, P: TransactionPool + 'static, diff --git a/crates/subspace-service/src/sync_from_dsn.rs b/crates/subspace-service/src/sync_from_dsn.rs index f9dc91ad48..bfad207855 100644 --- a/crates/subspace-service/src/sync_from_dsn.rs +++ b/crates/subspace-service/src/sync_from_dsn.rs @@ -17,7 +17,7 @@ use sc_network::NetworkBlock; use sc_service::ClientExt; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; +use sp_consensus_subspace::SubspaceApi; use sp_runtime::traits::{Block as BlockT, CheckedSub, NumberFor}; use std::error::Error; use std::fmt; @@ -25,7 +25,7 @@ use std::future::Future; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant}; -use subspace_core_primitives::{Piece, PieceIndex, SegmentIndex}; +use subspace_core_primitives::{Piece, PieceIndex, PublicKey, SegmentIndex}; use subspace_erasure_coding::ErasureCoding; use subspace_networking::utils::piece_provider::{PieceProvider, PieceValidator}; use subspace_networking::Node; @@ -115,7 +115,7 @@ where + Send + Sync + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, PG: DsnSyncPieceGetter + Send + Sync + 'static, { let (tx, rx) = mpsc::channel(0); @@ -281,7 +281,7 @@ where + Send + Sync + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, PG: DsnSyncPieceGetter, { let info = client.info(); diff --git a/crates/subspace-service/src/sync_from_dsn/snap_sync.rs b/crates/subspace-service/src/sync_from_dsn/snap_sync.rs index 84d8efc023..23e903c2c4 100644 --- a/crates/subspace-service/src/sync_from_dsn/snap_sync.rs +++ b/crates/subspace-service/src/sync_from_dsn/snap_sync.rs @@ -15,7 +15,7 @@ use sc_service::{ClientExt, Error}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_consensus::BlockOrigin; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; +use sp_consensus_subspace::SubspaceApi; use sp_objects::ObjectsApi; use sp_runtime::traits::{Block as BlockT, Header, NumberFor}; use std::collections::{HashSet, VecDeque}; @@ -23,7 +23,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; use subspace_archiving::reconstructor::Reconstructor; -use subspace_core_primitives::{BlockNumber, SegmentIndex}; +use subspace_core_primitives::{BlockNumber, PublicKey, SegmentIndex}; use subspace_erasure_coding::ErasureCoding; use subspace_networking::Node; use tokio::time::sleep; @@ -55,7 +55,7 @@ pub(crate) async fn snap_sync( + 'static, // TODO: Remove when https://github.com/paritytech/polkadot-sdk/pull/5339 is in our fork for<'a> &'a Client: BlockImport, - Client::Api: SubspaceApi + ObjectsApi, + Client::Api: SubspaceApi + ObjectsApi, PG: DsnSyncPieceGetter, NR: NetworkRequest, { @@ -272,7 +272,7 @@ where + 'static, // TODO: Remove when https://github.com/paritytech/polkadot-sdk/pull/5339 is in our fork for<'a> &'a Client: BlockImport, - Client::Api: SubspaceApi + ObjectsApi, + Client::Api: SubspaceApi + ObjectsApi, IQS: ImportQueueService + ?Sized, NR: NetworkRequest, { diff --git a/crates/subspace-service/src/transaction_pool.rs b/crates/subspace-service/src/transaction_pool.rs index bef1643352..c014a4f3bf 100644 --- a/crates/subspace-service/src/transaction_pool.rs +++ b/crates/subspace-service/src/transaction_pool.rs @@ -14,7 +14,7 @@ use sc_transaction_pool_api::{ }; use sp_api::ProvideRuntimeApi; use sp_blockchain::{HeaderMetadata, TreeRoute}; -use sp_consensus_subspace::{FarmerPublicKey, SubspaceApi}; +use sp_consensus_subspace::SubspaceApi; use sp_core::traits::SpawnEssentialNamed; use sp_domains::DomainsApi; use sp_runtime::generic::BlockId; @@ -26,6 +26,7 @@ use std::collections::HashMap; use std::marker::PhantomData; use std::pin::Pin; use std::sync::Arc; +use subspace_core_primitives::PublicKey; use substrate_prometheus_endpoint::Registry as PrometheusRegistry; /// Block hash type for a pool. @@ -68,7 +69,7 @@ where + Send + Sync + 'static, - Client::Api: TaggedTransactionQueue + SubspaceApi, + Client::Api: TaggedTransactionQueue + SubspaceApi, DomainHeader: HeaderT, { fn new( @@ -114,7 +115,7 @@ where + 'static, DomainHeader: HeaderT, Client::Api: TaggedTransactionQueue - + SubspaceApi + + SubspaceApi + DomainsApi, { type Block = Block; @@ -232,7 +233,7 @@ where + Sync + 'static, Client::Api: TaggedTransactionQueue - + SubspaceApi + + SubspaceApi + DomainsApi, { type Block = Block; @@ -385,7 +386,7 @@ where + 'static, DomainHeader: HeaderT, Client::Api: TaggedTransactionQueue - + SubspaceApi + + SubspaceApi + DomainsApi, { let pool_api = Arc::new(FullChainApiWrapper::new( diff --git a/crates/subspace-verification/src/lib.rs b/crates/subspace-verification/src/lib.rs index bbca5a5b69..ca2596ce8a 100644 --- a/crates/subspace-verification/src/lib.rs +++ b/crates/subspace-verification/src/lib.rs @@ -178,15 +178,14 @@ pub fn calculate_block_weight(solution_range: SolutionRange) -> BlockWeight { /// Verify whether solution is valid, returns solution distance that is `<= solution_range/2` on /// success. -pub fn verify_solution<'a, PosTable, FarmerPublicKey, RewardAddress>( - solution: &'a Solution, +pub fn verify_solution<'a, PosTable, RewardAddress>( + solution: &'a Solution, slot: SlotNumber, params: &'a VerifySolutionParams, kzg: &'a Kzg, ) -> Result where PosTable: Table, - PublicKey: From<&'a FarmerPublicKey>, { let VerifySolutionParams { proof_of_time, @@ -194,10 +193,7 @@ where piece_check_params, } = params; - let sector_id = SectorId::new( - PublicKey::from(&solution.public_key).hash(), - solution.sector_index, - ); + let sector_id = SectorId::new(solution.public_key.hash(), solution.sector_index); let global_randomness = proof_of_time.derive_global_randomness(); let global_challenge = global_randomness.derive_global_challenge(slot); diff --git a/test/subspace-test-client/src/lib.rs b/test/subspace-test-client/src/lib.rs index 6cbd629603..1af0990923 100644 --- a/test/subspace-test-client/src/lib.rs +++ b/test/subspace-test-client/src/lib.rs @@ -29,7 +29,7 @@ use sc_consensus_subspace::archiver::encode_block; use sc_consensus_subspace::notification::SubspaceNotificationStream; use sc_consensus_subspace::slot_worker::{NewSlotNotification, RewardSigningNotification}; use sp_api::ProvideRuntimeApi; -use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SubspaceApi}; +use sp_consensus_subspace::SubspaceApi; use sp_core::{Decode, Encode}; use std::num::{NonZeroU64, NonZeroUsize}; use std::slice; @@ -37,7 +37,8 @@ use std::sync::Arc; use subspace_core_primitives::crypto::kzg::{embedded_kzg_settings, Kzg}; use subspace_core_primitives::objects::BlockObjectMapping; use subspace_core_primitives::{ - HistorySize, PosSeed, PublicKey, Record, SegmentIndex, Solution, REWARD_SIGNING_CONTEXT, + HistorySize, PosSeed, PublicKey, Record, RewardSignature, SegmentIndex, Solution, + REWARD_SIGNING_CONTEXT, }; use subspace_erasure_coding::ErasureCoding; use subspace_farmer_components::auditing::audit_sector_sync; @@ -94,16 +95,12 @@ where }) = reward_signing_notification_stream.next().await { let header_hash: [u8; 32] = header_hash.into(); - let signature: subspace_core_primitives::RewardSignature = signing_pair - .sign(substrate_ctx.bytes(&header_hash)) - .to_bytes() - .into(); - signature_sender - .unbounded_send( - FarmerSignature::decode(&mut signature.encode().as_ref()) - .expect("Failed to decode schnorrkel block signature"), - ) - .unwrap(); + let signature = RewardSignature::from( + signing_pair + .sign(substrate_ctx.bytes(&header_hash)) + .to_bytes(), + ); + signature_sender.unbounded_send(signature).unwrap(); } }); } @@ -120,7 +117,7 @@ async fn start_farming( + Send + Sync + 'static, - Client::Api: SubspaceApi, + Client::Api: SubspaceApi, { let (plotting_result_sender, plotting_result_receiver) = futures::channel::oneshot::channel(); @@ -191,10 +188,7 @@ async fn start_farming( .expect("With max solution range there must be a solution; qed") .unwrap(); // Lazy conversion to a different type of public key and reward address - let solution = Solution::::decode( - &mut solution.encode().as_slice(), - ) - .unwrap(); + let solution = Solution::decode(&mut solution.encode().as_slice()).unwrap(); let _ = solution_sender.try_send(solution); } } diff --git a/test/subspace-test-runtime/src/lib.rs b/test/subspace-test-runtime/src/lib.rs index 9958bb8180..5eeae8d479 100644 --- a/test/subspace-test-runtime/src/lib.rs +++ b/test/subspace-test-runtime/src/lib.rs @@ -50,10 +50,9 @@ use scale_info::TypeInfo; use sp_api::impl_runtime_apis; use sp_consensus_slots::{Slot, SlotDuration}; use sp_consensus_subspace::{ - ChainConstants, EquivocationProof, FarmerPublicKey, PotParameters, SignedVote, SolutionRanges, - Vote, + ChainConstants, EquivocationProof, PotParameters, SignedVote, SolutionRanges, Vote, }; -use sp_core::crypto::{ByteArray, KeyTypeId}; +use sp_core::crypto::KeyTypeId; use sp_core::{OpaqueMetadata, H256}; use sp_domains::bundle_producer_election::BundleProducerElectionParams; use sp_domains::{ @@ -92,8 +91,8 @@ use sp_version::RuntimeVersion; use static_assertions::const_assert; use subspace_core_primitives::objects::{BlockObject, BlockObjectMapping}; use subspace_core_primitives::{ - crypto, HistorySize, Piece, Randomness, SegmentCommitment, SegmentHeader, SegmentIndex, - SlotNumber, SolutionRange, U256, + crypto, HistorySize, Piece, PublicKey, Randomness, SegmentCommitment, SegmentHeader, + SegmentIndex, SlotNumber, SolutionRange, U256, }; use subspace_runtime_primitives::{ AccountId, Balance, BlockNumber, FindBlockRewardAddress, Hash, Moment, Nonce, Signature, @@ -1091,15 +1090,10 @@ fn extract_bundle( struct RewardAddress([u8; 32]); -impl From for RewardAddress { +impl From for RewardAddress { #[inline] - fn from(farmer_public_key: FarmerPublicKey) -> Self { - Self( - farmer_public_key - .as_slice() - .try_into() - .expect("Public key is always of correct size; qed"), - ) + fn from(public_key: PublicKey) -> Self { + Self(*public_key) } } @@ -1218,7 +1212,7 @@ impl_runtime_apis! { } } - impl sp_consensus_subspace::SubspaceApi for Runtime { + impl sp_consensus_subspace::SubspaceApi for Runtime { fn pot_parameters() -> PotParameters { Subspace::pot_parameters() } @@ -1234,7 +1228,7 @@ impl_runtime_apis! { } fn submit_vote_extrinsic( - signed_vote: SignedVote, ::Hash, FarmerPublicKey>, + signed_vote: SignedVote, ::Hash, PublicKey>, ) { let SignedVote { vote, signature } = signed_vote; let Vote::V0 { @@ -1259,7 +1253,7 @@ impl_runtime_apis! { }) } - fn is_in_block_list(farmer_public_key: &FarmerPublicKey) -> bool { + fn is_in_block_list(farmer_public_key: &PublicKey) -> bool { // TODO: Either check tx pool too for pending equivocations or replace equivocation // mechanism with an alternative one, so that blocking happens faster Subspace::is_in_block_list(farmer_public_key) @@ -1289,7 +1283,7 @@ impl_runtime_apis! { } } - fn root_plot_public_key() -> Option { + fn root_plot_public_key() -> Option { Subspace::root_plot_public_key() } diff --git a/test/subspace-test-service/Cargo.toml b/test/subspace-test-service/Cargo.toml index 0207a937bc..a7d8e47d4e 100644 --- a/test/subspace-test-service/Cargo.toml +++ b/test/subspace-test-service/Cargo.toml @@ -41,7 +41,6 @@ sc-transaction-pool = { git = "https://github.com/subspace/polkadot-sdk", rev = sc-transaction-pool-api = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sc-utils = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-api = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } -sp-application-crypto = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-blockchain = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-core = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } sp-consensus = { git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" } diff --git a/test/subspace-test-service/src/lib.rs b/test/subspace-test-service/src/lib.rs index d1acdb1a22..c1d86baace 100644 --- a/test/subspace-test-service/src/lib.rs +++ b/test/subspace-test-service/src/lib.rs @@ -51,14 +51,13 @@ use sc_transaction_pool::error::Error as PoolError; use sc_transaction_pool_api::{InPoolTransaction, TransactionPool, TransactionSource}; use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use sp_api::{ApiExt, ProvideRuntimeApi}; -use sp_application_crypto::UncheckedFrom; use sp_blockchain::HeaderBackend; use sp_consensus::{BlockOrigin, Error as ConsensusError}; use sp_consensus_slots::Slot; use sp_consensus_subspace::digests::{ extract_pre_digest, CompatibleDigestItem, PreDigest, PreDigestPotInfo, }; -use sp_consensus_subspace::{FarmerPublicKey, PotExtension, SubspaceApi}; +use sp_consensus_subspace::{PotExtension, SubspaceApi}; use sp_core::offchain::storage::OffchainDb; use sp_core::offchain::OffchainDbExt; use sp_core::traits::{CodeExecutor, SpawnEssentialNamed}; @@ -85,7 +84,7 @@ use std::marker::PhantomData; use std::pin::Pin; use std::sync::Arc; use std::time; -use subspace_core_primitives::{BlockNumber, PotOutput, Solution}; +use subspace_core_primitives::{BlockNumber, PotOutput, PublicKey, Solution}; use subspace_runtime_primitives::opaque::Block; use subspace_runtime_primitives::{AccountId, Balance, Hash, Signature}; use subspace_service::transaction_pool::FullPool; @@ -369,7 +368,7 @@ pub struct MockConsensusNode { block_import: MockBlockImport, xdm_gossip_worker_builder: Option, /// Mock subspace solution used to mock the subspace `PreDigest` - mock_solution: Solution, + mock_solution: Solution, log_prefix: &'static str, /// Ferdie key pub key: Sr25519Keyring, @@ -490,10 +489,8 @@ impl MockConsensusNode { }) .expect("Should be able to spawn tasks"); - let mock_solution = Solution::genesis_solution( - FarmerPublicKey::unchecked_from(key.public().0), - key.to_account_id(), - ); + let mock_solution = + Solution::genesis_solution(PublicKey::from(key.public().0), key.to_account_id()); let mut gossip_builder = GossipWorkerBuilder::new(); @@ -883,7 +880,7 @@ impl MockConsensusNode { } fn mock_subspace_digest(&self, slot: Slot) -> Digest { - let pre_digest: PreDigest = PreDigest::V0 { + let pre_digest: PreDigest = PreDigest::V0 { slot, solution: self.mock_solution.clone(), pot_info: PreDigestPotInfo::V0 {