Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ipfs node info #116

Merged
merged 18 commits into from
Aug 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bin/node/pallets/pallet-ipfs/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use std::sync::Arc;
#[derive(Default, Debug, Serialize, Deserialize)]
pub struct GetStorageResponse {
pub available_storage: u64,
pub maximum_storage: u64,
pub files: usize,
pub total_files: usize,
}

#[rpc]
Expand Down Expand Up @@ -68,8 +68,8 @@ where
// TODO: this should change the IPFS partition path.
Ok(mount) => {
resp.available_storage = mount.avail.as_u64();
resp.maximum_storage = mount.total.as_u64();
resp.files = mount.files;
resp.total_files = mount.files_total;
},
Err(e) => {
log::error!("{:?}", e);
Expand Down
49 changes: 38 additions & 11 deletions bin/node/pallets/pallet-ipfs/src/functions.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
use super::*;

use frame_system::pallet_prelude::BlockNumberFor;
use sp_runtime::{
offchain::{http, ipfs, IpfsRequest, IpfsResponse},
SaturatedConversion,
};
use sp_std::str;

use serde::{Deserialize, Serialize};
use sp_runtime::offchain::{http, ipfs, IpfsRequest, IpfsResponse};
use sp_std::str;

#[derive(Default, Debug, Serialize, Deserialize)]
pub struct GetStorageResponseRPC {
pub available_storage: u64,
pub maximum_storage: u64,
pub files: usize,
pub total_files: usize,
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -480,20 +476,25 @@ impl<T: Config> Pallet<T> {
}

let avail_storage = Self::get_validator_storage().unwrap().result.available_storage;
let max_storage = Self::get_validator_storage().unwrap().result.maximum_storage;
let files = Self::get_validator_storage().unwrap().result.files;
let files_total = Self::get_validator_storage().unwrap().result.total_files;

let results = signer.send_signed_transaction(|_account| Call::submit_ipfs_identity {
public_key: public_key.clone(),
multiaddress: addrs.clone(),
storage_size: avail_storage.clone(),
available_storage: avail_storage.clone(),
max_storage,
files: files as u64,
files_total: files_total as u64,
});

for (_, res) in &results {
match res {
Ok(()) => log::info!("Submitted ipfs identity results"),
Ok(()) => {
log::info!("Submitted ipfs identity results");
// log::info!("\n\navailable storage: {:?}", avail_storage);
// log::info!("\nmax storage: {:?}", max_storage);
// log::info!("\nfiles: {:?}", files);
},
Err(e) => log::error!("Failed to submit tx: {:?}", e),
}
}
Expand Down Expand Up @@ -586,4 +587,30 @@ impl<T: Config> Pallet<T> {

Ok(resp)
}

pub fn emit_ipfs_stats() -> Result<(), Error<T>> {
let deadline = Some(timestamp().add(Duration::from_millis(5_0000)));

Self::ipfs_request(IpfsRequest::Identity, deadline)?;
// emit event
let signer = Signer::<T, T::AuthorityId>::all_accounts();
if !signer.can_sign() {
log::error!("No local accounts available. Consider adding one via `author_insertKey` RPC method.");
}

let results = signer.send_signed_transaction(|_account| {
Call::submit_ipfs_emit_stats_result { nodes: IPFSNodes::<T>::iter_values().collect() }
});

for (_, res) in &results {
match res {
Ok(()) => {
log::info!("Emitted ipfs node stats");
},
Err(e) => log::error!("Failed to submit transaction: {:?}", e),
}
}

Ok(())
}
}
59 changes: 50 additions & 9 deletions bin/node/pallets/pallet-ipfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ pub mod pallet {
#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct IpfsNode {
pub multiaddress: Vec<OpaqueMultiaddr>,
pub public_key: Vec<u8>,
pub multiaddress: Vec<OpaqueMultiaddr>,
pub avail_storage: u64,
pub max_storage: u64,
pub files: u64,
pub files_total: u64,
}

#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)]
Expand Down Expand Up @@ -154,6 +154,9 @@ pub mod pallet {
#[pallet::constant]
type DefaultAssetLifetime: Get<Self::BlockNumber>;

#[pallet::constant]
type UpdateDuration: Get<u64>;

type Call: From<Call<Self>>;

type AuthorityId: AppCrypto<Self::Public, Self::Signature>;
Expand Down Expand Up @@ -196,6 +199,7 @@ pub mod pallet {
RequestFailed,
FeeOutOfBounds,
HttpFetchingError,
IpfsNodeNotExist,
}

#[pallet::event]
Expand All @@ -218,6 +222,8 @@ pub mod pallet {
DeleteIpfsAsset(T::AccountId, Vec<u8>),
UnpinIpfsAsset(T::AccountId, Vec<u8>),
ExtendIpfsStorageDuration(T::AccountId, Vec<u8>),
ExportIpfsStats(Vec<IpfsNode>),
SessionResults(T::AccountId, Vec<u8>, BalanceOf<T>),
}

// Storage items.
Expand Down Expand Up @@ -272,6 +278,15 @@ pub mod pallet {
}
}

if block_no % T::UpdateDuration::get().try_into().ok().unwrap() == 0u32.into() {
if let Err(e) = Self::emit_ipfs_stats() {
log::error!(
"IPFS: Encountered an error while publishing IPFS Node stats {:?}",
e
);
}
}

if let Err(e) = Self::ipfs_garbage_collector(block_no) {
log::error!("IPFS::GARBAGE_COLLECTOR::ERROR: {:?}", e);
}
Expand Down Expand Up @@ -465,22 +480,23 @@ pub mod pallet {
origin: OriginFor<T>,
public_key: Vec<u8>,
multiaddress: Vec<OpaqueMultiaddr>,
storage_size: u64,
available_storage: u64,
max_storage: u64,
files: u64,
files_total: u64,
) -> DispatchResult {
let signer = ensure_signed(origin)?;

let ipfs_node: IpfsNode = IpfsNode {
multiaddress,
public_key: public_key.clone(),
avail_storage: storage_size,
multiaddress,
avail_storage: available_storage,
max_storage,
files,
files_total,
};
<IPFSNodes<T>>::insert(public_key.clone(), ipfs_node.clone());

Self::deposit_event(Event::PublishedIdentity(signer.clone()));
<IPFSNodes<T>>::insert(public_key, ipfs_node);

Self::deposit_event(Event::PublishedIdentity(signer));

Ok(())
}
Expand Down Expand Up @@ -581,6 +597,31 @@ pub mod pallet {
Ok(())
}

#[pallet::weight(0)]
pub fn submit_ipfs_emit_stats_result(
origin: OriginFor<T>,
nodes: Vec<IpfsNode>,
) -> DispatchResult {
ensure_signed(origin)?;

Self::deposit_event(Event::ExportIpfsStats(nodes));

Ok(())
}

#[pallet::weight(0)]
pub fn submit_session_results(
origin: OriginFor<T>,
peer_id: Vec<u8>,
payment: BalanceOf<T>,
) -> DispatchResult {
let signer = ensure_signed(origin)?;

Self::deposit_event(Event::SessionResults(signer, peer_id, payment));

Ok(())
}

/// Give ownership of an asset to user.
#[pallet::weight(0)]
pub fn add_owner(
Expand Down
2 changes: 2 additions & 0 deletions bin/node/pallets/pallet-ipfs/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ parameter_types! {
pub const MetadataDepositBase: u64 = 1;
pub const MetadataDepositPerByte: u64 = 1;
pub const MaxIpfsOwned: u32 = 5;
pub const EpochDuration: u64 = 6;
pub const DefaultAssetLifetime: u32 = 60;
}

Expand Down Expand Up @@ -135,6 +136,7 @@ impl Config for Test {
type Event = Event;
type AuthorityId = pallet_cherry::crypto::AuthorityId;
type MaxIpfsOwned = MaxIpfsOwned;
type UpdateDuration = EpochDuration;
type DefaultAssetLifetime = DefaultAssetLifetime;
type WeightInfo = pallet_cherry::weights::SubstrateWeight<Test>;
}
Expand Down
4 changes: 4 additions & 0 deletions bin/node/runtime/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ pub mod time_dev {
// Attempting to do so will brick block production.
pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 2 * MINUTES;
pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = EPOCH_DURATION_IN_BLOCKS;

pub const UPDATE_DURATION: BlockNumber = EPOCH_DURATION_IN_SLOTS * 3;

pub const SESSIONS_PER_ERA: sp_staking::SessionIndex = 3;
pub const BONDING_DURATION: pallet_staking::EraIndex = 24 * 8;
pub const SLASH_DEFER_DURATION: pallet_staking::EraIndex = 24 * 2;
Expand Down Expand Up @@ -137,6 +140,7 @@ pub mod time_prod {
pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES;
pub const EPOCH_DURATION_IN_SLOTS: BlockNumber = EPOCH_DURATION_IN_BLOCKS;

pub const UPDATE_DURATION: BlockNumber = EPOCH_DURATION_IN_SLOTS * 6;
// NOTE: Currently it is not possible to change the epoch duration after the chain has started.
// Attempting to do so will brick block production.
pub const SESSIONS_PER_ERA: sp_staking::SessionIndex = 6;
Expand Down
2 changes: 2 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,7 @@ impl pallet_transaction_storage::Config for Runtime {
}

parameter_types! {
pub const UpdateDuration: u64 = UPDATE_DURATION as u64;
pub const MaxIpfsOwned: u32 = 5;
pub const DefaultAssetLifetime: BlockNumber = DEFAULT_ASSET_LIFETIME;
}
Expand All @@ -925,6 +926,7 @@ impl pallet_ipfs::Config for Runtime {
type Currency = Balances;
type AuthorityId = pallet_ipfs::crypto::AuthorityId;
type Call = Call;
type UpdateDuration = UpdateDuration;
type MaxIpfsOwned = MaxIpfsOwned;
type DefaultAssetLifetime = DefaultAssetLifetime;
type WeightInfo = pallet_ipfs::weights::SubstrateWeight<Runtime>;
Expand Down