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(x/ecocredit): add buy/sell expiration #671

Merged
merged 18 commits into from
Jan 25, 2022
Merged
Show file tree
Hide file tree
Changes from 13 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
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func NewRegenApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest
// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)
app.mm.SetOrderBeginBlockers(
upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName,
evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName,
evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, /* ecocredit.ModuleName, */
Copy link
Member Author

Choose a reason for hiding this comment

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

Any ideas why adding this would cause the tests to hang?

Copy link
Member Author

Choose a reason for hiding this comment

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

It times out after 10 minutes with the following error:

    tx.go:102: 
                Error Trace:    tx.go:102
                                                        suite.go:118
                                                        tx.go:50
                                                        modules_test.go:12
                Error:          Received unexpected error:
                                rpc error: code = NotFound desc = rpc error: code = NotFound desc = account regen1huayfhrzpkxxws60dxlzv6p3l6e95nau7yk3as not found: key not found
                Test:           TestEcocreditIntegration
panic: test timed out after 10m0s

Copy link
Contributor

@technicallyty technicallyty Jan 14, 2022

Choose a reason for hiding this comment

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

i'm wondering if this has anything to do with the ecocredit module not fulfilling the interface that actually contains the BeginBlock signature.

might need to : add this to the ecocredit/module/module.go file var _ module.AppModule = Module{} and implement the methods it says its missing. maybe that would work?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it might be best to break this out into a separate issue. The ecocredit module does not implement the AppModule interface and in attempting to do so there are some conflicts with the RegisterServices method which uses a different Configurator. Opened #689.

Copy link
Contributor

Choose a reason for hiding this comment

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

is ecocredit commented out due to errors?

Copy link
Member Author

Choose a reason for hiding this comment

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

correct, not sure how to resolve at the moment: #671 (comment)

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 leave it for a next task.

)
app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName)
// NOTE: The genutils module must occur after staking so that pools are
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ require (
golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220114172242-44263ffb69e1 // indirect
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 // indirect
google.golang.org/grpc v1.40.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1535,8 +1535,8 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20220114172242-44263ffb69e1 h1:urkRJha5HC5u/IDXqy212/tSzWXRbU8eWMTj6yXP6u8=
google.golang.org/genproto v0.0.0-20220114172242-44263ffb69e1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 h1:zzNejm+EgrbLfDZ6lu9Uud2IVvHySPl8vQzf04laR5Q=
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
Expand Down
14 changes: 14 additions & 0 deletions proto/regen/ecocredit/v1alpha2/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ syntax = "proto3";

package regen.ecocredit.v1alpha2;

import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/regen-network/regen-ledger/x/ecocredit";

Expand Down Expand Up @@ -147,6 +149,10 @@ message EventSell {
// buyer to disable auto-retirement in their buy order enabling them to
// resell the credits to another buyer.
bool disable_auto_retire = 5;

// expiration is an optional timestamp when the sell order expires. When the
// expiration time is reached, the sell order is removed from state.
google.protobuf.Timestamp expiration = 6 [ (gogoproto.stdtime) = true ];
}

// EventUpdateSellOrder is an event emitted when a sell order is updated.
Expand All @@ -170,6 +176,10 @@ message EventUpdateSellOrder {

// disable_auto_retire updates the disable_auto_retire field in the sell order.
bool disable_auto_retire = 6;

// new_expiration is an optional timestamp when the sell order expires. When the
// expiration time is reached, the sell order is removed from state.
google.protobuf.Timestamp new_expiration = 7 [ (gogoproto.stdtime) = true ];
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we really want to use new_ prefix?

Copy link
Member Author

Choose a reason for hiding this comment

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

We are using new_quantity and new_ask_price so new_expiration made sense.

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, we don't do that in general. The other parts were not yet released. Let's chat about naming in the discord or standup.

}

// EventBuyOrderCreated is an event emitted when a buy order is created.
Expand Down Expand Up @@ -206,6 +216,10 @@ message EventBuyOrderCreated {
// retirement_location is the optional retirement location for the credits
// which will be used only if disable_auto_retire is false.
string retirement_location = 7;

// expiration is the optional timestamp when the buy order expires. When the
// expiration time is reached, the buy order is removed from state.
google.protobuf.Timestamp expiration = 8 [ (gogoproto.stdtime) = true ];
}

// EventBuyOrderFilled is an event emitted when a buy order is filled.
Expand Down
12 changes: 12 additions & 0 deletions proto/regen/ecocredit/v1alpha2/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ message MsgSell {
// buyer to disable auto-retirement in their buy order enabling them to
// resell the credits to another buyer.
bool disable_auto_retire = 4;

// expiration is an optional timestamp when the sell order expires. When the
// expiration time is reached, the sell order is removed from state.
google.protobuf.Timestamp expiration = 5 [ (gogoproto.stdtime) = true ];
}
}

