Skip to content

Commit

Permalink
define a custom SignedExtension for bill_contract_for_block
Browse files Browse the repository at this point in the history
  • Loading branch information
sameh-farouk committed Aug 13, 2024
1 parent 14cd8ed commit 3dcc930
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 25 deletions.
4 changes: 3 additions & 1 deletion substrate-node/node/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use sp_core::{Encode, Pair};
use sp_inherents::{InherentData, InherentDataProvider};
use sp_keyring::Sr25519Keyring;
use sp_runtime::{OpaqueExtrinsic, SaturatedConversion};
use tfchain_runtime as runtime;
use tfchain_runtime::{self as runtime, pallet_smart_contract};

use std::{sync::Arc, time::Duration};

Expand Down Expand Up @@ -132,6 +132,7 @@ pub fn create_benchmark_extrinsic(
frame_system::CheckNonce::<runtime::Runtime>::from(nonce),
frame_system::CheckWeight::<runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
pallet_smart_contract::types::ContractIdProvides::<runtime::Runtime>::new(),
);

let raw_payload = runtime::SignedPayload::from_raw(
Expand All @@ -146,6 +147,7 @@ pub fn create_benchmark_extrinsic(
(),
(),
(),
(),
),
);
let signature = raw_payload.using_encoded(|e| sender.sign(e));
Expand Down
9 changes: 0 additions & 9 deletions substrate-node/pallets/pallet-smart-contract/src/billing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,6 @@ impl<T: Config> Pallet<T> {
pub fn bill_contract(contract_id: u64) -> DispatchResultWithPostInfo {
log::debug!("Starting billing for contract_id: {:?}", contract_id);

// Check if contract is already processed in this block
let mut seen_contracts = SeenContracts::<T>::get();
ensure!(
!seen_contracts.contains(&contract_id),
Error::<T>::ContractAlreadyProcessedInBlock,
);
seen_contracts.push(contract_id);
SeenContracts::<T>::put(seen_contracts);

let mut contract = Contracts::<T>::get(contract_id).ok_or_else(|| {
log::error!("Contract not exists: {:?}", contract_id);
Error::<T>::ContractNotExists
Expand Down
8 changes: 0 additions & 8 deletions substrate-node/pallets/pallet-smart-contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,6 @@ pub mod pallet {
#[pallet::getter(fn dedicated_nodes_extra_fee)]
pub type DedicatedNodesExtraFee<T> = StorageMap<_, Blake2_128Concat, u32, u64, ValueQuery>;

#[pallet::storage]
pub type SeenContracts<T> = StorageValue<_, Vec<u64>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn contract_payment_state)]
pub type ContractPaymentState<T: Config> =
Expand Down Expand Up @@ -415,7 +412,6 @@ pub mod pallet {
WrongAuthority,
UnauthorizedToChangeSolutionProviderId,
UnauthorizedToSetExtraFee,
ContractAlreadyProcessedInBlock,
}

#[pallet::genesis_config]
Expand Down Expand Up @@ -722,9 +718,5 @@ pub mod pallet {
fn offchain_worker(block_number: BlockNumberFor<T>) {
Self::bill_contracts_for_block(block_number);
}

fn on_finalize(_n: BlockNumberFor<T>) {
SeenContracts::<T>::kill();
}
}
}
99 changes: 92 additions & 7 deletions substrate-node/pallets/pallet-smart-contract/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
use crate::{
pallet::{MaxDeploymentDataLength, MaxNodeContractPublicIPs},
Config,
Call, Config,
};
use core::{convert::TryInto, ops::Add};
use frame_support::{
pallet_prelude::ConstU32, traits::DefensiveSaturating, BoundedVec, RuntimeDebugNoBound,
pallet_prelude::ConstU32,
traits::{DefensiveSaturating, IsSubType},
BoundedVec, RuntimeDebugNoBound,
};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::{traits::Zero, SaturatedConversion};
use sp_std::prelude::*;
use sp_runtime::{
traits::{DispatchInfoOf, SignedExtension, Zero},
transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction},
SaturatedConversion,
};
use sp_std::{fmt::Debug, marker::PhantomData, prelude::*};
use substrate_fixed::types::U64F64;
use tfchain_support::{resources::Resources, types::PublicIP};
pub type BlockNumber = u64;
Expand Down Expand Up @@ -227,7 +233,6 @@ pub struct ContractLock<BalanceOf> {
PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo, MaxEncodedLen,
)]
pub struct ContractPaymentState<BalanceOf> {

pub standard_reserved: BalanceOf,
pub additional_reserved: BalanceOf,
pub standard_overdrafted: BalanceOf,
Expand Down Expand Up @@ -316,8 +321,7 @@ where

// Method to return weather the contract has overdrafted amount or not
pub fn has_overdrafted_amount(&self) -> bool {
!self.standard_overdrafted.is_zero()
|| !self.additional_overdrafted.is_zero()
!self.standard_overdrafted.is_zero() || !self.additional_overdrafted.is_zero()
}

// Method to settle partial overdrafted amount
Expand Down Expand Up @@ -405,3 +409,84 @@ pub enum ServiceContractState {
AgreementReady,
ApprovedByBoth,
}

#[derive(Encode, Decode, Clone, Eq, PartialEq, scale_info::TypeInfo)]
pub struct ContractIdProvides<T: Config + Send + Sync + scale_info::TypeInfo>(PhantomData<T>)
where
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>;

impl<T: Config + Send + Sync + scale_info::TypeInfo> SignedExtension for ContractIdProvides<T>
where
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
{
const IDENTIFIER: &'static str = "ContractIdProvides";
type AccountId = T::AccountId;
type Call = T::RuntimeCall;
type AdditionalSigned = ();
type Pre = ();

fn additional_signed(&self) -> Result<(), TransactionValidityError> {
Ok(())
}

fn validate(
&self,
_who: &Self::AccountId,
call: &Self::Call,
_info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
if let Some(local_call) = call.is_sub_type() {
if let Call::bill_contract_for_block { contract_id } = local_call {
return ValidTransaction::with_tag_prefix(Self::IDENTIFIER)
.and_provides(contract_id.to_le_bytes().to_vec())
.build()
.into();
}
}
Ok(ValidTransaction::default())
}

fn pre_dispatch(
self,
who: &Self::AccountId,
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
self.validate(who, call, info, len).map(|_| ())
}
}

impl<T: Config + Send + Sync + scale_info::TypeInfo> Debug for ContractIdProvides<T>
where
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
{
#[cfg(feature = "std")]
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
write!(f, "ContractIdProvides")
}

#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}

impl<T: Config + Send + Sync + scale_info::TypeInfo> Default for ContractIdProvides<T>
where
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
{
fn default() -> Self {
Self(PhantomData)
}
}

impl<T: Config + Send + Sync + scale_info::TypeInfo> ContractIdProvides<T>
where
<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
{
pub fn new() -> Self {
Self(PhantomData)
}
}
2 changes: 2 additions & 0 deletions substrate-node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ where
frame_system::CheckNonce::<Runtime>::from(index),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
pallet_smart_contract::types::ContractIdProvides::<Runtime>::new(),
);

#[cfg_attr(not(feature = "std"), allow(unused_variables))]
Expand Down Expand Up @@ -768,6 +769,7 @@ pub type SignedExtra = (
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
pallet_smart_contract::types::ContractIdProvides::<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
Expand Down

0 comments on commit 3dcc930

Please sign in to comment.