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): SellOrders query & sub-queries #917

Merged
merged 6 commits into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
116 changes: 116 additions & 0 deletions x/ecocredit/server/marketplace/query_sell_orders.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package marketplace

import (
"context"

"github.com/cosmos/cosmos-sdk/orm/model/ormlist"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

marketplacev1 "github.com/regen-network/regen-ledger/api/regen/ecocredit/marketplace/v1"
"github.com/regen-network/regen-ledger/types/ormutil"
v1 "github.com/regen-network/regen-ledger/x/ecocredit/marketplace"
technicallyty marked this conversation as resolved.
Show resolved Hide resolved
)

// SellOrders queries all sell orders in state with optional pagination
func (k Keeper) SellOrders(ctx context.Context, req *v1.QuerySellOrdersRequest) (*v1.QuerySellOrdersResponse, error) {
Copy link
Contributor Author

@technicallyty technicallyty Mar 21, 2022

Choose a reason for hiding this comment

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

put both the SellOrdersBy... queries in the same file, seemed like a sane thing to do as they're essentially SellOrders sub-queries, but can move them to separate files if that makes more sense

pg, err := ormutil.GogoPageReqToPulsarPageReq(req.Pagination)
if err != nil {
return nil, err
}

it, err := k.stateStore.SellOrderTable().List(ctx, marketplacev1.SellOrderSellerIndexKey{}, ormlist.Paginate(pg))
if err != nil {
return nil, err
}
defer it.Close()
aleem1314 marked this conversation as resolved.
Show resolved Hide resolved

orders := make([]*v1.SellOrder, 0, 10)
for it.Next() {
v, err := it.Value()
if err != nil {
return nil, err
}
var order v1.SellOrder
err = ormutil.PulsarToGogoSlow(v, &order)
if err != nil {
return nil, err
}
orders = append(orders, &order)
}
return &v1.QuerySellOrdersResponse{SellOrders: orders}, nil
}

// SellOrdersByBatchDenom queries all sell orders under a specific batch denom with optional pagination
func (k Keeper) SellOrdersByBatchDenom(ctx context.Context, req *v1.QuerySellOrdersByBatchDenomRequest) (*v1.QuerySellOrdersByBatchDenomResponse, error) {
pg, err := ormutil.GogoPageReqToPulsarPageReq(req.Pagination)
if err != nil {
return nil, err
}

batch, err := k.coreStore.BatchInfoTable().GetByBatchDenom(ctx, req.BatchDenom)
if err != nil {
return nil, sdkerrors.ErrInvalidRequest.Wrapf("could not get batch with denom %s: %s", req.BatchDenom, err.Error())
}

it, err := k.stateStore.SellOrderTable().List(ctx, marketplacev1.SellOrderBatchIdIndexKey{}.WithBatchId(batch.Id), ormlist.Paginate(pg))
if err != nil {
return nil, err
}
defer it.Close()
aleem1314 marked this conversation as resolved.
Show resolved Hide resolved

orders := make([]*v1.SellOrder, 0, 10)
for it.Next() {
v, err := it.Value()
if err != nil {
return nil, err
}

var order v1.SellOrder
err = ormutil.PulsarToGogoSlow(v, &order)
if err != nil {
return nil, err
}

orders = append(orders, &order)
}

return &v1.QuerySellOrdersByBatchDenomResponse{SellOrders: orders}, nil
}

// SellOrdersByAddress queries all sell orders created by the given address with optional pagination
func (k Keeper) SellOrdersByAddress(ctx context.Context, req *v1.QuerySellOrdersByAddressRequest) (*v1.QuerySellOrdersByAddressResponse, error) {
pg, err := ormutil.GogoPageReqToPulsarPageReq(req.Pagination)
if err != nil {
return nil, err
}

seller, err := sdk.AccAddressFromBech32(req.Address)
if err != nil {
return nil, err
}

it, err := k.stateStore.SellOrderTable().List(ctx, marketplacev1.SellOrderSellerIndexKey{}.WithSeller(seller), ormlist.Paginate(pg))
if err != nil {
return nil, err
}
defer it.Close()
aleem1314 marked this conversation as resolved.
Show resolved Hide resolved

orders := make([]*v1.SellOrder, 0, 10)
for it.Next() {
v, err := it.Value()
if err != nil {
return nil, err
}

var order v1.SellOrder
err = ormutil.PulsarToGogoSlow(v, &order)
if err != nil {
return nil, err
}

orders = append(orders, &order)
}

return &v1.QuerySellOrdersByAddressResponse{SellOrders: orders}, nil
}
138 changes: 138 additions & 0 deletions x/ecocredit/server/marketplace/query_sell_orders_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package marketplace

import (
"testing"

"google.golang.org/protobuf/types/known/timestamppb"
"gotest.tools/v3/assert"

"github.com/cosmos/cosmos-sdk/orm/types/ormerrors"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"

api "github.com/regen-network/regen-ledger/api/regen/ecocredit/marketplace/v1"
ecocreditv1 "github.com/regen-network/regen-ledger/api/regen/ecocredit/v1"
"github.com/regen-network/regen-ledger/x/ecocredit"
"github.com/regen-network/regen-ledger/x/ecocredit/marketplace"
technicallyty marked this conversation as resolved.
Show resolved Hide resolved
)

var (
classId = "C01"
batchDenom = "C01-20200101-20200201-001"
start, end = timestamppb.Now(), timestamppb.Now()
ask = sdk.NewInt64Coin("ufoo", 10)
creditType = ecocredit.CreditType{Name: "carbon", Abbreviation: "C", Unit: "tonnes", Precision: 6}
)

