|
| 1 | +// This file is part of Darwinia. |
| 2 | +// |
| 3 | +// Copyright (C) 2018-2021 Darwinia Network |
| 4 | +// SPDX-License-Identifier: GPL-3.0 |
| 5 | +// |
| 6 | +// Darwinia is free software: you can redistribute it and/or modify |
| 7 | +// it under the terms of the GNU General Public License as published by |
| 8 | +// the Free Software Foundation, either version 3 of the License, or |
| 9 | +// (at your option) any later version. |
| 10 | +// |
| 11 | +// Darwinia is distributed in the hope that it will be useful, |
| 12 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | +// GNU General Public License for more details. |
| 15 | +// |
| 16 | +// You should have received a copy of the GNU General Public License |
| 17 | +// along with Darwinia. If not, see <https://www.gnu.org/licenses/>. |
| 18 | + |
| 19 | +#![cfg(feature = "runtime-benchmarks")] |
| 20 | + |
| 21 | +//! Benchmarking |
| 22 | +use crate::{runner::Runner, Config, Pallet}; |
| 23 | +use frame_benchmarking::benchmarks; |
| 24 | +use rlp::RlpStream; |
| 25 | +use sha3::{Digest, Keccak256}; |
| 26 | +use sp_core::{H160, U256}; |
| 27 | +use sp_std::vec; |
| 28 | + |
| 29 | +benchmarks! { |
| 30 | + |
| 31 | + // This benchmark tests the relationship between gas and weight. It deploys a contract which |
| 32 | + // has an infinite loop in a public function. We then call this function with varying amounts |
| 33 | + // of gas, expecting it to OOG. The benchmarking framework measures the amount of time (aka |
| 34 | + // weight) it takes before OOGing and relates that to the amount of gas provided, leaving us |
| 35 | + // with an estimate for gas-to-weight mapping. |
| 36 | + runner_execute { |
| 37 | + |
| 38 | + let x in 1..10000000; |
| 39 | + |
| 40 | + // contract bytecode below is for: |
| 41 | + // |
| 42 | + // pragma solidity >=0.8.0; |
| 43 | + // |
| 44 | + // contract InfiniteContractVar { |
| 45 | + // uint public count; |
| 46 | + |
| 47 | + // constructor() public { |
| 48 | + // count = 0; |
| 49 | + // } |
| 50 | + |
| 51 | + // function infinite() public { |
| 52 | + // while (true) { |
| 53 | + // count=count+1; |
| 54 | + // } |
| 55 | + // } |
| 56 | + // } |
| 57 | + |
| 58 | + let contract_bytecode = array_bytes::hex2bytes("0x608060405234801561001057600080fd5b506000808190555061017c806100276000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806306661abd1461003b5780635bec9e6714610059575b600080fd5b610043610063565b604051610050919061009c565b60405180910390f35b610061610069565b005b60005481565b5b60011561008b57600160005461008091906100b7565b60008190555061006a565b565b6100968161010d565b82525050565b60006020820190506100b1600083018461008d565b92915050565b60006100c28261010d565b91506100cd8361010d565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561010257610101610117565b5b828201905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea26469706673582212207891ca3e64b75f98d843216c9d58cb2867b04996d7d4d731187616e330987fc764736f6c63430008040033").unwrap(); |
| 59 | + let caller = H160::default(); |
| 60 | + |
| 61 | + let mut nonce: u64 = 0; |
| 62 | + let nonce_as_u256: U256 = nonce.into(); |
| 63 | + |
| 64 | + let value = U256::default(); |
| 65 | + let gas_limit_create: u64 = 1_250_000 * 1_000_000_000; |
| 66 | + let create_runner_results = T::Runner::create( |
| 67 | + caller, |
| 68 | + contract_bytecode, |
| 69 | + value, |
| 70 | + gas_limit_create, |
| 71 | + None, |
| 72 | + Some(nonce_as_u256), |
| 73 | + T::config(), |
| 74 | + ); |
| 75 | + assert_eq!(create_runner_results.is_ok(), true, "create() failed"); |
| 76 | + |
| 77 | + // derive the resulting contract address from our create |
| 78 | + let mut rlp = RlpStream::new_list(2); |
| 79 | + rlp.append(&caller); |
| 80 | + rlp.append(&0u8); |
| 81 | + let contract_address = H160::from_slice(&Keccak256::digest(&rlp.out())[12..]); |
| 82 | + |
| 83 | + // derive encoded contract call -- in this case, just the function selector |
| 84 | + let mut encoded_call = vec![0u8; 4]; |
| 85 | + encoded_call[0..4].copy_from_slice(&Keccak256::digest(b"infinite()")[0..4]); |
| 86 | + |
| 87 | + let gas_limit_call = x as u64; |
| 88 | + |
| 89 | + }: { |
| 90 | + |
| 91 | + nonce = nonce + 1; |
| 92 | + let nonce_as_u256: U256 = nonce.into(); |
| 93 | + |
| 94 | + let call_runner_results = T::Runner::call( |
| 95 | + caller, |
| 96 | + contract_address, |
| 97 | + encoded_call, |
| 98 | + value, |
| 99 | + gas_limit_call, |
| 100 | + None, |
| 101 | + Some(nonce_as_u256), |
| 102 | + T::config(), |
| 103 | + ); |
| 104 | + assert_eq!(call_runner_results.is_ok(), true, "call() failed"); |
| 105 | + } |
| 106 | +} |
0 commit comments