Skip to content

Commit

Permalink
Send initial results in MintIntermediate to avoid extra queries
Browse files Browse the repository at this point in the history
  • Loading branch information
abright committed Oct 4, 2022
1 parent 953de29 commit b0a291b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 15 deletions.
31 changes: 23 additions & 8 deletions frc46_token/src/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,16 @@ where

// Increase the balance of the actor and increase total supply
let result = self.transaction(|state, bs| {
state.change_balance_by(&bs, owner_id, amount)?;
state.change_supply_by(amount)?;
Ok(MintIntermediate { recipient: *initial_owner, recipient_data: RawBytes::default() })
let balance = state.change_balance_by(&bs, owner_id, amount)?;
let supply = state.change_supply_by(amount)?;
Ok(MintIntermediate {
recipient: *initial_owner,
return_data: MintReturn {
balance,
supply: supply.clone(),
recipient_data: RawBytes::default(),
},
})
})?;

// return the params we'll send to the receiver hook
Expand All @@ -188,11 +195,19 @@ where
/// Finalise return data from MintIntermediate data returned by calling receiver hook after minting
/// This is done to allow reloading the state if it changed as a result of the hook call
/// so we can return an accurate balance even if the receiver transferred or burned tokens upon receipt
pub fn mint_return(&self, intermediate: MintIntermediate) -> Result<MintReturn> {
pub fn mint_return(
&self,
intermediate: MintIntermediate,
state_updated: bool,
) -> Result<MintReturn> {
if !state_updated {
return Ok(intermediate.return_data);
}

Ok(MintReturn {
balance: self.balance_of(&intermediate.recipient)?,
supply: self.total_supply(),
recipient_data: intermediate.recipient_data,
recipient_data: intermediate.return_data.recipient_data,
})
}

Expand Down Expand Up @@ -946,7 +961,7 @@ mod test {
.unwrap();
token.flush().unwrap();
let hook_ret = hook.call(token.msg()).unwrap();
let result = token.mint_return(hook_ret).unwrap();
let result = token.mint_return(hook_ret, false).unwrap();
assert_eq!(TokenAmount::from_atto(1_000_000), result.balance);
assert_eq!(TokenAmount::from_atto(1_000_000), result.supply);

Expand Down Expand Up @@ -1005,7 +1020,7 @@ mod test {
.unwrap();
token.flush().unwrap();
let hook_ret = hook.call(token.msg()).unwrap();
let result = token.mint_return(hook_ret).unwrap();
let result = token.mint_return(hook_ret, false).unwrap();
assert_eq!(TokenAmount::from_atto(2_000_000), result.balance);
assert_eq!(TokenAmount::from_atto(2_000_000), result.supply);

Expand Down Expand Up @@ -1038,7 +1053,7 @@ mod test {
.unwrap();
token.flush().unwrap();
let hook_ret = hook.call(token.msg()).unwrap();
let result = token.mint_return(hook_ret).unwrap();
let result = token.mint_return(hook_ret, false).unwrap();
assert_eq!(TokenAmount::from_atto(1_000_000), result.balance);
assert_eq!(TokenAmount::from_atto(3_000_000), result.supply);

Expand Down
7 changes: 4 additions & 3 deletions frc46_token/src/token/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,18 @@ pub struct MintReturn {
impl Cbor for MintReturn {}

/// Intermediate data used by mint_return to construct the return data
/// Used for handling state changes during the receiver hook call
#[derive(Debug)]
pub struct MintIntermediate {
/// Recipient address to use for querying balance
pub recipient: Address,
/// (Optional) data returned from receiver hook
pub recipient_data: RawBytes,
/// Return data from the originating mint() call
pub return_data: MintReturn,
}

impl RecipientData for MintIntermediate {
fn set_recipient_data(&mut self, data: RawBytes) {
self.recipient_data = data;
self.return_data.recipient_data = data;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,15 @@ pub struct MintParams {
impl Cbor for MintParams {}

impl BasicToken<'_> {
fn reload(&mut self, initial_cid: &Cid) -> Result<(), RuntimeError> {
fn reload(&mut self, initial_cid: &Cid) -> Result<bool, RuntimeError> {
// todo: revise error type here so it plays nice with the result and doesn't need unwrap
let new_cid = sdk::sself::root().unwrap();
if new_cid != *initial_cid {
self.util.load_replace(&new_cid)?;
Ok(true)
} else {
Ok(false)
}
Ok(())
}

fn mint(&mut self, params: MintParams) -> Result<MintReturn, RuntimeError> {
Expand All @@ -177,8 +179,8 @@ impl BasicToken<'_> {

let hook_ret = hook.call(self.util.msg())?;

self.reload(&cid)?;
let ret = self.util.mint_return(hook_ret)?;
let updated = self.reload(&cid)?;
let ret = self.util.mint_return(hook_ret, updated)?;

Ok(ret)
}
Expand Down

0 comments on commit b0a291b

Please sign in to comment.