func TestSellOrders(t *testing.T) {
t.Parallel()
s := setupBase(t)
testSellSetup(t, s, batchDenom, ask.Denom, ask.Denom[1:], classId, start, end, creditType)
_, _, addr2 := testdata.KeyTestPubAddr()

insertSellOrder(t, s, s.addr, 1)
insertSellOrder(t, s, addr2, 1)

res, err := s.k.SellOrders(s.ctx, &marketplace.QuerySellOrdersRequest{
Pagination: nil,
})
assert.NilError(t, err)
assert.Equal(t, 2, len(res.SellOrders))
technicallyty marked this conversation as resolved.
Show resolved Hide resolved
}

func TestSellOrdersByDenom(t *testing.T) {
t.Parallel()
s := setupBase(t)
testSellSetup(t, s, batchDenom, ask.Denom, ask.Denom[1:], classId, start, end, creditType)

// make another batch
otherDenom := "C01-19990101-20290101-001"
assert.NilError(t, s.coreStore.BatchInfoTable().Insert(s.ctx, &ecocreditv1.BatchInfo{
ProjectId: 1,
BatchDenom: otherDenom,
Metadata: "",
StartDate: nil,
EndDate: nil,
}))

insertSellOrder(t, s, s.addr, 1)
insertSellOrder(t, s, s.addr, 2)

// query the first denom
res, err := s.k.SellOrdersByBatchDenom(s.ctx, &marketplace.QuerySellOrdersByBatchDenomRequest{
BatchDenom: batchDenom,
Pagination: nil,
})
assert.NilError(t, err)
assert.Equal(t, 1, len(res.SellOrders))

// query the second denom
res, err = s.k.SellOrdersByBatchDenom(s.ctx, &marketplace.QuerySellOrdersByBatchDenomRequest{
BatchDenom: otherDenom,
Pagination: nil,
})
assert.NilError(t, err)
assert.Equal(t, 1, len(res.SellOrders))

// bad denom should error
res, err = s.k.SellOrdersByBatchDenom(s.ctx, &marketplace.QuerySellOrdersByBatchDenomRequest{
BatchDenom: "yikes!",
Pagination: nil,
})
assert.ErrorContains(t, err, ormerrors.NotFound.Error())
}

func TestSellOrdersByAddress(t *testing.T) {
t.Parallel()
s := setupBase(t)
testSellSetup(t, s, batchDenom, ask.Denom, ask.Denom[1:], classId, start, end, creditType)

_, _, otherAddr := testdata.KeyTestPubAddr()
_, _, noOrdersAddr := testdata.KeyTestPubAddr()

insertSellOrder(t, s, s.addr, 1)
insertSellOrder(t, s, otherAddr, 1)

res, err := s.k.SellOrdersByAddress(s.ctx, &marketplace.QuerySellOrdersByAddressRequest{
Address: s.addr.String(),
Pagination: nil,
})
assert.NilError(t, err)
assert.Equal(t, 1, len(res.SellOrders))

res, err = s.k.SellOrdersByAddress(s.ctx, &marketplace.QuerySellOrdersByAddressRequest{
Address: otherAddr.String(),
Pagination: nil,
})
assert.NilError(t, err)
assert.Equal(t, 1, len(res.SellOrders))

// addr with no sell orders should just return empty slice
res, err = s.k.SellOrdersByAddress(s.ctx, &marketplace.QuerySellOrdersByAddressRequest{
Address: noOrdersAddr.String(),
Pagination: nil,
})
assert.NilError(t, err)
assert.Equal(t, 0, len(res.SellOrders))

// bad address should fail
res, err = s.k.SellOrdersByAddress(s.ctx, &marketplace.QuerySellOrdersByAddressRequest{
Address: "foobar1vlk23jrkl",
Pagination: nil,
})
assert.ErrorContains(t, err, "decoding bech32 failed")
}

func insertSellOrder(t *testing.T, s *baseSuite, addr sdk.AccAddress, batchId uint64) {
sellOrder := &api.SellOrder{
Seller: addr,
BatchId: batchId,
Quantity: "10",
MarketId: 1,
AskPrice: "10",
DisableAutoRetire: false,
Expiration: timestamppb.Now(),
Maker: false,
}
assert.NilError(t, s.marketStore.SellOrderTable().Insert(s.ctx, sellOrder))
}
5 changes: 3 additions & 2 deletions x/ecocredit/server/marketplace/sell_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package marketplace

import (
"github.com/regen-network/regen-ledger/types/math"
"github.com/regen-network/regen-ledger/x/ecocredit/server"
"testing"
"time"

Expand All @@ -14,8 +12,10 @@ import (

marketApi "github.com/regen-network/regen-ledger/api/regen/ecocredit/marketplace/v1"
ecocreditv1 "github.com/regen-network/regen-ledger/api/regen/ecocredit/v1"
"github.com/regen-network/regen-ledger/types/math"
"github.com/regen-network/regen-ledger/x/ecocredit"
v1 "github.com/regen-network/regen-ledger/x/ecocredit/marketplace"
"github.com/regen-network/regen-ledger/x/ecocredit/server"
)

func TestSell_Valid(t *testing.T) {
Expand Down Expand Up @@ -193,6 +193,7 @@ func assertCoinsEscrowed(t *testing.T, balanceBefore, balanceAfter *ecocreditv1.
assert.Check(t, calculatedESupply.Equal(supAfterEscrowed))
}

// testSellSetup sets up a batch, class, market, and issues a balance of 100 retired and tradable to the base suite's addr.
func testSellSetup(t *testing.T, s *baseSuite, batchDenom, bankDenom, displayDenom, classId string, start, end *timestamppb.Timestamp, creditType ecocredit.CreditType) {
assert.NilError(t, s.coreStore.BatchInfoTable().Insert(s.ctx, &ecocreditv1.BatchInfo{
ProjectId: 1,
Expand Down