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

Add inspect message #59

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
121 changes: 82 additions & 39 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions xtc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ xtc-history = {path="../xtc-history/xtc-history"}
xtc-history-common = {path= "../xtc-history/xtc-history-common" }
serde_bytes = "0.11"
ic-kit = "0.4.2"
ic-kit-sys = "0.1.1"
ic-cdk = "0.3.1"
serde = { version="1.0.130", features = ["derive"] }
derive_builder = "0.10.2"
Expand Down
44 changes: 44 additions & 0 deletions xtc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,50 @@ mod utils;
#[cfg(test)]
mod tests;

// TODO(qti3e): Fix this mess when kit v0.5 is out. there shouldn't be any unsafe code.
use crate::fee::compute_fee;
use crate::ledger::Ledger;
use ic_kit::ic;
use ic_kit::macros::inspect_message;
use ic_kit_sys::ic0;

#[inspect_message]
fn inspect_message() {
let message_size = unsafe { ic0::msg_arg_data_size() as usize };

// based on our candid the largest fixed size payload we can accept is only 2 principals
// encode(opt principal, opt principal) -> 83 bytes
// encode(opt principal, opt principal, opt principal) -> 119 bytes
// the only unsized type used is our good friend `nat`, which is dynamically sized
// but supposing a u128 is only legal, it is 16 bytes, for nat.
// (nat, nat) -> ~40bytes
// here we allow an error margin, and reject messages larger than 500bytes.
if message_size <= 500 {
ic_cdk::api::call::accept_message();
return;
}

let method_name = ic_cdk::api::call::method_name();

// Exception: wallet_call should actually accept large payload, but only if user has
// the fee to pay.
if method_name == "wallet_call" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do this only if message size is greater than our threshold? This way this block doesn't need to run every wallet call. Very minor and I'm cool with leaving it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

// The fee is currently constant, but we assume the call is gonna spend 100B cycles.
let fee = compute_fee(100_000_000_000);
let ledger = ic::get_mut::<Ledger>();
let caller = ic_cdk::caller();
let balance = ledger.balance(&caller);

// Accept the message if the user does have the balance to pay the fee.
if balance > fee {
ic_cdk::api::call::accept_message();
return;
}
}
}

// inspect message mess ->

/// Perform only one pending async task, returns whether an async call was performed
/// as the result of calling this method or not.
/// This method should only be called from updates.
Expand Down