Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pallett-gear-voucher): Extend voucher with creation of a new program from uploaded code #4171

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0bf104e
remove voucher call_deprecated
vobradovich Aug 20, 2024
8d7d19e
wip: vocuher create program
vobradovich Aug 20, 2024
e27c851
wip: update voucher & tests
vobradovich Aug 20, 2024
1369f48
voucher payment tests
vobradovich Aug 21, 2024
bb3defa
pallet gear add prepaid create_program, test
vobradovich Aug 21, 2024
db2a533
do_create_program deposit value from origin
vobradovich Aug 21, 2024
a80928a
fix benchmarking
vobradovich Aug 21, 2024
1949523
gsdk voucher create program
vobradovich Aug 21, 2024
c016124
wip: introduce VoucherPermissions
vobradovich Aug 21, 2024
43e5e0d
wip: introduce VoucherPermissionsExtend
vobradovich Aug 22, 2024
f3467ef
wip: gsdk update metadata & tests
vobradovich Aug 22, 2024
9c6be94
Merge branch 'master' into vo/voucher_create_program
vobradovich Aug 22, 2024
36f8689
gsdk create_program_with_voucher and tests
vobradovich Aug 22, 2024
2b5fcff
fix generated & docs
vobradovich Aug 23, 2024
02ca2a7
gclient create_program_bytes_with_voucher, tesst
vobradovich Aug 23, 2024
6782665
fix comments
vobradovich Aug 23, 2024
3d3b340
fix clippy
vobradovich Aug 23, 2024
7154944
Merge branch 'master' into vo/voucher_create_program
vobradovich Aug 23, 2024
d8717e9
add migration & test
vobradovich Aug 29, 2024
c699b97
Merge remote-tracking branch 'origin/master' into vo/voucher_create_p…
vobradovich Aug 29, 2024
cc0e0f5
fix clippy
vobradovich Aug 29, 2024
3089ce5
add min transfer test
vobradovich Aug 29, 2024
65ab777
fix use
vobradovich Aug 29, 2024
74a7cfe
fix
vobradovich Aug 29, 2024
eaf7fd9
add to vara migrations
vobradovich Sep 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions gclient/src/api/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1469,6 +1469,74 @@ impl GearApi {
Err(Error::EventNotFound)
}

/// Same as [`create_program_bytes`](Self::create_program_bytes), but
/// creates program using voucher.
///
/// # See also
/// - [`upload_code_with_voucher`](Self::upload_code_with_voucher) function
/// uploads
#[allow(clippy::too_many_arguments)]
pub async fn create_program_bytes_with_voucher(
&self,
voucher_id: VoucherId,
code_id: CodeId,
salt: impl AsRef<[u8]>,
payload: impl AsRef<[u8]>,
gas_limit: u64,
value: u128,
keep_alive: bool,
) -> Result<(MessageId, ProgramId, H256)> {
let salt = salt.as_ref().to_vec();
let payload = payload.as_ref().to_vec();

let tx = self
.0
.calls
.create_program_with_voucher(
voucher_id, code_id, salt, payload, gas_limit, value, keep_alive,
)
.await?;

for event in tx.wait_for_success().await?.iter() {
if let Event::Gear(GearEvent::MessageQueued {
id,
destination,
entry: MessageEntry::Init,
..
}) = event?.as_root_event::<Event>()?
{
return Ok((id.into(), destination.into(), tx.block_hash()));
}
}

Err(Error::EventNotFound)
}

/// Same as [`create_program_bytes_with_voucher`](Self::create_program_bytes_with_voucher), but
/// initializes a newly created program with an encoded `payload`.
#[allow(clippy::too_many_arguments)]
pub async fn create_program_with_voucher(
&self,
voucher_id: VoucherId,
code_id: CodeId,
salt: impl AsRef<[u8]>,
payload: impl Encode,
gas_limit: u64,
value: u128,
keep_alive: bool,
) -> Result<(MessageId, ProgramId, H256)> {
self.create_program_bytes_with_voucher(
voucher_id,
code_id,
salt,
payload.encode(),
gas_limit,
value,
keep_alive,
)
.await
}

