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

added events, new view, upgrade function #1773

Merged
merged 2 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"to": "sc:ping-pong",
"function": "pongAll",
"arguments": [],
"gasLimit": "3,500,000",
"gasLimit": "4,500,000",
"gasPrice": "0"
},
"expect": {
Expand Down
71 changes: 63 additions & 8 deletions contracts/examples/ping-pong-egld/src/ping_pong.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use multiversx_sc::imports::*;

mod user_status;
mod types;

use user_status::UserStatus;
use types::{ContractState, UserStatus};

/// Derived empirically.
const PONG_ALL_LOW_GAS_LIMIT: u64 = 3_000_000;
Expand All @@ -25,7 +25,7 @@ const PONG_ALL_LOW_GAS_LIMIT: u64 = 3_000_000;
#[multiversx_sc::contract]
pub trait PingPong {
/// Necessary configuration when deploying:
/// `ping_amount` - the exact EGLD amounf that needs to be sent when `ping`-ing.
/// `ping_amount` - the exact EGLD amount that needs to be sent when `ping`-ing.
/// `duration_in_seconds` - how much time (in seconds) until contract expires.
/// `opt_activation_timestamp` - optionally specify the contract to only actvivate at a later date.
/// `max_funds` - optional funding cap, no more funds than this can be added to the contract.
Expand All @@ -48,7 +48,20 @@ pub trait PingPong {
}

#[upgrade]
fn upgrade(&self) {}
fn upgrade(
&self,
ping_amount: &BigUint,
duration_in_seconds: u64,
opt_activation_timestamp: Option<u64>,
max_funds: OptionalValue<BigUint>,
) {
self.init(
ping_amount,
duration_in_seconds,
opt_activation_timestamp,
max_funds,
)
}

/// User sends some EGLD to be locked in the contract for a period of time.
/// Optional `_data` argument is ignored.
Expand Down Expand Up @@ -98,6 +111,8 @@ pub trait PingPong {
sc_panic!("already withdrawn")
},
}

self.ping_event(&caller, &payment);
}

fn pong_by_user_id(&self, user_id: usize) -> Result<(), &'static str> {
Expand All @@ -108,7 +123,8 @@ pub trait PingPong {
self.user_status(user_id).set(UserStatus::Withdrawn);
if let Some(user_address) = self.user_mapper().get_user_address(user_id) {
let amount = self.ping_amount().get();
self.tx().to(user_address).egld(amount).transfer();
self.tx().to(&user_address).egld(&amount).transfer();
self.pong_event(&user_address, &amount);
Result::Ok(())
} else {
Result::Err("unknown user")
Expand Down Expand Up @@ -142,31 +158,38 @@ pub trait PingPong {
/// Can only be called after expiration.
#[endpoint(pongAll)]
fn pong_all(&self) -> OperationCompletionStatus {
let now = self.blockchain().get_block_timestamp();
require!(
self.blockchain().get_block_timestamp() >= self.deadline().get(),
now >= self.deadline().get(),
"can't withdraw before deadline"
);

let num_users = self.user_mapper().get_user_count();
let mut pong_all_last_user = self.pong_all_last_user().get();
let mut status = OperationCompletionStatus::InterruptedBeforeOutOfGas;
loop {
if pong_all_last_user >= num_users {
// clear field and reset to 0
pong_all_last_user = 0;
self.pong_all_last_user().set(pong_all_last_user);
return OperationCompletionStatus::Completed;
status = OperationCompletionStatus::Completed;
break;
}

if self.blockchain().get_gas_left() < PONG_ALL_LOW_GAS_LIMIT {
self.pong_all_last_user().set(pong_all_last_user);
return OperationCompletionStatus::InterruptedBeforeOutOfGas;
break;
}

pong_all_last_user += 1;

// in case of error just ignore the error and skip
let _ = self.pong_by_user_id(pong_all_last_user);
}

self.pong_all_event(now, &status, pong_all_last_user);

status
}

/// Lists the addresses of all users that have `ping`-ed,
Expand All @@ -176,6 +199,19 @@ pub trait PingPong {
self.user_mapper().get_all_addresses().into()
}

/// Returns the current contract state as a struct
/// for faster fetching from external parties
#[view(getContractState)]
fn get_contract_state(&self) -> ContractState<Self::Api> {
ContractState {
ping_amount: self.ping_amount().get(),
deadline: self.deadline().get(),
activation_timestamp: self.activation_timestamp().get(),
max_funds: self.max_funds().get(),
pong_all_last_user: self.pong_all_last_user().get(),
}
}

// storage

#[view(getPingAmount)]
Expand Down Expand Up @@ -213,4 +249,23 @@ pub trait PingPong {
#[view(pongAllLastUser)]
#[storage_mapper("pongAllLastUser")]
fn pong_all_last_user(&self) -> SingleValueMapper<usize>;

// events

/// Signals a successful ping by user with amount
#[event]
fn ping_event(&self, #[indexed] caller: &ManagedAddress, pinged_amount: &BigUint);

/// Signals a successful pong by user with amount
#[event]
fn pong_event(&self, #[indexed] caller: &ManagedAddress, ponged_amount: &BigUint);

/// Signals the beginning of the pong_all operation, status and last user
#[event]
fn pong_all_event(
&self,
#[indexed] timestamp: u64,
#[indexed] status: &OperationCompletionStatus,
#[indexed] pong_all_last_user: usize,
);
}
20 changes: 20 additions & 0 deletions contracts/examples/ping-pong-egld/src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use multiversx_sc::derive_imports::*;
use multiversx_sc::imports::*;

#[type_abi]
#[derive(TopEncode, TopDecode, PartialEq, Eq, Clone, Copy)]
pub enum UserStatus {
New,
Registered,
Withdrawn,
}

#[type_abi]
#[derive(TopEncode, TopDecode, Default)]
pub struct ContractState<M: ManagedTypeApi> {
pub ping_amount: BigUint<M>,
pub deadline: u64,
pub activation_timestamp: u64,
pub max_funds: Option<BigUint<M>>,
pub pong_all_last_user: usize,
}
8 changes: 0 additions & 8 deletions contracts/examples/ping-pong-egld/src/user_status.rs

This file was deleted.

5 changes: 3 additions & 2 deletions contracts/examples/ping-pong-egld/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

// Init: 1
// Upgrade: 1
// Endpoints: 10
// Endpoints: 11
// Async Callback (empty): 1
// Total number of exported functions: 13
// Total number of exported functions: 14

#![no_std]

Expand All @@ -24,6 +24,7 @@ multiversx_sc_wasm_adapter::endpoints! {
pong => pong
pongAll => pong_all
getUserAddresses => get_user_addresses
getContractState => get_contract_state
getPingAmount => ping_amount
getDeadline => deadline
getActivationTimestamp => activation_timestamp
Expand Down
Loading