diff --git a/substrate-node/node/src/benchmarking.rs b/substrate-node/node/src/benchmarking.rs index 06f55b394..24d086117 100644 --- a/substrate-node/node/src/benchmarking.rs +++ b/substrate-node/node/src/benchmarking.rs @@ -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}; @@ -132,6 +132,7 @@ pub fn create_benchmark_extrinsic( frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(0), + pallet_smart_contract::types::ContractIdProvides::::new(), ); let raw_payload = runtime::SignedPayload::from_raw( @@ -146,6 +147,7 @@ pub fn create_benchmark_extrinsic( (), (), (), + (), ), ); let signature = raw_payload.using_encoded(|e| sender.sign(e)); diff --git a/substrate-node/pallets/pallet-smart-contract/src/billing.rs b/substrate-node/pallets/pallet-smart-contract/src/billing.rs index a4a45a106..ac7a34deb 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/billing.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/billing.rs @@ -123,15 +123,6 @@ impl Pallet { 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::::get(); - ensure!( - !seen_contracts.contains(&contract_id), - Error::::ContractAlreadyProcessedInBlock, - ); - seen_contracts.push(contract_id); - SeenContracts::::put(seen_contracts); - let mut contract = Contracts::::get(contract_id).ok_or_else(|| { log::error!("Contract not exists: {:?}", contract_id); Error::::ContractNotExists diff --git a/substrate-node/pallets/pallet-smart-contract/src/lib.rs b/substrate-node/pallets/pallet-smart-contract/src/lib.rs index f1c6e2b34..5727bf264 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/lib.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/lib.rs @@ -196,9 +196,6 @@ pub mod pallet { #[pallet::getter(fn dedicated_nodes_extra_fee)] pub type DedicatedNodesExtraFee = StorageMap<_, Blake2_128Concat, u32, u64, ValueQuery>; - #[pallet::storage] - pub type SeenContracts = StorageValue<_, Vec, ValueQuery>; - #[pallet::storage] #[pallet::getter(fn contract_payment_state)] pub type ContractPaymentState = @@ -415,7 +412,6 @@ pub mod pallet { WrongAuthority, UnauthorizedToChangeSolutionProviderId, UnauthorizedToSetExtraFee, - ContractAlreadyProcessedInBlock, } #[pallet::genesis_config] @@ -722,9 +718,5 @@ pub mod pallet { fn offchain_worker(block_number: BlockNumberFor) { Self::bill_contracts_for_block(block_number); } - - fn on_finalize(_n: BlockNumberFor) { - SeenContracts::::kill(); - } } } diff --git a/substrate-node/pallets/pallet-smart-contract/src/types.rs b/substrate-node/pallets/pallet-smart-contract/src/types.rs index ac204d562..682fb8488 100644 --- a/substrate-node/pallets/pallet-smart-contract/src/types.rs +++ b/substrate-node/pallets/pallet-smart-contract/src/types.rs @@ -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; @@ -227,7 +233,6 @@ pub struct ContractLock { PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, Debug, TypeInfo, MaxEncodedLen, )] pub struct ContractPaymentState { - pub standard_reserved: BalanceOf, pub additional_reserved: BalanceOf, pub standard_overdrafted: BalanceOf, @@ -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 @@ -405,3 +409,84 @@ pub enum ServiceContractState { AgreementReady, ApprovedByBoth, } + +#[derive(Encode, Decode, Clone, Eq, PartialEq, scale_info::TypeInfo)] +pub struct ContractIdProvides(PhantomData) +where + ::RuntimeCall: IsSubType>; + +impl SignedExtension for ContractIdProvides +where + ::RuntimeCall: IsSubType>, +{ + 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, + _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, + len: usize, + ) -> Result { + self.validate(who, call, info, len).map(|_| ()) + } +} + +impl Debug for ContractIdProvides +where + ::RuntimeCall: IsSubType>, +{ + #[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 Default for ContractIdProvides +where + ::RuntimeCall: IsSubType>, +{ + fn default() -> Self { + Self(PhantomData) + } +} + +impl ContractIdProvides +where + ::RuntimeCall: IsSubType>, +{ + pub fn new() -> Self { + Self(PhantomData) + } +} diff --git a/substrate-node/runtime/src/lib.rs b/substrate-node/runtime/src/lib.rs index 3169a9740..75e6a96ec 100644 --- a/substrate-node/runtime/src/lib.rs +++ b/substrate-node/runtime/src/lib.rs @@ -551,6 +551,7 @@ where frame_system::CheckNonce::::from(index), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + pallet_smart_contract::types::ContractIdProvides::::new(), ); #[cfg_attr(not(feature = "std"), allow(unused_variables))] @@ -768,6 +769,7 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + pallet_smart_contract::types::ContractIdProvides::, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic =