-
Notifications
You must be signed in to change notification settings - Fork 257
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
docs: document callback_unwrap
attribute
#1313
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -277,6 +277,63 @@ extern crate quickcheck; | |||||||||
/// } | ||||||||||
/// ``` | ||||||||||
/// | ||||||||||
/// ## `#[callback_unwrap]` (annotates function parameters) | ||||||||||
/// | ||||||||||
/// Automatically unwraps the successful result of a callback from a cross-contract call. | ||||||||||
/// Used on parameters in callback methods that are invoked as part of a cross-contract call chain. | ||||||||||
/// If the promise fails, the method will panic with the error message. | ||||||||||
/// | ||||||||||
/// This attribute is commonly used with [`PromiseOrValue<T>`], which represents either an immediate value | ||||||||||
/// or a promise that will resolve to that value. | ||||||||||
Comment on lines
+286
to
+287
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this reference+applied_suggestion can stay, despite the #1313 (comment) comment |
||||||||||
/// | ||||||||||
/// ### Example with Cross-Contract Factorial: | ||||||||||
/// | ||||||||||
/// ```rust | ||||||||||
/// # use near_sdk::{near, env, PromiseOrValue}; | ||||||||||
/// #[near(contract_state)] | ||||||||||
/// #[derive(Default)] | ||||||||||
/// pub struct CrossContract {} | ||||||||||
/// | ||||||||||
/// #[near] | ||||||||||
/// impl CrossContract { | ||||||||||
/// pub fn factorial(&self, n: u32) -> PromiseOrValue<u32> { | ||||||||||
/// if n <= 1 { | ||||||||||
/// return PromiseOrValue::Value(1); | ||||||||||
/// } | ||||||||||
/// let account_id = env::current_account_id(); | ||||||||||
/// Self::ext(account_id.clone()) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EDIT: discard this comment completely This should mention that As the documentation for this should mention that impl CrossContractExt {
pub fn factorial(self, n: u32) -> ::near_sdk::Promise {
...
}
pub fn factorial_mult(self, n: u32) -> ::near_sdk::Promise {
...
}
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TobieTom in order to avoid explaning higher-level concepts with other unexplained higher-level primitives ( #[near]
impl CrossContract {
pub fn factorial(&self, n: u32) {
if n <= 1 {
env::value_return(&serde_json::to_vec(&1u32).unwrap());
return;
}
let account_id = env::current_account_id();
let prepaid_gas = env::prepaid_gas().saturating_sub(FACTORIAL_CALL_GAS);
let promise0 = env::promise_create(
account_id.clone(),
"factorial",
&serde_json::to_vec(&(n - 1,)).unwrap(),
NearToken::from_near(0),
prepaid_gas.saturating_sub(FACTORIAL_MULT_CALL_GAS),
);
let promise1 = env::promise_then(
promise0,
account_id,
"factorial_mult",
&serde_json::to_vec(&(n,)).unwrap(),
NearToken::from_near(0),
FACTORIAL_MULT_CALL_GAS,
);
env::promise_return(promise1);
}
/// Used for callbacks only. Multiplies current factorial result by the next value. Panics if
/// it is not called by the contract itself.
#[private]
pub fn factorial_mult(&self, n: u32, #[callback_unwrap] factorial_n_minus_one_result: u32) -> u32 {
log!("Received n: {:?}", n);
log!("Received factorial_n_minus_one_result: {:?}", factorial_n_minus_one_result);
let result = n * factorial_n_minus_one_result;
log!("Multiplied {:?}", result.clone());
result
}
} and mention with references that [env::promise_create], [env::promise_then] and [env::promise_return] are used in this definetely works (adjusted to some imports required) . i can see logs: [
"Received n: 5",
"Received factorial_n_minus_one_result: 24",
"Multiplied 120",
], in the log |
||||||||||
/// .factorial(n - 1) | ||||||||||
/// .then(Self::ext(account_id).factorial_mult(n)) | ||||||||||
/// .into() | ||||||||||
/// } | ||||||||||
/// | ||||||||||
/// #[private] | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it can be mentioned with link to |
||||||||||
/// pub fn factorial_mult(&self, n: u32, #[callback_unwrap] cur: u32) -> u32 { | ||||||||||
/// n * cur | ||||||||||
/// } | ||||||||||
Comment on lines
+311
to
+313
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for task #1312 (NOT in scope of current pr) it can be mentioned that the attribute works by doing the following: #[no_mangle]
pub extern "C" fn factorial_mult() {
....
let data: ::std::vec::Vec<u8> = match ::near_sdk::env::promise_result(0u64) {
::near_sdk::PromiseResult::Successful(x) => x,
_ => ::near_sdk::env::panic_str("Callback computation 0 was not successful"),
};
let cur: u32 = match ::near_sdk::serde_json::from_slice(&data) {
Ok(deserialized) => deserialized,
Err(_) => ::near_sdk::env::panic_str("Failed to deserialize callback using JSON"),
};
let contract: CrossContract = ::near_sdk::env::state_read().unwrap_or_default();
let result = CrossContract::factorial_mult(&contract, n, cur);
... with links to corresponding [near_sdk::env] host-functions used |
||||||||||
/// } | ||||||||||
/// ``` | ||||||||||
/// | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should also mention 4 in-repo examples with doc-links # ran in ./examples sub-folder of repo root
❯ : grep callback_unwrap -R .
./cross-contract-calls/high-level/src/lib.rs: pub fn factorial_mult(&self, n: u32, #[callback_unwrap] factorial_n_minus_one_result: u32) -> u32 {
./adder/src/lib.rs: #[callback_unwrap] a: DoublePair,
./adder/src/lib.rs: #[callback_unwrap] b: DoublePair,
./callback-results/src/lib.rs: #[callback_unwrap] a: u8, |
||||||||||
/// ### Error Handling Alternative | ||||||||||
/// | ||||||||||
/// If you need to handle failed promises explicitly, receive the `Result<T, PromiseError>` directly | ||||||||||
/// instead of using `#[callback_unwrap]`: | ||||||||||
/// | ||||||||||
/// ```rust | ||||||||||
/// # use near_sdk::{near, PromiseError}; | ||||||||||
/// # #[near(contract_state)] | ||||||||||
/// # pub struct Contract {} | ||||||||||
/// # #[near] | ||||||||||
/// # impl Contract { | ||||||||||
/// #[private] | ||||||||||
/// pub fn handle_callback(&mut self, result: Result<u8, PromiseError>) { | ||||||||||
/// match result { | ||||||||||
/// Ok(value) => { /* Handle success */ }, | ||||||||||
/// Err(err) => { /* Handle error */ }, | ||||||||||
/// } | ||||||||||
/// } | ||||||||||
/// # } | ||||||||||
/// ``` | ||||||||||
Comment on lines
+317
to
+336
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this example looks a superficial copy-paste from elsewhere, and it's not very clear how it's an alternative one to the first heading if it's indeed an alternative to the first heading, it should accomplish the same purpose as first heading, but without using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TobieTom i suggest that you remove this example completely, as from what i can see the #[callback_result] c: Result<u8, PromiseError>, |
||||||||||
/// ## `#[result_serializer(...)]` (annotates methods of a type in its `impl` block) | ||||||||||
/// | ||||||||||
/// The attribute defines the serializer for function return serialization. | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole anchor/heading of this attribute should be blaced after
#[handle_result]
attribute's anchor