--- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -17,17 +17,17 @@ use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_core::{ crypto::KeyTypeId, crypto::Public, OpaqueMetadata }; +use sp_core::{ crypto::KeyTypeId, crypto::Public, OpaqueMetadata, H160, U256 }; use sp_runtime::{ - Permill, Perbill, Percent, - ModuleId, - create_runtime_str, generic, impl_opaque_keys, - traits::{ - Convert, ConvertInto, BlakeTwo256, Block as BlockT, IdentifyAccount, - IdentityLookup, NumberFor, Verify, AccountIdConversion, - }, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, MultiSignature, + Permill, Perbill, Percent, + ModuleId, + create_runtime_str, generic, impl_opaque_keys, + traits::{ + Convert, ConvertInto, BlakeTwo256, Block as BlockT, IdentifyAccount, + IdentityLookup, NumberFor, Verify, AccountIdConversion, + }, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, MultiSignature, }; #[cfg(feature = "std")] use sp_version::NativeVersion; @@ -35,32 +35,38 @@ pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment, CurrencyAdapter, FeeDetails, RuntimeDispatchInfo}; // A few exports that help ease life for downstream crates. pub use pallet_balances::Call as BalancesCall; +pub use pallet_evm::{EnsureAddressTruncated, HashedAddressMapping, Runner}; pub use pallet_contracts::{Schedule as ContractsSchedule }; pub use frame_support::{ - construct_runtime, - dispatch::DispatchResult, - parameter_types, - StorageValue, - traits::{ - Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness, - LockIdentifier, - }, - weights::{ - constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, - DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight, - WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients - }, + construct_runtime, + dispatch::DispatchResult, + parameter_types, + StorageValue, + traits::{ + Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness, + LockIdentifier, FindAuthor, + }, + weights::{ + constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, + DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight, + WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients + }, + ConsensusEngineId, }; use pallet_contracts::weights::WeightInfo; // #[cfg(any(feature = "std", test))] use frame_system::{ - self as system, - EnsureRoot, + self as system, + EnsureRoot, limits::{BlockWeights, BlockLength}, }; use sp_std::{prelude::*, marker::PhantomData}; use sp_arithmetic::{traits::{BaseArithmetic, Unsigned}}; use smallvec::smallvec; +use codec::{Encode, Decode}; +use pallet_evm::{Account as EVMAccount, FeeCalculator}; +use fp_rpc::TransactionStatus; +use sp_core::H256; pub use pallet_timestamp::Call as TimestampCall; @@ -127,34 +133,34 @@ /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core data structures. pub mod opaque { - use super::*; + use super::*; - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - /// Opaque block header type. - pub type Header = generic::Header; - /// Opaque block type. - pub type Block = generic::Block; - /// Opaque block identifier type. - pub type BlockId = generic::BlockId; + /// Opaque block header type. + pub type Header = generic::Header; + /// Opaque block type. + pub type Block = generic::Block; + /// Opaque block identifier type. + pub type BlockId = generic::BlockId; - impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - pub grandpa: Grandpa, - } - } + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, + } + } } /// This runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("nft"), - impl_name: create_runtime_str!("nft"), - authoring_version: 1, - spec_version: 3, - impl_version: 1, - apis: RUNTIME_API_VERSIONS, - transaction_version: 1, + spec_name: create_runtime_str!("nft"), + impl_name: create_runtime_str!("nft"), + authoring_version: 1, + spec_version: 3, + impl_version: 1, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, }; pub const MILLISECS_PER_BLOCK: u64 = 6000; @@ -169,37 +175,37 @@ /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } + NativeVersion { + runtime_version: VERSION, + can_author_with: Default::default(), + } } /// Provides a membership set with only the configured aura users pub struct ValiudatorsOnly(PhantomData); impl frame_support::traits::Contains for ValiudatorsOnly { fn contains(t: &AccountId) -> bool { - let arr: [u8; 32] = *t.as_ref(); - let raw_key: Vec = Vec::from(arr); + let arr: [u8; 32] = *t.as_ref(); + let raw_key: Vec = Vec::from(arr); - match pallet_aura::Module::::authorities().iter().find(|auth| auth.to_raw_vec() == raw_key) { - Some(_) => true, - None => false, - } + match pallet_aura::Module::::authorities().iter().find(|auth| auth.to_raw_vec() == raw_key) { + Some(_) => true, + None => false, + } } fn sorted_members() -> Vec { - let mut members: Vec = Vec::new(); - for auth in pallet_aura::Module::::authorities() { - let mut arr: [u8; 32] = Default::default(); - let bor_arr = auth.clone().to_raw_vec(); - let slice = bor_arr.as_slice(); - arr.copy_from_slice(slice); - members.push(AccountId::from(arr)); - } - members + let mut members: Vec = Vec::new(); + for auth in pallet_aura::Module::::authorities() { + let mut arr: [u8; 32] = Default::default(); + let bor_arr = auth.clone().to_raw_vec(); + let slice = bor_arr.as_slice(); + arr.copy_from_slice(slice); + members.push(AccountId::from(arr)); + } + members } fn count() -> usize { - pallet_aura::Module::::authorities().len() + pallet_aura::Module::::authorities().len() } } @@ -255,11 +261,11 @@ const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND; parameter_types! { - pub const BlockHashCount: BlockNumber = 2400; + pub const BlockHashCount: BlockNumber = 2400; pub RuntimeBlockLength: BlockLength = BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() .base_block(BlockExecutionWeight::get()) .for_class(DispatchClass::all(), |weights| { @@ -278,59 +284,102 @@ }) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic(); - pub const Version: RuntimeVersion = VERSION; - pub const SS58Prefix: u8 = 42; + pub const Version: RuntimeVersion = VERSION; + pub const SS58Prefix: u8 = 42; } impl system::Config for Runtime { - /// The basic call filter to use in dispatchable. - type BaseCallFilter = (); - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = IdentityLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = generic::Header; - /// The ubiquitous event type. - type Event = Event; - /// The ubiquitous origin type. - type Origin = Origin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// The weight of the overhead invoked on the block import process, independent of the - /// extrinsics included in that block. + /// The basic call filter to use in dispatchable. + type BaseCallFilter = (); + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = IdentityLookup; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = generic::Header; + /// The ubiquitous event type. + type Event = Event; + /// The ubiquitous origin type. + type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The weight of the overhead invoked on the block import process, independent of the + /// extrinsics included in that block. type BlockWeights = RuntimeBlockWeights; - /// Version of the runtime. - type Version = Version; + /// Version of the runtime. + type Version = Version; /// This type is being generated by `construct_runtime!`. - type PalletInfo = PalletInfo; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; + type PalletInfo = PalletInfo; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; /// Weight information for the extrinsics of this pallet. - type SystemWeightInfo = system::weights::SubstrateWeight; - + type SystemWeightInfo = system::weights::SubstrateWeight; + type BlockLength = RuntimeBlockLength; type SS58Prefix = SS58Prefix; } impl pallet_aura::Config for Runtime { - type AuthorityId = AuraId; + type AuthorityId = AuraId; +} + +parameter_types! { + pub const ChainId: u64 = 8888; +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = (); + type GasWeightMapping = (); + type CallOrigin = EnsureAddressTruncated; + type WithdrawOrigin = EnsureAddressTruncated; + type AddressMapping = HashedAddressMapping; + type Currency = Balances; + type Event = Event; + type Precompiles = (); + type ChainId = ChainId; + type Runner = pallet_evm::runner::stack::Runner; + type OnChargeTransaction = (); +} + +pub struct EthereumFindAuthor(PhantomData); +impl> FindAuthor for EthereumFindAuthor +{ + fn find_author<'a, I>(digests: I) -> Option where + I: 'a + IntoIterator + { + if let Some(author_index) = F::find_author(digests) { + let authority_id = Aura::authorities()[author_index as usize].clone(); + return Some(H160::from_slice(&authority_id.to_raw_vec()[4..24])); + } + None + } +} + +parameter_types! { + pub BlockGasLimit: U256 = U256::from(u32::max_value()); +} + +impl pallet_ethereum::Config for Runtime { + type Event = Event; + type FindAuthor = EthereumFindAuthor; + type StateRoot = pallet_ethereum::IntermediateStateRoot; + type BlockGasLimit = BlockGasLimit; } impl pallet_grandpa::Config for Runtime { @@ -353,7 +402,7 @@ } parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } impl pallet_timestamp::Config for Runtime { @@ -365,8 +414,8 @@ } parameter_types! { - // pub const ExistentialDeposit: u128 = 500; - pub const ExistentialDeposit: u128 = 0; + // pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: u128 = 0; pub const MaxLocks: u32 = 50; } @@ -388,7 +437,7 @@ pub const UNIQUE: Balance = 100 * CENTIUNIQUE; pub const fn deposit(items: u32, bytes: u32) -> Balance { - items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE + items as Balance * 15 * CENTIUNIQUE + (bytes as Balance) * 6 * CENTIUNIQUE } parameter_types! { @@ -404,7 +453,7 @@ pub const SignedClaimHandicap: u32 = 2; pub const MaxDepth: u32 = 32; pub const MaxValueSize: u32 = 16 * 1024; - pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb + pub const MaxCodeSize: u32 = 1024 * 1024 * 25; // 25 Mb // The lazy deletion runs inside on_initialize. pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO * RuntimeBlockWeights::get().max_block; @@ -441,10 +490,10 @@ } parameter_types! { - pub const TransactionByteFee: Balance = 501 * MICROUNIQUE; // Targeting 0.1 Unique per NFT transfer + pub const TransactionByteFee: Balance = 501 * MICROUNIQUE; // Targeting 0.1 Unique per NFT transfer } -/// Linear implementor of `WeightToFeePolynomial` +/// Linear implementor of `WeightToFeePolynomial` pub struct LinearFee(sp_std::marker::PhantomData); impl WeightToFeePolynomial for LinearFee where @@ -504,8 +553,8 @@ } impl pallet_sudo::Config for Runtime { - type Event = Event; - type Call = Call; + type Event = Event; + type Call = Call; } parameter_types! { @@ -527,34 +576,52 @@ /// Used for the module nft in `./nft.rs` impl pallet_nft::Config for Runtime { - type Event = Event; - type WeightInfo = nft_weights::WeightInfo; + type Event = Event; + type WeightInfo = nft_weights::WeightInfo; type Currency = Balances; type CollectionCreationPrice = CollectionCreationPrice; type TreasuryAccountId = TreasuryAccountId; } construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system::{Module, Call, Config, Storage, Event}, - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, - Contracts: pallet_contracts::{Module, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, - Aura: pallet_aura::{Module, Config }, - Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, - Balances: pallet_balances::{Module, Call, Storage, Config, Event}, - TransactionPayment: pallet_transaction_payment::{Module, Storage}, - Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, - Nft: pallet_nft::{Module, Call, Config, Storage, Event}, - Treasury: pallet_treasury::{Module, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Module, Call, Config, Storage, Event}, - } + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Config, Storage, Event}, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, + Contracts: pallet_contracts::{Module, Call, Config, Storage, Event}, + Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, + Aura: pallet_aura::{Module, Config }, + EVM: pallet_evm::{Module, Config, Call, Storage, Event}, + Ethereum: pallet_ethereum::{Module, Config, Call, Storage, Event}, + Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, + Balances: pallet_balances::{Module, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Module, Storage}, + Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, + Nft: pallet_nft::{Module, Call, Config, Storage, Event}, + Treasury: pallet_treasury::{Module, Call, Storage, Config, Event}, + Vesting: pallet_vesting::{Module, Call, Config, Storage, Event}, + } ); +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned(pallet_ethereum::Call::::transact(transaction).into()) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned(pallet_ethereum::Call::::transact(transaction).into()); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]).expect("Encoded extrinsic is always valid") + } +} + /// The address format for describing accounts. pub type Address = AccountId; /// Block header type as expected by this runtime. @@ -567,13 +634,13 @@ pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( - system::CheckSpecVersion, - system::CheckTxVersion, - system::CheckGenesis, - system::CheckEra, - system::CheckNonce, - system::CheckWeight, - pallet_nft::ChargeTransactionPayment, + system::CheckSpecVersion, + system::CheckTxVersion, + system::CheckGenesis, + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + pallet_nft::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -581,7 +648,7 @@ pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = - frame_executive::Executive, Runtime, AllModules>; + frame_executive::Executive, Runtime, AllModules>; impl_runtime_apis! { @@ -612,87 +679,197 @@ } } - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + + fn random_seed() -> ::Hash { + RandomnessCollectiveFlip::random_seed().0 + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) + } + } - fn execute_block(block: Block) { - Executive::execute_block(block) - } + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> u64 { + Aura::slot_duration() + } + + fn authorities() -> Vec { + Aura::authorities() + } + } + + impl fp_rpc::EthereumRuntimeRPCApi for Runtime { + fn chain_id() -> u64 { + ::ChainId::get() + } + + fn account_basic(address: H160) -> EVMAccount { + EVM::account_basic(&address) + } - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } + fn gas_price() -> U256 { + ::FeeCalculator::min_gas_price() + } - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - Runtime::metadata().into() - } - } + fn account_code_at(address: H160) -> Vec { + EVM::account_codes(address) + } + + fn author() -> H160 { + >::find_author() + } - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + EVM::account_storages(address, H256::from_slice(&tmp[..])) + } - fn finalize_block() -> ::Header { - Executive::finalize_block() - } + fn call( + from: H160, + to: H160, + data: Vec, + value: U256, + gas_limit: U256, + gas_price: Option, + nonce: Option, + estimate: bool, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } + ::Runner::call( + from, + to, + data, + value, + gas_limit.low_u64(), + gas_price, + nonce, + config.as_ref().unwrap_or(::config()), + ).map_err(|err| err.into()) + } - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } + fn create( + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + gas_price: Option, + nonce: Option, + estimate: bool, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; - fn random_seed() -> ::Hash { - RandomnessCollectiveFlip::random_seed() - } - } + ::Runner::create( + from, + data, + value, + gas_limit.low_u64(), + gas_price, + nonce, + config.as_ref().unwrap_or(::config()), + ).map_err(|err| err.into()) + } - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx) - } - } + fn current_transaction_statuses() -> Option> { + Ethereum::current_transaction_statuses() + } - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } + fn current_block() -> Option { + Ethereum::current_block() + } - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> u64 { - Aura::slot_duration() - } + fn current_receipts() -> Option> { + Ethereum::current_receipts() + } - fn authorities() -> Vec { - Aura::authorities() - } - } + fn current_all() -> ( + Option, + Option>, + Option> + ) { + ( + Ethereum::current_block(), + Ethereum::current_receipts(), + Ethereum::current_transaction_statuses() + ) + } + } - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - opaque::SessionKeys::generate(seed) - } + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + opaque::SessionKeys::generate(seed) + } - fn decode_session_keys( - encoded: Vec, - ) -> Option, KeyTypeId)>> { - opaque::SessionKeys::decode_into_raw_public_keys(&encoded) - } - } + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + } + } impl fg_primitives::GrandpaApi for Runtime { fn grandpa_authorities() -> GrandpaAuthorityList { @@ -718,8 +895,8 @@ // with no values). None } - } - + } + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Index { System::account_nonce(account) @@ -735,7 +912,7 @@ } } - #[cfg(feature = "runtime-benchmarks")] + #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig @@ -753,7 +930,7 @@ // hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), // // System Events // hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), - ]; + ]; let mut batches = Vec::::new(); let params = (&config, &whitelist); @@ -764,4 +941,4 @@ Ok(batches) } } -} \ No newline at end of file +}