Skip to content

Commit

Permalink
feat(pallet-gear-rpc): Introduce gas spent for vouchers
Browse files Browse the repository at this point in the history
  • Loading branch information
ukint-vs committed Dec 4, 2023
1 parent b46adb6 commit 5c90a34
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 17 deletions.
8 changes: 6 additions & 2 deletions pallets/gear/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ use sp_runtime::traits::Block as BlockT;
use sp_std::vec::Vec;

sp_api::decl_runtime_apis! {
#[api_version(2)]
#[api_version(3)]
pub trait GearApi {
#[allow(clippy::too_many_arguments)]
fn calculate_gas_info(source: H256, kind: HandleKind, payload: Vec<u8>, value: u128, allow_other_panics: bool, initial_gas: Option<u64>, allowance_multiplier: Option<u64>) -> Result<GasInfo, Vec<u8>>;
fn calculate_gas_info(source: H256, kind: HandleKind, payload: Vec<u8>, value: u128, is_prepaid: bool, allow_other_panics: bool, initial_gas: Option<u64>, allowance_multiplier: Option<u64>) -> Result<GasInfo, Vec<u8>>;

/// Generate inherent-like extrinsic that runs message queue processing.
fn gear_run_extrinsic(max_gas: Option<u64>) -> <Block as BlockT>::Extrinsic;
Expand All @@ -43,6 +43,10 @@ sp_api::decl_runtime_apis! {

// DEPRECATED APIS

#[allow(clippy::too_many_arguments)]
#[changed_in(3)]
fn calculate_gas_info(source: H256, kind: HandleKind, payload: Vec<u8>, value: u128, allow_other_panics: bool, initial_gas: Option<u64>, allowance_multiplier: Option<u64>) -> Result<GasInfo, Vec<u8>>;

#[allow(clippy::too_many_arguments)]
#[changed_in(2)]
fn calculate_gas_info(source: H256, kind: HandleKind, payload: Vec<u8>, value: u128, allow_other_panics: bool, initial_gas: Option<u64>) -> Result<GasInfo, Vec<u8>>;
Expand Down
124 changes: 124 additions & 0 deletions pallets/gear/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ pub trait GearApi<BlockHash, ResponseType> {
at: Option<BlockHash>,
) -> RpcResult<GasInfo>;

#[method(name = "unstable_gear_voucher_calculateHandleGas")]
fn get_voucher_handle_gas_spent(
&self,
source: H256,
dest: H256,
payload: Bytes,
value: u128,
allow_other_panics: bool,
at: Option<BlockHash>,
) -> RpcResult<GasInfo>;

#[method(name = "unstable_gear_voucher_calculateReplyGas")]
fn get_voucher_reply_gas_spent(
&self,
source: H256,
message_id: H256,
payload: Bytes,
value: u128,
allow_other_panics: bool,
at: Option<BlockHash>,
) -> RpcResult<GasInfo>;

#[method(name = "gear_readState")]
fn read_state(
&self,
Expand Down Expand Up @@ -197,6 +219,7 @@ where
kind: HandleKind,
payload: Vec<u8>,
value: u128,
is_prepaid: bool,
allow_other_panics: bool,
min_limit: Option<u64>,
) -> RpcResult<GasInfo> {
Expand All @@ -214,13 +237,26 @@ where
allow_other_panics,
min_limit,
)
} else if api_version < 3 {
#[allow(deprecated)]
api.calculate_gas_info_before_version_3(
at_hash,
source,
kind,
payload,
value,
allow_other_panics,
min_limit,
Some(self.allowance_multiplier),
)
} else {
api.calculate_gas_info(
at_hash,
source,
kind,
payload,
value,
is_prepaid,
allow_other_panics,
min_limit,
Some(self.allowance_multiplier),
Expand Down Expand Up @@ -258,6 +294,8 @@ where
C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
C::Api: GearRuntimeApi<Block>,
{
// Calculate gas spent

fn get_init_create_gas_spent(
&self,
source: H256,
Expand All @@ -275,6 +313,7 @@ where
HandleKind::InitByHash(CodeId::from_origin(code_id)),
payload.to_vec(),
value,
false,
allow_other_panics,
None,
)?;
Expand All @@ -285,6 +324,7 @@ where
HandleKind::InitByHash(CodeId::from_origin(code_id)),
payload.to_vec(),
value,
false,
allow_other_panics,
Some(min_limit),
)
Expand All @@ -307,6 +347,7 @@ where
HandleKind::Init(code.to_vec()),
payload.to_vec(),
value,
false,
allow_other_panics,
None,
)?;
Expand All @@ -317,6 +358,7 @@ where
HandleKind::Init(code.to_vec()),
payload.to_vec(),
value,
false,
allow_other_panics,
Some(min_limit),
)
Expand All @@ -339,6 +381,7 @@ where
HandleKind::Handle(ProgramId::from_origin(dest)),
payload.to_vec(),
value,
false,
allow_other_panics,
None,
)?;
Expand All @@ -349,6 +392,7 @@ where
HandleKind::Handle(ProgramId::from_origin(dest)),
payload.to_vec(),
value,
false,
allow_other_panics,
Some(min_limit),
)
Expand All @@ -374,6 +418,7 @@ where
),
payload.to_vec(),
value,
false,
allow_other_panics,
None,
)?;
Expand All @@ -387,11 +432,90 @@ where
),
payload.to_vec(),
value,
false,
allow_other_panics,
Some(min_limit),
)
}

