Skip to content

Commit

Permalink
customised RuntimeCalls works
Browse files Browse the repository at this point in the history
  • Loading branch information
ndkazu committed Jan 9, 2025
1 parent c0f9f9d commit 2526c04
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 48 deletions.
46 changes: 22 additions & 24 deletions pop-api/examples/dao/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]

use ink::{env::Error as EnvError, prelude::vec::Vec, storage::Mapping};
use ink::{
env::Error as EnvError,
prelude::vec::Vec,
storage::{traits::Storable, Mapping},
};
use pop_api::{
primitives::TokenId,
v0::fungibles::{
Expand All @@ -9,7 +13,6 @@ use pop_api::{
Psp22Error,
},
};
use sp_runtime::serde::Serialize;

#[cfg(test)]
mod tests;
Expand All @@ -28,7 +31,7 @@ mod dao {
Executed,
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[derive(Debug, Clone, PartialEq)]
#[ink::scale_derive(Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "std", derive(ink::storage::traits::StorageLayout))]
pub enum RuntimeCall {
Expand All @@ -37,7 +40,7 @@ mod dao {
Fungibles(FungiblesCall),
}

#[derive(Debug, Clone, PartialEq, Serialize)]
#[derive(Debug, Clone, PartialEq)]
#[ink::scale_derive(Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "std", derive(ink::storage::traits::StorageLayout))]
pub enum FungiblesCall {
Expand Down Expand Up @@ -66,7 +69,7 @@ mod dao {
pub transaction: Option<Transaction>,

// Call top be executed
pub call: Option<RuntimeCall>
pub call: Option<Vec<u8>>,
}

impl Default for Proposal {
Expand All @@ -80,8 +83,7 @@ mod dao {
let current_block = ink::env::block_number::<Environment>();
let end = current_block.saturating_add(voting_period);
let call = None;
let round =
Some(VoteRound { start: current_block, end, yes_votes: 0, no_votes: 0 });
let round = Some(VoteRound { start: current_block, end, yes_votes: 0, no_votes: 0 });
Proposal {
description: Vec::new(),
status: ProposalStatus::Submitted,
Expand Down Expand Up @@ -137,8 +139,7 @@ mod dao {
fn update_votes(&mut self, approved: bool, member: Member) {
match approved {
true => {
self.yes_votes =
self.yes_votes.saturating_add(member.voting_power);
self.yes_votes = self.yes_votes.saturating_add(member.voting_power);
},
false => {
self.no_votes = self.no_votes.saturating_add(member.voting_power);
Expand Down Expand Up @@ -232,13 +233,14 @@ mod dao {
/// if the proposal is accepted.
/// - `amount` - Amount requested for this proposal
/// - `description` - Description of the proposal
/// - `call` - Proposal call to be executed
#[ink(message)]
pub fn create_proposal(
&mut self,
beneficiary: AccountId,
amount: Balance,
mut description: Vec<u8>,
call: RuntimeCall,
call: Vec<u8>,
) -> Result<(), Error> {
let caller = self.env().caller();
let contract = self.env().account_id();
Expand All @@ -249,8 +251,11 @@ mod dao {
}

self.proposal_count = self.proposal_count.saturating_add(1);
let mut proposal =
Proposal { proposal_id: self.proposal_count, call: wrapped_call, ..Default::default() };
let mut proposal = Proposal {
proposal_id: self.proposal_count,
call: wrapped_call,
..Default::default()
};
proposal.description.append(&mut description);
let transaction = Transaction { beneficiary, amount };
proposal.transaction = Some(transaction);
Expand Down Expand Up @@ -317,8 +322,7 @@ mod dao {
let mut proposal = self.proposals.get(proposal_id).ok_or(Error::ProposalNotFound)?;
let round = proposal.round.clone().ok_or(Error::ProblemWithTheContract)?;

let transaction =
proposal.transaction.clone().ok_or(Error::ProblemWithTheContract)?;
let transaction = proposal.transaction.clone().ok_or(Error::ProblemWithTheContract)?;

// Check the voting period
if self.env().block_number() <= round.end {
Expand All @@ -341,16 +345,10 @@ mod dao {
};

// RuntimeCall.
let call = proposal.call.clone().expect("There should be a call");
let _ = self.env().call_runtime(&call).map_err(EnvError::from);
/*let _ = self.env()
.call_runtime(&RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: self.token_id,
from: contract,
to: transaction.beneficiary,
value: transaction.amount,
}))
.map_err(EnvError::from);*/
let call = &proposal.call.clone().expect("There should be a call");
if let Ok(call0) = RuntimeCall::decode(&mut &call[..]) {
let _ = self.env().call_runtime(&call0).map_err(EnvError::from);
}

self.env().emit_event(Transfer {
from: Some(contract),
Expand Down
65 changes: 41 additions & 24 deletions pop-api/examples/dao/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use drink::{
session::Session,
AssetsAPI, TestExternalities, NO_SALT,
};
use ink::scale::Encode;
use ink::scale::Decode;
use pop_api::{
primitives::TokenId,
v0::fungibles::events::{Approval, Created, Transfer},
};

use super::*;
use crate::dao::{Error, Member, Proposal, Vote, FungiblesCall, RuntimeCall};
use crate::dao::{Error, FungiblesCall, Member, Proposal, RuntimeCall, Vote};

const UNIT: Balance = 10_000_000_000;
const INIT_AMOUNT: Balance = 100_000_000 * UNIT;
Expand Down Expand Up @@ -119,13 +119,15 @@ fn member_create_proposal_works(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = AMOUNT * 3;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

assert_last_contract_event!(
&session,
Expand All @@ -140,13 +142,15 @@ fn member_create_proposal_works(mut session: Session) {
let description_bis =
"Funds for creation of another Dao contract".to_string().as_bytes().to_vec();
session.set_actor(BOB);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&ALICE),
value: amount,
});
assert_ok!(create_proposal(&mut session, ALICE, amount, description_bis, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, ALICE, amount, description_bis, call_f));
assert_last_contract_event!(
&session,
Created {
Expand All @@ -169,14 +173,15 @@ fn members_vote_system_works(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = AMOUNT * 3;
session.set_actor(ALICE);

let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

session.set_actor(CHARLIE);
// Charlie vote
Expand Down Expand Up @@ -205,13 +210,15 @@ fn double_vote_fails(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = AMOUNT * 3;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

session.set_actor(CHARLIE);
// Charlie tries to vote twice for the same proposal
Expand All @@ -231,13 +238,15 @@ fn vote_fails_if_voting_period_ended(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = AMOUNT * 3;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

// Moving to blocks beyond voting period
session.sandbox().build_blocks(VOTING_PERIOD + 1);
Expand All @@ -259,13 +268,15 @@ fn vote_fails_if_not_a_member(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = AMOUNT * 3;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

session.set_actor(NON_MEMBER);
assert_eq!(vote(&mut session, 1, true), Err(Error::MemberNotFound));
Expand All @@ -286,13 +297,15 @@ fn proposal_enactment_works(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = MIN_BALANCE;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

let now = session.sandbox().block_number();
session.set_actor(CHARLIE);
Expand Down Expand Up @@ -346,13 +359,15 @@ fn same_proposal_consecutive_claim_fails(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = MIN_BALANCE;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

let now = session.sandbox().block_number();
session.set_actor(CHARLIE);
Expand Down Expand Up @@ -409,13 +424,15 @@ fn proposal_enactment_fails_if_proposal_is_rejected(mut session: Session) {
let description = "Funds for creation of a Dao contract".to_string().as_bytes().to_vec();
let amount = MIN_BALANCE;
session.set_actor(ALICE);
let mut call_f = Vec::new();
let call0 = RuntimeCall::Fungibles(FungiblesCall::TransferFrom {
token: TOKEN,
from: account_id_from_slice(&contract),
to: account_id_from_slice(&BOB),
value: amount,
});
assert_ok!(create_proposal(&mut session, BOB, amount, description, call0));
})
.encode(&mut call_f);
assert_ok!(create_proposal(&mut session, BOB, amount, description, call_f));

let now = session.sandbox().block_number();
session.set_actor(CHARLIE);
Expand Down Expand Up @@ -475,18 +492,18 @@ fn create_proposal(
beneficiary: AccountId,
amount: Balance,
description: Vec<u8>,
call: RuntimeCall,
runtimecall: Vec<u8>,
) -> Result<(), Error> {
let desc: &[u8] = &description;
let call0: Vec<u8> = serde_json::to_vec(&call).unwrap();
let call0: &[u8] = &runtimecall;
call::<Pop, (), Error>(
session,
"create_proposal",
vec![
beneficiary.to_string(),
amount.to_string(),
serde_json::to_string::<[u8]>(desc).unwrap(),
serde_json::to_string::<[u8]>(&call0).unwrap(),
serde_json::to_string::<[u8]>(call0).unwrap(),
],
None,
)
Expand Down

0 comments on commit 2526c04

Please sign in to comment.