mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 21:11:07 +00:00
If contract reaches max depth, return Err (#503)
This commit is contained in:
committed by
Gav Wood
parent
6f4a401afa
commit
dce3e8c477
@@ -14,14 +14,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::{CodeOf, ContractAddressFor, Module, Trait};
|
||||
use super::{CodeOf, MaxDepth, ContractAddressFor, Module, Trait};
|
||||
use account_db::{AccountDb, OverlayAccountDb};
|
||||
use gas::GasMeter;
|
||||
use vm;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use runtime_primitives::traits::{Zero, CheckedAdd, CheckedSub};
|
||||
use runtime_support::StorageMap;
|
||||
use runtime_support::{StorageMap, StorageValue};
|
||||
use staking;
|
||||
use system;
|
||||
|
||||
@@ -50,15 +50,17 @@ impl<'a, T: Trait> ExecutionContext<'a, T> {
|
||||
gas_meter: &mut GasMeter<T>,
|
||||
_data: &[u8],
|
||||
) -> Result<CallReceipt, &'static str> {
|
||||
let dest_code = <CodeOf<T>>::get(&dest);
|
||||
|
||||
// TODO: check the new depth
|
||||
if self.depth == <MaxDepth<T>>::get() as usize {
|
||||
return Err("reached maximum depth, cannot make a call");
|
||||
}
|
||||
|
||||
let call_base_fee = <Module<T>>::call_base_fee();
|
||||
if gas_meter.charge(call_base_fee).is_out_of_gas() {
|
||||
return Err("not enough gas to pay base call fee");
|
||||
}
|
||||
|
||||
let dest_code = <CodeOf<T>>::get(&dest);
|
||||
|
||||
let (exec_result, change_set) = {
|
||||
let mut overlay = OverlayAccountDb::new(&self.overlay);
|
||||
|
||||
@@ -112,6 +114,10 @@ impl<'a, T: Trait> ExecutionContext<'a, T> {
|
||||
ctor: &[u8],
|
||||
_data: &[u8],
|
||||
) -> Result<CreateReceipt<T>, &'static str> {
|
||||
if self.depth == <MaxDepth<T>>::get() as usize {
|
||||
return Err("reached maximum depth, cannot create");
|
||||
}
|
||||
|
||||
let create_base_fee = <Module<T>>::create_base_fee();
|
||||
if gas_meter.charge(create_base_fee).is_out_of_gas() {
|
||||
return Err("not enough gas to pay base create fee");
|
||||
|
||||
@@ -121,7 +121,7 @@ fn new_test_ext(existential_deposit: u64, gas_price: u64) -> runtime_io::TestExt
|
||||
call_base_fee: 135,
|
||||
create_base_fee: 175,
|
||||
gas_price,
|
||||
max_depth: 1024,
|
||||
max_depth: 100,
|
||||
}.build_storage()
|
||||
.unwrap(),
|
||||
);
|
||||
@@ -221,6 +221,38 @@ fn contract_transfer_oog() {
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn contract_transfer_max_depth() {
|
||||
const CONTRACT_SHOULD_TRANSFER_TO: u64 = 9;
|
||||
|
||||
let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap();
|
||||
|
||||
with_externalities(&mut new_test_ext(0, 2), || {
|
||||
<CodeOf<Test>>::insert(CONTRACT_SHOULD_TRANSFER_TO, code_transfer.to_vec());
|
||||
|
||||
Staking::set_free_balance(&0, 100_000_000);
|
||||
Staking::set_free_balance(&CONTRACT_SHOULD_TRANSFER_TO, 11);
|
||||
|
||||
assert_err!(
|
||||
Contract::call(&0, CONTRACT_SHOULD_TRANSFER_TO, 3, 100_000, Vec::new()),
|
||||
"vm execute returned error while call"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Staking::free_balance(&0),
|
||||
// 3 - value sent with the transaction
|
||||
// 2 * 6 * 100 - gas used by the contract (6) multiplied by gas price (2)
|
||||
// multiplied by max depth (100).
|
||||
// 2 * 135 * 100 - base gas fee for call (by transaction) multiplied by max depth (100).
|
||||
100_000_000 - (2 * 135 * 100) - (2 * 6 * 100),
|
||||
);
|
||||
assert_eq!(
|
||||
Staking::free_balance(&CONTRACT_SHOULD_TRANSFER_TO),
|
||||
11,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Convert a byte slice to a string with hex values.
|
||||
///
|
||||
/// Each value is preceeded with a `\` character.
|
||||
|
||||
Reference in New Issue
Block a user