// Voucher

fn get_voucher_reply_gas_spent(
&self,
source: H256,
message_id: H256,
payload: Bytes,
value: u128,
allow_other_panics: bool,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<GasInfo> {
let at_hash = at.unwrap_or_else(|| self.client.info().best_hash);

let GasInfo { min_limit, .. } = self.calculate_gas_info(
at_hash,
source,
HandleKind::Reply(
MessageId::from_origin(message_id),
ReplyCode::Success(SuccessReplyReason::Manual),
),
payload.to_vec(),
value,
true,
allow_other_panics,
None,
)?;

self.calculate_gas_info(
at_hash,
source,
HandleKind::Reply(
MessageId::from_origin(message_id),
ReplyCode::Success(SuccessReplyReason::Manual),
),
payload.to_vec(),
value,
true,
allow_other_panics,
Some(min_limit),
)
}

fn get_voucher_handle_gas_spent(
&self,
source: H256,
dest: H256,
payload: Bytes,
value: u128,
allow_other_panics: bool,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<GasInfo> {
let at_hash = at.unwrap_or_else(|| self.client.info().best_hash);

let GasInfo { min_limit, .. } = self.calculate_gas_info(
at_hash,
source,
HandleKind::Handle(ProgramId::from_origin(dest)),
payload.to_vec(),
value,
true,
allow_other_panics,
None,
)?;

self.calculate_gas_info(
at_hash,
source,
HandleKind::Handle(ProgramId::from_origin(dest)),
payload.to_vec(),
value,
true,
allow_other_panics,
Some(min_limit),
)
}

// Read state

fn read_state(
&self,
program_id: H256,
Expand Down
3 changes: 3 additions & 0 deletions pallets/gear/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ pub mod pallet {
kind: HandleKind,
payload: Vec<u8>,
value: u128,
is_prepaid: bool,
allow_other_panics: bool,
initial_gas: Option<u64>,
gas_allowance: Option<u64>,
Expand All @@ -732,6 +733,7 @@ pub mod pallet {
initial_gas.unwrap_or_else(BlockGasLimitOf::<T>::get),
payload,
value,
is_prepaid,
allow_other_panics,
false,
gas_allowance,
Expand Down Expand Up @@ -762,6 +764,7 @@ pub mod pallet {
initial_gas,
payload.clone(),
value,
false,
allow_other_panics,
allow_skip_zero_replies,
None,
Expand Down
54 changes: 40 additions & 14 deletions pallets/gear/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ where
initial_gas: u64,
payload: Vec<u8>,
value: u128,
is_prepaid: bool,
allow_other_panics: bool,
allow_skip_zero_replies: bool,
allowance_multiplier: Option<u64>,
Expand All @@ -64,23 +65,32 @@ where
+ value.unique_saturated_into();
CurrencyOf::<T>::deposit_creating(&account, max_balance.saturating_sub(balance));

let who = frame_support::dispatch::RawOrigin::Signed(account);
let value: BalanceOf<T> = value.unique_saturated_into();

QueueOf::<T>::clear();

match kind {
HandleKind::Init(code) => {
let origin = frame_support::dispatch::RawOrigin::Signed(account);
let salt = b"calculate_gas_salt".to_vec();
Self::upload_program(who.into(), code, salt, payload, initial_gas, value, false)
.map_err(|e| {
format!("Internal error: upload_program failed with '{e:?}'").into_bytes()
})?;
Self::upload_program(
origin.into(),
code,
salt,
payload,
initial_gas,
value,
false,
)
.map_err(|e| {
format!("Internal error: upload_program failed with '{e:?}'").into_bytes()
})?;
}
HandleKind::InitByHash(code_id) => {
let origin = frame_support::dispatch::RawOrigin::Signed(account);
let salt = b"calculate_gas_salt".to_vec();
Self::create_program(
who.into(),
origin.into(),
code_id,
salt,
payload,
Expand All @@ -93,16 +103,32 @@ where
})?;
}
HandleKind::Handle(destination) => {
Self::send_message(who.into(), destination, payload, initial_gas, value, false)
.map_err(|e| {
format!("Internal error: send_message failed with '{e:?}'").into_bytes()
})?;
Self::send_message_impl(
account,
destination,
payload,
initial_gas,
value,
is_prepaid,
false,
)
.map_err(|e| {
format!("Internal error: send_message failed with '{e:?}'").into_bytes()
})?;
}
HandleKind::Reply(reply_to_id, _status_code) => {
Self::send_reply(who.into(), reply_to_id, payload, initial_gas, value, false)
.map_err(|e| {
format!("Internal error: send_reply failed with '{e:?}'").into_bytes()
})?;
Self::send_reply_impl(
account,
reply_to_id,
payload,
initial_gas,
value,
is_prepaid,
false,
)
.map_err(|e| {
format!("Internal error: send_reply failed with '{e:?}'").into_bytes()
})?;
}
HandleKind::Signal(_signal_from, _status_code) => {
return Err(b"Gas calculation for `handle_signal` is not supported".to_vec());
Expand Down
1 change: 1 addition & 0 deletions pallets/gear/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13995,6 +13995,7 @@ fn calculate_gas_fails_when_calculation_limit_exceeded() {
BlockGasLimitOf::<Test>::get(),
Command::ConsumeReservationsFromList.encode(),
0,
false,
true,
false,
Some(64),
Expand Down
3 changes: 2 additions & 1 deletion runtime/common/src/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,12 @@ macro_rules! impl_runtime_apis_plus_common {
kind: HandleKind,
payload: Vec<u8>,
value: u128,
is_prepaid: bool,
allow_other_panics: bool,
initial_gas: Option<u64>,
gas_allowance: Option<u64>,
) -> Result<pallet_gear::GasInfo, Vec<u8>> {
Gear::calculate_gas_info(account_id, kind, payload, value, allow_other_panics, initial_gas, gas_allowance)
Gear::calculate_gas_info(account_id, kind, payload, value, is_prepaid, allow_other_panics, initial_gas, gas_allowance)
}

fn gear_run_extrinsic(max_gas: Option<u64>) -> <Block as BlockT>::Extrinsic {
Expand Down

0 comments on commit 5c90a34

Please sign in to comment.