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

Add extrinsic weight and lenght check #637

Merged
merged 13 commits into from
May 12, 2022
2 changes: 1 addition & 1 deletion client/rpc/src/eth/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ where
let base_fee = if let Some(base_fee) = handler.base_fee(&id) {
base_fee
} else {
client.runtime_api().gas_price(&id).unwrap_or(U256::zero())
client.runtime_api().gas_price(&id).unwrap_or_else(|_|U256::zero())
};
let receipts = handler.current_receipts(&id);
let mut result = FeeHistoryCacheItem {
Expand Down
4 changes: 2 additions & 2 deletions frame/base-fee/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ pub mod pallet {
// Normalize to GWEI.
let increase = scaled_basefee
.checked_div(U256::from(1_000_000))
.unwrap_or(U256::zero());
.unwrap_or_else(U256::zero);
*bf = bf.saturating_add(increase);
} else {
Self::deposit_event(Event::BaseFeeOverflow);
Expand All @@ -196,7 +196,7 @@ pub mod pallet {
// Normalize to GWEI.
let decrease = scaled_basefee
.checked_div(U256::from(1_000_000))
.unwrap_or(U256::zero());
.unwrap_or_else(U256::zero);
*bf = bf.saturating_sub(decrease);
} else {
Self::deposit_event(Event::BaseFeeOverflow);
Expand Down
21 changes: 16 additions & 5 deletions frame/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ use frame_support::{
dispatch::DispatchResultWithPostInfo,
scale_info::TypeInfo,
traits::{EnsureOrigin, Get, PalletInfoAccess},
weights::{Pays, PostDispatchInfo, Weight},
weights::{DispatchInfo, Pays, PostDispatchInfo, Weight},
};
use frame_system::{pallet_prelude::OriginFor, WeightInfo};
use frame_system::{pallet_prelude::OriginFor, CheckWeight, WeightInfo};
use pallet_evm::{BlockHashMapping, FeeCalculator, GasWeightMapping, Runner};
use sha3::{Digest, Keccak256};
use sp_runtime::{
generic::DigestItem,
traits::{One, Saturating, UniqueSaturatedInto, Zero},
traits::{DispatchInfoOf, Dispatchable, One, Saturating, UniqueSaturatedInto, Zero},
transaction_validity::{
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransactionBuilder,
},
Expand Down Expand Up @@ -108,9 +108,11 @@ impl<O: Into<Result<RawOrigin, O>> + From<RawOrigin>> EnsureOrigin<O>
}
}

impl<T: Config> Call<T>
impl<T> Call<T>
where
OriginFor<T>: Into<Result<RawOrigin, OriginFor<T>>>,
T: Send + Sync + Config,
T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
{
pub fn is_self_contained(&self) -> bool {
matches!(self, Call::transact { .. })
Expand Down Expand Up @@ -146,8 +148,17 @@ where
}
}

pub fn validate_self_contained(&self, origin: &H160) -> Option<TransactionValidity> {
pub fn validate_self_contained(
&self,
origin: &H160,
dispatch_info: &DispatchInfoOf<T::Call>,
len: usize,
) -> Option<TransactionValidity> {
if let Call::transact { transaction } = self {
if let Err(e) = CheckWeight::<T>::do_validate(dispatch_info, len) {
return Some(Err(e));
}

Some(Pallet::<T>::validate_transaction_in_pool(
*origin,
transaction,
Expand Down
9 changes: 7 additions & 2 deletions frame/ethereum/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,14 @@ impl fp_self_contained::SelfContainedCall for Call {
}
}

fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option<TransactionValidity> {
fn validate_self_contained(
&self,
info: &Self::SignedInfo,
dispatch_info: &DispatchInfoOf<Call>,
len: usize,
) -> Option<TransactionValidity> {
match self {
Call::Ethereum(call) => call.validate_self_contained(info),
Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len),
_ => None,
}
}
Expand Down
32 changes: 23 additions & 9 deletions frame/ethereum/src/tests/eip1559.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,14 @@ fn transaction_without_enough_gas_should_not_work() {

let call = crate::Call::<Test>::transact { transaction };
let source = call.check_self_contained().unwrap().unwrap();

let extrinsic = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call.clone()),
};
let dispatch_info = extrinsic.get_dispatch_info();
assert_err!(
call.validate_self_contained(&source).unwrap(),
call.validate_self_contained(&source, &dispatch_info, 0)
.unwrap(),
InvalidTransaction::Payment
);
});
Expand All @@ -83,9 +88,15 @@ fn transaction_with_to_low_nonce_should_not_work() {
transaction: signed,
};
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, H160> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call.clone()),
};
let dispatch_info = extrinsic.get_dispatch_info();

assert_eq!(
call.validate_self_contained(&source).unwrap(),
call.validate_self_contained(&source, &dispatch_info, 0)
.unwrap(),
ValidTransactionBuilder::default()
.and_provides((alice.address, U256::from(1)))
.priority(0u64)
Expand All @@ -97,17 +108,22 @@ fn transaction_with_to_low_nonce_should_not_work() {

// nonce is 1
assert_ok!(Ethereum::execute(alice.address, &t, None,));

transaction.nonce = U256::from(0);

let signed2 = transaction.sign(&alice.private_key, None);
let call2 = crate::Call::<Test>::transact {
transaction: signed2,
};
let source2 = call2.check_self_contained().unwrap().unwrap();
let extrinsic2 = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call2.clone()),
};

assert_err!(
call2.validate_self_contained(&source2).unwrap(),
call2
.validate_self_contained(&source2, &extrinsic2.get_dispatch_info(), 0)
.unwrap(),
InvalidTransaction::Stale
);
});
Expand All @@ -127,11 +143,10 @@ fn transaction_with_to_hight_nonce_should_fail_in_block() {
transaction: signed,
};
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = fp_self_contained::CheckedExtrinsic::<_, _, SignedExtra, _> {
let extrinsic = CheckedExtrinsic::<_, _, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call),
};
use frame_support::weights::GetDispatchInfo as _;
let dispatch_info = extrinsic.get_dispatch_info();
assert_err!(
extrinsic.apply::<Test>(&dispatch_info, 0),
Expand All @@ -151,11 +166,10 @@ fn transaction_with_invalid_chain_id_should_fail_in_block() {

let call = crate::Call::<Test>::transact { transaction };
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = fp_self_contained::CheckedExtrinsic::<_, _, SignedExtra, _> {
let extrinsic = CheckedExtrinsic::<_, _, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call),
};
use frame_support::weights::GetDispatchInfo as _;
let dispatch_info = extrinsic.get_dispatch_info();
assert_err!(
extrinsic.apply::<Test>(&dispatch_info, 0),
Expand Down
24 changes: 21 additions & 3 deletions frame/ethereum/src/tests/eip2930.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ fn transaction_without_enough_gas_should_not_work() {

let call = crate::Call::<Test>::transact { transaction };
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call.clone()),
};
let dispatch_info = extrinsic.get_dispatch_info();

assert_err!(
call.validate_self_contained(&source).unwrap(),
call.validate_self_contained(&source, &dispatch_info, 0)
.unwrap(),
InvalidTransaction::Payment
);
});
Expand All @@ -83,9 +89,15 @@ fn transaction_with_to_low_nonce_should_not_work() {
transaction: signed,
};
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, H160> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call.clone()),
};
let dispatch_info = extrinsic.get_dispatch_info();