Expand Down Expand Up @@ -415,6 +419,10 @@ message MsgUpdateSellOrders {

// disable_auto_retire updates the disable_auto_retire field in the sell order.
bool disable_auto_retire = 4;

// new_expiration is an optional timestamp when the sell order expires. When the
// expiration time is reached, the sell order is removed from state.
google.protobuf.Timestamp new_expiration = 5 [ (gogoproto.stdtime) = true ];
}
}

Expand Down Expand Up @@ -479,6 +487,10 @@ message MsgBuy {
// retirement_location is the optional retirement location for the credits
// which will be used only if disable_auto_retire is false.
string retirement_location = 6;

// expiration is the optional timestamp when the buy order expires. When the
// expiration time is reached, the buy order is removed from state.
google.protobuf.Timestamp expiration = 7 [ (gogoproto.stdtime) = true ];
}
}

Expand Down
8 changes: 8 additions & 0 deletions proto/regen/ecocredit/v1alpha2/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ message SellOrder {
// buyer to disable auto-retirement in their buy order enabling them to
// resell the credits to another buyer.
bool disable_auto_retire = 6;

// expiration is an optional timestamp when the sell order expires. When the
// expiration time is reached, the sell order is removed from state.
google.protobuf.Timestamp expiration = 7 [ (gogoproto.stdtime) = true ];
}

// BuyOrder represents the information for a buy order.
Expand Down Expand Up @@ -209,6 +213,10 @@ message BuyOrder {
// disable_partial_fill disables the default behavior of partially filling
// buy orders if the requested quantity is not available.
bool disable_partial_fill = 7;

// expiration is the optional timestamp when the buy order expires. When the
// expiration time is reached, the buy order is removed from state.
google.protobuf.Timestamp expiration = 8 [ (gogoproto.stdtime) = true ];
}

// AskDenom represents the information for an ask denom.
Expand Down
17 changes: 17 additions & 0 deletions x/ecocredit/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ecocredit

import (
"time"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// BeginBlocker checks if there are any expired sell or buy orders and removes them from state.
func BeginBlocker(ctx sdk.Context, k Keeper) {
defer telemetry.ModuleMeasureSince(ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

if err := k.PruneOrders(ctx); err != nil {
panic(err)
ryanchristo marked this conversation as resolved.
Show resolved Hide resolved
}
}
14 changes: 4 additions & 10 deletions x/ecocredit/client/testsuite/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"

"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/regen-network/regen-ledger/types/testutil/cli"
"github.com/regen-network/regen-ledger/x/ecocredit"
"github.com/regen-network/regen-ledger/x/ecocredit/client"
Expand Down Expand Up @@ -482,7 +482,8 @@ func (s *IntegrationTestSuite) TestQueryParams() {
require.NoError(err)

var params ecocredit.QueryParamsResponse
json.Unmarshal(out.Bytes(), &params)
err = json.Unmarshal(out.Bytes(), &params)
require.NoError(err)

require.Equal(ecocredit.DefaultParams(), *params.Params)
}
Expand Down Expand Up @@ -521,14 +522,7 @@ func (s *IntegrationTestSuite) TestQuerySellOrder() {
args: []string{"1"},
expErr: false,
expErrMsg: "",
expOrder: &ecocredit.SellOrder{
OrderId: 1,
Owner: val.Address.String(),
BatchDenom: batchDenom,
Quantity: "1",
AskPrice: &sdk.Coin{Denom: "regen", Amount: sdk.NewInt(100)},
DisableAutoRetire: false,
},
expOrder: s.sellOrders[0],
},
}

Expand Down
125 changes: 101 additions & 24 deletions x/ecocredit/client/testsuite/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
tmcli "github.com/tendermint/tendermint/libs/cli"

"github.com/regen-network/regen-ledger/types/testutil/cli"
"github.com/regen-network/regen-ledger/types/testutil/network"
"github.com/regen-network/regen-ledger/x/ecocredit"
"github.com/regen-network/regen-ledger/x/ecocredit/client"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
tmcli "github.com/tendermint/tendermint/libs/cli"
)

