diff --git a/Cargo.lock b/Cargo.lock index 0f04d5f8dce..4906d2629c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4973,6 +4973,8 @@ dependencies = [ name = "pallet-gear-rpc" version = "2.0.0" dependencies = [ + "gear-common", + "gear-core", "jsonrpsee", "pallet-gear-rpc-runtime-api", "sp-api", diff --git a/pallets/gear/Cargo.toml b/pallets/gear/Cargo.toml index 5a7e4d94482..0c0fbe0ffb5 100644 --- a/pallets/gear/Cargo.toml +++ b/pallets/gear/Cargo.toml @@ -38,6 +38,7 @@ sp-core = { version = "6.0.0", git = "https://github.com/gear-tech/substrate.git sp-std = { version = "4.0.0-dev", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false } sp-io = { version = "6.0.0", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false } sp-runtime = { version = "6.0.0", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false } +sp-externalities = { version = "0.12.0", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false } pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable" } pallet-authorship = { version = "4.0.0-dev", default-features = false, git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable" } pallet-timestamp = { version = "4.0.0-dev", default-features = false, git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable" } @@ -50,7 +51,6 @@ rand = { version = "0.8", optional = true, default-features = false } rand_pcg = { version = "0.3", optional = true } [dev-dependencies] -sp-externalities = { version = "0.12.0", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false } env_logger = "0.9" wabt = "0.10" demo-async-tester = { path = "../../examples/binaries/async-tester" } diff --git a/pallets/gear/rpc/Cargo.toml b/pallets/gear/rpc/Cargo.toml index 64c2ecdeccc..658a76a0ba1 100644 --- a/pallets/gear/rpc/Cargo.toml +++ b/pallets/gear/rpc/Cargo.toml @@ -18,4 +18,6 @@ sp-rpc = { version = "6.0.0", git = "https://github.com/gear-tech/substrate.git" sp-runtime = { version = "6.0.0", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false } # Local packages +gear-core = { path = "../../../core" } +gear-common = { path = "../../../common" } pallet-gear-rpc-runtime-api = { version = "2.0.0", path = "./runtime-api" } diff --git a/pallets/gear/rpc/runtime-api/src/lib.rs b/pallets/gear/rpc/runtime-api/src/lib.rs index fd2477a2db4..1b25713ba1d 100644 --- a/pallets/gear/rpc/runtime-api/src/lib.rs +++ b/pallets/gear/rpc/runtime-api/src/lib.rs @@ -18,12 +18,13 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub use pallet_gear::manager::HandleKind; +pub use pallet_gear::{manager::HandleKind, GasInfo}; use sp_core::H256; use sp_std::vec::Vec; sp_api::decl_runtime_apis! { pub trait GearApi { - fn get_gas_spent(source: H256, kind: HandleKind, payload: Vec, value: u128) -> Result>; + #[allow(clippy::too_many_arguments)] + fn calculate_gas_info(source: H256, kind: HandleKind, payload: Vec, value: u128, allow_other_panics: bool,) -> Result>; } } diff --git a/pallets/gear/rpc/src/lib.rs b/pallets/gear/rpc/src/lib.rs index 190d5d49dfe..87f689fec44 100644 --- a/pallets/gear/rpc/src/lib.rs +++ b/pallets/gear/rpc/src/lib.rs @@ -18,22 +18,22 @@ //! RPC interface for the gear module. -use std::{convert::TryInto, sync::Arc}; +#![allow(clippy::too_many_arguments)] +use gear_common::Origin; +use gear_core::ids::{MessageId, ProgramId}; use jsonrpsee::{ core::{async_trait, Error as JsonRpseeError, RpcResult}, proc_macros::rpc, types::error::{CallError, ErrorObject}, }; - -pub use pallet_gear_rpc_runtime_api::HandleKind; +pub use pallet_gear_rpc_runtime_api::GearApi as GearRuntimeApi; +use pallet_gear_rpc_runtime_api::{GasInfo, HandleKind}; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; use sp_core::{Bytes, H256}; -use sp_rpc::number::NumberOrHex; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; - -pub use pallet_gear_rpc_runtime_api::GearApi as GearRuntimeApi; +use std::sync::Arc; /// Converts a runtime trap into a [`CallError`]. fn runtime_error_into_rpc_error(err: impl std::fmt::Debug) -> JsonRpseeError { @@ -47,27 +47,29 @@ fn runtime_error_into_rpc_error(err: impl std::fmt::Debug) -> JsonRpseeError { #[rpc(client, server)] pub trait GearApi { - #[method(name = "gear_getInitGasSpent")] + #[method(name = "gear_calculateInitGas")] fn get_init_gas_spent( &self, source: H256, code: Bytes, payload: Bytes, value: u128, + allow_other_panics: bool, at: Option, - ) -> RpcResult; + ) -> RpcResult; - #[method(name = "gear_getHandleGasSpent")] + #[method(name = "gear_calculateHandleGas")] fn get_handle_gas_spent( &self, source: H256, dest: H256, payload: Bytes, value: u128, + allow_other_panics: bool, at: Option, - ) -> RpcResult; + ) -> RpcResult; - #[method(name = "gear_getReplyGasSpent")] + #[method(name = "gear_calculateReplyGas")] fn get_reply_gas_spent( &self, source: H256, @@ -75,8 +77,9 @@ pub trait GearApi { exit_code: i32, payload: Bytes, value: u128, + allow_other_panics: bool, at: Option, - ) -> RpcResult; + ) -> RpcResult; } /// A struct that implements the [`GearApi`]. @@ -127,29 +130,26 @@ where code: Bytes, payload: Bytes, value: u128, + allow_other_panics: bool, at: Option<::Hash>, - ) -> RpcResult { + ) -> RpcResult { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); + // If the block hash is not supplied assume the best block. + self.client.info().best_hash)); let runtime_api_result = api - .get_gas_spent( + .calculate_gas_info( &at, source, HandleKind::Init(code.to_vec()), payload.to_vec(), value, + allow_other_panics, ) .map_err(runtime_error_into_rpc_error)?; - match runtime_api_result { - Ok(gas) => Ok(gas.try_into().map_err(runtime_error_into_rpc_error)?), - Err(message) => Err(runtime_error_into_rpc_error(String::from_utf8_lossy( - &message, - ))), - } + runtime_api_result.map_err(|e| runtime_error_into_rpc_error(String::from_utf8_lossy(&e))) } fn get_handle_gas_spent( @@ -158,29 +158,26 @@ where dest: H256, payload: Bytes, value: u128, + allow_other_panics: bool, at: Option<::Hash>, - ) -> RpcResult { + ) -> RpcResult { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); + // If the block hash is not supplied assume the best block. + self.client.info().best_hash)); let runtime_api_result = api - .get_gas_spent( + .calculate_gas_info( &at, source, - HandleKind::Handle(dest), + HandleKind::Handle(ProgramId::from_origin(dest)), payload.to_vec(), value, + allow_other_panics, ) .map_err(runtime_error_into_rpc_error)?; - match runtime_api_result { - Ok(gas) => Ok(gas.try_into().map_err(runtime_error_into_rpc_error)?), - Err(message) => Err(runtime_error_into_rpc_error(String::from_utf8_lossy( - &message, - ))), - } + runtime_api_result.map_err(|e| runtime_error_into_rpc_error(String::from_utf8_lossy(&e))) } fn get_reply_gas_spent( @@ -190,28 +187,25 @@ where exit_code: i32, payload: Bytes, value: u128, + allow_other_panics: bool, at: Option<::Hash>, - ) -> RpcResult { + ) -> RpcResult { let api = self.client.runtime_api(); let at = BlockId::hash(at.unwrap_or_else(|| - // If the block hash is not supplied assume the best block. - self.client.info().best_hash)); + // If the block hash is not supplied assume the best block. + self.client.info().best_hash)); let runtime_api_result = api - .get_gas_spent( + .calculate_gas_info( &at, source, - HandleKind::Reply(message_id, exit_code), + HandleKind::Reply(MessageId::from_origin(message_id), exit_code), payload.to_vec(), value, + allow_other_panics, ) .map_err(runtime_error_into_rpc_error)?; - match runtime_api_result { - Ok(gas) => Ok(gas.try_into().map_err(runtime_error_into_rpc_error)?), - Err(message) => Err(runtime_error_into_rpc_error(String::from_utf8_lossy( - &message, - ))), - } + runtime_api_result.map_err(|e| runtime_error_into_rpc_error(String::from_utf8_lossy(&e))) } } diff --git a/pallets/gear/src/benchmarking/mod.rs b/pallets/gear/src/benchmarking/mod.rs index 6d0c63a96d0..c7179ea5070 100644 --- a/pallets/gear/src/benchmarking/mod.rs +++ b/pallets/gear/src/benchmarking/mod.rs @@ -192,7 +192,7 @@ where Message::new( root_message_id, ProgramId::from_origin(source), - ProgramId::from_origin(dest), + dest, payload, Some(u64::MAX), value, @@ -200,11 +200,8 @@ where ), ), HandleKind::Reply(msg_id, exit_code) => { - let msg = MailboxOf::::remove( - ::from_origin(source), - MessageId::from_origin(msg_id), - ) - .map_err(|_| "Internal error: unable to find message in mailbox")?; + let msg = MailboxOf::::remove(::from_origin(source), msg_id) + .map_err(|_| "Internal error: unable to find message in mailbox")?; Dispatch::new( DispatchKind::Reply, Message::new( @@ -427,7 +424,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -513,7 +510,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -566,7 +563,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -607,7 +604,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -648,7 +645,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -689,7 +686,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -731,7 +728,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< @@ -773,7 +770,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -814,7 +811,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -867,7 +864,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -931,7 +928,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -999,7 +996,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![0xff; (n * 1024) as usize], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![0xff; (n * 1024) as usize], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -1052,7 +1049,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -1105,7 +1102,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { core_processor::process::< ext::LazyPagesExt, @@ -1159,7 +1156,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1225,7 +1222,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1291,7 +1288,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1368,7 +1365,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 10000000u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 10000000u32.into())?; }: { let journal = core_processor::process::< @@ -1447,7 +1444,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 10000000u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 10000000u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1515,7 +1512,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 10000000u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 10000000u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1581,7 +1578,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 10000000u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 10000000u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1639,7 +1636,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Reply(msg_id.into_origin(), 0), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Reply(msg_id, 0), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1695,7 +1692,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1753,7 +1750,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Reply(msg_id.into_origin(), 0), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Reply(msg_id, 0), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1818,7 +1815,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1873,7 +1870,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1928,7 +1925,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -1998,7 +1995,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, @@ -2086,7 +2083,7 @@ benchmarks! { program_id, gas_allowance, outgoing_limit, - } = prepare::(instance.caller.into_origin(), HandleKind::Handle(instance.addr), vec![], 0u32.into())?; + } = prepare::(instance.caller.into_origin(), HandleKind::Handle(ProgramId::from_origin(instance.addr)), vec![], 0u32.into())?; }: { let journal = core_processor::process::< ext::LazyPagesExt, diff --git a/pallets/gear/src/lib.rs b/pallets/gear/src/lib.rs index 4ac72b3f16a..6f9bca9df57 100644 --- a/pallets/gear/src/lib.rs +++ b/pallets/gear/src/lib.rs @@ -22,6 +22,7 @@ extern crate alloc; use alloc::string::ToString; +use codec::{Decode, Encode}; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; @@ -101,6 +102,19 @@ impl DebugInfo for () { } } +/// The struct contains results of gas calculation required to process +/// a message. +#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, scale_info::TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))] +pub struct GasInfo { + /// Represents minimum gas limit required for execution. + pub min_limit: u64, + /// Gas amount that we reserve for some other on-chain interactions. + pub reserved: u64, + /// Contains number of gas burned during message processing. + pub burned: u64, +} + #[frame_support::pallet] pub mod pallet { use super::*; @@ -493,66 +507,137 @@ pub mod pallet { Ok(().into()) } - #[cfg(not(test))] - pub fn get_gas_spent( + pub fn calculate_gas_info( source: H256, kind: HandleKind, payload: Vec, value: u128, - ) -> Result> { - Self::get_gas_spent_impl(source, kind, payload, value) + allow_other_panics: bool, + ) -> Result> { + let GasInfo { min_limit, .. } = Self::run_with_ext_copy(|| { + let initial_gas = ::BlockGasLimit::get(); + Self::calculate_gas_info_impl( + source, + kind.clone(), + initial_gas, + payload.clone(), + value, + allow_other_panics, + b"calculate_gas_salt".to_vec(), + ) + })?; + + Self::run_with_ext_copy(|| { + Self::calculate_gas_info_impl( + source, + kind, + min_limit, + payload, + value, + allow_other_panics, + b"calculate_gas_salt".to_vec(), + ) + .map( + |GasInfo { + reserved, burned, .. + }| GasInfo { + min_limit, + reserved, + burned, + }, + ) + }) } - #[cfg(test)] - pub fn get_gas_spent( - source: H256, - kind: HandleKind, - payload: Vec, - value: u128, - ) -> Result> { - mock::run_with_ext_copy(|| Self::get_gas_spent_impl(source, kind, payload, value)) + pub fn run_with_ext_copy R>(f: F) -> R { + sp_externalities::with_externalities(|ext| { + ext.storage_start_transaction(); + }) + .expect("externalities should be set"); + + let result = f(); + + sp_externalities::with_externalities(|ext| { + ext.storage_rollback_transaction() + .expect("transaction was started"); + }) + .expect("externalities should be set"); + + result } - fn get_gas_spent_impl( + fn calculate_gas_info_impl( source: H256, kind: HandleKind, + initial_gas: u64, payload: Vec, value: u128, - ) -> Result> { + allow_other_panics: bool, + salt: Vec, + ) -> Result> { let account = ::from_origin(source); - let balance = ::Currency::total_balance(&account); - let max_balance: BalanceOf = u128::MAX.unique_saturated_into(); + let balance = ::Currency::free_balance(&account); + let max_balance: BalanceOf = + T::GasPrice::gas_price(initial_gas) + value.unique_saturated_into(); ::Currency::deposit_creating( &account, max_balance.saturating_sub(balance), ); let who = frame_support::dispatch::RawOrigin::Signed(account); - let initial_gas = ::BlockGasLimit::get(); let value: BalanceOf = value.unique_saturated_into(); QueueOf::::clear(); - match kind { + let main_program_id = match kind { HandleKind::Init(code) => { - let salt = b"gas_spent_salt".to_vec(); Self::submit_program(who.into(), code, salt, payload, initial_gas, value) - .map_err(|_| b"Internal error: submit_program failed".to_vec())?; + .map_err(|e| { + format!("Internal error: submit_program failed with '{:?}'", e) + .into_bytes() + })?; + + QueueOf::::iter() + .next() + .ok_or_else(|| b"Internal error: failed to get last message".to_vec()) + .and_then(|queued| { + queued + .map_err(|_| { + b"Internal error: failed to retrieve queued dispatch".to_vec() + }) + .map(|dispatch| dispatch.destination()) + })? } - HandleKind::Handle(dest) => { - let destination = ProgramId::from_origin(dest); + HandleKind::Handle(destination) => { Self::send_message(who.into(), destination, payload, initial_gas, value) - .map_err(|_| b"Internal error: send_message failed".to_vec())?; + .map_err(|e| { + format!("Internal error: send_message failed with '{:?}'", e) + .into_bytes() + })?; + + destination } - HandleKind::Reply(msg_id, _exit_code) => { - let reply_to_id = MessageId::from_origin(msg_id); + HandleKind::Reply(reply_to_id, _exit_code) => { Self::send_reply(who.into(), reply_to_id, payload, initial_gas, value) - .map_err(|_| b"Internal error: send_reply failed".to_vec())?; + .map_err(|e| { + format!("Internal error: send_reply failed with '{:?}'", e).into_bytes() + })?; + + QueueOf::::iter() + .next() + .ok_or_else(|| b"Internal error: failed to get last message".to_vec()) + .and_then(|queued| { + queued + .map_err(|_| { + b"Internal error: failed to retrieve queued dispatch".to_vec() + }) + .map(|dispatch| dispatch.destination()) + })? } - } + }; let block_info = BlockInfo { height: >::block_number().unique_saturated_into(), @@ -562,7 +647,9 @@ pub mod pallet { let existential_deposit = ::Currency::minimum_balance().unique_saturated_into(); - let mut max_gas_spent = 0; + let mut min_limit = 0; + let mut reserved = 0; + let mut burned = 0; let schedule = T::Schedule::get(); let mut ext_manager = ExtManager::::default(); @@ -641,25 +728,47 @@ pub mod pallet { }) .transpose()? { - max_gas_spent = - max_gas_spent.max(initial_gas.saturating_sub(remaining_gas)); + min_limit = min_limit.max(initial_gas.saturating_sub(remaining_gas)); } - if let JournalNote::MessageDispatched { - outcome: CoreDispatchOutcome::MessageTrap { trap, .. }, - .. - } = note - { - return Err(format!( - "Program terminated with a trap: {}", - trap.unwrap_or_else(|| "No reason".to_string()) - ) - .into_bytes()); + match note { + JournalNote::SendDispatch { dispatch, .. } => { + let gas_limit = dispatch.gas_limit().unwrap_or(0); + if ext_manager.check_user_id(&dispatch.destination()) && gas_limit > 0 { + return Err( + b"Message sent to user with non zero gas limit".to_vec() + ); + } + + // TODO change calculation of the field #1074 + reserved = reserved.saturating_add(gas_limit); + } + + JournalNote::GasBurned { amount, .. } => { + burned = burned.saturating_add(amount); + } + + JournalNote::MessageDispatched { + outcome: CoreDispatchOutcome::MessageTrap { trap, program_id }, + .. + } if program_id == main_program_id || !allow_other_panics => { + return Err(format!( + "Program terminated with a trap: {}", + trap.unwrap_or_else(|| "No reason".to_string()) + ) + .into_bytes()); + } + + _ => (), } } } - Ok(max_gas_spent) + Ok(GasInfo { + min_limit, + reserved, + burned, + }) } /// Returns true if a program has been successfully initialized diff --git a/pallets/gear/src/manager.rs b/pallets/gear/src/manager.rs index 99cd836bb5b..2f9e7875fdb 100644 --- a/pallets/gear/src/manager.rs +++ b/pallets/gear/src/manager.rs @@ -64,7 +64,6 @@ use gear_core::{ program::Program as NativeProgram, }; use pallet_gas::Pallet as GasPallet; -use primitive_types::H256; use sp_runtime::{ traits::{UniqueSaturatedInto, Zero}, SaturatedConversion, @@ -79,11 +78,11 @@ use sp_std::{ // Tolerance towards rounding error when converting gas to balance etc. pub(crate) const TOL: u128 = 10; -#[derive(Decode, Encode)] +#[derive(Clone, Decode, Encode)] pub enum HandleKind { Init(Vec), - Handle(H256), - Reply(H256, ExitCode), + Handle(ProgramId), + Reply(MessageId, ExitCode), } /// Journal handler implementation for `pallet_gear`. diff --git a/pallets/gear/src/mock.rs b/pallets/gear/src/mock.rs index a76167cd175..d960d3832a2 100644 --- a/pallets/gear/src/mock.rs +++ b/pallets/gear/src/mock.rs @@ -17,34 +17,13 @@ // along with this program. If not, see . use crate as pallet_gear; -use crate::{ - ext::LazyPagesExt, - manager::{ExtManager, HandleKind}, - *, -}; -use alloc::format; -use common::{self, lazy_pages, Origin as _, ValueTree}; -use core_processor::{ - common::{DispatchOutcome, DispatchOutcome as CoreDispatchOutcome, JournalNote}, - configs::{AllocationsConfig, BlockInfo}, - Ext, -}; -use frame_support::{ - construct_runtime, - pallet_prelude::*, - parameter_types, - traits::{Currency, FindAuthor, Get}, -}; +use crate::*; +use frame_support::{construct_runtime, pallet_prelude::*, parameter_types, traits::FindAuthor}; use frame_system as system; -use gear_backend_sandbox::SandboxEnvironment; -use gear_core::{ - ids::ProgramId, - message::{Dispatch, DispatchKind, Message}, -}; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup, UniqueSaturatedInto}, + traits::{BlakeTwo256, IdentityLookup}, }; use sp_std::convert::{TryFrom, TryInto}; @@ -239,313 +218,3 @@ pub fn run_to_block(n: u64, remaining_weight: Option) { pub fn run_to_next_block(remaining_weight: Option) { run_to_block(System::block_number() + 1, remaining_weight); } - -pub fn calc_handle_gas_spent(source: H256, dest: ProgramId, payload: Vec) -> (u64, u64) { - let ext_manager: ExtManager = Default::default(); - - let initial_gas = ::BlockGasLimit::get(); - - let message = Message::new( - Default::default(), - ProgramId::from_origin(source), - dest, - payload, - Some(initial_gas), - 0, - None, - ); - - let lazy_pages_enabled = cfg!(feature = "lazy-pages") && lazy_pages::try_to_enable_lazy_pages(); - - let actor = ext_manager - .get_executable_actor(dest, !lazy_pages_enabled) - .expect("Can't find a program"); - - let dispatch = Dispatch::new(DispatchKind::Handle, message); - - let block_info = BlockInfo { - height: System::block_number() as u32, - timestamp: Timestamp::get(), - }; - - let schedule = ::Schedule::get(); - let allocations_config = AllocationsConfig { - max_pages: gear_core::memory::WasmPageNumber(schedule.limits.memory_pages), - init_cost: schedule.memory_weights.initial_cost, - alloc_cost: schedule.memory_weights.allocation_cost, - mem_grow_cost: schedule.memory_weights.grow_cost, - load_page_cost: schedule.memory_weights.load_cost, - }; - let existential_deposit = - ::Currency::minimum_balance().unique_saturated_into(); - - let journal = if lazy_pages_enabled { - core_processor::process::>( - Some(actor), - dispatch.into_stored().into_incoming(initial_gas), - block_info, - allocations_config, - existential_deposit, - ProgramId::from_origin(source), - dest, - u64::MAX, - ::OutgoingLimit::get(), - schedule.host_fn_weights.into_core(), - ["gr_gas_available"].into(), - ) - } else { - core_processor::process::>( - Some(actor), - dispatch.into_stored().into_incoming(initial_gas), - block_info, - allocations_config, - existential_deposit, - ProgramId::from_origin(source), - dest, - u64::MAX, - ::OutgoingLimit::get(), - schedule.host_fn_weights.into_core(), - ["gr_gas_available"].into(), - ) - }; - - let mut gas_burned: u64 = 0; - let mut gas_to_send: u64 = 0; - - for note in &journal { - match note { - JournalNote::GasBurned { amount, .. } => { - gas_burned = gas_burned.saturating_add(*amount); - } - JournalNote::SendDispatch { dispatch, .. } => { - gas_to_send = gas_to_send.saturating_add(dispatch.gas_limit().unwrap_or(0)); - } - JournalNote::MessageDispatched { - outcome: DispatchOutcome::MessageTrap { .. }, - .. - } => { - panic!("Program terminated with a trap"); - } - _ => (), - } - } - - (gas_burned, gas_to_send) -} - -pub fn run_with_ext_copy R>(f: F) -> R { - sp_externalities::with_externalities(|ext| { - ext.storage_start_transaction(); - }) - .expect("externalities should be set"); - - let result = f(); - - sp_externalities::with_externalities(|ext| { - ext.storage_rollback_transaction() - .expect("transaction was started"); - }) - .expect("externalities should be set"); - - result -} - -pub fn get_gas_burned( - source: H256, - kind: HandleKind, - payload: Vec, - gas_limit: Option, - value: u128, -) -> Result> -where - T: crate::Config, - T::AccountId: common::Origin, -{ - run_with_ext_copy(|| get_gas_burned_internal::(source, kind, payload, gas_limit, value)) -} - -fn get_gas_burned_internal( - source: H256, - kind: HandleKind, - payload: Vec, - gas_limit: Option, - value: u128, -) -> Result> -where - T: crate::Config, - T::AccountId: common::Origin, -{ - let schedule = T::Schedule::get(); - let mut ext_manager = ExtManager::::default(); - - let bn: u64 = >::block_number().unique_saturated_into(); - let root_message_id = MessageId::from(bn); - - let dispatch = match kind { - HandleKind::Init(ref code) => { - let program_id = ProgramId::generate(CodeId::generate(code), b"gas_spent_salt"); - - let schedule = T::Schedule::get(); - let code = Code::try_new( - code.clone(), - schedule.instruction_weights.version, - |module| schedule.rules(module), - ) - .map_err(|_| b"Code failed to load: {}".to_vec())?; - - let code_and_id = CodeAndId::new(code); - let code_id = code_and_id.code_id(); - - let _ = crate::Pallet::::set_code_with_metadata(code_and_id, source); - - ExtManager::::default().set_program(program_id, code_id, root_message_id); - - Dispatch::new( - DispatchKind::Init, - Message::new( - root_message_id, - ProgramId::from_origin(source), - program_id, - payload, - Some(u64::MAX), - value, - None, - ), - ) - } - HandleKind::Handle(dest) => Dispatch::new( - DispatchKind::Handle, - Message::new( - root_message_id, - ProgramId::from_origin(source), - ProgramId::from_origin(dest), - payload, - Some(u64::MAX), - value, - None, - ), - ), - HandleKind::Reply(msg_id, exit_code) => { - let msg = MailboxOf::::remove( - ::from_origin(source), - MessageId::from_origin(msg_id), - ) - .map_err(|_| b"Internal error: unable to find message in mailbox".to_vec())?; - Dispatch::new( - DispatchKind::Reply, - Message::new( - root_message_id, - ProgramId::from_origin(source), - msg.source(), - payload, - Some(u64::MAX), - value, - Some((msg.id(), exit_code)), - ), - ) - } - }; - - let initial_gas = gas_limit.unwrap_or_else(::BlockGasLimit::get); - T::GasHandler::create( - source.into_origin(), - root_message_id.into_origin(), - initial_gas, - ) - .map_err(|_| b"Internal error: unable to create gas handler".to_vec())?; - - let dispatch = dispatch.into_stored(); - - QueueOf::::clear(); - - QueueOf::::queue(dispatch).map_err(|_| b"Messages storage corrupted".to_vec())?; - - let block_info = BlockInfo { - height: >::block_number().unique_saturated_into(), - timestamp: >::get().unique_saturated_into(), - }; - - let existential_deposit = ::Currency::minimum_balance().unique_saturated_into(); - - let mut burned = 0; - - while let Some(queued_dispatch) = - QueueOf::::dequeue().map_err(|_| b"MQ storage corrupted".to_vec())? - { - let actor_id = queued_dispatch.destination(); - - let lazy_pages_enabled = - cfg!(feature = "lazy-pages") && lazy_pages::try_to_enable_lazy_pages(); - - let actor = ext_manager - .get_executable_actor(actor_id, !lazy_pages_enabled) - .ok_or_else(|| b"Program not found in the storage".to_vec())?; - - let allocations_config = AllocationsConfig { - max_pages: gear_core::memory::WasmPageNumber(schedule.limits.memory_pages), - init_cost: schedule.memory_weights.initial_cost, - alloc_cost: schedule.memory_weights.allocation_cost, - mem_grow_cost: schedule.memory_weights.grow_cost, - load_page_cost: schedule.memory_weights.load_cost, - }; - - let gas_limit = T::GasHandler::get_limit(queued_dispatch.id().into_origin()) - .ok() - .flatten() - .ok_or_else(|| b"Internal error: unable to get gas limit after execution".to_vec())?; - - let journal = if lazy_pages_enabled { - core_processor::process::>( - Some(actor), - queued_dispatch.into_incoming(gas_limit), - block_info, - allocations_config, - existential_deposit, - ProgramId::from_origin(source), - actor_id, - u64::MAX, - T::OutgoingLimit::get(), - schedule.host_fn_weights.clone().into_core(), - ["gr_gas_available"].into(), - ) - } else { - core_processor::process::>( - Some(actor), - queued_dispatch.into_incoming(gas_limit), - block_info, - allocations_config, - existential_deposit, - ProgramId::from_origin(source), - actor_id, - u64::MAX, - T::OutgoingLimit::get(), - schedule.host_fn_weights.clone().into_core(), - ["gr_gas_available"].into(), - ) - }; - - // TODO: Check whether we charge gas fee for submitting code after #646 - for note in &journal { - match note { - JournalNote::GasBurned { amount, .. } => { - burned += amount; - } - JournalNote::MessageDispatched { - outcome: CoreDispatchOutcome::MessageTrap { trap, .. }, - .. - } => { - return Err(format!( - "Program terminated with a trap: {}", - trap.clone().unwrap_or_else(|| "No reason".to_string()) - ) - .into_bytes()); - } - _ => {} - } - } - - core_processor::handle_journal(journal, &mut ext_manager); - } - - Ok(burned) -} diff --git a/pallets/gear/src/tests.rs b/pallets/gear/src/tests.rs index c75956d120d..3a35e264c00 100644 --- a/pallets/gear/src/tests.rs +++ b/pallets/gear/src/tests.rs @@ -19,11 +19,11 @@ use crate::{ manager::HandleKind, mock::{ - calc_handle_gas_spent, get_gas_burned, new_test_ext, run_to_block, run_to_next_block, - Event as MockEvent, Gear, GearProgram, Origin, System, Test, BLOCK_AUTHOR, - LOW_BALANCE_USER, USER_1, USER_2, USER_3, + new_test_ext, run_to_block, run_to_next_block, Event as MockEvent, Gear, GearProgram, + Origin, System, Test, BLOCK_AUTHOR, LOW_BALANCE_USER, USER_1, USER_2, USER_3, }, - pallet, Config, Error, Event, GearProgramPallet, MailboxOf, Pallet as GearPallet, WaitlistOf, + pallet, Config, Error, Event, GasInfo, GearProgramPallet, MailboxOf, Pallet as GearPallet, + WaitlistOf, }; use codec::{Decode, Encode}; use common::{event::*, storage::*, CodeStorage, GasPrice as _, Origin as _, ValueTree}; @@ -62,8 +62,17 @@ fn unstoppable_block_execution_works() { run_to_block(2, None); - let (expected_burned_gas, _) = - calc_handle_gas_spent(USER_1.into_origin(), program_id, EMPTY_PAYLOAD.to_vec()); + let GasInfo { + burned: expected_burned_gas, + .. + } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(program_id), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + ) + .expect("calculate_gas_info failed"); assert!(balance_for_each_execution > expected_burned_gas); @@ -801,7 +810,9 @@ fn lazy_pages() { }); } +// TODO: ignored until #642 implemented #[test] +#[ignore] fn block_gas_limit_works() { // Same as `ProgramCodeKind::OutgoingWithValueInHandle`, but without value sending let wat1 = r#" @@ -883,10 +894,28 @@ fn block_gas_limit_works() { assert_last_dequeued(2); // Count gas needed to process programs with default payload - let (expected_gas_msg_to_pid1, _) = - calc_handle_gas_spent(USER_1.into_origin(), pid1, EMPTY_PAYLOAD.to_vec()); - let (expected_gas_msg_to_pid2, _) = - calc_handle_gas_spent(USER_1.into_origin(), pid2, EMPTY_PAYLOAD.to_vec()); + let GasInfo { + burned: expected_gas_msg_to_pid1, + .. + } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(pid1), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + ) + .expect("calculate_gas_info failed"); + let GasInfo { + burned: expected_gas_msg_to_pid2, + .. + } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(pid2), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + ) + .expect("calculate_gas_info failed"); // TrapInHandle code kind is used because processing default payload in its // context requires such an amount of gas, that the following assertion can be passed. @@ -1387,7 +1416,9 @@ fn send_reply_value_claiming_works() { // prog send to user 1 msg to mailbox // user 1 claims it from mailbox +// TODO: ignored until #642 implemented #[test] +#[ignore] fn claim_value_from_mailbox_works() { init_logger(); new_test_ext().execute_with(|| { @@ -1406,8 +1437,16 @@ fn claim_value_from_mailbox_works() { let reply_to_id = populate_mailbox_from_program(prog_id, USER_2, 2, gas_sent, value_sent); assert!(!MailboxOf::::is_empty(&USER_1)); - let (gas_burned, _) = - calc_handle_gas_spent(USER_1.into_origin(), prog_id, EMPTY_PAYLOAD.to_vec()); + let GasInfo { + burned: gas_burned, .. + } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(prog_id), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + ) + .expect("calculate_gas_info failed"); let gas_burned = GasPrice::gas_price(gas_burned); run_to_block(3, None); @@ -2474,8 +2513,17 @@ fn no_redundant_gas_value_after_exiting() { run_to_block(2, None); - let (gas_spent, _) = - calc_handle_gas_spent(USER_1.into_origin(), prog_id, EMPTY_PAYLOAD.to_vec()); + let GasInfo { + min_limit: gas_spent, + .. + } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(prog_id), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + ) + .expect("calculate_gas_info failed"); assert_ok!(GearPallet::::send_message( Origin::signed(USER_1), prog_id, @@ -2887,15 +2935,19 @@ fn gas_spent_vs_balance() { let balance_after_handle = BalancesPallet::::free_balance(USER_1); let total_balance_after_handle = BalancesPallet::::total_balance(&USER_1); - let init_gas_spent = Gear::get_gas_spent( + let GasInfo { + min_limit: init_gas_spent, + .. + } = Gear::calculate_gas_info( USER_1.into_origin(), HandleKind::Init(WASM_BINARY.to_vec()), EMPTY_PAYLOAD.to_vec(), 0, + true, ) .unwrap_or_else(|e| panic!("{}", String::from_utf8(e).expect("Unable to form string"))); - // check that all changes made by get_gas_spent are rollbacked + // check that all changes made by calculate_gas_info are rollbacked assert_eq!( balance_after_handle, BalancesPallet::::free_balance(USER_1) @@ -2912,11 +2964,15 @@ fn gas_spent_vs_balance() { run_to_block(4, None); - let handle_gas_spent = Gear::get_gas_spent( + let GasInfo { + min_limit: handle_gas_spent, + .. + } = Gear::calculate_gas_info( USER_1.into_origin(), - HandleKind::Handle(prog_id.into_origin()), + HandleKind::Handle(prog_id), request, 0, + true, ) .unwrap_or_else(|e| panic!("{}", String::from_utf8(e).expect("Unable to form string"))); @@ -2930,9 +2986,9 @@ fn gas_spent_vs_balance() { #[test] fn gas_spent_precalculated() { let wat = r#" - (module - (import "env" "memory" (memory 0)) - (export "handle" (func $handle)) + (module + (import "env" "memory" (memory 0)) + (export "handle" (func $handle)) (func $add (; 0 ;) (param $0 i32) (param $1 i32) (local $2 i32) get_local $0 @@ -2945,8 +3001,8 @@ fn gas_spent_precalculated() { (i32.const 2) (i32.const 2) ) - ) - )"#; + ) + )"#; init_logger(); new_test_ext().execute_with(|| { @@ -2955,11 +3011,15 @@ fn gas_spent_precalculated() { run_to_block(2, None); - let gas_spent_1 = Gear::get_gas_spent( + let GasInfo { + min_limit: gas_spent_1, + .. + } = Gear::calculate_gas_info( USER_1.into_origin(), - HandleKind::Handle(prog_id.into_origin()), + HandleKind::Handle(prog_id), EMPTY_PAYLOAD.to_vec(), 0, + true, ) .unwrap_or_else(|e| panic!("{}", String::from_utf8(e).expect("Unable to form string"))); @@ -2981,8 +3041,17 @@ fn gas_spent_precalculated() { assert_eq!(gas_spent_1, total_cost as u64); - let (gas_spent_2, _) = - calc_handle_gas_spent(USER_1.into_origin(), prog_id, EMPTY_PAYLOAD.to_vec()); + let GasInfo { + min_limit: gas_spent_2, + .. + } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(prog_id), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + ) + .expect("calculate_gas_info failed"); assert_eq!(gas_spent_1, gas_spent_2); }); @@ -3378,24 +3447,23 @@ fn cascading_messages_with_value_do_not_overcharge() { let user_balance_before_calculating = BalancesPallet::::free_balance(USER_1); - let gas_reserved = Gear::get_gas_spent( - USER_1.into_origin(), - HandleKind::Handle(wrapper_id.into_origin()), - payload.clone(), - 0, - ) - .expect("Failed to get gas spent"); - run_to_block(3, None); - let gas_to_spend = get_gas_burned::( + // The constant added for checks. + let value = 10_000_000; + + let GasInfo { + min_limit: gas_reserved, + burned: gas_to_spend, + .. + } = Gear::calculate_gas_info( USER_1.into_origin(), - HandleKind::Handle(wrapper_id.into_origin()), + HandleKind::Handle(wrapper_id), payload.clone(), - Some(gas_reserved), - 0, + value, + true, ) - .expect("Failed to get gas burned"); + .expect("Failed to get gas spent"); assert!(gas_reserved >= gas_to_spend); @@ -3415,9 +3483,6 @@ fn cascading_messages_with_value_do_not_overcharge() { assert_eq!(user_balance_before_calculating, user_initial_balance); assert_eq!(BalancesPallet::::reserved_balance(USER_1), 0); - // The constant added for checks. - let value = 10_000_000; - assert_ok!(Gear::send_message( Origin::signed(USER_1), wrapper_id, @@ -3426,8 +3491,8 @@ fn cascading_messages_with_value_do_not_overcharge() { value, )); - let gas_to_spend = gas_to_spend as u128; - let gas_reserved = gas_reserved as u128; + let gas_to_spend = GasPrice::gas_price(gas_to_spend); + let gas_reserved = GasPrice::gas_price(gas_reserved); let reserved_balance = gas_reserved + value; assert_eq!( @@ -3471,11 +3536,12 @@ fn call_forbidden_function() { run_to_block(2, None); - let res = Gear::get_gas_spent( + let res = Gear::calculate_gas_info( USER_1.into_origin(), - HandleKind::Handle(prog_id.into_origin()), + HandleKind::Handle(prog_id), EMPTY_PAYLOAD.to_vec(), 0, + true, ) .map_err(|e| String::from_utf8(e).unwrap()); diff --git a/pallets/usage/src/offchain.rs b/pallets/usage/src/offchain.rs index 5103ceb0591..7241e5b6198 100644 --- a/pallets/usage/src/offchain.rs +++ b/pallets/usage/src/offchain.rs @@ -122,7 +122,7 @@ impl core::fmt::Debug for PayeeInfo { } } -#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug, scale_info::TypeInfo)] +#[derive(Encode, Decode, Default, Clone, Eq, PartialEq, RuntimeDebug, scale_info::TypeInfo)] pub struct WaitListInvoiceData { pub program_id: H256, pub message_id: H256, diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 43eec30225f..5ebc5d58485 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -123,7 +123,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // The version of the runtime specification. A full node will not attempt to use its native // runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, // `spec_version`, and `authoring_version` are the same between Wasm and native. - spec_version: 1110, + spec_version: 1120, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -666,13 +666,14 @@ impl_runtime_apis! { // Here we implement our custom runtime API. impl pallet_gear_rpc_runtime_api::GearApi for Runtime { - fn get_gas_spent( + fn calculate_gas_info( account_id: H256, kind: HandleKind, payload: Vec, value: u128, - ) -> Result> { - Gear::get_gas_spent(account_id, kind, payload, value) + allow_other_panics: bool, + ) -> Result> { + Gear::calculate_gas_info(account_id, kind, payload, value, allow_other_panics) } } diff --git a/scripts/calc-gas-spent.sh b/scripts/calc-gas-spent.sh index 294cd7b8ac1..7a770dd45ee 100755 --- a/scripts/calc-gas-spent.sh +++ b/scripts/calc-gas-spent.sh @@ -17,18 +17,23 @@ PROG_ID="$ALICE" # Replace it by the real program ID MSG_ID="$ALICE" # Replace it by the real message ID PAYLOAD="0x50494e47" # "PING" +VALUE_INIT=0 +VALUE_HANDLE=0 +VALUE_REPLY=0 + set -e echo "Init message:" curl http://localhost:9933 -H "Content-Type:application/json;charset=utf-8" -d "{ \"jsonrpc\":\"2.0\", \"id\":1, - \"method\":\"gear_getInitGasSpent\", + \"method\":\"gear_calculateInitGas\", \"params\": [ \"$ALICE\", \"0x0061736d01000000017a1260037f7f7f017f60027f7f017f6000017f60037f7f7f0060057f7f7e7f7f0060027f7f0060017f017f60017f0060000060057f7f7f7f7f0060027e7f017f60057f7f7f7f7f017f60047f7f7f7f0060017f017e60047f7f7f7f017f60077f7f7f7f7f7f7f017f60067f7f7f7f7f7f0060077f7f7f7f7f7f7f0002600703656e76066d656d6f727902001103656e760767725f73697a65000203656e760767725f72656164000303656e760867725f7265706c79000403656e760867725f6465627567000503656e7605616c6c6f63000603656e760466726565000703717007070808080103080907010501080a0b03010706070c0705080805080808080309000700010501010b01010101030107070d0e03000101030009010103010f01010001010000010101010101010101010110070707000101070001010707070607010507050000010105070111010000040501700131310609017f01418080c0000b0711020668616e646c65000804696e697400130936010041010b3010123c3b346e3271736d4041062d28302f55292a2c36373e45464c4748494d4e53504f545251565a5b5c5d595e5f60610ab5e901700600200010070bca0101037f02400240024020002802004100200028020422011b2200450d002001450d00100a0240200041c0aac000490d00200041f0abc0004d0d020b2000417c6a2802004110490d02200041786a1019101a100a0b0f0b200041c0aac0006b2102417f2100410021010240034020004104460d01200041016a21002001411c712103200141046a21014190843a20037641037441f800712002470d000b200041044b0d00410041002d00f0ab40417e200041077177713a00f0ab400f0b41e40f1018000b41ec0f1018000bad0a010a7f230041c0006b2200240002400240024002400240024002400240024002400240100022014100480d0020010d01410121020c020b1009000b100a20014101100b2202450d0120024100200110751a0b024010002001470d0041002001200210012001450d084100200141796a2203200320014b1b2104200241036a417c7120026b2105410021030340024002400240200220036a2d0000220641187441187522074100480d002005417f460d01200520036b4103710d010240200320044f0d000340200220036a2206280200200641046a28020072418081828478710d01200341086a22032004490d000b0b200320014f0d020340200220036a2c00004100480d032001200341016a2203470d000c0c0b0b41800221084101210902400240024002400240200641b789c0006a2d0000417e6a0e030002010e0b200341016a22062001490d02410021080c0c0b41002108200341016a220920014f0d0b200220096a2d000021090240024002400240200641907e6a0e050100000002000b2007410f6a41ff017141024b0d0c2009411874411875417f4a0d0c200941ff017141c0014f0d0c0c020b200941f0006a41ff017141304f0d0b0c010b2009411874411875417f4a0d0a200941ff0171418f014b0d0a0b200341026a220620014f0d0b200220066a2c000041bf7f4a0d0841002109200341036a220620014f0d0c200220066a2c000041bf7f4c0d0241800621080c0a0b41002108200341016a220920014f0d0a200220096a2d000021090240024002400240200641e001460d00200641ed01460d012007411f6a41ff0171410c490d022007417e71416e470d0c2009411874411875417f4a0d0c200941ff017141c0014f0d0c0c030b200941e0017141a001470d0b0c020b2009411874411875417f4a0d0a200941ff017141a0014f0d0a0c010b2009411874411875417f4a0d09200941ff017141bf014b0d090b41002109200341026a220620014f0d0b200220066a2c000041bf7f4a0d070c010b418002210841012109200220066a2c000041bf7f4a0d0a0b200641016a21030c010b200341016a21030b20032001490d000c080b0b41d7a5c000413241dca6c000100c000b100d000b41800421080c010b41800221080b410121090c010b410021090b200041206a20092008723602002000200336021c200020013602182000200136021420002002360210418080c000410f200041106a41e080c00041a080c000100e000b20014104470d00200228000041d092b9ba04470d00200041286a4200370300200041206a4200370300200041186a420037030020004200370310200042003703382000420037033041b080c00041044280b6dc05200041306a200041106a10020b024041002802b0aa40220341002802acaa40470d002003100f41002802b0aa4021030b41002802a8aa402003410c6c6a2206200136020820062001360204200620023602004100200341016a22033602b0aa40200041246a410136020020004202370214200041d080c0003602102000410136020c200020033602042000200041086a3602202000200041046a360208200041306a200041106a1011200028023020002802381003200041306a1007024041002802b0aa402202450d0041002802a8aa4021032002410c6c21020340200020033602042000410136022420004201370214200041eca6c0003602102000410236020c2000200041086a3602202000200041046a360208200041306a200041106a10112000280230200028023810032003410c6a2103200041306a1007200241746a22020d000b0b200041c0006a24000b3f01017f230041206b220024002000411c6a4100360200200041eca6c0003602182000420137020c200041a081c000360208200041086a41a881c0001020000b9f0801077f41002100034041002802f4ab40410120007471210102400240200041037422024188acc0006a2802002203200241fcabc0006a2204460d002001450d0103402003106202400240024002400240024002400240200328020422014103714101470d002003200141787122024104726a28020022054101710d01200320026a22062802002002470d022005410271450d030240410028028caf402003460d004100280290af402003460d0002402002410f4b0d0020024108460d0141a7111018000b0240200328020c2802082003470d00200328020828020c2003460d0141a5111018000b41a4111018000b20014103762000470d040240200328020c22022004460d00200228020420017341074b0d060b20054107470d060c070b419d111018000b419e111018000b419f111018000b41a0111018000b41f5111018000b41f6111018000b20061063200328020c21020b2002210320022004470d000c020b0b2001450d0041ef111018000b200041016a22004120470d000b41002802f8ab4021054184aec000210241002103024002400240024002400240024002400340200541012003747121010240200228020022040d0020010d020b200341016a210302402001450d002004106441002802f8ab4021050b200241046a210220034120470d000b02404100280284af40450d00410028028caf4010624100280284af402202410028028caf4022012802042203417871470d0220024110490d032003410171450d0420034102710d05200110650d060b4100280290af402203450d07200310664100280288af40450d064100280290af401065450d0741c1111018000b418b121018000b41b8111018000b41b9111018000b41ba111018000b41bb111018000b41bc111018000b41c0111018000b02400240024002400240024002404100280294af402200450d00034002402000280204200028020022036a41686a220620034d0d00410028028caf4021044100280290af4021050340024020032005460d0020032004460d0002400240024020052003490d002005200320032802044178716a490d010b200328020422014178712102024020042003490d002004200320026a490d020b20014102710d0220024108460d02024020031065450d00410028028caf4021044100280290af4021050c030b41cd111018000b41cb111018000b41cc111018000b2003280204220241027121010240200241988008490d002001450d050b024020024101710d00200320032802006b41046a2d00004102710d060b2001410047200320024178716a22032802042202410171730d062001200241027172450d07200620034b0d000b0b20062003470d0620032802044178714110470d07200028020822000d000b0b0f0b41d3111018000b41d7111018000b41d9111018000b41da111018000b41de111018000b41df111018000bde1001087f024002400240024002400240024002400240024002400240024002402001450d004100280294af400d00200041c1004f0d004100210241002d00f0ab40210341002101034002404101200141ff017174220420037141ff01710d004191cc2120027641037441f800712000490d00200141044b0d02410020032004723a00f0ab404190843a20027641037441f8007141c0aac0006a21010c030b200241046a2102200141016a22014105470d000b0b0240024002400240024002400240024041102000410b6a4178712000410d491b220241ff014b0d0002400240024041002802f4ab40200241037622037622014103710d004100280284af4020024f0d0a20010d0141002802f8ab402201450d0a2001684102744184aec0006a280200220428020441787120026b21032004210103402001106220014110411420012802101b6a2802002201450d03200128020441787120026b22052003200520034922051b21032001200420051b21040c000b0b2001417f7341017120036a220141214f0d042001410374220241fcabc0006a2001106722042002410372360204200420026a41046a220120012802004101723602000c0b0b2001200374682203410374220141fcabc0006a200310672104200120026b2203450d0420042002410372360204200420026a22022003410172360204200420016a200336020020034110490d0a2002200310680c0a0b2004280204417871200320026a470d0120041069024020034108490d0020042002410372360204200420026a22012003410172360204200120034178716a20033602002003410f4d0d0a2001200310680c0a0b024020030d0020042002410372360204200420024104726a220120012802004101723602000c0a0b41c40a1018000b41002802f8ab402206450d06411f210702400240200241ffffff074b0d002002410620024108766722016b7641017120014101746b413e6a220741204f0d010b410020026b210320074102744184aec0006a2802002201450d044100210520024100411920074101766b411f712007411f461b7421084100210403400240200128020441787122092002490d00200920026b220920034f0d00200921032001210420090d0041002103200121040c070b200141146a28020022092005200920012008411d764104716a41106a2802002201471b200520091b21052008410174210820010d000b02402005450d00200521010c060b2004450d040c060b41ba0b1018000b41bf0a1018000b41b30b1018000b20042001410372360204200420014104726a220120012802004101723602000c050b417e2007742006712201450d02410021042001684102744184aec0006a2802002201450d020b0340200120042001280204417871220520024f200520026b22052003497122081b21042005200320081b210320014110411420012802101b6a28020022010d000b2004450d010b02404100280284af4022012002490d002003200120026b4f0d010b02402004280204417871200320026a470d0020041069024020034108490d0020042002410372360204200420026a22012003410172360204200120034178716a20033602002003410f4d0d0420012003101d0c040b024020030d0020042002410372360204200420024104726a220120012802004101723602000c040b41960b1018000b41930b1018000b0240024002404100280284af4020024f0d004100280288af402002490d024100280290af402204200420024101101b4100280290af4010660c010b410028028caf402204200420024101101b0b20040d020b100a410021012002419f80046a220441107610042203417f4622080d0020034110742205450d00410020044180807c7120081b21084100280298af40220145200120054b7221014100280294af40450d0202402001450d0041002005360298af400b20052008106a4100280294af402204450d0b200428020020042802046a2005460d04200421010c030b20010f0b200441046a28020021012004106220041063200141787122014110490d052001200041046a490d06100a200441086a0f0b02402001450d0041002005360298af400b20052008106a41002101034020014184acc0006a200141fcabc0006a220336020020014188acc0006a2003360200200141086a2201418002470d000b4100280290af4010664100280290af40220121050c090b02400340200122032802082201450d01200128020020012802046a2005460d030c000b0b200521090c060b200421012004210320042802082004460d0141aa061018000b200128020821040b200320043602084100280294af402203450d022001280200200141046a2802002003106b21094100280294af4021040c030b418b111018000b418c111018000b41aca5c000412b419ca5c000100c000b024002402004450d00200520086a210320042101034020012802002003460d02200128020822010d000b0b200921050c010b200428020821032004280200200441046a2802002001106b210541002003360294af400b4100280290af4021010b024020010d0041002103024002404100280288af400d004100280294af402201450d01410028028caf402108410021004100210903402001280200210320012802042104200128020821010240200420036a2203416c6a2d00004101710d002008200341686a220320032802006b2203460d00200328020441787122044110490d00200420094d0d0041002004360288af4041002003360290af4020032100200421090b20010d000b024020000d00410021030c020b2000101c4100280290af4021030c010b41c8061018000b200310660b024002400240200528020441787122012002490d00200120024b0d010c020b41e3061018000b2005200520024100101b200520052802044178716a101a0b200541086a0b4701017f230041206b22032400200341146a4100360200200341eca6c000360210200342013702042003200136021c200320003602182003200341186a360200200320021020000b05001021000b7e01017f230041c0006b220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41033602002005420237021c200541e083c000360218200541043602342005200541306a3602282005200541106a3602382005200541086a360230200541186a20041020000ba30102037f017e230041106b220124000240200041016a22022000490d00200141002802acaa40220041017422032002200320024b1b22024104200241044b1b2202ad420c7e2204a72004422088a74541027441002802a8aa40410020001b2000410c6c41041057024020012802004101470d00200141086a280200450d01100d000b410020023602acaa40410020012802043602a8aa40200141106a24000f0b1009000bc20201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d0120003502002001101421000c040b20002802002100410021030340200220036a41ff006a413041d7002000410f712204410a491b20046a3a00002003417f6a21032000410f4b21042000410476210020040d000b20034180016a22004181014f0d01200141a485c0004102200220036a4180016a410020036b101521000c030b20002802002100410021030340200220036a41ff006a413041372000410f712204410a491b20046a3a00002003417f6a21032000410f4b21042000410476210020040d000b20034180016a22004181014f0d01200141a485c0004102200220036a4180016a410020036b101521000c020b2000418001419485c0001016000b2000418001419485c0001016000b20024180016a240020000b880401097f230041206b22022400200141146a28020021032001280200210402400240200141046a280200220541037422060d00410021070c010b200641786a220641037641016a2208410771210902400240200641384f0d0041002107200421080c010b2004413c6a2106410021074100200841f8ffffff03716b210803402006280200200641786a280200200641706a280200200641686a280200200641606a280200200641586a280200200641506a280200200641486a28020020076a6a6a6a6a6a6a6a2107200641c0006a2106200841086a22080d000b200641446a21080b2009450d00410020096b2106200841046a21080340200828020020076a2107200641016a220920064f210a20092106200841086a2108200a0d000b0b024002400240024020030d00200721060c010b02402005450d0020042802040d0020074110490d020b200720076a22062007490d010b0240024020064100480d002006450d02100a20064101100b2207450d010c030b1009000b100d000b41012107410021060b20004100360208200020063602042000200736020020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a290200370300200220012902003703080240200241046a41e082c000200241086a10270d00200241206a24000f0b41b881c0004133200241086a41d082c000418482c000100e000b15002000280200220028020020002802082001104b0b02000bd20203027f017e037f230041306b22022400412721030240024020004290ce005a0d00200021040c010b412721030340200241096a20036a2205417c6a20004290ce0080220442f0b17f7e20007ca7220641ffff037141e4006e220741017441a685c0006a2f00003b00002005417e6a2007419c7f6c20066a41ffff037141017441a685c0006a2f00003b00002003417c6a2103200042ffc1d72f5621052004210020050d000b0b02402004a7220541e3004c0d00200241096a2003417e6a22036a2004a7220641ffff037141e4006e2205419c7f6c20066a41ffff037141017441a685c0006a2f00003b00000b024002402005410a480d00200241096a2003417e6a22036a200541017441a685c0006a2f00003b00000c010b200241096a2003417f6a22036a200541306a3a00000b200141eca6c0004100200241096a20036a412720036b10152103200241306a240020030b820501077f20002802002205410171220620046a21070240024020054104710d00410021010c010b0240024020020d00410021080c010b0240200241037122090d000c010b410021082001210a03402008200a2c000041bf7f4a6a2108200a41016a210a2009417f6a22090d000b0b200820076a21070b412b418080c40020061b21060240024020002802084101460d004101210a200020062001200210380d012000280218200320042000411c6a28020028020c1100000f0b024002400240024002402000410c6a280200220820074d0d0020054108710d044100210a200820076b22092105410120002d0020220820084103461b4103710e03030102030b4101210a200020062001200210380d042000280218200320042000411c6a28020028020c1100000f0b410021052009210a0c010b2009410176210a200941016a41017621050b200a41016a210a2000411c6a2802002109200028020421082000280218210702400340200a417f6a220a450d01200720082009280210110100450d000b41010f0b4101210a2008418080c400460d01200020062001200210380d01200720032004200928020c1100000d014100210a0240034002402005200a470d002005210a0c020b200a41016a210a200720082009280210110100450d000b200a417f6a210a0b200a200549210a0c010b200028020421052000413036020420002d0020210b4101210a200041013a0020200020062001200210380d00200820076b41016a210a2000411c6a28020021082000280218210902400340200a417f6a220a450d01200941302008280210110100450d000b41010f0b4101210a200920032004200828020c1100000d002000200b3a00202000200536020441000f0b200a0b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41053602002003420237020c200341b088c000360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a20021020000be005010a7f100a02400240024002400240024002400240024002400240200041c0aac000490d00200041f0abc0004d0d010b2000417c6a22022802002203410271450d014100280290af402204200041786a2205460d02410028028caf4022062005460d022003417871220741102001410b6a4178712001410d491b2208470d0320000f0b200041c0aac0006b2103417f210541002108034020054104460d06200541016a21052008411c712107200841046a21084190843a20077641037441f800712003470d000b200541054f0d054191cc2120077641037441f8007122082001490d0320000f0b41a9071018000b41aa071018000b024002400240200720084b0d00410021094100200520074104726a280200220a417871220b200a410271220a1b20076a20084f0d0120014100100b2208450d042008417c6a280200417871417c6a2007417c6a2207490d022008200020071074210820051019101a100a20080f0b2005200520084100101b0240200520022802004178716a22052d00044102710d00200510191a2005101a20000f0b41b2071018000b200a0d042004200520076a2201460d0620062001470d050c060b41f7071018000b410041002d00f0ab40417e200541077177713a00f0ab4020014101100b22092000200810741a0b20090f0b418d041018000b41b9071018000b2001101c0b02400240200720086b200b6a2207450d002001200128020441787120076b6a22092007410172360204200920076a20073602000240200920092802044178716a41046a2d00004101710d0020074110490d010c020b41d2071018000b41002109410021070b200341017121030240024002404100280290af402001460d00410028028caf402001460d012007410f4d0d0220092007101d0c020b41002007360288af4041002009360290af400c010b41002007360284af404100200936028caf400b20022008200372410272360200200520084104726a22052005280200410172360200100a20000b5401017f230041306b220124002001200036020c200141246a41013602002001420137021420014180a3c0003602102001410536022c2001200141286a36022020012001410c6a360228200141106a1058100d000beb0301037f0240024002400240200028020422014108490d0020014101710d03200020002802006b22002802042202410171450d012001417871210320024178712101024002404100280290af402000460d00410028028caf402000460d012000101c0c040b41004100280288af4020036a360288af400c030b41004100280284af4020036a360284af400c020b41ad0d1018000b41b40d1018000b2000200120036a41017222013602040b02400240200020014178716a22032d0004410271450d0020002001417d7136020420032003280204417e71360204200028020441787121010c010b0240024002400240024020004100280290af402201460d000240024020012003460d00410028028caf402003460d012003101c2000200328020441787120002802044178716a220141017222033602042000410028028caf40470d0641002001360284af400c060b41002000360290af4041004100280288af4020002802044178716a2203360288af402000410028028caf40460d020c030b4100200036028caf4041004100280284af4020002802044178716a2203360284af40200341017221030c030b41d20d1018000b41004100360284af404100410036028caf400b200341017221030b200020033602040b2000200341787122016a21030b2003200136020020000bb407010b7f024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802042201410171450d002000200141787122026a220341046a2d0000410271450d012002450d0202400240200241186a41808004490d004100210402404100280294af402201450d00200041046a21050340024020012201280200220620004b0d002006200128020422076a220820004b0d040b20012104200128020822010d000b0b41990e1018000b4100280290af402000460d08410028028caf402000460d08200241104f0d070c080b200720024d0d03200320084f0d0402402006410771450d00419f0e1018000b200741ffff0371450d0541a00e1018000b41ff0d1018000b41800e1018000b41830e1018000b419a0e1018000b419e0e1018000b0240024020062000470d0041002109200021070c010b200020066b4110490d06200620052006417f736a419880046a4180807c7122096a21070b02400240200820036b220541184b0d0020054118470d094100210a200821050c010b20054128490d072008200541ffff036a4180807c71220a6b21050b024020054180807c6a2007490d00200520076b220241ffff03710d0320090d042007210b0c050b4100280290af402000460d01410028028caf402000460d010b20002002101d0b0f0b41d40e1018000b200741686a220b20006b4108490d04200241186a21020b0240200a0d0020052008470d05200841686a2003470d06200241686a21020b2000200b20024101101b410021034100210202402009450d00200b28020441017121020b0240200a450d002001417c6a28020041017121030b200741ffff03710d062001280208210b0240200741107622002005411076200541ffff0371456b22084b0d00034020001005200020084f0d01200020002008496a220020084d0d000b0b0240024020090d00200421000c010b200620092002106c2100024002402004450d00200441086a21060c010b4194afc000210620014100280294af40470d090b200620003602000b0240200a450d002005200a2003106c210602402000450d00200041086a21000c0b0b4194afc000210020014100280294af40460d0a41a40f1018000b20000d0a20014100280294af40470d080240200b450d004100200b360294af400f0b41004100360294af400f0b41ac0e1018000b41c20e1018000b41c70e1018000b41e10e1018000b41ea0e1018000b41eb0e1018000b411a1018000b41910f1018000b41ad0f1018000b20002006360200200621000b2000200b3602080b8e0501047f02400240024002400240024002400240024020024107710d0020024110490d0120014107710d0220012000490d0320002000280204220441787122056a200120026a2206490d042004410171210720012000460d08200120006b22044108490d06200020072004722207360204200520046b21054100280290af402000460d05410028028caf402000470d0741002005360284af404100200136028caf400c070b41a9081018000b41aa081018000b41ab081018000b41ac081018000b41b1081018000b41002005360288af4041002001360290af400c010b41c1081018000b02402003450d002004410f4d0d0002402007410171450d0020002004101d0c010b41c7081018000b20012004360200410021070b02400240024020052002490d00200120056a2104024002402005200241086a4f0d0020052002460d0141f2081018000b2006200520026b2200410172360204200620004178716a41046a22052005280200417e71360200200620062802044178716a2000360200200041104f0d0220004108462105410021064100210020050d0241e1081018000b20042002360200200420042802044101723602040c020b41d3081018000b0240024002404100280290af402001460d000240410028028caf402001470d0041002000360284af404100200636028caf400c020b2003450d032000410f4d0d0320042d0004410271450d0220062000101d0c030b41002000360288af4041002006360290af400b20042d00044102710d0141e9081018000b41eb081018000b2001200720027241027236020402404100280290af402001460d000240410028028caf402001470d0041004100360284af404100410036028caf400b0f0b41004100360288af4041004100360290af400b940101037f024002400240024002402000280204220141787122024110490d002002418002490d01200010690f0b20024108470d010f0b200028020c22022000460d01200028020822032000460d02024020022003460d002003200236020c200220033602080f0b410041002802f4ab40417e200141037677713602f4ab400f0b41b90c1018000b41cd0c1018000b41ce0c1018000bf30301047f0240024002400240200028020422024178712001470d0020014110490d0120024102710d0202402001418002490d00411f21020240200141ffffff074b0d002001410620014108766722026b7641017120024101746b413e6a220241204f0d050b200042003702102000411c6a200236020020024102744184aec0006a21030240024002400240024041002802f8ab4022044101200274220571450d00200328020022042802044178712001470d01200421020c020b410020042005723602f8ab40200041186a2003360200200320003602000c030b20014100411920024101766b411f712002411f461b742103034020042003411d764104716a41106a22052802002202450d02200341017421032002210420022802044178712001470d000b0b20022802082201200036020c20022000360208200041186a41003602002000200236020c200020013602080f0b20052000360200200041186a20043602000b2000200036020c200020003602080f0b2001410376220241037441fcabc0006a21010240024041002802f4ab4022034101200274220271450d00200128020821020c010b410020032002723602f4ab40200121020b200120003602082002200036020c2000200136020c200020023602080f0b41ec0b1018000b41ed0b1018000b41ee0b1018000b41ba0b1018000b0500101f000b05001024000b3e01017f230041206b22022400200241013a001820022001360214200220003602102002418883c00036020c200241eca6c000360208200241086a1035000b05001022000b05001023000b0500101e000b5e01017f230041306b22002400200041246a410136020020004201370214200041eca6c0003602102000410636022c20004198a7c0003602282000200041286a3602202000200041106a101120002802002000280208106f2000107000000b8e0101037f230041106b220324000240200120026a22022001490d002003200041046a2204280200220141017422052002200520024b1b22024108200241084b1b22022000280200410020011b200141011026024020032802004101470d00200341086a280200450d01100d000b200328020421012004200236020020002001360200200341106a24000f0b1009000b8b010002400240200141004e0d0041012102410021010c010b024002400240024002402002450d0020030d0220010d01410121020c040b20010d00410121020c030b100a20014101100b2202450d010c020b20022001101722020d010b2000200136020441012101410121020c010b20002002360204410021020b20002002360200200041086a20013602000b8f05010a7f230041306b22032400200341246a2001360200200341033a0028200342808080808004370308200320003602204100210420034100360218200341003602100240024002400240200228020822050d00200241146a2802002206450d012002280200210120022802102100200641037441786a41037641016a2204210603400240200141046a2802002207450d00200328022020012802002007200328022428020c1100000d040b2000280200200341086a200041046a2802001101000d03200041086a2100200141086a21012006417f6a22060d000c020b0b2002410c6a2802002200450d002000410574220841606a41057641016a2104200228020021014100210603400240200141046a2802002200450d00200328022020012802002000200328022428020c1100000d030b2003200520066a2200411c6a2d00003a00282003200041046a290200422089370308200041186a28020021092002280210210a4100210b41002107024002400240200041146a2802000e03010002010b2009410374210c41002107200a200c6a220c2802044107470d01200c28020028020021090b410121070b2003200936021420032007360210200041106a28020021070240024002402000410c6a2802000e03010002010b20074103742109200a20096a22092802044107470d01200928020028020021070b4101210b0b2003200736021c2003200b360218200a20002802004103746a2200280200200341086a20002802041101000d02200141086a21012008200641206a2206470d000b0b4100210020042002280204492201450d012003280220200228020020044103746a410020011b22012802002001280204200328022428020c110000450d010b410121000b200341306a240020000b02000b5001027f02402000280200220341046a280200200341086a220428020022006b20024f0d002003200020021025200428020021000b200328020020006a2001200210741a2004200020026a36020041000be60201037f230041106b220224002000280200210002400240200141ff004b0d00024020002802082203200041046a280200470d0020002003102b200028020821030b2000200341016a360208200028020020036a20013a00000c010b2002410036020c024002402001418010490d0002402001418080044f0d0020022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c020b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c010b20022001413f71418001723a000d2002200141067641c001723a000c410221010b0240200041046a280200200041086a220428020022036b20014f0d002000200320011025200428020021030b200028020020036a2002410c6a200110741a2004200320016a3602000b200241106a240041000b8e0101047f230041106b220224000240200141016a22032001490d002002200041046a2204280200220141017422052003200520034b1b22034108200341084b1b22032000280200410020011b200141011026024020022802004101470d00200241086a280200450d01100d000b200228020421012004200336020020002001360200200241106a24000f0b1009000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e082c000200241086a10272101200241206a240020010bf40101017f230041106b22022400200242808080801042002001280218419482c000410d2001411c6a28020028020c1100001b2001ad843703002002200036020c200241a182c00041052002410c6a41a882c000102e210120022000410c6a36020c200141b882c00041052002410c6a41c082c000102e22002d00042101024020002d0005450d00200141ff017121004101210120000d000240200228020022012d00004104710d00200128021841de84c00041022001411c6a28020028020c11000021010c010b200128021841d684c00041012001411c6a28020028020c11000021010b200241106a2400200141ff01714100470bb40302057f027e230041c0006b2205240041012106024020002d00040d0020002d0005210702402000280200220828020022094104710d0041012106200828021841d184c00041d384c000200741ff017122071b4102410320071b2008411c6a28020028020c1100000d0141012106200828021820012002200828021c28020c1100000d0141012106200828021841dd83c0004102200828021c28020c1100000d0120032008200428020c11010021060c010b0240200741ff01710d0041012106200828021841cc84c00041032008411c6a28020028020c1100000d01200828020021090b41012106200541013a0017200541346a41f083c000360200200541106a200541176a36020020052009360218200520082902183703082008290208210a2008290210210b200520082d00203a00382005200828020436021c2005200b3703282005200a3703202005200541086a360230200541086a20012002103e0d00200541086a41dd83c0004102103e0d002003200541186a200428020c1101000d00200528023041cf84c0004102200528023428020c11000021060b200041013a0005200020063a0004200541c0006a240020000bfb0101017f230041106b220224002000280200210020024280808080104200200128021841fb9ac00041092001411c6a28020028020c1100001b2001ad843703002002200036020c200241849bc000410b2002410c6a41c499c000102e21012002200041046a36020c2001418f9bc00041092002410c6a41989bc000102e22002d00042101024020002d0005450d00200141ff017121004101210120000d000240200228020022012d00004104710d00200128021841de84c00041022001411c6a28020028020c11000021010c010b200128021841d684c00041012001411c6a28020028020c11000021010b200241106a2400200141ff01714100470bb60301057f230041c0006b220224002000280200220041086a280200210320002802002100200128021841e684c00041012001411c6a28020028020c110000210402402003450d0041012105034020022000360204200441ff0171210641012104024020060d000240024002400240200128020022044104710d002005410171450d010c030b2005410171450d0141012104200128021841e584c0004101200128021c28020c1100000d03200128020021040c010b41012104200128021841d184c0004102200128021c28020c110000450d010c020b200241013a001720022004360218200241f083c00036023420022001290218370308200220012d00203a00382002200128020436021c20022001290210370328200220012902083703202002200241176a3602102002200241086a3602300240200241046a200241186a10310d00200228023041cf84c0004102200228023428020c11000021040c020b410121040c010b200241046a2001103121040b200041016a2100410021052003417f6a22030d000b0b41012100024020040d00200128021841f884c0004101200128021c28020c11000021000b200241c0006a240020000bcc0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020034120710d0120003100002001101421000c020b20002d00002103410021000340200220006a41ff006a413041d7002003410f712204410a491b20046a3a00002000417f6a2100200341ff0171220441047621032004410f4b0d000b20004180016a22034181014f0d02200141a485c0004102200220006a4180016a410020006b101521000c010b20002d00002103410021000340200220006a41ff006a413041372003410f712204410a491b20046a3a00002000417f6a2100200341ff0171220441047621032004410f4b0d000b20004180016a22034181014f0d02200141a485c0004102200220006a4180016a410020006b101521000b20024180016a240020000f0b2003418001419485c0001016000b2003418001419485c0001016000b0d0020002802001a037f0c000b0b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41053602002003420237020c200341cc83c000360208200341053602242003200341206a360218200320033602282003200341046a360220200341086a20021020000b0b002000350200200110140b8d0601047f230041a0016b220124002001200036020c200141dc006a41013602002001420237024c200141b4a7c0003602482001410836028c01200120014188016a36025820012001410c6a36028801200141106a200141c8006a1011024002400240024002402001280218220041c100490d00200128021022022c003b4140480d0320022c003f41bf7f4c0d032002413b6a28000041d3deb5ab06460d010b200141c8a8c000360220410721030c010b20014184016a4101360200200141fc006a2000360200200141ec006a428080808010370200200141e8006a2000360200200141e0006a4201370300200141d8006a428080808010370300200141d0006a220342808080808080808008370300200141b4a8c00036028001200120023602782001410136024820014188016a20032002200041b4a8c0004101410010724100200128028c01220341aa7f6a2204200420034b1b41002001280288011b220341c0006a210420022c00404140480d0202400240200020044b0d0020002004460d010c040b200220046a2c000041bf7f4c0d030b2001200241c0006a3602200b20012003360224200128020c28020c2100200141dc006a4102360200200028020021022001200028020436022c200120023602282000280208210020014194016a41053602002001420237024c20014180a9c0003602482001410636028c012001200036029c01200120014188016a3602582001200141286a3602880120012001419c016a36029001200141386a200141c8006a10110240024020012802380d002001420037022c20014100280290a9403602280c010b200141286a41086a200141386a41086a280200360200200120012903383703280b200141dc006a410236020020014194016a41093602002001420237024c200141e0a8c0003602482001410a36028c01200120014188016a3602582001200141286a360290012001200141206a36028801200141386a200141c8006a101120012802382001280240106f200141386a107000000b20022000413b413f41a0a8c000103f000b2002200041c000200441b8a8c000103f000b02000b0c0042e98ff1818ff0d3aa730b5401017f0240024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b20020d01410021040b20040f0b2000280218200220032000411c6a28020028020c1100000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41053602002003420237020c200341d088c000360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a20021020000ba10701067f200028021021030240024002400240200028020822044101460d0020034101460d012000280218200120022000411c6a28020028020c11000021030c030b20034101470d010b200120026a2105024002400240200041146a28020022060d0041002107200121080c010b41002107200121080340200822032005460d020240024020032c00002208417f4c0d00200341016a21080c010b0240200841ff0171220841e0014f0d00200341026a21080c010b0240200841f0014f0d00200341036a21080c010b20032d0002413f7141067420032d0001413f71410c747220032d0003413f71722008411274418080f0007172418080c400460d03200341046a21080b200720036b20086a21072006417f6a22060d000b0b20082005460d00024020082d0000220341f001490d0020082d0002413f7141067420082d0001413f71410c747220082d0003413f71722003411274418080f0007172418080c400460d010b02400240024020070d00410021080c010b024020072002490d00410021032002210820072002460d010c020b4100210320072108200120076a2c00004140480d010b20082107200121030b2007200220031b21022003200120031b21010b20044101460d002000280218200120022000411c6a28020028020c1100000f0b2000410c6a28020021050240024020020d00410021080c010b20024103712107024002402002417f6a41034f0d0041002108200121030c010b4100210841002002417c716b2106200121030340200820032c000041bf7f4a6a200341016a2c000041bf7f4a6a200341026a2c000041bf7f4a6a200341036a2c000041bf7f4a6a2108200341046a2103200641046a22060d000b0b2007450d000340200820032c000041bf7f4a6a2108200341016a21032007417f6a22070d000b0b0240200520084d0d0041002103200520086b22072105024002400240410020002d0020220820084103461b4103710e03020001020b41002105200721030c010b20074101762103200741016a41017621050b200341016a21032000411c6a28020021072000280204210820002802182106024003402003417f6a2203450d01200620082007280210110100450d000b41010f0b410121032008418080c400460d01200620012002200728020c1100000d01410021030340024020052003470d0020052005490f0b200341016a2103200620082007280210110100450d000b2003417f6a2005490f0b2000280218200120022000411c6a28020028020c1100000f0b20030b1000200120002802002000280204103a0b140020002802002001200028020428020c1101000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41053602002003420237020c2003418489c000360208200341053602242003200341206a3602182003200341046a36022820032003360220200341086a20021020000bf40501097f0240024002402002450d002000280204210320002802002104200028020821050340024020052d0000450d002004418884c0004104200328020c110000450d0041010f0b41002106200221070240024002400340200120066a21080240024002400240024020074108490d000240200841036a417c7120086b22000d00200741786a2109410021000c030b20072000200020074b1b21004100210a03402008200a6a2d0000410a460d052000200a41016a220a460d020c000b0b2007450d054100210a20082d0000410a460d034100210020074101460d064101210a20082d0001410a460d0320074102460d064102210a20082d0002410a460d0320074103460d064103210a20082d0003410a460d0320074104460d064104210a20082d0004410a460d0320074105460d064105210a20082d0005410a460d0320074106460d064106210a20082d0006410a470d060c030b2000200741786a22094b0d010b02400340200820006a220a280200220b417f73200b418a94a8d0007341fffdfb776a71200a41046a280200220a417f73200a418a94a8d0007341fffdfb776a7172418081828478710d01200041086a220020094d0d000b0b200020074d0d002000200741ec87c0001016000b20002007460d02200720006b210b2001200020066a6a21084100210a024003402008200a6a2d0000410a460d01200b200a41016a220a460d040c000b0b2000200a6a210a0b0240200a20066a220041016a22062000490d0020022006490d00200120006a2d0000410a470d00410121000c040b200220066b2107200220064f0d000b0b410021000b200221060b200520003a000002400240200220064b0d0020022006470d04200420012002200328020c110000450d0141010f0b200120066a22002c000041bf7f4c0d030240200420012006200328020c110000450d0041010f0b20002c000041bf7f4c0d040b200120066a2101200220066b22020d000b0b41000f0b200120024100200641ac84c000103f000b200120022006200241bc84c000103f000bdf0801037f230041f0006b220524002005200336020c200520023602080240024002400240024002402001418102490d004100210603400240200020066a22074180026a2c00004140480d0020064180026a21070c050b0240200741ff016a2c000041bf7f4c0d00200641ff016a21070c050b200741fe016a2c000041bf7f4a0d03200741fd016a2c000041bf7f4a0d022006417c6a220641807e470d000b410021060c040b2005200136021420052000360210200541eca6c000360218410021070c040b200641fd016a21070c010b200641fe016a21070b0240200720014f0d00200721060c010b2001210620072001460d00200020014100200741b88bc000103f000b2005200636021420052000360210200541c88bc000360218410521070b2005200736021c0240024002400240024002400240200220014b22070d00200320014b0d00200220034b0d012002450d020240024020022001490d0020012002470d010c040b200020026a2c000041bf7f4a0d030b20052002360220200221030c030b20052002200320071b360228200541306a41146a4103360200200541c8006a41146a4104360200200541d4006a410436020020054203370234200541f08bc0003602302005410536024c2005200541c8006a3602402005200541186a3602582005200541106a3602502005200541286a360248200541306a20041020000b200541e4006a4104360200200541c8006a41146a4104360200200541d4006a4105360200200541306a41146a410436020020054204370234200541ac8cc0003602302005410536024c2005200541c8006a3602402005200541186a3602602005200541106a36025820052005410c6a3602502005200541086a360248200541306a20041020000b200520033602202003450d010b03400240024020032001490d0020012003460d050c010b200020036a2c000041bf7f4a0d030b2003417f6a22030d000b0b410021030b20032001460d00200020036a22002c0000220741ff0171210602400240024002402007417f4a0d0020002d0001413f7121022007411f712101200641df014b0d01200141067420027221060c020b20052006360224410121070c020b200241067420002d0002413f717221060240200741ff017141f0014f0d0020062001410c747221060c010b200641067420002d0003413f71722001411274418080f00071722206418080c400460d020b20052006360224410121072006418001490d00410221072006418010490d0041034104200641808004491b21070b200520033602282005200720036a36022c200541306a41146a4105360200200541ec006a4104360200200541e4006a4104360200200541c8006a41146a410b360200200541d4006a410c36020020054205370234200541808dc0003602302005410536024c2005200541c8006a3602402005200541186a3602682005200541106a3602602005200541286a3602582005200541246a3602502005200541206a360248200541306a20041020000b41aca5c000412b2004100c000b7301047f230041206b220224004101210302402000200110430d002001411c6a2802002104200128021821052002411c6a4100360200200241eca6c0003602182002420137020c200241fc82c00036020820052004200241086a10270d00200041046a2001104321030b200241206a240020030be70301077f230041106b220224004101210302402001280218220441272001411c6a28020028021022051101000d002002200028020041810210422002410c6a2d00002106200241086a28020021072002280200210102400240024020022802042208418080c400460d0003402001210041dc00210341012101024002400240024020000e0407010300070b200641ff01712100410021064103210141fd00210302400240024020000e06090504000102090b4102210641fb0021030c040b4103210141f5002103410321060c030b4104210641dc0021030c020b41002101200821030c010b4102410120071b2106413041d7002008200741027476410f712203410a491b20036a21032007417f6a410020071b21070b200420032005110100450d000c020b0b03402001210041dc002103410121010240024020000e0404040100040b200641ff01712100410021064103210141fd002103024002400240024020000e06070403020100070b4104210641dc0021030c030b4103210141f5002103410321060c020b4102210641fb0021030c010b4102410120071b2106418080c40020074102747641017141307221032007417f6a410020071b21070b200420032005110100450d000b0b410121030c010b20044127200511010021030b200241106a240020030ba40602047f017e41f40021034102210402400240024002400240024002400240200141776a0e1f07020505010505050505050505050505050505050505050505030505050504000b41dc002103200141dc00460d050c040b41f20021030c040b41ee0021030c030b20024180800471450d01412221030c020b200241800271450d00412721030c010b0240024002400240024002402002410171450d002001410b74210541002103412021024120210402400240034002400240200241017620036a220241027441a89bc0006a280200410b7422062005490d0020062005460d03200221040c010b200241016a21030b200420036b2102200420034b0d000c020b0b200241016a21030b2003411f4b0d012003410274210241c305210402402003411f460d00200241ac9bc0006a28020041157621040b4100210602402003417f6a220520034b0d00200541204f0d03200541027441a89bc0006a28020041ffffff007121060b02402004200241a89bc0006a280200411576220341016a460d00200120066b2105200341c305200341c3054b1b21022004417f6a210641002104034020022003460d052004200341a89cc0006a2d00006a220420054b0d012006200341016a2203470d000b200621030b2003410171450d00200141017267410276410773ad4280808080d0008421070c050b024002400240200141808004490d002001418080084f0d012001418f93c000412a41e393c00041c00141a395c00041b60310440d060c020b200141f08dc000412841c08ec00041a00241e090c00041af021044450d010c050b200141e0ffff007141e0cd0a460d00200141c791756a4107490d00200141feffff0071419ef00a460d00200141dee2746a410e490d002001419fa8746a419f18490d00200141e28b746a41e20b490d00200141b5d9736a41b5db2b490d00200141f08338490d040b200141017267410276410773ad4280808080d0008421070c040b20034120418499c0001033000b2005412041a499c0001033000b200241c305419499c0001033000b41012104200121030c010b41032104200121030c010b0b2000200336020420002004360200200041086a20073702000bc20201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d0120003502002001101421000c040b20002802002100410021030340200220036a41ff006a413041d7002000410f712204410a491b20046a3a00002003417f6a21032000410f4b21042000410476210020040d000b20034180016a22004181014f0d01200141a485c0004102200220036a4180016a410020036b101521000c030b20002802002100410021030340200220036a41ff006a413041372000410f712204410a491b20046a3a00002003417f6a21032000410f4b21042000410476210020040d000b20034180016a22004181014f0d01200141a485c0004102200220036a4180016a410020036b101521000c020b2000418001419485c0001016000b2000418001419485c0001016000b20024180016a240020000bea0201067f200120024101746a210720004180fe0371410876210841002109200041ff0171210a0240024002400340200141026a210b200920012d000122026a210c024020012d000022012008460d00200120084b0d03200c2109200b2101200b2007470d010c030b0240200c2009490d00200c20044b0d02200320096a2101024003402002450d012002417f6a210220012d00002109200141016a21012009200a470d000b410021020c050b200c2109200b2101200b2007470d010c030b0b2009200c41d08dc000103d000b200c200441d08dc0001039000b200041ffff03712109200520066a210c4101210202400340200541016a210a0240024020052d00002201411874411875220b4100480d00200a21050c010b200a200c460d02200b41ff007141087420052d0001722101200541026a21050b200920016b22094100480d02200241017321022005200c470d000c020b0b41aca5c000412b41e08dc000100c000b20024101710bf30101017f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d2002200141067641c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002002410c6a2001103e2101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41f086c000200241086a10272101200241206a240020010b0d00200028020020012002103e0bfa0101017f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d2002200141067641c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002002410c6a2001103e2101200241106a240020010b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41f086c000200241086a10272101200241206a240020010bf00202057f027e230041c0006b220324000240024020002d0008450d0020002802042104410121050c010b2000280204210402402000280200220628020022074104710d0041012105200628021841d184c00041e284c00020041b4102410120041b2006411c6a28020028020c1100000d0120012006200228020c11010021050c010b024020040d000240200628021841e084c00041022006411c6a28020028020c110000450d0041012105410021040c020b200628020021070b41012105200341013a0017200341346a41f083c000360200200341106a200341176a36020020032007360218200320062902183703082006290208210820062902102109200320062d00203a00382003200628020436021c20032009370328200320083703202003200341086a3602302001200341186a200228020c1101000d00200328023041cf84c0004102200328023428020c11000021050b200020053a00082000200441016a360204200341c0006a240020000b8408010f7f230041106b2203240041012104024002402002280218220541222002411c6a280200220628021022071101000d000240024020010d00410021020c010b200020016a2108200021094100210a4100210b0240024003402009210c0240024020092c00002202417f4c0d00200941016a2109200241ff0171210d0c010b20092d0001413f71210e2002411f71210f0240200241ff0171220241df014b0d00200f410674200e72210d200941026a21090c010b200e41067420092d0002413f7172210e0240200241f0014f0d00200e200f410c7472210d200941036a21090c010b200e41067420092d0003413f7172200f411274418080f0007172220d418080c400460d03200941046a21090b2003200d4181800410420240024002400240200328020022020e0401020100010b200328020820032d000c6a4101460d010b200b200a490d030240200a450d000240200a2001490d00200a2001460d010c050b2000200a6a2c00004140480d040b0240200b450d000240200b2001490d00200b2001470d050c010b2000200b6a2c000041bf7f4c0d040b20052000200a6a200b200a6b200628020c1100000d0120032d000c210e200328020821100240024020032802042211418080c400470d0003402002210f4101210241dc00210a02400240200f0e0404040100040b200e41ff0171210f410321024100210e41fd00210a0240024002400240200f0e06070403020100070b4104210e41dc00210a0c030b4103210e41f500210a410321020c020b4102210e41fb00210a0c010b4102410120101b210e418080c400201041027476410171413072210a2010417f6a410020101b21100b2005200a2007110100450d000c040b0b03402002210f4101210241dc00210a0240024002400240200f0e0405010300050b200e41ff0171210f410321024100210e41fd00210a024002400240200f0e06070504000102070b4102210e41fb00210a0c040b4103210e41f500210a410321020c030b4104210e41dc00210a0c020b410021022011210a0c010b4102410120101b210e413041d7002011201041027476410f71220a410a491b200a6a210a2010417f6a410020101b21100b2005200a20071101000d030c000b0b410121020240200d418001490d0041022102200d418010490d0041034104200d41808004491b21020b2002200b6a210a0b200b200c6b20096a210b20092008470d010c030b0b410121040c030b20002001200a200b41ac87c000103f000b0240200a0d00410021020c010b0240200a2001490d0020012102200a2001460d010c030b2000200a6a2c000041bf7f4c0d02200a21020b2005200020026a200120026b200628020c1100000d0020054122200711010021040b200341106a240020040f0b20002001200a200141bc87c000103f000bcc0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020034120710d0120003100002001101421000c020b20002d00002103410021000340200220006a41ff006a413041d7002003410f712204410a491b20046a3a00002000417f6a2100200341ff0171220441047621032004410f4b0d000b20004180016a22034181014f0d02200141a485c0004102200220006a4180016a410020006b101521000c010b20002d00002103410021000340200220006a41ff006a413041372003410f712204410a491b20046a3a00002000417f6a2100200341ff0171220441047621032004410f4b0d000b20004180016a22034181014f0d02200141a485c0004102200220006a4180016a410020006b101521000b20024180016a240020000f0b2003418001419485c0001016000b2003418001419485c0001016000b2600024020002802002d00000d00200141a787c0004105103a0f0b200141a387c0004104103a0b0b002000280200200110430bc80201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020034120710d0120003502002001101421000c020b20002802002100410021030340200220036a41ff006a413041d7002000410f712204410a491b20046a3a00002003417f6a21032000410f4b21042000410476210020040d000b20034180016a22004181014f0d02200141a485c0004102200220036a4180016a410020036b101521000c010b20002802002100410021030340200220036a41ff006a413041372000410f712204410a491b20046a3a00002003417f6a21032000410f4b21042000410476210020040d000b20034180016a22004181014f0d02200141a485c0004102200220036a4180016a410020036b101521000b20024180016a240020000f0b2000418001419485c0001016000b2000418001419485c0001016000b15002000280200220028020020002802042001104b0b9f0201017f230041106b220224002000280200280200210020024280808080104200200128021841e899c00041082001411c6a28020028020c1100001b2001ad843703002002200036020c200241f099c00041042002410c6a41f499c000102e21012002200041086a36020c200141849ac00041042002410c6a41889ac000102e210120022000410c6a36020c200141989ac00041032002410c6a41889ac000102e22002d00042101024020002d0005450d00200141ff017121004101210120000d000240200228020022012d00004104710d00200128021841de84c00041022001411c6a28020028020c11000021010c010b200128021841d684c00041012001411c6a28020028020c11000021010b200241106a2400200141ff01714100470ba20201027f230041106b2202240002400240200028020022002802000d00200128021841d499c00041042001411c6a28020028020c11000021010c010b2002200128021841b0a8c00041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41d899c000104a1a20022d00082101024020022802042203450d00200141ff017121004101210120000d0020022802002100024020034101470d0020022d000941ff0171450d0020002d00004104710d0041012101200028021841e384c00041012000411c6a28020028020c1100000d010b200028021841e484c00041012000411c6a28020028020c11000021010b200141ff017141004721010b200241106a240020010b6f01037f230041206b220224002001411c6a2802002103200141186a2802002104200241086a41106a2000280200280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10272101200241206a240020010b3d01027f41012102024020012802182203418483c00041032001411c6a28020028020c22011100000d00200341d784c0004107200111000021020b20020b1c00200128021841f69ac00041052001411c6a28020028020c1100000ba80201027f230041106b2202240002400240200028020022002d00004101460d00200128021841d499c00041042001411c6a28020028020c11000021010c010b2002200128021841b0a8c00041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200041016a36020c20022002410c6a41e884c000104a1a20022d00082101024020022802042203450d00200141ff017121004101210120000d0020022802002100024020034101470d0020022d000941ff0171450d0020002d00004104710d0041012101200028021841e384c00041012000411c6a28020028020c1100000d010b200028021841e484c00041012000411c6a28020028020c11000021010b200141ff017141004721010b200241106a240020010bac0101017f02400240024002402002450d0041012106200141004e0d010c020b20002001360204410121060c010b024002400240024002402003450d0020040d022001450d01100a20014101100b22030d040c030b2001450d00100a20014101100b22030d030c020b200221030c020b20032001101722030d010b20002001360204200221010c020b20002003360204410021060c010b410021010b20002006360200200041086a20013602000b8b0101017f230041206b22012400200141086a41106a200041106a290200370300200141086a41086a200041086a29020037030020012000290200370308024041a0afc00041eca1c000200141086a1027450d004188a3c000412b200141086a41b4a3c00041e0a2c000100e000b41a0afc00041002d00e8b0401003410041003a00e8b040200141206a24000b02000b02000bf40101047f2002410041c80120002d00c80122036b2204200220042002491b22051b2106024002402005450d00200420024f0d000240200120056a2c000041bf7f4a0d00410021062005417f6a2204450d0103400240024020042002490d0020022004470d01200221060c040b200120046a2c000041bf7f4a0d020b2004417f6a22040d000c020b0b024020042002490d002002210620042002460d010c020b200120046a2c000041bf7f4c0d01200421060b200020036a2001200610741a200020002d00c801200641ff01716a220441ff01200441ff01491b3a00c80120062002470f0b2001200241002004419ca4c000103f000be30301057f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410c7641e001723a000c20022001410676413f71418001723a000d410321030c030b200220013a000c410121030c020b20022001413f71418001723a000d2002200141067641c001723a000c410221030c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421030b2003410041c80120002d00c80122046b2201200320012003491b22051b2106024002402005450d00200120034f0d0002402002410c6a20056a2c000041bf7f4a0d00410021062005417f6a2201450d0103400240024020012003490d0020032001470d01200321060c040b2002410c6a20016a2c000041bf7f4a0d020b2001417f6a22010d000c020b0b024020012003490d002003210620012003460d010c020b2002410c6a20016a2c000041bf7f4c0d01200121060b200020046a2002410c6a200610741a200020002d00c801200641ff01716a220141ff01200141ff01491b3a00c801200241106a240020062003470f0b2002410c6a200341002001419ca4c000103f000b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41aca4c000200241086a10272101200241206a240020010b02000bf90101047f2002410041c801200028020022032d00c80122046b2200200220002002491b22051b2106024002402005450d00200020024f0d000240200120056a2c000041bf7f4a0d00410021062005417f6a2200450d0103400240024020002002490d0020022000470d01200221060c040b200120006a2c000041bf7f4a0d020b2000417f6a22000d000c020b0b024020002002490d002002210620002002460d010c020b200120006a2c000041bf7f4c0d01200021060b200320046a2001200610741a200320032d00c801200641ff01716a220041ff01200041ff01491b3a00c80120062002470f0b2001200241002000419ca4c000103f000b0b0020002802002001105c0b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41aca4c000200241086a10272101200241206a240020010bdb0101047f024002402000450d00024020004107710d000240200041086a4107710d004100280298af4020004b0d0302404100280294af402201450d00034002402001280204200128020022026a41686a220320024d0d00024003400240200220004d0d002002200020002802044178716a490d020b2002280204417871210402400240200220004f0d00200220046a20004b0d010b2003200220046a22024d0d030c010b0b41e5101018000b41e4101018000b200128020822010d000b0b0f0b41db101018000b41d9101018000b41d8101018000b41dc101018000b6301017f2000106202400240024020002802042201410271450d00200020014178716a41046a2d0000410171450d0120014101710d02200020002802006b220120012802044178716a2000460d024193111018000b4191111018000b4192111018000b0b830501087f200028021c210102400240024002400240200028020422024178712203418002490d00411f21040240200341ffffff074b0d002003410620024108766722046b7641017120044101746b413e6a21040b20012004470d03200341012001410176220441086a742001410171200441076a7472490d012001411f470d020c040b20010d02419b121018000b419c121018000b20034101200141016a2204410176220241086a742004410171200241076a7472490d01419d121018000b419a121018000b410021052003410472210620002104034020041062024002400240024002400240024002400240200428021c2001470d00200428020422024178712003470d0120024103714101470d02200420066a2d00004101710d03200428020c2802082004470d04200428020828020c2004470d05200441146a2802002107200428021021020240024002400240024020042802182208450d0020050d0120082004460d02024020082802102004460d00200841146a2802002004460d0020082802002004470d040b20020d040c0c0b024020020d002007450d0d41ae121018000b41ad121018000b41b0121018000b41b2121018000b41b3121018000b20022802182004470d06024020022004460d00200210640c080b41ba121018000b41a4121018000b41a5121018000b41a6121018000b41a7121018000b41a8121018000b41a9121018000b41b9121018000b200421052007450d000240024020072802182004470d0020072004460d0120071064200421052002450d022004210520022802044178712007280204417871490d0241c3121018000b41be121018000b41bf121018000b200428020822042000470d000b024020050d0041ce121018000b0bc60201047f0240024002400240200028020422014178712202418002490d0002400240200241ffffff074b0d004100210341002802f8ab402002410620014108766722016b7641017120014101746b413e6a220476410171450d0420044120490d0141ba0b1018000b4100210341002802f8ab40417f4a0d03411f21040b20044102744184aec0006a28020022010d010c030b4100210341002802f4ab402001410376220176410171450d01200141037441fcabc0006a220421010340200120004622030d02200128020822012004470d000c020b0b20024100411920044101766b411f712004411f461b7421030240034020012802044178712002460d012003411d76210420034101742103200120044104716a41106a2802002201450d030c000b0b200121040340200420004622030d01200428020822042001470d000b0b20030f0b41000bdc0101047f02400240024002400240024002404100280290af40450d002000106202404100280294af402201450d00034002402001280200220220004b0d002002200128020422036a20004b0d040b200128020822010d000b0b41f8101018000b4100280288af400d010c050b2000280204220441787122014100280288af40470d012001450d022001200220006b20036a41686a470d0302402004410171450d00200020014104726a2d0000410171450d0541fd101018000b41fc101018000b41f1101018000b41f9101018000b41fa101018000b41fb101018000b0b7901027f024002400240200028020822022000460d00200220022802082203460d0120022802044178712001410374470d02024020032000460d002003200036020c2000200336020820020f0b410041002802f4ab40417e200177713602f4ab4020020f0b41cf0b1018000b41d00b1018000b41d10b1018000b4201017f02404100280284af4022024180024f0d0002402002450d00410028028caf402002101d0b4100200036028caf4041002001360284af400f0b41df0b1018000bcd0201057f20002802182101024002400240200028020c22022000470d00200041144110200041146a220228020022031b6a28020022040d01410021020c020b20002802082204200236020c200220043602080c010b2002200041106a20031b210303402003210502402004220241146a220328020022040d00200241106a2103200228021021040b20040d000b200541003602000b02402001450d0002400240200028021c220441204f0d00024020044102744184aec0006a22042802002000460d0020014110411420012802102000461b6a20023602002002450d030c020b2004200236020020020d01410041002802f8ab40417e200028021c77713602f8ab400f0b41ba0b1018000b20022001360218024020002802102204450d0020022004360210200420023602180b200041146a2802002204450d00200241146a2004360200200420023602180f0b0bbf0101027f02400240024020004107710d00200141ffff03710d01200020014100106c22024100280294af403602084100280290af402203450d02200320032802044178716a4100280288af403602004100280290af404100280288af40101d0c020b41ff091018000b41800a1018000b0240200041086a4107710d004100200141686a2201360288af4041002000360290af4020002001410172360204200020014178716a200136020041002002360294af40200010660f0b41af091018000bf40101027f02400240024002400240200020016a22032002280200470d00200141ffff03710d012002280204220441ffff03710d0220004107710d0320034107710d04200220003602002002200420016a22043602042003416c6a220220022802002201410771411872360200200341686a2102024020014101710d004100280290af40200220022802006b2201470d002000280204417871200441686a460d0041004100360288af4041004100360290af4020012001280204417871101d0b2002101921024100280290af40106620020f0b41c3091018000b41c4091018000b41c5091018000b41c6091018000b41c7091018000b7801037f0240024002400240200020016a22034107710d00200341686a22044107710d01200341706a22054107710d02200341786a4107710d03200441073602142004200136020c200420003602082004200241127236020420050f0b41ec091018000b41ed091018000b41ee091018000b41ef091018000b1000200028020020002802042001104b0b1000200120002802002000280204103a0b08002000200110030b0600200010070bbd0201017f230041106b2202240020002802002100200242808080801042002001280218419b9ac00041092001411c6a28020028020c1100001b2001ad843703002002200036020c200241a49ac00041072002410c6a41ac9ac000102e21012002200041086a36020c200141bc9ac00041072002410c6a41c49ac000102e210120022000410c6a36020c200141d49ac00041082002410c6a41dc9ac000102e21012002200041106a36020c200141ec9ac000410a2002410c6a41b499c000102e22012d00042100024020012d0005450d00200041ff017121014101210020010d000240200228020022002d00004104710d00200028021841de84c00041022000411c6a28020028020c11000021000c010b200028021841d684c00041012000411c6a28020028020c11000021000b200241106a2400200041ff01714100470b810403037f017e097f0240024002402001280218220720056b220820034f0d00200128021021092001290300210a200128020c220b2005200b20054b1b210c4100200b6b210d0340024002400240200a200220086a220e31000088420183500d00200b2001280220220f200b200b200f4b1b20061b417f6a2210211102400240034002402011417f470d002005200f20061b2211200b2011200b4b1b2110200b21110240024002400340024020102011470d00200120083602182006450d020c0e0b200c2011460d02200820116a20034f0d03200e20116a2112200420116a2113201141016a211120132d000020122d0000460d000b2001200720096b2207360218200921112006450d080c090b200120053602200c0b0b200c20054188aac0001033000b2003200b20086a2211200320114b1b20034198aac0001033000b201020054f0d01200820116a221220034f0d02200e20116a2112200420116a21132011417f6a211120132d000020122d0000460d000b2001200d20076a20116a41016a2207360218200521112006450d030c040b2011200541e8a9c0001033000b2012200341f8a9c0001033000b20012008360218200521112008210720060d010b200120113602200b200720056b22082003490d000b0b41002111200141003602180c010b20002008360204200041086a2007360200410121110b200020113602000b1000200120002802002000280208103a0bc30201077f024002402002410f4b0d00200021030c010b2000410020006b41037122046a210502402004450d0020002103200121060340200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a2209410371450d0020084101480d01200941037422014118712102410020016b41187121042009417c71220641046a2101200628020021060340200520062002762001280200220620047472360200200141046a2101200541046a22052003490d000c020b0b20084101480d0020092101034020052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b024020024101480d00200320026a21050340200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000bb70101037f024002402002410f4b0d00200021030c010b2000410020006b41037122046a210502402004450d00200021030340200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d00200141ff017141818284086c2102034020052002360200200541046a22052003490d000b0b200441037121020b024020024101480d00200320026a21050340200320013a0000200341016a22032005490d000b0b20000b0bf8300300418080c0000ba82a496e76616c6964206d65737361676570696e672f7372632f6c69622e727300000f0010000f0000000900000038000000504f4e4720746f74616c206d6573736167652873292073746f7265643a2000006c13100000000000340010001a0000000d00000014000000040000000e0000006c6962726172792f616c6c6f632f7372632f7261775f7665632e72736361706163697479206f766572666c6f770000008c00100011000000700010001c00000006020000050000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f726c6962726172792f616c6c6f632f7372632f666d742e727300eb00100018000000550200001c00000046726f6d557466384572726f72627974657300000f0000000400000004000000100000006572726f720000000f0000000400000004000000110000000f0000000000000001000000120000000f00000004000000040000001300000014000000150000002e2e00007801100002000000416e790016000000000000000100000017000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e6465782069732000009801100020000000b801100012000000603a20006c13100000000000dd01100002000000160000000c0000000400000018000000190000001a000000202020206c6962726172792f636f72652f7372632f666d742f6275696c646572732e72730c021000200000002f000000210000000c021000200000003000000012000000207b0a2c0a2c20207b207d207b202e2e207d207d280a282c290a5b001600000004000000040000001b0000005d6c6962726172792f636f72652f7372632f666d742f6e756d2e7273790210001b00000065000000140000003078303030313032303330343035303630373038303931303131313231333134313531363137313831393230323132323233323432353236323732383239333033313332333333343335333633373338333934303431343234333434343534363437343834393530353135323533353435353536353735383539363036313632363336343635363636373638363937303731373237333734373537363737373837393830383138323833383438353836383738383839393039313932393339343935393639373938393900001600000004000000040000001c0000001d0000001e0000006c6962726172792f636f72652f7372632f666d742f6d6f642e72737472756566616c7365880310001b000000860800001e000000880310001b0000008d080000160000006c6962726172792f636f72652f7372632f736c6963652f6d656d6368722e7273cc031000200000005b0000000500000072616e676520737461727420696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820fc031000120000000e0410002200000072616e676520656e6420696e6465782040041000100000000e04100022000000736c69636520696e64657820737461727473206174202062757420656e647320617420006004100016000000760410000d0000006c6962726172792f636f72652f7372632f7374722f76616c69646174696f6e732e7273010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202020202020202020202020202020202020202020203030303030303030303030303030303040404040400000000000000000000000094041000230000001e010000110000005b2e2e2e5d6279746520696e64657820206973206f7574206f6620626f756e6473206f6620600000cd0510000b000000d805100016000000dc01100001000000626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e6720600000080610000e00000016061000040000001a06100010000000dc01100001000000206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f662060cd0510000b0000004c0610002600000072061000080000007a06100006000000dc011000010000006c6962726172792f636f72652f7372632f756e69636f64652f7072696e7461626c652e7273000000a8061000250000000a0000001c000000a8061000250000001a0000003600000000010305050606020706080709110a1c0b190c1a0d100e0d0f0410031212130916011704180119031a071b011c021f1620032b032d0b2e01300331023201a702a902aa04ab08fa02fb05fd02fe03ff09ad78798b8da23057588b8c901cdd0e0f4b4cfbfc2e2f3f5c5d5fe2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d11293a3b4549575b5c5e5f64658d91a9b4babbc5c9dfe4e5f00d11454964658084b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff806d71dedf0e1f6e6f1c1d5f7d7eaeaf7fbbbc16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f747596262e2fa7afb7bfc7cfd7df9a409798308f1fd2d4ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab051f09811b03190801042f043404070301070607110a500f1207550703041c0a090308030703020303030c0405030b06010e15054e071b0757070206160d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd03590716091809140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a062f314d0380a4083c030f033c0738082b0582ff1118082f112d03210f210f808c048297190b158894052f053b07020e180980be22740c80d61a0c0580ff0580df0cf29d033709815c1480b80880cb050a183b030a06380846080c06740b1e035a0459098083181c0a16094c04808a06aba40c170431a10481da26070c050580a61081f50701202a064c04808d0480be031b030f0d000601010301040205070702080809020a050b020e041001110212051311140115021702190d1c051d0824016a046b02af03bc02cf02d102d40cd509d602d702da01e005e102e704e802ee20f004f802fa02fb010c273b3e4e4f8f9e9e9f7b8b9396a2b2ba86b1060709363d3e56f3d0d1041418363756577faaaeafbd35e01287898e9e040d0e11122931343a4546494a4e4f64655cb6b71b1c07080a0b141736393aa8a9d8d909379091a8070a3b3e66698f926f5fbfeeef5a62f4fcff9a9b2e2f2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fe7ecefffc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d0aeaf6e6f935e227b0503042d036603012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b4e43813709160a08183b45390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a8126524e28082a161a261c1417094e042409440d19070a0648082709750b3f412a063b050a0651060105100305808b621e48080a80a65e22450b0a060d133a060a362c041780b93c64530c48090a46451b4808530d498107460a1d03474937030e080a0639070a81361980b7010f320d839b66750b80c48a4c630d842f8fd18247a1b98239072a045c06260a460a28051382b05b654b0439071140050b020e97f80884d62a09a2e781332d03110408818c89046b050d0309071092604709743c80f60a7308701546809a140c570919808781470385420f1584501f80e12b80d52d031a040281401f113a050184e080f7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a80ae381d0d2c040907020e06809a83d80510030d03740c59070c04010f0c0438080a062808224e81540c1503050307091d030b05060a0a060808070980cb250a84066c6962726172792f636f72652f7372632f756e69636f64652f756e69636f64655f646174612e7273000000590c1000280000004b00000028000000590c1000280000005700000016000000590c100028000000520000003e0000001600000004000000040000001f000000160000000400000004000000200000004e6f6e65160000000400000004000000210000004c6f636174696f6e66696c65160000000400000004000000220000006c696e6516000000040000000400000023000000636f6c50616e6963496e666f7061796c6f616400160000000400000004000000240000006d65737361676500160000000400000004000000250000006c6f636174696f6e1600000004000000040000002600000063616e5f756e77696e644572726f72557466384572726f7276616c69645f75705f746f6572726f725f6c656e160000000400000004000000270000000003000083042000910560005d13a0001217201f0c20601fef2ca02b2a30202c6fa6e02c02a8602d1efb602e00fe20369eff6036fd01e136010a2137240de137ab0e61392f18a139301ce147f31e214cf06ae14f4f6f21509dbca15000cf615165d1a15100da215200e0e15330e16155aee2a156d0e8e15620006e57f001ff5700700007002d0101010201020101480b30151001650702060202010423011e1b5b0b3a09090118040109010301052b033c082a180120370101010408040103070a021d013a0101010204080109010a021a010202390104020402020303011e0203010b0239010405010204011402160601013a0101020104080107030a021e013b0101010c01090128010301370101030503010407020b021d013a01020102010301050207020b021c02390201010204080109010a021d0148010401020301010801510102070c08620102090b064a021b0101010101370e01050102050b0124090166040106010202021902040310040d01020206010f01000300031d021e021e02400201070801020b09012d030101750222017603040209010603db0202013a010107010101010208060a0201301f310430070101050128090c0220040202010338010102030101033a0802029803010d0107040106010302c6400001c32100038d016020000669020004010a200250020001030104011902050197021a120d012608190b2e0330010204020227014306020202020c0108012f01330101030202050201012a020801ee010201040100010010101000020001e201950500030102050428030401a50200040002990b31047b01360f290102020a033104020207013d03240501083e010c0234090a0402015f03020101020601a0010308150239020101010116010e070305c308020301011701510102060101020101020102eb010204060201021b025508020101026a0101010206010165030204010500090102f5010a0201010401900402020401200a280602040801090602032e0d010200070106010152160207010201027a060301010201070101480203010101000200053b0700013f0451010002002e0217000101030405080802071e0494030037043208010e011605010f00070111020701020105000700013d0400076d07006080f0000028000000c900000001000000290000002a0000002b0000002f686f6d652f72756e6e65722f2e636172676f2f6769742f636865636b6f7574732f646c6d616c6c6f632d727573742d383066396666393866343237306163662f613938316262382f7372632f646c766572626f73652e727300000004111000590000002500000031000000414c4c4f43204153534552543a200000701110000e00000063616c6c65642060526573756c743a3a756e77726170282960206f6e20616e2060457272602076616c7565002c0000000000000001000000120000002f686f6d652f72756e6e65722f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7374722d6275662d322e302e342f7372632f6c69622e7273000000c411100055000000f7000000260000002d00000004000000040000002e0000002f000000300000002f686f6d652f72756e6e65722f2e636172676f2f6769742f636865636b6f7574732f646c6d616c6c6f632d727573742d383066396666393866343237306163662f613938316262382f7372632f646c6d616c6c6f632e727344121000580000002f0300005a00000063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c756543616e6e6f74206c6f6164206d657373616765202d20627566666572206c656e67746820646f6573206e6f74206d617463682f686f6d652f72756e6e65722f2e636172676f2f6769742f636865636b6f7574732f676561722d626463326237643438656633616362642f356431326135372f67636f72652f7372632f6d73672e727300000009131000500000007f0000000d0000006c1310000000000052756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e670000741310002200000070616e6963206f636375727265643a2027270000a013100011000000b1131000010000002f686f6d652f72756e6e65722f2e636172676f2f6769742f636865636b6f7574732f676561722d626463326237643438656633616362642f356431326135372f677374642f7372632f636f6d6d6f6e2f68616e646c6572732e727300c41310005b0000003c0000002a000000536f6d657b000000c41310005b0000003f0000000a000000554e4b4e4f574e50616e69636b65642077697468200000004f1410000e0000006c131000000000002c2061742060602c206c696e652000007014100006000000761410000800000001000000000000002f72757374632f323766356438333065623131636437626463383334643666306437383132303937366637353434332f6c6962726172792f636f72652f7372632f7374722f7061747465726e2e727300981410004f000000e305000014000000981410004f000000e305000021000000981410004f000000ef05000014000000981410004f000000ef050000210000000041a8aac0000b0c0400000000000000000000000041c0aac0000ba9060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\", \"$PAYLOAD\", - 0] + $VALUE_INIT, + true] }" echo @@ -36,12 +41,13 @@ echo "Handle message:" curl http://localhost:9933 -H "Content-Type:application/json;charset=utf-8" -d "{ \"jsonrpc\":\"2.0\", \"id\":2, - \"method\":\"gear_getHandleGasSpent\", + \"method\":\"gear_calculateHandleGas\", \"params\": [ \"$ALICE\", \"$PROG_ID\", \"$PAYLOAD\", - 0] + $VALUE_HANDLE, + true] }" echo @@ -49,11 +55,12 @@ echo "Reply message:" curl http://localhost:9933 -H "Content-Type:application/json;charset=utf-8" -d "{ \"jsonrpc\":\"2.0\", \"id\":3, - \"method\":\"gear_getReplyGasSpent\", + \"method\":\"gear_calculateReplyGas\", \"params\": [ \"$ALICE\", \"$MSG_ID\", 0, \"$PAYLOAD\", - 0] + $VALUE_REPLY, + true] }"