assert_eq!(
call.validate_self_contained(&source).unwrap(),
call.validate_self_contained(&source, &dispatch_info, 0)
.unwrap(),
ValidTransactionBuilder::default()
.and_provides((alice.address, U256::from(1)))
.priority(0u64)
Expand All @@ -105,9 +117,15 @@ fn transaction_with_to_low_nonce_should_not_work() {
transaction: signed2,
};
let source2 = call2.check_self_contained().unwrap().unwrap();
let extrinsic2 = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call2.clone()),
};

assert_err!(
call2.validate_self_contained(&source2).unwrap(),
call2
.validate_self_contained(&source2, &extrinsic2.get_dispatch_info(), 0)
.unwrap(),
InvalidTransaction::Stale
);
});
Expand Down
24 changes: 21 additions & 3 deletions frame/ethereum/src/tests/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ fn transaction_without_enough_gas_should_not_work() {

let call = crate::Call::<Test>::transact { transaction };
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call.clone()),
};
let dispatch_info = extrinsic.get_dispatch_info();

assert_err!(
call.validate_self_contained(&source).unwrap(),
call.validate_self_contained(&source, &dispatch_info, 0)
.unwrap(),
InvalidTransaction::Payment
);
});
Expand All @@ -83,9 +89,15 @@ fn transaction_with_to_low_nonce_should_not_work() {
transaction: signed,
};
let source = call.check_self_contained().unwrap().unwrap();
let extrinsic = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, H160> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call.clone()),
};
let dispatch_info = extrinsic.get_dispatch_info();