/// Same as [`send_message_bytes`](Self::send_message_bytes), but sends a
/// message using voucher.
pub async fn send_message_bytes_with_voucher(
Expand Down
47 changes: 20 additions & 27 deletions gclient/src/api/voucher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,43 @@ use gear_core::ids::ProgramId;
use gsdk::{
ext::sp_core::H256,
metadata::{
runtime_types::pallet_gear_voucher::{internal::VoucherId, pallet::Event as VoucherEvent},
runtime_types::pallet_gear_voucher::{
internal::{VoucherId, VoucherPermissions, VoucherPermissionsExtend},
pallet::Event as VoucherEvent,
},
Event,
},
};

impl GearApi {
/// Issue a new voucher.
///
/// Returns issued `voucher_id` at specified `at_block_hash`.
///
/// Arguments:
/// * spender: user id that is eligible to use the voucher;
/// * balance: voucher balance could be used for transactions fees and gas;
/// * programs: pool of programs spender can interact with, if None - means
/// any program, limited by Config param;
/// * code_uploading: allow voucher to be used as payer for `upload_code`
/// transactions fee;
/// * duration: amount of blocks voucher could be used by spender and
/// * spender: user id that is eligible to use the voucher;
/// * balance: voucher balance could be used for transactions fees and
/// gas;
/// * programs: pool of programs spender can interact with, if None -
/// means
/// * duration: amount of blocks voucher could be used by spender and
/// couldn't be revoked by owner. Must be out in [MinDuration;
/// MaxDuration] constants. Expiration block of the voucher calculates as:
/// current bn (extrinsic exec bn) + duration + 1.
/// * permissions: voucher permissions
///
/// Returns issued `voucher_id` at specified `at_block_hash`.
pub async fn issue_voucher(
&self,
spender: ProgramId,
balance: u128,
programs: Option<Vec<ProgramId>>,
code_uploading: bool,
duration: u32,
permissions: VoucherPermissions,
) -> Result<(VoucherId, H256)> {
let spender: [u8; 32] = spender.into();

let tx = self
.0
.calls
.issue_voucher(spender, balance, programs, code_uploading, duration)
.issue_voucher(spender, balance, duration, permissions)
.await?;

for event in tx.wait_for_success().await?.iter() {
Expand All @@ -72,37 +74,29 @@ impl GearApi {

/// Update existing voucher.
///
/// This extrinsic updates existing voucher: it can only extend vouchers
/// rights in terms of balance, validity or programs to interact pool.
///
/// Can only be called by the voucher owner.
///
/// Arguments:
/// * spender: account id of the voucher spender;
/// * voucher_id: voucher id to be updated;
/// * move_ownership: optionally moves ownership to another account;
/// * balance_top_up: optionally top ups balance of the voucher from
/// origins balance;
/// * append_programs: optionally extends pool of programs by
/// `Some(programs_set)` passed or allows it to interact with any program
/// by `None` passed;
/// * code_uploading: optionally allows voucher to be used to pay fees for
/// `upload_code` extrinsics;
/// * prolong_duration: optionally increases expiry block number. If voucher
/// is expired, prolongs since current bn. Validity prolongation (since
/// current block number for expired or since storage written expiry)
/// should be in [MinDuration; MaxDuration], in other words voucher
/// couldn't have expiry greater than current block number + MaxDuration.
/// * permissions_extnend: optionally extned perimissions for voucher
///
/// Can only be called by the voucher owner.
#[allow(clippy::too_many_arguments)]
pub async fn update_voucher(
&self,
spender: ProgramId,
voucher_id: VoucherId,
move_ownership: Option<ProgramId>,
balance_top_up: Option<u128>,
append_programs: Option<Option<Vec<ProgramId>>>,
code_uploading: Option<bool>,
prolong_duration: u32,
permissions_extnend: VoucherPermissionsExtend,
) -> Result<(VoucherId, H256)> {
let spender: [u8; 32] = spender.into();
let move_ownership: Option<[u8; 32]> = move_ownership.map(|v| v.into());
Expand All @@ -115,9 +109,8 @@ impl GearApi {
voucher_id,
move_ownership,
balance_top_up,
append_programs,
code_uploading,
prolong_duration,
permissions_extnend,
)
.await?;

Expand Down
25 changes: 21 additions & 4 deletions gclient/tests/voucher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use demo_custom::{InitMessage, WASM_BINARY};
use gclient::{EventProcessor, GearApi};
use gear_core::ids::ProgramId;
use gsdk::metadata::runtime_types::pallet_gear_voucher::internal::VoucherPermissions;
use parity_scale_codec::Encode;

#[tokio::test]
Expand All @@ -35,25 +36,38 @@ async fn voucher_issue_and_upload_code_and_send_message() -> anyhow::Result<()>
let gas_limit = api.block_gas_limit()?;

// Taking account balance.
let _balance = api.total_balance(api.account_id()).await?;
let _initial_balance = api.free_balance(api.account_id()).await?;

// Subscribing for events.
let mut listener = api.subscribe().await?;

// Issue voucher
let (voucher_id, ..) = api
.issue_voucher(actor_id, voucher_initial_balance, None, true, 100)
.issue_voucher(
actor_id,
voucher_initial_balance,
100,
VoucherPermissions::all(),
)
.await?;

// Upload code with voucher
let (code_id, _) = api
.upload_code_with_voucher(voucher_id.clone(), WASM_BINARY)
.await?;

// Create program
// Create program with voucher
let payload = InitMessage::Capacitor("15".to_string()).encode();
let (message_id, program_id, ..) = api
.create_program_bytes(code_id, vec![], payload, gas_limit, 0)
.create_program_bytes_with_voucher(
voucher_id.clone(),
code_id,
vec![],
payload,
gas_limit,
0,
false,
)
.await?;

// Asserting message succeed
Expand All @@ -78,5 +92,8 @@ async fn voucher_issue_and_upload_code_and_send_message() -> anyhow::Result<()>
// Decline voucher
let (_voucher_id, ..) = api.decline_voucher_with_voucher(voucher_id.clone()).await?;

// Revoke voucher
let (_voucher_id, ..) = api.revoke_voucher(actor_id, voucher_id.clone()).await?;

Ok(())
}
63 changes: 48 additions & 15 deletions gsdk/src/metadata/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3078,19 +3078,56 @@ pub mod runtime_types {
},
#[codec(index = 3)]
DeclineVoucher,
#[codec(index = 4)]
CreateProgram {
code_id: runtime_types::gprimitives::CodeId,
salt: ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>,
payload: ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>,
gas_limit: ::core::primitive::u64,
value: _0,
keep_alive: ::core::primitive::bool,
},
}
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
pub struct VoucherId(pub [::core::primitive::u8; 32usize]);
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
pub struct VoucherInfo<_0, _1> {
pub owner: _0,
pub expiry: _1,
pub permissions:
runtime_types::pallet_gear_voucher::internal::VoucherPermissions,
}
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
pub struct VoucherPermissions {
pub programs: ::core::option::Option<
::subxt::ext::subxt_core::alloc::vec::Vec<
runtime_types::gprimitives::ActorId,
>,
>,
pub code_uploading: ::core::primitive::bool,
pub expiry: _1,
pub code_ids: ::core::option::Option<
::subxt::ext::subxt_core::alloc::vec::Vec<
runtime_types::gprimitives::CodeId,
>,
>,
}
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
pub struct VoucherPermissionsExtend {
pub append_programs: ::core::option::Option<
::core::option::Option<
::subxt::ext::subxt_core::alloc::vec::Vec<
runtime_types::gprimitives::ActorId,
>,
>,
>,
pub code_uploading: ::core::option::Option<::core::primitive::bool>,
pub append_code_ids: ::core::option::Option<
::core::option::Option<
::subxt::ext::subxt_core::alloc::vec::Vec<
runtime_types::gprimitives::CodeId,
>,
>,
>,
}
}
pub mod pallet {
Expand All @@ -3103,13 +3140,9 @@ pub mod runtime_types {
issue {
spender: ::subxt::ext::subxt_core::utils::AccountId32,
balance: ::core::primitive::u128,
programs: ::core::option::Option<
::subxt::ext::subxt_core::alloc::vec::Vec<
runtime_types::gprimitives::ActorId,
>,
>,
code_uploading: ::core::primitive::bool,
duration: ::core::primitive::u32,
permissions:
runtime_types::pallet_gear_voucher::internal::VoucherPermissions,
},
#[codec(index = 1)]
#[doc = "See [`Pallet::call`]."]
Expand All @@ -3133,15 +3166,9 @@ pub mod runtime_types {
move_ownership:
::core::option::Option<::subxt::ext::subxt_core::utils::AccountId32>,
balance_top_up: ::core::option::Option<::core::primitive::u128>,
append_programs: ::core::option::Option<
::core::option::Option<
::subxt::ext::subxt_core::alloc::vec::Vec<
runtime_types::gprimitives::ActorId,
>,
>,
>,
code_uploading: ::core::option::Option<::core::primitive::bool>,
prolong_duration: ::core::option::Option<::core::primitive::u32>,
permissions_extend:
runtime_types::pallet_gear_voucher::internal::VoucherPermissionsExtend,
},
#[codec(index = 4)]
#[doc = "See [`Pallet::decline`]."]
Expand Down Expand Up @@ -3185,6 +3212,12 @@ pub mod runtime_types {
#[codec(index = 10)]
#[doc = "Voucher is disabled for code uploading, but requested."]
CodeUploadingDisabled,
#[codec(index = 11)]
#[doc = "CodeId is not in whitelisted set for voucher."]
InappropriateCodeId,
#[codec(index = 12)]
#[doc = "Try to whitelist more CodeId than allowed."]
MaxCodeIdsLimitExceeded,
}
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
#[doc = "Pallet Gear Voucher event."]
Expand Down
Loading
Loading