type IntegrationTestSuite struct {
Expand Down Expand Up @@ -1418,12 +1419,16 @@ func (s *IntegrationTestSuite) TestTxSell() {
val0 := s.network.Validators[0]
clientCtx := val0.ClientCtx

expiration, err := client.ParseDate("expiration", "2024-01-01")
s.Require().NoError(err)

testCases := []struct {
name string
args []string
expErr bool
expErrMsg string
expOrder *ecocredit.SellOrder
name string
args []string
sellOrderId string
expErr bool
expErrMsg string
expOrder *ecocredit.SellOrder
}{
{
name: "missing args",
Expand Down Expand Up @@ -1518,7 +1523,8 @@ func (s *IntegrationTestSuite) TestTxSell() {
},
s.commonTxFlags()...,
),
expErr: false,
sellOrderId: "4",
expErr: false,
expOrder: &ecocredit.SellOrder{
OrderId: 4,
Owner: val0.Address.String(),
Expand All @@ -1528,6 +1534,27 @@ func (s *IntegrationTestSuite) TestTxSell() {
DisableAutoRetire: false,
},
},
{
name: "valid with expiration",
args: append(
[]string{
"[{batch_denom: \"C01-20210101-20210201-001\", quantity: \"5\", ask_price: \"100regen\", disable_auto_retire: false, expiration: \"2024-01-01\"}]",
makeFlagFrom(val0.Address.String()),
},
s.commonTxFlags()...,
),
sellOrderId: "5",
expErr: false,
expOrder: &ecocredit.SellOrder{
OrderId: 5,
Owner: val0.Address.String(),
BatchDenom: batchDenom,
Quantity: "5",
AskPrice: &sdk.Coin{Denom: "regen", Amount: sdk.NewInt(100)},
DisableAutoRetire: false,
Expiration: &expiration,
},
},
}

for _, tc := range testCases {
Expand All @@ -1542,7 +1569,10 @@ func (s *IntegrationTestSuite) TestTxSell() {

// query sell order
query := client.QuerySellOrderCmd()
out, err := cli.ExecTestCLICmd(clientCtx, query, []string{"4", flagOutputJSON})
out, err := cli.ExecTestCLICmd(clientCtx, query, []string{
tc.sellOrderId,
flagOutputJSON,
})
s.Require().NoError(err, out.String())

// unmarshal query response
Expand All @@ -1561,12 +1591,16 @@ func (s *IntegrationTestSuite) TestTxUpdateSellOrders() {
val0 := s.network.Validators[0]
clientCtx := val0.ClientCtx

expiration, err := client.ParseDate("expiration", "2026-01-01")
s.Require().NoError(err)

testCases := []struct {
name string
args []string
expErr bool
expErrMsg string
expOrder *ecocredit.SellOrder
name string
args []string
sellOrderId string
expErr bool
expErrMsg string
expOrder *ecocredit.SellOrder
}{
{
name: "missing args",
Expand Down Expand Up @@ -1661,7 +1695,8 @@ func (s *IntegrationTestSuite) TestTxUpdateSellOrders() {
},
s.commonTxFlags()...,
),
expErr: false,
sellOrderId: "4",
expErr: false,
expOrder: &ecocredit.SellOrder{
OrderId: 4,
Owner: val0.Address.String(),
Expand All @@ -1671,6 +1706,27 @@ func (s *IntegrationTestSuite) TestTxUpdateSellOrders() {
DisableAutoRetire: false,
},
},
{
name: "valid with expiration",
args: append(
[]string{
"[{sell_order_id: \"5\", new_quantity: \"5\", new_ask_price: \"200regen\", disable_auto_retire: false, new_expiration: \"2026-01-01\"}]",
makeFlagFrom(val0.Address.String()),
},
s.commonTxFlags()...,
),
sellOrderId: "5",
expErr: false,
expOrder: &ecocredit.SellOrder{
OrderId: 5,
Owner: val0.Address.String(),
BatchDenom: batchDenom,
Quantity: "5",
AskPrice: &sdk.Coin{Denom: "regen", Amount: sdk.NewInt(200)},
DisableAutoRetire: false,
Expiration: &expiration,
},
},
}

for _, tc := range testCases {
Expand All @@ -1685,7 +1741,10 @@ func (s *IntegrationTestSuite) TestTxUpdateSellOrders() {

// query sell order
query := client.QuerySellOrderCmd()
out, err := cli.ExecTestCLICmd(clientCtx, query, []string{"4", flagOutputJSON})
out, err := cli.ExecTestCLICmd(clientCtx, query, []string{
tc.sellOrderId,
flagOutputJSON,
})
s.Require().NoError(err, out.String())

// unmarshal query response
Expand All @@ -1705,10 +1764,11 @@ func (s *IntegrationTestSuite) TestTxBuy() {
clientCtx := val0.ClientCtx

testCases := []struct {
name string
args []string
expErr bool
expErrMsg string
name string
args []string
sellOrderId string
expErr bool
expErrMsg string
}{
{
name: "missing args",
Expand Down Expand Up @@ -1803,8 +1863,22 @@ func (s *IntegrationTestSuite) TestTxBuy() {
},
s.commonTxFlags()...,
),
expErr: false,
expErrMsg: "",
sellOrderId: "4",
expErr: false,
expErrMsg: "",
},
{
name: "valid with expiration",
args: append(
[]string{
"[{sell_order_id: \"5\", quantity: \"5\", bid_price: \"100regen\", disable_auto_retire: false, expiration: \"2024-01-01\"}]",
makeFlagFrom(val0.Address.String()),
},
s.commonTxFlags()...,
),
sellOrderId: "5",
expErr: false,
expErrMsg: "",
},
}

Expand All @@ -1820,7 +1894,10 @@ func (s *IntegrationTestSuite) TestTxBuy() {

// query sell order (should no longer exist)
query := client.QuerySellOrderCmd()
_, err := cli.ExecTestCLICmd(clientCtx, query, []string{"4", flagOutputJSON})
_, err := cli.ExecTestCLICmd(clientCtx, query, []string{
tc.sellOrderId,
flagOutputJSON,
})
s.Require().Error(err)
s.Require().Contains(err.Error(), "not found")
}
Expand Down
Loading