assert_eq!(
call.validate_self_contained(&source).unwrap(),
call.validate_self_contained(&source, &dispatch_info, 0)
.unwrap(),
ValidTransactionBuilder::default()
.and_provides((alice.address, U256::from(1)))
.priority(0u64)
Expand All @@ -105,9 +117,15 @@ fn transaction_with_to_low_nonce_should_not_work() {
transaction: signed2,
};
let source2 = call2.check_self_contained().unwrap().unwrap();
let extrinsic2 = CheckedExtrinsic::<u64, crate::mock::Call, SignedExtra, _> {
signed: fp_self_contained::CheckedSignature::SelfContained(source),
function: Call::Ethereum(call2.clone()),
};

assert_err!(
call2.validate_self_contained(&source2).unwrap(),
call2
.validate_self_contained(&source2, &extrinsic2.get_dispatch_info(), 0)
.unwrap(),
InvalidTransaction::Stale
);
});
Expand Down
5 changes: 4 additions & 1 deletion frame/ethereum/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use frame_support::{assert_err, assert_ok, unsigned::TransactionValidityError};
use frame_support::{
assert_err, assert_ok, unsigned::TransactionValidityError, weights::GetDispatchInfo,
};
use rustc_hex::{FromHex, ToHex};
use sp_runtime::{
traits::Applyable,
Expand All @@ -26,6 +28,7 @@ use std::str::FromStr;
use crate::{
mock::*, CallOrCreateInfo, RawOrigin, Transaction, TransactionAction, H160, H256, U256,
};
use fp_self_contained::CheckedExtrinsic;

mod eip1559;
mod eip2930;
Expand Down
11 changes: 6 additions & 5 deletions primitives/self-contained/src/checked_extrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ where
let unsigned_validation = U::validate_unsigned(source, &self.function)?;
Ok(valid.combine_with(unsigned_validation))
}
CheckedSignature::SelfContained(signed_info) => {
self.function.validate_self_contained(signed_info).ok_or(
TransactionValidityError::Invalid(InvalidTransaction::BadProof),
)?
}
CheckedSignature::SelfContained(signed_info) => self
.function
.validate_self_contained(signed_info, info, len)
.ok_or(TransactionValidityError::Invalid(
InvalidTransaction::BadProof,
))?,
}
}

Expand Down
9 changes: 7 additions & 2 deletions primitives/self-contained/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use crate::{
};

use sp_runtime::{
traits::{Dispatchable, PostDispatchInfoOf},
traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf},
transaction_validity::{TransactionValidity, TransactionValidityError},
};

Expand All @@ -43,7 +43,12 @@ pub trait SelfContainedCall: Dispatchable {
fn check_self_contained(&self) -> Option<Result<Self::SignedInfo, TransactionValidityError>>;
/// Validate a self-contained function. Returns `None` if the
/// function is not a self-contained.
fn validate_self_contained(&self, info: &Self::SignedInfo) -> Option<TransactionValidity>;
fn validate_self_contained(
&self,
info: &Self::SignedInfo,
dispatch_info: &DispatchInfoOf<Self>,
len: usize,
) -> Option<TransactionValidity>;
/// Do any pre-flight stuff for a self-contained call.
///
/// Note this function by default delegates to `validate_self_contained`, so that
Expand Down
2 changes: 1 addition & 1 deletion template/examples/contract-erc20/create-erc20-rpc.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Web3 from "web3";
import * as web3Utils from 'web3-utils';

const web3 = new Web3("http://localhost:9933");
const web3 = new Web3("http://127.0.0.1:9933");
const ERC20_BYTECODE = require("./truffle/contracts/MyToken.json").bytecode;
const STORAGE_SLOT = "0";

Expand Down
4 changes: 2 additions & 2 deletions template/examples/contract-erc20/create-erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { U8aFixed } from '@polkadot/types/codec';
import * as web3Utils from 'web3-utils';
import * as crypto from '@polkadot/util-crypto';

// Provider is set to localhost for development
const wsProvider = new WsProvider("ws://localhost:9944");
// Provider is set to 127.0.0.1 for development
const wsProvider = new WsProvider("ws://127.0.0.1:9944");

// Keyring needed to sign using Alice account
const keyring = new Keyring({ type: 'sr25519' });
Expand Down
2 changes: 1 addition & 1 deletion template/examples/contract-hello/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Web3 = require('web3');
const web3 = new Web3('http://localhost:8545');
const web3 = new Web3('http://127.0.0.1:8545');

const ABI = [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Said","type":"event"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}];
const BYTECODE = "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fc68045c3c562488255b55aa2c4c7849de001859ff0d8a36a75c2d5ed80100fb660405180806020018281038252600d8152602001807f48656c6c6f2c20776f726c64210000000000000000000000000000000000000081525060200191505060405180910390a160cf806100c76000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80638da5cb5b14602d575b600080fd5b60336075565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fea265627a7a72315820fae816ad954005c42bea7bc7cb5b19f7fd5d3a250715ca2023275c9ca7ce644064736f6c634300050f0032";
Expand Down
Loading