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: SDK::send returns ExitCode and Option<IpldBlock> #177

Merged
merged 4 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@ members = [
[patch.crates-io]
# tracking issue: https://github.com/bitvecto-rs/funty/issues/7
funty = { git = "https://github.com/bitvecto-rs/funty/", rev = "7ef0d890fbcd8b3def1635ac1a877fc298488446" }
fvm_shared = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
fvm_sdk = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
fvm_ipld_hamt = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
fvm_ipld_amt = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
fvm_ipld_bitfield = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
fvm_ipld_encoding = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
fvm_ipld_blockstore = { git = "https://github.com/filecoin-project/ref-fvm", branch = "asr/send-refactor-v2" }
2 changes: 1 addition & 1 deletion dispatch_examples/greeter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ fvm_shared = { version = "2.0.0" }
cid = { version = "0.8.5", default-features = false }
fvm = { version = "2.0.0", default-features = false }
fvm_integration_tests = "2.0.0-alpha.1"
actors-v10 = { package = "fil_builtin_actors_bundle", git = "https://github.com/filecoin-project/builtin-actors", rev = "ad37e93e525d9f6f69ec9b2eba37c27ebca120f3" }
actors-v10 = { package = "fil_builtin_actors_bundle", git = "https://github.com/filecoin-project/builtin-actors", rev = "4e7fe33eaea6b4a01b2eccd6daa7650224fc02ad" }

[build-dependencies]
substrate-wasm-builder = "4.0"
9 changes: 5 additions & 4 deletions frc42_dispatch/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use fvm_ipld_encoding::ipld_block::IpldBlock;
#[cfg(not(feature = "no_sdk"))]
use fvm_sdk::send;
use fvm_shared::{address::Address, econ::TokenAmount, error::ErrorNumber, receipt::Receipt};
use fvm_sdk::send::Response;
use fvm_shared::{address::Address, econ::TokenAmount, error::ErrorNumber};
use thiserror::Error;

use crate::hash::{Hasher, MethodNameErr, MethodResolver};
Expand Down Expand Up @@ -35,7 +36,7 @@ impl<T: Hasher> MethodMessenger<T> {
method: &str,
params: Option<IpldBlock>,
value: TokenAmount,
) -> Result<Receipt, MethodMessengerError> {
) -> Result<Response, MethodMessengerError> {
let method = self.method_resolver.method_number(method)?;
send::send(to, method, params, value).map_err(MethodMessengerError::from)
}
Expand All @@ -46,9 +47,9 @@ impl<T: Hasher> MethodMessenger<T> {
&self,
to: &Address,
method: &str,
params: RawBytes,
params: Option<IpldBlock>,
value: TokenAmount,
) -> Result<Receipt, MethodMessengerError> {
) -> Result<Response, MethodMessengerError> {
let _method = self.method_resolver.method_number(method)?;
unimplemented!()
}
Expand Down
2 changes: 1 addition & 1 deletion frc46_factory_token/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ cid = { version = "0.8.5", default-features = false }
fvm = { version = "2.0.0", default-features = false }
fvm_integration_tests = "2.0.0"
frc46_test_actor = { path = "../testing/fil_token_integration/actors/frc46_test_actor" }
actors-v10 = { package = "fil_builtin_actors_bundle", git = "https://github.com/filecoin-project/builtin-actors", rev = "ad37e93e525d9f6f69ec9b2eba37c27ebca120f3" }
actors-v10 = { package = "fil_builtin_actors_bundle", git = "https://github.com/filecoin-project/builtin-actors", rev = "4e7fe33eaea6b4a01b2eccd6daa7650224fc02ad" }

[build-dependencies]
wasm-builder = "3.0"
14 changes: 7 additions & 7 deletions frc46_token/src/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,20 +670,20 @@ where
token_receiver: &Address,
params: FRC46TokenReceived,
) -> Result<()> {
let receipt = self.msg.send(
let ret = self.msg.send(
token_receiver,
RECEIVER_HOOK_METHOD_NUM,
IpldBlock::serialize_cbor(&params)?,
&TokenAmount::zero(),
)?;

match receipt.exit_code {
match ret.exit_code {
ExitCode::OK => Ok(()),
abort_code => Err(ReceiverHookError::Receiver {
address: *token_receiver,
exit_code: abort_code,
return_data: receipt.return_data,
}
abort_code => Err(ReceiverHookError::new_receiver_error(
*token_receiver,
abort_code,
ret.return_data,
)
.into()),
}
}
Expand Down
4 changes: 2 additions & 2 deletions frc46_token/src/token/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub struct MintReturn {
pub balance: TokenAmount,
/// The new total supply.
pub supply: TokenAmount,
/// (Optional) data returned from receiver hook
/// (Optional) CBOR-encoded data returned from receiver hook
Copy link
Member

Choose a reason for hiding this comment

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

I don't think anything here forces this to be CBOR, and this comment is likely to rot. cc @Stebalien

Copy link
Member

Choose a reason for hiding this comment

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

We should probably just switch this over to Option<IpldBlock> (or actually check the codec).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you're both right -- I'm gonna open an issue to make this change. It shouldn't be too hard to do, but I don't wanna increase the scope of this PR.

@anorth I will revert the change to the comment, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pub recipient_data: RawBytes,
}

Expand All @@ -127,7 +127,7 @@ pub struct MintReturn {
pub struct MintIntermediate {
/// Recipient address to use for querying balance
pub recipient: Address,
/// (Optional) data returned from receiver hook
/// (Optional) CBOR-encoded data returned from receiver hook
pub recipient_data: RawBytes,
}

Expand Down
32 changes: 21 additions & 11 deletions fvm_actor_utils/src/messaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_ipld_encoding::Error as IpldError;
use fvm_sdk::{actor, message, send, sys::ErrorNumber};
use fvm_shared::error::ExitCode;
use fvm_shared::receipt::Receipt;
use fvm_shared::MethodNum;
use fvm_shared::METHOD_SEND;
use fvm_shared::{address::Address, econ::TokenAmount, ActorID};
Expand Down Expand Up @@ -51,6 +50,21 @@ impl From<&MessagingError> for ExitCode {
}
}

/// Matches the SDK's Response type
/// We duplicate the type here, because this trait must be implemented
Copy link
Member

Choose a reason for hiding this comment

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

trait?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I'm referring to the Messaging trait below -- I'll clarify.

/// by actors that shouldn't depend on the SDK
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Response {
pub exit_code: ExitCode,
pub return_data: Option<IpldBlock>,
}

impl Response {
pub fn new(r: send::Response) -> Self {
Self { exit_code: (r.exit_code), return_data: r.return_data }
}
}

/// An abstraction used to send messages to other actors
pub trait Messaging {
/// Returns the address of the current actor as an ActorID
Expand All @@ -63,7 +77,7 @@ pub trait Messaging {
method: MethodNum,
params: Option<IpldBlock>,
value: &TokenAmount,
) -> Result<Receipt>;
) -> Result<Response>;

/// Attempts to resolve the given address to its ID address form
///
Expand Down Expand Up @@ -131,8 +145,8 @@ impl Messaging for FvmMessenger {
method: MethodNum,
params: Option<IpldBlock>,
value: &TokenAmount,
) -> Result<Receipt> {
Ok(send::send(to, method, params, value.clone())?)
) -> Result<Response> {
Ok(Response::new(send::send(to, method, params, value.clone())?))
}

fn resolve_id(&self, address: &Address) -> Result<ActorID> {
Expand Down Expand Up @@ -200,19 +214,15 @@ impl Messaging for FakeMessenger {
method: MethodNum,
params: Option<IpldBlock>,
_value: &TokenAmount,
) -> Result<Receipt> {
) -> Result<Response> {
self.last_message.borrow_mut().replace(FakeMessage { params, method });

if *self.abort_next_send.borrow() {
self.abort_next_send.replace(false);
return Ok(Receipt {
exit_code: ExitCode::USR_UNSPECIFIED,
gas_used: 0,
return_data: Default::default(),
});
return Ok(Response { exit_code: ExitCode::USR_UNSPECIFIED, return_data: None });
}

Ok(Receipt { exit_code: ExitCode::OK, return_data: Default::default(), gas_used: 0 })
Ok(Response { exit_code: ExitCode::OK, return_data: None })
}

fn resolve_id(&self, address: &Address) -> Result<ActorID> {
Expand Down
33 changes: 25 additions & 8 deletions fvm_actor_utils/src/receiver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ pub enum ReceiverHookError {
Receiver { address: Address, exit_code: ExitCode, return_data: RawBytes },
}

impl ReceiverHookError {
/// Construct a new ReceiverHookError::Receiver
pub fn new_receiver_error(
address: Address,
exit_code: ExitCode,
return_data: Option<IpldBlock>,
) -> Self {
Self::Receiver {
address,
exit_code,
return_data: return_data.map_or(RawBytes::default(), |b| RawBytes::new(b.data)),
}
}
}

impl From<&ReceiverHookError> for ExitCode {
fn from(error: &ReceiverHookError) -> Self {
match error {
Expand Down Expand Up @@ -120,7 +135,7 @@ impl<T: RecipientData> ReceiverHook<T> {
payload: mem::take(&mut self.token_params), // once encoded and sent, we don't need this anymore
};

let receipt = msg.send(
let ret = msg.send(
&self.address,
RECEIVER_HOOK_METHOD_NUM,
IpldBlock::serialize_cbor(&params).map_err(|e| {
Expand All @@ -132,16 +147,18 @@ impl<T: RecipientData> ReceiverHook<T> {
&TokenAmount::zero(),
)?;

match receipt.exit_code {
match ret.exit_code {
ExitCode::OK => {
self.result_data.as_mut().unwrap().set_recipient_data(receipt.return_data);
self.result_data.as_mut().unwrap().set_recipient_data(
ret.return_data.map_or(RawBytes::default(), |b| RawBytes::new(b.data)),
);
Ok(self.result_data.take().unwrap())
}
abort_code => Err(ReceiverHookError::Receiver {
address: self.address,
exit_code: abort_code,
return_data: receipt.return_data,
}),
abort_code => Err(ReceiverHookError::new_receiver_error(
self.address,
abort_code,
ret.return_data,
)),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion testing/fil_token_integration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_tuple = { version = "0.5.0" }

[dev-dependencies]
actors-v10 = { package = "fil_builtin_actors_bundle", git = "https://github.com/filecoin-project/builtin-actors", rev = "ad37e93e525d9f6f69ec9b2eba37c27ebca120f3" }
actors-v10 = { package = "fil_builtin_actors_bundle", git = "https://github.com/filecoin-project/builtin-actors", rev = "4e7fe33eaea6b4a01b2eccd6daa7650224fc02ad" }
basic_nft_actor = {path = "actors/basic_nft_actor"}
basic_receiving_actor = { path = "actors/basic_receiving_actor" }
basic_token_actor = { path = "actors/basic_token_actor" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,23 @@ fn invoke(input: u32) -> u32 {

// get our balance
let self_address = Address::new_id(sdk::message::receiver());
let balance_receipt = sdk::send::send(&state.token_address.unwrap(), method_hash!("BalanceOf"),
let balance_ret = sdk::send::send(&state.token_address.unwrap(), method_hash!("BalanceOf"),
IpldBlock::serialize_cbor(&self_address).unwrap(), TokenAmount::zero()).unwrap();
if !balance_receipt.exit_code.is_success() {
if !balance_ret.exit_code.is_success() {
panic!("unable to get balance");
}
let balance = balance_receipt.return_data.deserialize::<TokenAmount>().unwrap();
let balance = balance_ret.return_data.unwrap().deserialize::<TokenAmount>().unwrap();

// transfer to target address
let params = TransferParams {
to: target,
amount: balance, // send everything
operator_data: RawBytes::default(),
};
let transfer_receipt = sdk::send::send(&state.token_address.unwrap(), method_hash!("Transfer"),
let transfer_ret = sdk::send::send(&state.token_address.unwrap(), method_hash!("Transfer"),

IpldBlock::serialize_cbor(&params).unwrap(), TokenAmount::zero()).unwrap();
if !transfer_receipt.exit_code.is_success() {
if !transfer_ret.exit_code.is_success() {
panic!("transfer call failed");
}

Expand Down
19 changes: 12 additions & 7 deletions testing/fil_token_integration/actors/frc46_test_actor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use fvm_ipld_encoding::{
RawBytes, DAG_CBOR,
};
use fvm_sdk as sdk;
use fvm_shared::receipt::Receipt;
use fvm_shared::{address::Address, bigint::Zero, econ::TokenAmount, error::ExitCode};
use sdk::NO_DATA_BLOCK_ID;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -68,28 +69,32 @@ pub fn action(action: TestAction) -> RawBytes {
/// Execute the Transfer action
fn transfer(token: Address, to: Address, amount: TokenAmount, operator_data: RawBytes) -> u32 {
let transfer_params = TransferParams { to, amount, operator_data };
let receipt = sdk::send::send(
let ret = sdk::send::send(
&token,
method_hash!("Transfer"),
IpldBlock::serialize_cbor(&transfer_params).unwrap(),
TokenAmount::zero(),
)
.unwrap();
// ignore failures at this level and return the transfer call receipt so caller can decide what to do
return_ipld(&receipt)
return_ipld(&Receipt {
exit_code: ret.exit_code,
return_data: ret.return_data.map_or(RawBytes::default(), |b| RawBytes::new(b.data)),
gas_used: 0,
})
}

/// Execute the Burn action
fn burn(token: Address, amount: TokenAmount) -> u32 {
let burn_params = BurnParams { amount };
let receipt = sdk::send::send(
let ret = sdk::send::send(
&token,
method_hash!("Burn"),
IpldBlock::serialize_cbor(&burn_params).unwrap(),
TokenAmount::zero(),
)
.unwrap();
if !receipt.exit_code.is_success() {
if !ret.exit_code.is_success() {
panic!("burn call failed");
}
NO_DATA_BLOCK_ID
Expand Down Expand Up @@ -150,11 +155,11 @@ fn invoke(input: u32) -> u32 {
// get our balance
let get_balance = || {
let self_address = Address::new_id(sdk::message::receiver());
let balance_receipt = sdk::send::send(&params.token_address, method_hash!("BalanceOf"), IpldBlock::serialize_cbor(&self_address).unwrap(), TokenAmount::zero()).unwrap();
if !balance_receipt.exit_code.is_success() {
let balance_ret = sdk::send::send(&params.token_address, method_hash!("BalanceOf"), IpldBlock::serialize_cbor(&self_address).unwrap(), TokenAmount::zero()).unwrap();
if !balance_ret.exit_code.is_success() {
panic!("unable to get balance");
}
balance_receipt.return_data.deserialize::<TokenAmount>().unwrap()
balance_ret.return_data.unwrap().deserialize::<TokenAmount>().unwrap()
};

match params.action {
Expand Down
13 changes: 9 additions & 4 deletions testing/fil_token_integration/actors/frcxx_test_actor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use fvm_ipld_encoding::{
RawBytes, DAG_CBOR,
};
use fvm_sdk as sdk;
use fvm_shared::receipt::Receipt;
use fvm_shared::{address::Address, bigint::Zero, econ::TokenAmount, error::ExitCode};
use sdk::NO_DATA_BLOCK_ID;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -67,27 +68,31 @@ pub fn action(action: TestAction) -> RawBytes {
/// Execute the Transfer action
fn transfer(token: Address, to: Address, token_ids: Vec<TokenID>, operator_data: RawBytes) -> u32 {
let transfer_params = TransferParams { to, token_ids, operator_data };
let receipt = sdk::send::send(
let ret = sdk::send::send(
&token,
method_hash!("Transfer"),
IpldBlock::serialize_cbor(&transfer_params).unwrap(),
TokenAmount::zero(),
)
.unwrap();
// ignore failures at this level and return the transfer call receipt so caller can decide what to do
return_ipld(&receipt)
return_ipld(&Receipt {
exit_code: ret.exit_code,
return_data: ret.return_data.map_or(RawBytes::default(), |b| RawBytes::new(b.data)),
gas_used: 0,
})
}

/// Execute the Burn action
fn burn(token: Address, token_ids: Vec<TokenID>) -> u32 {
let receipt = sdk::send::send(
let ret = sdk::send::send(
&token,
method_hash!("Burn"),
IpldBlock::serialize_cbor(&token_ids).unwrap(),
TokenAmount::zero(),
)
.unwrap();
if !receipt.exit_code.is_success() {
if !ret.exit_code.is_success() {
panic!("burn call failed");
}
NO_DATA_BLOCK_ID
Expand Down