Skip to content

Commit

Permalink
feat: Add deal activation after prove commit
Browse files Browse the repository at this point in the history
Implement deal activation by coupling the SP and Market pallet. Tests
have been added to check if prove commit functionality works.
  • Loading branch information
aidan46 committed Jul 8, 2024
1 parent 7fb69b3 commit c7eebb8
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 125 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion pallets/market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ pub mod pallet {
// We don't want to store another BTreeSet of DealProposals
// We only care about hashes.
// It is not an associated function, because T::Hashing is hard to use inside of there.
pub(crate) fn hash_proposal(
pub fn hash_proposal(
proposal: &DealProposal<T::AccountId, BalanceOf<T>, BlockNumberFor<T>>,
) -> T::Hash {
let bytes = Encode::encode(proposal);
Expand Down
1 change: 1 addition & 0 deletions pallets/storage-provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ frame-system = { workspace = true, default-features = false }
[dev-dependencies]
multihash-codetable = { workspace = true, features = ["blake2b"] }
pallet-balances = { workspace = true, default-features = false }
pallet-market = { workspace = true, default-features = false }
sp-io = { workspace = true }
sp-runtime = { workspace = true, default-features = false }

Expand Down
33 changes: 23 additions & 10 deletions pallets/storage-provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,17 @@ pub mod pallet {
pallet_prelude::*,
traits::{Currency, ReservableCurrency},
};
use frame_system::{
ensure_signed,
pallet_prelude::{BlockNumberFor, *},
Config as SystemConfig,
};
use frame_system::{ensure_signed, pallet_prelude::*, Config as SystemConfig};
use primitives_proofs::{Market, RegisteredPoStProof, RegisteredSealProof, SectorNumber};
use scale_info::TypeInfo;

use crate::{
proofs::{
assign_proving_period_offset, current_deadline_index, current_proving_period_start,
RegisteredPoStProof, RegisteredSealProof,
},
sector::{
ProveCommitSector, SectorNumber, SectorOnChainInfo, SectorPreCommitInfo,
SectorPreCommitOnChainInfo, SECTORS_MAX,
ProveCommitSector, SectorOnChainInfo, SectorPreCommitInfo, SectorPreCommitOnChainInfo,
SECTORS_MAX,
},
storage_provider::{StorageProviderInfo, StorageProviderState},
};
Expand All @@ -81,6 +77,8 @@ pub mod pallet {
type PeerId: Clone + Debug + Decode + Encode + Eq + TypeInfo;
/// Currency mechanism, used for collateral
type Currency: ReservableCurrency<Self::AccountId>;
/// Market trait implementation for activating deals
type Market: Market<Self::AccountId, BlockNumberFor<Self>>;
/// Proving period for submitting Window PoSt, 24 hours is blocks
#[pallet::constant]
type WPoStProvingPeriod: Get<BlockNumberFor<Self>>;
Expand Down Expand Up @@ -165,6 +163,8 @@ pub mod pallet {
MaxSectorLifetimeExceeded,
/// Emitted when a CID is invalid
InvalidCid,
/// Emitted when a sector fails to activate
CouldNotActivateSector,
}

#[pallet::call]
Expand Down Expand Up @@ -215,7 +215,10 @@ pub mod pallet {
.map_err(|_| Error::<T>::StorageProviderNotFound)?;
let sector_number = sector.sector_number;
let current_block = <frame_system::Pallet<T>>::block_number();
ensure!(sector_number <= SECTORS_MAX, Error::<T>::InvalidSector);
ensure!(
sector_number <= SECTORS_MAX.into(),
Error::<T>::InvalidSector
);
ensure!(
sp.info.window_post_proof_type == sector.seal_proof.registered_window_post_proof(),
Error::<T>::InvalidProofType
Expand Down Expand Up @@ -262,7 +265,7 @@ pub mod pallet {
let sp = StorageProviders::<T>::try_get(&owner)
.map_err(|_| Error::<T>::StorageProviderNotFound)?;
let sector_num = sector.sector_number;
ensure!(sector_num <= SECTORS_MAX, Error::<T>::InvalidSector);
ensure!(sector_num <= SECTORS_MAX.into(), Error::<T>::InvalidSector);
let precommit = sp
.get_precommitted_sector(sector_num)
.map_err(|_| Error::<T>::InvalidSector)?;
Expand All @@ -271,6 +274,7 @@ pub mod pallet {
precommit.pre_commit_block_number + T::MaxProveCommitDuration::get();
if current_block > prove_commit_due {
// TODO(@aidan46, no-ref, 2024-06-25): Flag this sector for late submission fee.
// I am not sure what to do here yet
log::warn!("Prove commit sent after the deadline");
}
ensure!(
Expand All @@ -290,6 +294,15 @@ pub mod pallet {
.map_err(|_| Error::<T>::CouldNotRemoveSector)?;
Ok(().into())
})?;
let mut sector_deals = BoundedVec::new();
sector_deals
.try_push(precommit.into())
.map_err(|_| Error::<T>::CouldNotActivateSector)?;
if sector_deals.len() > 0 {
T::Market::activate_deals(&owner, sector_deals, true)?;
} else {
T::Market::activate_deals(&owner, sector_deals, false)?;
}
Self::deposit_event(Event::SectorProven {
owner,
sector_number: sector_num,
Expand Down
59 changes: 54 additions & 5 deletions pallets/storage-provider/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use cid::Cid;
use frame_support::{
derive_impl, pallet_prelude::ConstU32, parameter_types, sp_runtime::BoundedVec,
derive_impl, pallet_prelude::ConstU32, parameter_types, sp_runtime::BoundedVec, PalletId,
};
use frame_system::pallet_prelude::BlockNumberFor;
use multihash_codetable::{Code, MultihashDigest};
use sp_runtime::BuildStorage;
use pallet_market::{BalanceOf, DealProposal};
use sp_core::Pair;
use sp_runtime::{
traits::{ConstU64, IdentifyAccount, IdentityLookup, Verify},
BuildStorage, MultiSignature, MultiSigner,
};

use crate::{self as pallet_storage_provider, pallet::CID_CODEC};

Expand All @@ -23,20 +29,44 @@ frame_support::construct_runtime!(
System: frame_system,
Balances: pallet_balances,
StorageProvider: pallet_storage_provider::pallet,
Market: pallet_market,
}
);

pub type Signature = MultiSignature;
pub type AccountPublic = <Signature as Verify>::Signer;
pub type AccountId = <AccountPublic as IdentifyAccount>::AccountId;

#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Test {
type Block = Block;
type AccountData = pallet_balances::AccountData<u64>;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
}

#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
impl pallet_balances::Config for Test {
type AccountStore = System;
}

parameter_types! {
pub const MarketPalletId: PalletId = PalletId(*b"spMarket");
}

impl pallet_market::Config for Test {
type RuntimeEvent = RuntimeEvent;
type PalletId = MarketPalletId;
type Currency = Balances;
type OffchainSignature = Signature;
type OffchainPublic = AccountPublic;
type MaxDeals = ConstU32<32>;
type BlocksPerDay = ConstU64<1>;
type MinDealDuration = ConstU64<1>;
type MaxDealDuration = ConstU64<30>;
type MaxDealsPerBlock = ConstU32<32>;
}

parameter_types! {
pub const WpostProvingPeriod: BlockNumber = DAYS;
// Half an hour (=48 per day)
Expand All @@ -53,6 +83,7 @@ impl pallet_storage_provider::Config for Test {
type RuntimeEvent = RuntimeEvent;
type PeerId = BoundedVec<u8, ConstU32<256>>; // Arbitrary length
type Currency = Balances;
type Market = Market;
type WPoStProvingPeriod = WpostProvingPeriod;
type WPoStChallengeWindow = WpostChallengeWindow;
type MinSectorExpiration = MinSectorExpiration;
Expand All @@ -61,8 +92,20 @@ impl pallet_storage_provider::Config for Test {
type MaxProveCommitDuration = MaxProveCommitDuration;
}

pub const ALICE: u64 = 0;
pub const BOB: u64 = 1;
pub type AccountIdOf<Test> = <Test as frame_system::Config>::AccountId;

pub fn key_pair(name: &str) -> sp_core::sr25519::Pair {
sp_core::sr25519::Pair::from_string(name, None).unwrap()
}

pub fn account(name: &str) -> AccountIdOf<Test> {
let user_pair = key_pair(name);
let signer = MultiSigner::Sr25519(user_pair.public());
signer.into_account()
}

pub const ALICE: &'static str = "//Alice";
pub const BOB: &'static str = "//Bob";
pub const INITIAL_FUNDS: u64 = 100;

// Build genesis storage according to the mock runtime.
Expand All @@ -72,7 +115,10 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
.unwrap()
.into();
pallet_balances::GenesisConfig::<Test> {
balances: vec![(ALICE, INITIAL_FUNDS), (BOB, INITIAL_FUNDS)],
balances: vec![
(account(ALICE), INITIAL_FUNDS),
(account(BOB), INITIAL_FUNDS),
],
}
.assimilate_storage(&mut t)
.unwrap();
Expand All @@ -93,3 +139,6 @@ pub fn events() -> Vec<RuntimeEvent> {
pub fn cid_of(data: &str) -> cid::Cid {
Cid::new_v1(CID_CODEC, Code::Blake2b256.digest(data.as_bytes()))
}

pub(crate) type DealProposalOf<T> =
DealProposal<<T as frame_system::Config>::AccountId, BalanceOf<T>, BlockNumberFor<T>>;
46 changes: 1 addition & 45 deletions pallets/storage-provider/src/proofs.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,17 @@
use codec::{Decode, Encode};
use frame_support::{pallet_prelude::ConstU32, sp_runtime::BoundedVec};
use primitives_proofs::RegisteredPoStProof;
use scale_info::TypeInfo;
use sp_arithmetic::traits::BaseArithmetic;
use sp_core::blake2_64;

use crate::sector::SectorSize;

/// Proof of Spacetime type, indicating version and sector size of the proof.
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone, Copy)]
pub enum RegisteredPoStProof {
StackedDRGWindow2KiBV1P1,
}

impl RegisteredPoStProof {
/// Returns the sector size of the proof type, which is measured in bytes.
pub(crate) fn sector_size(self) -> SectorSize {
match self {
RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => SectorSize::_2KiB,
}
}

/// Returns the partition size, in sectors, associated with a proof type.
/// The partition size is the number of sectors proven in a single PoSt proof.
pub(crate) fn window_post_partitions_sector(self) -> u64 {
// Resolve to post proof and then compute size from that.
match self {
RegisteredPoStProof::StackedDRGWindow2KiBV1P1 => 2,
}
}
}

/// Proof of Spacetime data stored on chain.
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct PoStProof {
pub post_proof: RegisteredPoStProof,
pub proof_bytes: BoundedVec<u8, ConstU32<256>>, // Arbitrary length
}

/// Seal proof type which defines the version and sector size.
#[allow(non_camel_case_types)]
#[derive(Debug, Decode, Encode, TypeInfo, Eq, PartialEq, Clone)]
pub enum RegisteredSealProof {
StackedDRG2KiBV1P1,
}

impl RegisteredSealProof {
/// Produces the windowed PoSt-specific RegisteredProof corresponding
/// to the receiving RegisteredProof.
pub(crate) fn registered_window_post_proof(&self) -> RegisteredPoStProof {
match self {
RegisteredSealProof::StackedDRG2KiBV1P1 => {
RegisteredPoStProof::StackedDRGWindow2KiBV1P1
}
}
}
}

#[derive(Debug)]
pub enum ProofError {
Conversion,
Expand Down
31 changes: 18 additions & 13 deletions pallets/storage-provider/src/sector.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
use codec::{Decode, Encode};
use primitives_proofs::{DealId, SectorId};
use frame_support::{pallet_prelude::*, BoundedVec};
use primitives_proofs::{
DealId, RegisteredSealProof, SectorDeal, SectorId, SectorNumber, MAX_DEALS_PER_SECTOR,
};
use scale_info::TypeInfo;

use crate::proofs::RegisteredSealProof;

// https://github.com/filecoin-project/builtin-actors/blob/17ede2b256bc819dc309edf38e031e246a516486/runtime/src/runtime/policy.rs#L262
pub const SECTORS_MAX: u32 = 32 << 20;

/// SectorNumber is a numeric identifier for a sector.
pub type SectorNumber = u32;

/// SectorSize indicates one of a set of possible sizes in the network.
#[derive(Encode, Decode, TypeInfo, Clone, Debug, PartialEq, Eq, Copy)]
pub enum SectorSize {
_2KiB,
}

/// This type is passed into the pre commit function on the storage provider pallet
#[derive(Clone, Debug, Decode, Encode, PartialEq, TypeInfo)]
pub struct SectorPreCommitInfo<BlockNumber> {
Expand All @@ -26,7 +18,7 @@ pub struct SectorPreCommitInfo<BlockNumber> {
/// Using sealed_cid as I think that is more descriptive.
/// Some docs on commR here: <https://proto.school/verifying-storage-on-filecoin/03>
pub sealed_cid: SectorId,
pub deal_id: DealId,
pub deal_ids: BoundedVec<DealId, ConstU32<MAX_DEALS_PER_SECTOR>>,
/// Expiration of the pre-committed sector.
pub expiration: BlockNumber,
/// CommD
Expand Down Expand Up @@ -57,6 +49,19 @@ impl<Balance, BlockNumber> SectorPreCommitOnChainInfo<Balance, BlockNumber> {
}
}

impl<Balance, BlockNumber: Clone> From<&SectorPreCommitOnChainInfo<Balance, BlockNumber>>
for SectorDeal<BlockNumber>
{
fn from(precommit: &SectorPreCommitOnChainInfo<Balance, BlockNumber>) -> Self {
Self {
sector_number: precommit.info.sector_number,
sector_expiry: precommit.info.expiration.clone(),
sector_type: precommit.info.seal_proof.clone(),
deal_ids: precommit.info.deal_ids.clone(),
}
}
}

#[derive(Debug, Decode, Encode, TypeInfo)]
pub struct SectorOnChainInfo<BlockNumber> {
pub sector_number: SectorNumber,
Expand Down
12 changes: 4 additions & 8 deletions pallets/storage-provider/src/storage_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ use frame_support::{
pallet_prelude::{ConstU32, RuntimeDebug},
sp_runtime::BoundedBTreeMap,
};
use primitives_proofs::{RegisteredPoStProof, SectorNumber, SectorSize};
use scale_info::TypeInfo;
use sp_arithmetic::{traits::BaseArithmetic, ArithmeticError};

use crate::{
proofs::RegisteredPoStProof,
sector::{
SectorNumber, SectorOnChainInfo, SectorPreCommitOnChainInfo, SectorSize, SECTORS_MAX,
},
};
use crate::sector::{SectorOnChainInfo, SectorPreCommitOnChainInfo, SECTORS_MAX};

/// This struct holds the state of a single storage provider.
#[derive(Debug, Decode, Encode, TypeInfo)]
Expand All @@ -20,14 +16,14 @@ pub struct StorageProviderState<PeerId, Balance, BlockNumber> {
pub info: StorageProviderInfo<PeerId>,
/// Information for all proven and not-yet-garbage-collected sectors.
pub sectors:
BoundedBTreeMap<SectorNumber, SectorOnChainInfo<BlockNumber>, ConstU32<SECTORS_MAX>>,
BoundedBTreeMap<SectorNumber, SectorOnChainInfo<BlockNumber>, ConstU32<SECTORS_MAX>>, // Cannot use ConstU64 here because of BoundedBTreeMap trait bound `Get<u32>`
/// Total funds locked as pre_commit_deposit
pub pre_commit_deposits: Balance,
/// Sectors that have been pre-committed but not yet proven.
pub pre_committed_sectors: BoundedBTreeMap<
SectorNumber,
SectorPreCommitOnChainInfo<Balance, BlockNumber>,
ConstU32<SECTORS_MAX>,
ConstU32<SECTORS_MAX>, // Cannot use ConstU64 here because of BoundedBTreeMap trait bound `Get<u32>`
>,
/// The first block in this storage provider's current proving period. This is the first block in which a PoSt for a
/// partition at the storage provider's first deadline may arrive. Alternatively, it is after the last block at which
Expand Down
Loading

0 comments on commit c7eebb8

Please sign in to comment.