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(marketplace): escrow sell order credits #878

Merged
merged 11 commits into from
Mar 15, 2022
Merged

Conversation

technicallyty
Copy link
Contributor

@technicallyty technicallyty commented Mar 12, 2022

Description

  • adds Escrowed field to both BatchBalance and BatchSupply
  • updates Sell to escrow the credits in the order
  • updates Sell test to check balances/supplies are updated
  • updates Sell to emit EventSell

Closes: #821


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title
  • added ! to the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • followed the guidelines for building modules
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • included comments for documenting Go code
  • updated the relevant documentation or specification
  • reviewed "Files changed" and left comments if necessary
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed ! in the type prefix if API or client breaking change
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic
  • reviewed API design and naming
  • reviewed documentation is accurate
  • reviewed tests and test coverage
  • manually tested (if applicable)

Copy link
Member

@ryanchristo ryanchristo left a comment

Choose a reason for hiding this comment

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

The escrowed credits need to be returned to the seller upon expiration: https://github.com/regen-network/regen-ledger/blob/master/x/ecocredit/server/expiration.go#L23-L35.

Also, we should add a message for cancel sell order, allowing the seller to cancel their order at any time to reclaim their escrowed credits, which we can do in a separate pull request (#880).

Looking good otherwise. I'll give it a closer look after the expired sell orders update.

Copy link
Collaborator

@robert-zaremba robert-zaremba left a comment

Choose a reason for hiding this comment

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

utACK. Left few suggestions.

x/ecocredit/server/marketplace/sell.go Outdated Show resolved Hide resolved
x/ecocredit/server/marketplace/sell.go Outdated Show resolved Hide resolved
// subtract the desired sell amount from tradable balance
newTradable, err := math.SafeSubBalance(tradable, sellQty)
if err != nil {
return fmt.Errorf("tradable balance: %s, sell order request: %s - %w", tradable.String(), sellQty.String(), err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's use .ErrInvalidRequest.Wrapf in all validation errors.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, if we use %v then we don't need to call String()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, although i had to change the inner error to %s", err.Error(). the sdkerrors.Wrapf uses Sprintf under the hood which doesn't support %w :(

return err
}
supply.EscrowedAmount = supEscrow.String()
supply.TradableAmount = supTradable.String()
Copy link
Collaborator

Choose a reason for hiding this comment

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

@aaronc shouldn't we have another type to serialize big numbers in the state? One type for response, another type for state.

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 so. State is directly exposed to clients and in the absence of any standard that clients can decode, string is the best choice. If someone defines a standard that's well specified this could change in the future

@@ -195,6 +195,9 @@ message BatchBalance {

// retired is the retired amount of credits
string retired = 4;

// escrowed is the amount of credits locked up in escrow for the marketplace.
string escrowed = 5;
Copy link
Member

Choose a reason for hiding this comment

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

Is escrowed there right user facing name? Maybe in_sell_orders?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is there a specific concern you have regarding users and the word escrowed? i felt like it was a good fit - in_sell_orders seems a bit verbose

Copy link
Member

Choose a reason for hiding this comment

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

I could go either way. in_sell_orders is more specific and potentially more user friendly but provided the supporting documentation, escrowed seems ok to me as well.

Copy link
Member

Choose a reason for hiding this comment

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

How about you make a call @ryanchristo

Copy link
Member

Choose a reason for hiding this comment

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

Ok, escrowed it is. More aligned with tradable and retired.


// escrowed_amount is the amount of credits in the batch that have been
// locked up in escrow for use in the marketplace.
string escrowed_amount = 5;
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need to have a separate supply here? I guess maybe that's a useful invariant?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it seemed right to have it as the credits aren't necessarily tradable nor retired. if anything, it might be useful to be able to query a batch to see how many credits are in the market?

return err
}
supply.EscrowedAmount = supEscrow.String()
supply.TradableAmount = supTradable.String()
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 so. State is directly exposed to clients and in the absence of any standard that clients can decode, string is the best choice. If someone defines a standard that's well specified this could change in the future

@codecov
Copy link

codecov bot commented Mar 15, 2022

Codecov Report

Merging #878 (c7b4bdb) into master (f0faf4c) will decrease coverage by 0.13%.
The diff coverage is 48.93%.

❗ Current head c7b4bdb differs from pull request most recent head 3ab6cf8. Consider uploading reports for the commit 3ab6cf8 to get more accurate results

@@            Coverage Diff             @@
##           master     #878      +/-   ##
==========================================
- Coverage   73.99%   73.85%   -0.14%     
==========================================
  Files         172      173       +1     
  Lines       22142    22233      +91     
==========================================
+ Hits        16383    16421      +38     
- Misses       4640     4671      +31     
- Partials     1119     1141      +22     
Flag Coverage Δ
experimental-codecov 73.82% <48.93%> (-0.14%) ⬇️
stable-codecov 67.02% <48.93%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Copy link
Member

@ryanchristo ryanchristo left a comment

Choose a reason for hiding this comment

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

PruneOrders was not updated and I believe we want to include pruning of expired buy and sell orders in BeginBlocker not EndBlocker. We are still deleting sell orders without returning escrowed funds in the current implementation.

@@ -195,6 +195,9 @@ message BatchBalance {

// retired is the retired amount of credits
string retired = 4;

// escrowed is the amount of credits locked up in escrow for the marketplace.
string escrowed = 5;
Copy link
Member

Choose a reason for hiding this comment

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

I could go either way. in_sell_orders is more specific and potentially more user friendly but provided the supporting documentation, escrowed seems ok to me as well.

Comment on lines 12 to 14
// PruneSellOrders is an EndBlock function that moves escrowed credits back into their tradable balance and deletes orders
// that have expired.
func (k Keeper) PruneSellOrders(ctx context.Context) error {
Copy link
Member

@ryanchristo ryanchristo Mar 15, 2022

Choose a reason for hiding this comment

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

Why is this separate from the existing PruneOrders that includes both buy and sell orders? And this should be for BeginBlocker not EndBlocker, correct? This is how PruneOrders is wired up at the moment. This is only being called in the added test and we are still deleting and not properly returning escrowed credits.

Copy link
Member

Choose a reason for hiding this comment

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

for {
_, err := sellOrdersIter.LoadNext(&sellOrder)
if err != nil {
if orm.ErrIteratorDone.Is(err) {
break
}
return err
}
err = s.sellOrderTable.Delete(ctx, sellOrder.OrderId)
if err != nil {
return err
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not properly returning escrowed credits.

if err = k.unescrowCredits(ctx, sellOrder.Seller, sellOrder.BatchId, sellOrder.Quantity); err != nil {
?

Copy link
Member

@ryanchristo ryanchristo Mar 15, 2022

Choose a reason for hiding this comment

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

It's not wired up in BeginBlocker like PruneOrders is. We are still deleting sell orders without returning escrowed funds because of this. This should be called within PruneOrders or the way BeginBlocker is currently implemented needs to be updated (i.e. to include the PruneSellOrders method you created).

Copy link
Contributor Author

@technicallyty technicallyty Mar 15, 2022

Choose a reason for hiding this comment

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

Why is this separate from the existing PruneOrders

not sure im following, is this a concern with where the function is placed?

that includes both buy

buy orders are not stored in state at the moment, so im not sure i see the value in adding them at this time.

This is only being called in the added test and we are still deleting and not properly returning escrowed credits.

well, none of these PR's are truly wired in yet. This is just impl + unit tests. I think that concern should be addressed when we tackle integration tests.

And this should be for BeginBlocker not EndBlocker

updated the comment

Copy link
Member

@ryanchristo ryanchristo Mar 15, 2022

Choose a reason for hiding this comment

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

is this a concern with where the function is placed?

Not a concern about where the function is placed. PruneOrders is currently wired up in BeginBlocker.

well, none of these PR's are truly wired in yet

PruneOrders is already wired up in BeginBlocker.

buy orders are not stored in state at the moment

Correct but the pruning buy orders was already implemented. We can delete if need be or comment out but also does not hurt to have it included as it currently is.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the clarification in discord. Sounds like we have more migrations to do for what I'm requesting.

Copy link
Member

@ryanchristo ryanchristo left a comment

Choose a reason for hiding this comment

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

Ok, unblocking and approving now that we are tracking in #898. Nice work!

@@ -195,6 +195,9 @@ message BatchBalance {

// retired is the retired amount of credits
string retired = 4;

// escrowed is the amount of credits locked up in escrow for the marketplace.
string escrowed = 5;
Copy link
Member

Choose a reason for hiding this comment

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

Ok, escrowed it is. More aligned with tradable and retired.

@technicallyty technicallyty enabled auto-merge (squash) March 15, 2022 23:22
@technicallyty technicallyty merged commit 3f1dff4 into master Mar 15, 2022
@technicallyty technicallyty deleted the ty/821-escrow branch March 15, 2022 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement escrow model for sell orders
4 participants