From 32f4b5f58e2bfc166e6439d32f4bd37ec1480a31 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 7 May 2021 20:28:22 +0300 Subject: [PATCH 01/41] #30 Add timeInForce to CancelOrReplace Msg --- docs/proto/em/proto-docs.md | 1 + proto/em/market/v1/tx.proto | 7 +- x/market/client/cli/tx.go | 13 +++ x/market/keeper/keeper_test.go | 17 ++++ x/market/keeper/msg_server.go | 2 +- x/market/keeper/msg_server_test.go | 14 ++- x/market/spec/02_messages.md | 1 + x/market/types/tx.pb.go | 142 ++++++++++++++++++----------- 8 files changed, 140 insertions(+), 57 deletions(-) diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index 2aecd808..53ddb975 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -1407,6 +1407,7 @@ | `owner` | [string](#string) | | | | `original_client_order_id` | [string](#string) | | | | `new_client_order_id` | [string](#string) | | | +| `time_in_force` | [TimeInForce](#em.market.v1.TimeInForce) | | | | `source` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | | | `destination` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | | diff --git a/proto/em/market/v1/tx.proto b/proto/em/market/v1/tx.proto index dad23630..8d0a93a1 100644 --- a/proto/em/market/v1/tx.proto +++ b/proto/em/market/v1/tx.proto @@ -85,11 +85,14 @@ message MsgCancelReplaceLimitOrder { (gogoproto.moretags) = "yaml:\"new_client_order_id\"" ]; - cosmos.base.v1beta1.Coin source = 4 [ + TimeInForce time_in_force = 4 + [ (gogoproto.moretags) = "yaml:\"time_in_force\"" ]; + + cosmos.base.v1beta1.Coin source = 5 [ (gogoproto.moretags) = "yaml:\"source\"", (gogoproto.nullable) = false ]; - cosmos.base.v1beta1.Coin destination = 5 [ + cosmos.base.v1beta1.Coin destination = 6 [ (gogoproto.moretags) = "yaml:\"destination\"", (gogoproto.nullable) = false ]; diff --git a/x/market/client/cli/tx.go b/x/market/client/cli/tx.go index 32a5b8c8..31f71719 100644 --- a/x/market/client/cli/tx.go +++ b/x/market/client/cli/tx.go @@ -208,8 +208,19 @@ func CancelReplaceOrder() *cobra.Command { origClientOrderID := args[0] newClientOrderID := args[3] + tif, err := cmd.Flags().GetString(flag_TimeInForce) + if err != nil { + return err + } + + timeInForce, err := types.TimeInForceFromString(tif) + if err != nil { + return err + } + msg := &types.MsgCancelReplaceLimitOrder{ Owner: clientCtx.GetFromAddress().String(), + TimeInForce: timeInForce, Source: src, Destination: dst, OrigClientOrderId: origClientOrderID, @@ -225,5 +236,7 @@ func CancelReplaceOrder() *cobra.Command { }, } flags.AddTxFlagsToCmd(cmd) + cmd.Flags().String(flag_TimeInForce, "GTC", flag_TimeInForceDescription) + return cmd } diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 82383fba..c70d1974 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -1144,6 +1144,23 @@ func TestTimeInForceIO(t *testing.T) { require.NoError(t, err) _, err = clientCtx.TxConfig.TxJSONDecoder()(txBz) require.NoError(t, err) + + msgCRL := &types.MsgCancelReplaceLimitOrder{ + TimeInForce: types.TimeInForce_FillOrKill, + Owner: msg.Owner, + Source: sdk.NewCoin("echf", sdk.NewInt(50000)), + Destination: sdk.NewCoin("eeur", sdk.NewInt(60000)), + OrigClientOrderId: "foobar", + NewClientOrderId: "newOrder", + } + + txb, err = clienttx.BuildUnsignedTx(txf, msgCRL) + require.NoError(t, err) + txBz, err = encodingConfig.TxConfig.TxJSONEncoder()(txb.GetTx()) + require.NoError(t, err) + _, err = clientCtx.TxConfig.TxJSONDecoder()(txBz) + require.NoError(t, err) + } func TestGetNextOrderNumber(t *testing.T) { diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index 2561a1ba..fc6256e4 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -88,7 +88,7 @@ func (m msgServer) CancelReplaceLimitOrder(c context.Context, msg *types.MsgCanc if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") } - order, err := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, msg.Source, msg.Destination, owner, msg.NewClientOrderId) + order, err := types.NewOrder(ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, msg.NewClientOrderId) if err != nil { return nil, err } diff --git a/x/market/keeper/msg_server_test.go b/x/market/keeper/msg_server_test.go index ac3414ce..d841e06f 100644 --- a/x/market/keeper/msg_server_test.go +++ b/x/market/keeper/msg_server_test.go @@ -304,6 +304,7 @@ func TestCancelReplaceLimitOrder(t *testing.T) { Owner: ownerAddr.String(), OrigClientOrderId: "origClientID", NewClientOrderId: "myNewClientID", + TimeInForce: types.TimeInForce_ImmediateOrCancel, Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, @@ -321,7 +322,7 @@ func TestCancelReplaceLimitOrder(t *testing.T) { Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}, }}, expOrder: types.Order{ - TimeInForce: types.TimeInForce_GoodTillCancel, + TimeInForce: types.TimeInForce_ImmediateOrCancel, Owner: ownerAddr.String(), ClientOrderID: "myNewClientID", Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, @@ -331,6 +332,17 @@ func TestCancelReplaceLimitOrder(t *testing.T) { DestinationFilled: sdk.ZeroInt(), }, }, + "Time In Force invalid": { + req: &types.MsgCancelReplaceLimitOrder{ + Owner: ownerAddr.String(), + OrigClientOrderId: "origClientID", + NewClientOrderId: "myNewClientID", + TimeInForce: -1, + Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + }, + expErr: true, + }, "owner missing": { req: &types.MsgCancelReplaceLimitOrder{ OrigClientOrderId: "origClientID", diff --git a/x/market/spec/02_messages.md b/x/market/spec/02_messages.md index 30a627b5..01b0651a 100644 --- a/x/market/spec/02_messages.md +++ b/x/market/spec/02_messages.md @@ -67,6 +67,7 @@ MsgCancelReplaceLimitOrder struct { Owner sdk.AccAddress `json:"owner" yaml:"owner"` OrigClientOrderId string `json:"original_client_order_id" yaml:"original_client_order_id"` NewClientOrderId string `json:"new_client_order_id" yaml:"new_client_order_id"` + TimeInForce string `json:"time_in_force" yaml:"time_in_force"` Source sdk.Coin `json:"source" yaml:"source"` Destination sdk.Coin `json:"destination" yaml:"destination"` } diff --git a/x/market/types/tx.pb.go b/x/market/types/tx.pb.go index 3076dbf0..34fe7669 100644 --- a/x/market/types/tx.pb.go +++ b/x/market/types/tx.pb.go @@ -345,11 +345,12 @@ func (m *MsgCancelOrderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCancelOrderResponse proto.InternalMessageInfo type MsgCancelReplaceLimitOrder struct { - Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` - OrigClientOrderId string `protobuf:"bytes,2,opt,name=original_client_order_id,json=originalClientOrderId,proto3" json:"original_client_order_id,omitempty" yaml:"original_client_order_id"` - NewClientOrderId string `protobuf:"bytes,3,opt,name=new_client_order_id,json=newClientOrderId,proto3" json:"new_client_order_id,omitempty" yaml:"new_client_order_id"` - Source types.Coin `protobuf:"bytes,4,opt,name=source,proto3" json:"source" yaml:"source"` - Destination types.Coin `protobuf:"bytes,5,opt,name=destination,proto3" json:"destination" yaml:"destination"` + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + OrigClientOrderId string `protobuf:"bytes,2,opt,name=original_client_order_id,json=originalClientOrderId,proto3" json:"original_client_order_id,omitempty" yaml:"original_client_order_id"` + NewClientOrderId string `protobuf:"bytes,3,opt,name=new_client_order_id,json=newClientOrderId,proto3" json:"new_client_order_id,omitempty" yaml:"new_client_order_id"` + TimeInForce TimeInForce `protobuf:"varint,4,opt,name=time_in_force,json=timeInForce,proto3,enum=em.market.v1.TimeInForce" json:"time_in_force,omitempty" yaml:"time_in_force"` + Source types.Coin `protobuf:"bytes,5,opt,name=source,proto3" json:"source" yaml:"source"` + Destination types.Coin `protobuf:"bytes,6,opt,name=destination,proto3" json:"destination" yaml:"destination"` } func (m *MsgCancelReplaceLimitOrder) Reset() { *m = MsgCancelReplaceLimitOrder{} } @@ -406,6 +407,13 @@ func (m *MsgCancelReplaceLimitOrder) GetNewClientOrderId() string { return "" } +func (m *MsgCancelReplaceLimitOrder) GetTimeInForce() TimeInForce { + if m != nil { + return m.TimeInForce + } + return TimeInForce_Unspecified +} + func (m *MsgCancelReplaceLimitOrder) GetSource() types.Coin { if m != nil { return m.Source @@ -470,52 +478,53 @@ func init() { func init() { proto.RegisterFile("em/market/v1/tx.proto", fileDescriptor_636272ab2288df51) } var fileDescriptor_636272ab2288df51 = []byte{ - // 716 bytes of a gzipped FileDescriptorProto + // 729 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0xcd, 0x6e, 0xd3, 0x4a, - 0x14, 0x8e, 0x9b, 0xdb, 0x4a, 0x9d, 0xf4, 0x27, 0xf5, 0xed, 0x8f, 0xe3, 0x7b, 0x65, 0x57, 0xa3, - 0xaa, 0x37, 0x57, 0xa8, 0x36, 0x09, 0x1b, 0xc4, 0x8e, 0x14, 0x10, 0x95, 0x08, 0x15, 0x06, 0xa9, - 0xa8, 0x9b, 0xc8, 0xb1, 0x4f, 0xcd, 0xa8, 0x1e, 0x4f, 0xb0, 0x9d, 0x36, 0x95, 0xd8, 0xc1, 0x03, - 0xf0, 0x42, 0xec, 0xbb, 0xec, 0x12, 0xb1, 0xb0, 0x50, 0xfa, 0x06, 0x59, 0xb2, 0x42, 0xf6, 0x38, - 0xc1, 0x71, 0x9a, 0x16, 0xb1, 0xa8, 0x04, 0xab, 0x24, 0xf3, 0xfd, 0x1d, 0x9d, 0xe3, 0x39, 0x0e, - 0x5a, 0x03, 0xaa, 0x53, 0xd3, 0x3f, 0x86, 0x50, 0x3f, 0xa9, 0xe9, 0x61, 0x4f, 0xeb, 0xf8, 0x2c, - 0x64, 0xe2, 0x02, 0x50, 0x8d, 0x1f, 0x6b, 0x27, 0x35, 0x79, 0xd5, 0x61, 0x0e, 0x4b, 0x00, 0x3d, - 0xfe, 0xc6, 0x39, 0xb2, 0x62, 0xb1, 0x80, 0xb2, 0x40, 0x6f, 0x9b, 0x01, 0xe8, 0x27, 0xb5, 0x36, - 0x84, 0x66, 0x4d, 0xb7, 0x18, 0xf1, 0x52, 0xbc, 0x32, 0x66, 0x9d, 0xba, 0x71, 0x48, 0x75, 0x18, - 0x73, 0x5c, 0xd0, 0x93, 0x5f, 0xed, 0xee, 0x91, 0x1e, 0x12, 0x0a, 0x41, 0x68, 0xd2, 0x0e, 0x27, - 0xe0, 0x6f, 0x33, 0xa8, 0xdc, 0x0c, 0x9c, 0x87, 0xb6, 0xfd, 0x8c, 0x50, 0x12, 0xee, 0xfb, 0x36, - 0xf8, 0xe2, 0x36, 0x9a, 0x65, 0xa7, 0x1e, 0xf8, 0x92, 0xb0, 0x29, 0x54, 0xe7, 0x1b, 0xe5, 0x41, - 0xa4, 0x2e, 0x9c, 0x99, 0xd4, 0x7d, 0x80, 0x93, 0x63, 0x6c, 0x70, 0x58, 0x6c, 0xa0, 0x65, 0xcb, - 0x25, 0xe0, 0x85, 0x2d, 0x16, 0xeb, 0x5a, 0xc4, 0x96, 0x66, 0x12, 0x85, 0x3c, 0x88, 0xd4, 0x75, - 0xae, 0xc8, 0x11, 0xb0, 0xb1, 0xc8, 0x4f, 0x92, 0xa4, 0x3d, 0x5b, 0x3c, 0x40, 0x8b, 0x71, 0x4d, - 0x2d, 0xe2, 0xb5, 0x8e, 0x98, 0x6f, 0x81, 0x54, 0xdc, 0x14, 0xaa, 0x4b, 0xf5, 0x8a, 0x96, 0x6d, - 0x8c, 0xf6, 0x8a, 0x50, 0xd8, 0xf3, 0x9e, 0xc4, 0x84, 0x86, 0x34, 0x88, 0xd4, 0x55, 0x6e, 0x3e, - 0xa6, 0xc4, 0x46, 0x29, 0xfc, 0x41, 0x13, 0x9f, 0xa2, 0xb9, 0x80, 0x75, 0x63, 0xc7, 0xbf, 0x36, - 0x85, 0x6a, 0xa9, 0x5e, 0xd1, 0x78, 0x1b, 0xb5, 0xb8, 0x8d, 0x5a, 0xda, 0x46, 0x6d, 0x97, 0x11, - 0xaf, 0xb1, 0x76, 0x1e, 0xa9, 0x85, 0x41, 0xa4, 0x2e, 0x72, 0x57, 0x2e, 0xc3, 0x46, 0xaa, 0x17, - 0x0f, 0x50, 0xc9, 0x86, 0x20, 0x24, 0x9e, 0x19, 0x12, 0xe6, 0x49, 0xb3, 0x37, 0xd9, 0xc9, 0xa9, - 0x9d, 0xc8, 0xed, 0x32, 0x5a, 0x6c, 0x64, 0x9d, 0xb0, 0x8c, 0xa4, 0x7c, 0xef, 0x0d, 0x08, 0x3a, - 0xcc, 0x0b, 0x00, 0xf7, 0x8b, 0x68, 0x85, 0x83, 0xcd, 0xa4, 0x0b, 0x7f, 0xd0, 0x64, 0xfe, 0x1f, - 0x9b, 0xcc, 0x7c, 0x63, 0xe5, 0xf6, 0x5b, 0x2f, 0xbe, 0x17, 0x50, 0x99, 0x9a, 0x3d, 0x42, 0xbb, - 0xb4, 0x15, 0xb8, 0xa4, 0xd3, 0x31, 0x1d, 0x90, 0xe6, 0x92, 0x72, 0x5e, 0xc7, 0x1e, 0x5f, 0x22, - 0x75, 0xdb, 0x21, 0xe1, 0x9b, 0x6e, 0x5b, 0xb3, 0x18, 0xd5, 0xd3, 0x1b, 0xc8, 0x3f, 0x76, 0x02, - 0xfb, 0x58, 0x0f, 0xcf, 0x3a, 0x10, 0x68, 0x8f, 0xc0, 0xea, 0x47, 0x6a, 0xa9, 0x69, 0xf6, 0x5e, - 0xa6, 0x26, 0x83, 0x48, 0xdd, 0xe0, 0xe1, 0x79, 0x7b, 0x6c, 0x2c, 0xa7, 0x47, 0x43, 0x2e, 0xfe, - 0x07, 0x55, 0x26, 0x66, 0x3c, 0x7a, 0x02, 0xde, 0xa1, 0xa5, 0x66, 0xe0, 0xec, 0x9a, 0x9e, 0x05, - 0xee, 0xad, 0x4f, 0x1f, 0x4b, 0x68, 0x7d, 0x3c, 0x7d, 0x54, 0xd7, 0xa7, 0x22, 0x92, 0x47, 0x90, - 0x01, 0x1d, 0xd7, 0xb4, 0xe0, 0x17, 0x96, 0xc7, 0x5b, 0x24, 0x31, 0x9f, 0x38, 0xc4, 0x33, 0xdd, - 0xd6, 0xd5, 0xd5, 0xde, 0xef, 0x47, 0xea, 0xca, 0xbe, 0x4f, 0x9c, 0xdd, 0x6c, 0x65, 0x83, 0x48, - 0x55, 0x53, 0xbf, 0x29, 0x72, 0x6c, 0xac, 0x0d, 0xa1, 0x31, 0xa5, 0x68, 0xa2, 0xbf, 0x3d, 0x38, - 0x9d, 0x48, 0x2b, 0x26, 0x69, 0xf5, 0x7e, 0xa4, 0x96, 0x9f, 0xc3, 0x69, 0x3e, 0x4c, 0xe6, 0x61, - 0x57, 0x08, 0xb1, 0x51, 0xf6, 0x72, 0xfc, 0xdf, 0x61, 0xeb, 0x6c, 0x21, 0x3c, 0x7d, 0x7c, 0xc3, - 0x29, 0xd7, 0x3f, 0x14, 0x51, 0xb1, 0x19, 0x38, 0xf1, 0x16, 0x18, 0x7f, 0x39, 0x28, 0xe3, 0xf7, - 0x3f, 0xbf, 0xc0, 0xe4, 0xed, 0xeb, 0xf1, 0x61, 0x80, 0x78, 0x88, 0x96, 0x72, 0xcb, 0x4d, 0xbd, - 0x4a, 0x99, 0x21, 0xc8, 0xff, 0xdd, 0x40, 0x18, 0x79, 0xbf, 0x40, 0xa5, 0xec, 0xbd, 0xf9, 0x77, - 0x42, 0x97, 0x41, 0xe5, 0xad, 0xeb, 0xd0, 0x91, 0x65, 0x17, 0x6d, 0x4c, 0x7b, 0xe2, 0xab, 0x53, - 0x0c, 0x26, 0x98, 0xf2, 0xdd, 0x9f, 0x65, 0x0e, 0x63, 0x1b, 0x8f, 0xcf, 0xfb, 0x8a, 0x70, 0xd1, - 0x57, 0x84, 0xaf, 0x7d, 0x45, 0xf8, 0x78, 0xa9, 0x14, 0x2e, 0x2e, 0x95, 0xc2, 0xe7, 0x4b, 0xa5, - 0x70, 0x78, 0x27, 0xb3, 0x9e, 0x60, 0x87, 0x32, 0x0f, 0xce, 0x74, 0xa0, 0x3b, 0x2e, 0xd8, 0x0e, - 0xf8, 0x7a, 0x6f, 0xf8, 0x8f, 0x20, 0xd9, 0x53, 0xed, 0xb9, 0xe4, 0x6d, 0x7f, 0xef, 0x7b, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xb2, 0xd1, 0x0f, 0x8f, 0x86, 0x08, 0x00, 0x00, + 0x14, 0x8e, 0x9b, 0x36, 0x52, 0x27, 0xfd, 0x49, 0x7d, 0xfb, 0xe3, 0xf8, 0x5e, 0xd9, 0xd5, 0xa8, + 0xea, 0xcd, 0xd5, 0x55, 0x6d, 0x12, 0x36, 0x88, 0x1d, 0x29, 0x20, 0x2a, 0x11, 0x2a, 0x0c, 0x52, + 0x51, 0x37, 0x91, 0x63, 0x9f, 0x9a, 0x51, 0x3d, 0x9e, 0x60, 0x3b, 0x6d, 0x2a, 0xb1, 0x83, 0x07, + 0x60, 0xc5, 0x33, 0x75, 0xd9, 0x25, 0x62, 0x61, 0xa1, 0xf4, 0x0d, 0xb2, 0x64, 0x85, 0xec, 0x71, + 0x82, 0x93, 0x34, 0x2d, 0x42, 0x55, 0x17, 0xac, 0x92, 0xcc, 0xf7, 0x73, 0x8e, 0xbe, 0x99, 0x39, + 0x19, 0xb4, 0x06, 0x54, 0xa7, 0xa6, 0x7f, 0x0c, 0xa1, 0x7e, 0x52, 0xd5, 0xc3, 0xae, 0xd6, 0xf6, + 0x59, 0xc8, 0xc4, 0x05, 0xa0, 0x1a, 0x5f, 0xd6, 0x4e, 0xaa, 0xf2, 0xaa, 0xc3, 0x1c, 0x96, 0x00, + 0x7a, 0xfc, 0x8d, 0x73, 0x64, 0xc5, 0x62, 0x01, 0x65, 0x81, 0xde, 0x32, 0x03, 0xd0, 0x4f, 0xaa, + 0x2d, 0x08, 0xcd, 0xaa, 0x6e, 0x31, 0xe2, 0xa5, 0x78, 0x79, 0xc4, 0x3a, 0x75, 0xe3, 0x90, 0xea, + 0x30, 0xe6, 0xb8, 0xa0, 0x27, 0xbf, 0x5a, 0x9d, 0x23, 0x3d, 0x24, 0x14, 0x82, 0xd0, 0xa4, 0x6d, + 0x4e, 0xc0, 0xdf, 0x67, 0x50, 0xa9, 0x11, 0x38, 0x8f, 0x6c, 0xfb, 0x39, 0xa1, 0x24, 0xdc, 0xf7, + 0x6d, 0xf0, 0xc5, 0x6d, 0x34, 0xc7, 0x4e, 0x3d, 0xf0, 0x25, 0x61, 0x53, 0xa8, 0xcc, 0xd7, 0x4b, + 0xfd, 0x48, 0x5d, 0x38, 0x33, 0xa9, 0xfb, 0x10, 0x27, 0xcb, 0xd8, 0xe0, 0xb0, 0x58, 0x47, 0xcb, + 0x96, 0x4b, 0xc0, 0x0b, 0x9b, 0x2c, 0xd6, 0x35, 0x89, 0x2d, 0xcd, 0x24, 0x0a, 0xb9, 0x1f, 0xa9, + 0xeb, 0x5c, 0x31, 0x46, 0xc0, 0xc6, 0x22, 0x5f, 0x49, 0x2a, 0xed, 0xd9, 0xe2, 0x01, 0x5a, 0x8c, + 0x7b, 0x6a, 0x12, 0xaf, 0x79, 0xc4, 0x7c, 0x0b, 0xa4, 0xfc, 0xa6, 0x50, 0x59, 0xaa, 0x95, 0xb5, + 0x6c, 0x30, 0xda, 0x6b, 0x42, 0x61, 0xcf, 0x7b, 0x1a, 0x13, 0xea, 0x52, 0x3f, 0x52, 0x57, 0xb9, + 0xf9, 0x88, 0x12, 0x1b, 0xc5, 0xf0, 0x27, 0x4d, 0x7c, 0x86, 0x0a, 0x01, 0xeb, 0xc4, 0x8e, 0xb3, + 0x9b, 0x42, 0xa5, 0x58, 0x2b, 0x6b, 0x3c, 0x46, 0x2d, 0x8e, 0x51, 0x4b, 0x63, 0xd4, 0x76, 0x19, + 0xf1, 0xea, 0x6b, 0xe7, 0x91, 0x9a, 0xeb, 0x47, 0xea, 0x22, 0x77, 0xe5, 0x32, 0x6c, 0xa4, 0x7a, + 0xf1, 0x00, 0x15, 0x6d, 0x08, 0x42, 0xe2, 0x99, 0x21, 0x61, 0x9e, 0x34, 0x77, 0x93, 0x9d, 0x9c, + 0xda, 0x89, 0xdc, 0x2e, 0xa3, 0xc5, 0x46, 0xd6, 0x09, 0xcb, 0x48, 0x1a, 0xcf, 0xde, 0x80, 0xa0, + 0xcd, 0xbc, 0x00, 0x70, 0x2f, 0x8f, 0x56, 0x38, 0xd8, 0x48, 0x52, 0xf8, 0x83, 0x76, 0xe6, 0xbf, + 0x91, 0x9d, 0x99, 0xaf, 0xaf, 0xdc, 0x7d, 0xf4, 0xe2, 0x07, 0x01, 0x95, 0xa8, 0xd9, 0x25, 0xb4, + 0x43, 0x9b, 0x81, 0x4b, 0xda, 0x6d, 0xd3, 0x01, 0xa9, 0x90, 0xb4, 0xf3, 0x26, 0xf6, 0xf8, 0x1a, + 0xa9, 0xdb, 0x0e, 0x09, 0xdf, 0x76, 0x5a, 0x9a, 0xc5, 0xa8, 0x9e, 0xde, 0x40, 0xfe, 0xb1, 0x13, + 0xd8, 0xc7, 0x7a, 0x78, 0xd6, 0x86, 0x40, 0x7b, 0x0c, 0x56, 0x2f, 0x52, 0x8b, 0x0d, 0xb3, 0xfb, + 0x2a, 0x35, 0xe9, 0x47, 0xea, 0x06, 0x2f, 0x3e, 0x6e, 0x8f, 0x8d, 0xe5, 0x74, 0x69, 0xc0, 0xc5, + 0x7f, 0xa3, 0xf2, 0xc4, 0x1e, 0x0f, 0x4f, 0xc0, 0x7b, 0xb4, 0xd4, 0x08, 0x9c, 0x5d, 0xd3, 0xb3, + 0xc0, 0xbd, 0xf3, 0xdd, 0xc7, 0x12, 0x5a, 0x1f, 0xad, 0x3e, 0xec, 0xeb, 0xf3, 0x2c, 0x92, 0x87, + 0x90, 0x01, 0x6d, 0xd7, 0xb4, 0xe0, 0x37, 0x86, 0xc7, 0x3b, 0x24, 0x31, 0x9f, 0x38, 0xc4, 0x33, + 0xdd, 0xe6, 0xd5, 0xdd, 0x3e, 0xe8, 0x45, 0xea, 0xca, 0xbe, 0x4f, 0x9c, 0xdd, 0x6c, 0x67, 0xfd, + 0x48, 0x55, 0x53, 0xbf, 0x29, 0x72, 0x6c, 0xac, 0x0d, 0xa0, 0x11, 0xa5, 0x68, 0xa2, 0xbf, 0x3c, + 0x38, 0x9d, 0xa8, 0x96, 0x4f, 0xaa, 0xd5, 0x7a, 0x91, 0x5a, 0x7a, 0x01, 0xa7, 0xe3, 0xc5, 0x64, + 0x5e, 0xec, 0x0a, 0x21, 0x36, 0x4a, 0xde, 0x18, 0x7f, 0xf2, 0xd2, 0xcc, 0xde, 0xfa, 0x38, 0x9b, + 0xbb, 0xdd, 0x71, 0x56, 0xb8, 0xb5, 0x71, 0xb6, 0x85, 0xf0, 0xf4, 0x73, 0x31, 0x38, 0x3e, 0xb5, + 0x8f, 0x79, 0x94, 0x6f, 0x04, 0x4e, 0x9c, 0xd4, 0xe8, 0xbf, 0x8e, 0x32, 0x9a, 0xd1, 0xf8, 0x64, + 0x94, 0xb7, 0xaf, 0xc7, 0x07, 0x05, 0xc4, 0x43, 0xb4, 0x34, 0x36, 0x35, 0xd5, 0xab, 0x94, 0x19, + 0x82, 0xfc, 0xef, 0x0d, 0x84, 0xa1, 0xf7, 0x4b, 0x54, 0xcc, 0x5e, 0xc8, 0x7f, 0x26, 0x74, 0x19, + 0x54, 0xde, 0xba, 0x0e, 0x1d, 0x5a, 0x76, 0xd0, 0xc6, 0xb4, 0xab, 0x54, 0x99, 0x62, 0x30, 0xc1, + 0x94, 0xef, 0xfd, 0x2a, 0x73, 0x50, 0xb6, 0xfe, 0xe4, 0xbc, 0xa7, 0x08, 0x17, 0x3d, 0x45, 0xf8, + 0xd6, 0x53, 0x84, 0x4f, 0x97, 0x4a, 0xee, 0xe2, 0x52, 0xc9, 0x7d, 0xb9, 0x54, 0x72, 0x87, 0xff, + 0x67, 0xe6, 0x1e, 0xec, 0x50, 0xe6, 0xc1, 0x99, 0x0e, 0x74, 0xc7, 0x05, 0xdb, 0x01, 0x5f, 0xef, + 0x0e, 0x9e, 0x1a, 0xc9, 0x00, 0x6c, 0x15, 0x92, 0x67, 0xc4, 0xfd, 0x1f, 0x01, 0x00, 0x00, 0xff, + 0xff, 0x41, 0xad, 0x6b, 0x6e, 0xdf, 0x08, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -972,7 +981,7 @@ func (m *MsgCancelReplaceLimitOrder) MarshalToSizedBuffer(dAtA []byte) (int, err i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x32 { size, err := m.Source.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -982,7 +991,12 @@ func (m *MsgCancelReplaceLimitOrder) MarshalToSizedBuffer(dAtA []byte) (int, err i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a + if m.TimeInForce != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TimeInForce)) + i-- + dAtA[i] = 0x20 + } if len(m.NewClientOrderId) > 0 { i -= len(m.NewClientOrderId) copy(dAtA[i:], m.NewClientOrderId) @@ -1155,6 +1169,9 @@ func (m *MsgCancelReplaceLimitOrder) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.TimeInForce != 0 { + n += 1 + sovTx(uint64(m.TimeInForce)) + } l = m.Source.Size() n += 1 + l + sovTx(uint64(l)) l = m.Destination.Size() @@ -1998,6 +2015,25 @@ func (m *MsgCancelReplaceLimitOrder) Unmarshal(dAtA []byte) error { m.NewClientOrderId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeInForce", wireType) + } + m.TimeInForce = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeInForce |= TimeInForce(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) } @@ -2030,7 +2066,7 @@ func (m *MsgCancelReplaceLimitOrder) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Destination", wireType) } From 5afe33a49c3954bbf40e9b2b69c24ddb257eebf2 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 7 May 2021 20:39:47 +0300 Subject: [PATCH 02/41] Merge Develop into 30-emcli-market-cancelreplace --- x/market/keeper/grpc_query_test.go | 5 +++-- x/market/keeper/querier.go | 2 +- x/market/spec/01_state.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/x/market/keeper/grpc_query_test.go b/x/market/keeper/grpc_query_test.go index f50527ea..7789aa6e 100644 --- a/x/market/keeper/grpc_query_test.go +++ b/x/market/keeper/grpc_query_test.go @@ -31,7 +31,7 @@ func TestQueryByAccount(t *testing.T) { k.setOrder(ctx, &o) expectedPlusOne := o - expectedPlusOne.Created.Add(1*time.Second) + expectedPlusOne.Created = expectedPlusOne.Created.Add(1*time.Second) specs := map[string]struct { req *types.QueryByAccountRequest @@ -47,6 +47,7 @@ func TestQueryByAccount(t *testing.T) { "created plus a sec": { req: &types.QueryByAccountRequest{Address: myAddress.String()}, expState: []*types.Order{&expectedPlusOne}, + createdPlusOne: true, }, "empty address": { req: &types.QueryByAccountRequest{Address: ""}, @@ -72,7 +73,7 @@ func TestQueryByAccount(t *testing.T) { if spec.createdPlusOne { assert.NotEqual(t, spec.expState, gotRsp.Orders) // set equal - gotRsp.Orders[0].Created.Add(1*time.Second) + gotRsp.Orders[0].Created = gotRsp.Orders[0].Created.Add(1*time.Second) } assert.Equal(t, spec.expState, gotRsp.Orders) diff --git a/x/market/keeper/querier.go b/x/market/keeper/querier.go index adfd1212..82e381d0 100644 --- a/x/market/keeper/querier.go +++ b/x/market/keeper/querier.go @@ -68,7 +68,7 @@ func queryByAccount(ctx sdk.Context, k *Keeper, path []string, req abci.RequestQ sort.Slice( orders, func(i, j int) bool { - return orders[i].Created.Before(orders[j].Created) + return orders[i].ID < orders[i].ID }) resp := types.QueryByAccountResponse{Orders: orders} diff --git a/x/market/spec/01_state.md b/x/market/spec/01_state.md index 4967a54e..7682455e 100644 --- a/x/market/spec/01_state.md +++ b/x/market/spec/01_state.md @@ -14,4 +14,4 @@ Order state consists of the following data: * Destination: a `Coin` representing the minimum amount of tokens to buy. * DestinationFilled: `Int` that tracks the bought amount so far. * Price: a `Dec` calculated as *Destination* / *Source*. -* Created: the `timestamp` of the order acceptance, creation event. +* Created: the Block 'Timestamp' at which the order is processed. From 82dd5cffd2b1115eced48e32b4b580305df34f9d Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Mon, 10 May 2021 20:43:55 +0300 Subject: [PATCH 03/41] Add implementation --- docs/proto/em/proto-docs.md | 34 ++ proto/em/market/v1/tx.proto | 37 +- x/market/keeper/keeper.go | 77 +++- x/market/keeper/keeper_test.go | 154 ++++++- x/market/keeper/msg_server.go | 32 +- x/market/keeper/msg_server_test.go | 132 +++++- x/market/types/msgs.go | 46 ++ x/market/types/tx.pb.go | 710 +++++++++++++++++++++++++++-- 8 files changed, 1159 insertions(+), 63 deletions(-) diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index 53ddb975..8f71d408 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -120,6 +120,8 @@ - [MsgCancelOrderResponse](#em.market.v1.MsgCancelOrderResponse) - [MsgCancelReplaceLimitOrder](#em.market.v1.MsgCancelReplaceLimitOrder) - [MsgCancelReplaceLimitOrderResponse](#em.market.v1.MsgCancelReplaceLimitOrderResponse) + - [MsgCancelReplaceMarketOrder](#em.market.v1.MsgCancelReplaceMarketOrder) + - [MsgCancelReplaceMarketOrderResponse](#em.market.v1.MsgCancelReplaceMarketOrderResponse) - [Msg](#em.market.v1.Msg) @@ -1425,6 +1427,37 @@ + + + +### MsgCancelReplaceMarketOrder + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `owner` | [string](#string) | | | +| `original_client_order_id` | [string](#string) | | | +| `new_client_order_id` | [string](#string) | | | +| `time_in_force` | [TimeInForce](#em.market.v1.TimeInForce) | | | +| `source` | [string](#string) | | | +| `destination` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | | +| `maximum_slippage` | [string](#string) | | | + + + + + + + + +### MsgCancelReplaceMarketOrderResponse + + + + + + @@ -1443,6 +1476,7 @@ | `AddMarketOrder` | [MsgAddMarketOrder](#em.market.v1.MsgAddMarketOrder) | [MsgAddMarketOrderResponse](#em.market.v1.MsgAddMarketOrderResponse) | | | | `CancelOrder` | [MsgCancelOrder](#em.market.v1.MsgCancelOrder) | [MsgCancelOrderResponse](#em.market.v1.MsgCancelOrderResponse) | | | | `CancelReplaceLimitOrder` | [MsgCancelReplaceLimitOrder](#em.market.v1.MsgCancelReplaceLimitOrder) | [MsgCancelReplaceLimitOrderResponse](#em.market.v1.MsgCancelReplaceLimitOrderResponse) | | | +| `CancelReplaceMarketOrder` | [MsgCancelReplaceMarketOrder](#em.market.v1.MsgCancelReplaceMarketOrder) | [MsgCancelReplaceMarketOrderResponse](#em.market.v1.MsgCancelReplaceMarketOrderResponse) | | | diff --git a/proto/em/market/v1/tx.proto b/proto/em/market/v1/tx.proto index 8d0a93a1..0af5c221 100644 --- a/proto/em/market/v1/tx.proto +++ b/proto/em/market/v1/tx.proto @@ -16,6 +16,8 @@ service Msg { rpc CancelOrder(MsgCancelOrder) returns (MsgCancelOrderResponse); rpc CancelReplaceLimitOrder(MsgCancelReplaceLimitOrder) returns (MsgCancelReplaceLimitOrderResponse); + rpc CancelReplaceMarketOrder(MsgCancelReplaceMarketOrder) + returns (MsgCancelReplaceMarketOrderResponse); } message MsgAddLimitOrder { @@ -98,4 +100,37 @@ message MsgCancelReplaceLimitOrder { ]; } -message MsgCancelReplaceLimitOrderResponse {} \ No newline at end of file +message MsgCancelReplaceLimitOrderResponse {} + +message MsgCancelReplaceMarketOrder { + string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + + string original_client_order_id = 2 [ + (gogoproto.customname) = "OrigClientOrderId", + (gogoproto.moretags) = "yaml:\"original_client_order_id\"" + ]; + + string new_client_order_id = 3 [ + (gogoproto.customname) = "NewClientOrderId", + (gogoproto.moretags) = "yaml:\"new_client_order_id\"" + ]; + + TimeInForce time_in_force = 4 + [ (gogoproto.moretags) = "yaml:\"time_in_force\"" ]; + + string source = 5 [ (gogoproto.moretags) = "yaml:\"source\"" ]; + + cosmos.base.v1beta1.Coin destination = 6 [ + (gogoproto.moretags) = "yaml:\"destination\"", + (gogoproto.nullable) = false + ]; + + string maximum_slippage = 7 [ + (gogoproto.customname) = "MaxSlippage", + (gogoproto.moretags) = "yaml:\"maximum_slippage\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} + +message MsgCancelReplaceMarketOrderResponse {} \ No newline at end of file diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 312d60b3..561d811d 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -24,8 +24,13 @@ const ( gasPriceNewOrder = uint64(25000) gasPriceCancelReplaceOrder = uint64(25000) gasPriceCancelOrder = uint64(12500) + + gasCancelReplaceLimitOrder = "CancelReplaceMarketOrder" + gasCancelReplaceMarketOrder = "CancelReplaceMarketOrder" ) +var _ marketKeeper = &Keeper{} + type Keeper struct { key sdk.StoreKey keyIndices sdk.StoreKey @@ -377,7 +382,7 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { return total.AmountOf(asset.Denom).GT(sdk.ZeroInt()) } -func (k *Keeper) CancelReplaceOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { +func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { // Use a fixed gas amount ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, "CancelReplaceOrder") ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) @@ -401,19 +406,87 @@ func (k *Keeper) CancelReplaceOrder(ctx sdk.Context, newOrder types.Order, origC k.deleteOrder(ctx, origOrder) types.EmitExpireEvent(ctx, *origOrder) + setRemainingLimit(origOrder, &newOrder) + + resAdd, err := k.NewOrderSingle(ctx, newOrder) + if err != nil { + return nil, err + } + + evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) + return &sdk.Result{Events: evts}, nil +} + +func setRemainingLimit(origOrder *types.Order, newOrder *types.Order) { // Adjust remaining according to how much of the replaced order was filled: newOrder.SourceFilled = origOrder.SourceFilled newOrder.SourceRemaining = newOrder.Source.Amount.Sub(newOrder.SourceFilled) newOrder.DestinationFilled = origOrder.DestinationFilled newOrder.TimeInForce = origOrder.TimeInForce +} - resAdd, err := k.NewOrderSingle(ctx, newOrder) +func setRemainingMarket(origOrder *types.Order, newOrder *types.Order) { + // Adjust remaining according to how much of the replaced order was filled: + newOrder.SourceFilled = origOrder.SourceFilled + newOrder.SourceRemaining = newOrder.Source.Amount.Sub(newOrder.SourceFilled) + newOrder.DestinationFilled = origOrder.DestinationFilled + + newOrder.TimeInForce = origOrder.TimeInForce +} + +func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { + // Use a fixed gas amount + ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, gasCancelReplaceMarketOrder) + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + + origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) + + if origOrder == nil { + return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, msg.OrigClientOrderId) + } + + // Verify that instrument is the same. + if origOrder.Source.Denom != msg.Source || origOrder.Destination.Denom != msg.Destination.Denom { + return nil, sdkerrors.Wrap( + types.ErrOrderInstrumentChanged, fmt.Sprintf( + "source %s != %s Or dest %s != %s", origOrder.Source, msg.Source, + origOrder.Destination.Denom, msg.Destination.Denom, + ), + ) + } + + // Has the previous order already achieved the goal on the source side? + if origOrder.DestinationFilled.GTE(msg.Destination.Amount) { + return nil, sdkerrors.Wrap( + types.ErrNoSourceRemaining, fmt.Sprintf( + "has already been filled filled:%s >= %s", + origOrder.Destination.Amount.String(), msg.Destination.Amount.String()), + ) + } + + k.deleteOrder(ctx, origOrder) + types.EmitExpireEvent(ctx, *origOrder) + + ownerAddr, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") + } + + destinationFilled := origOrder.DestinationFilled + dstRemaining := msg.Destination.Amount.Sub(destinationFilled) + remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) + + resAdd, err := k.NewMarketOrderWithSlippage( + ctx, msg.Source, remDstCoin, msg.MaxSlippage, ownerAddr, + msg.TimeInForce, msg.NewClientOrderId, + ) if err != nil { return nil, err } evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) + return &sdk.Result{Events: evts}, nil } diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index c70d1974..87b63671 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -226,6 +226,65 @@ func TestMarketOrderSlippage1(t *testing.T) { require.True(t, types.ErrAccountBalanceInsufficient.Is(err)) } +func TestCancelReplaceMarketOrderSlippage1(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "500gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + + var o types.Order + var err error + + // Establish market price by executing a 1:1 trade + o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + // Sell eur at various prices + o = order(ctx.BlockTime(), acc2, "50eur", "50gbp") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + o = order(ctx.BlockTime(), acc2, "50eur", "75gbp") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + o = order(ctx.BlockTime(), acc2, "50eur", "100gbp") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + // Make a market order that allows slippage + + clientID := cid() + slippage := sdk.NewDecWithPrec(1, 2) + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(200)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + clientID, + ) + require.NoError(t, err) + + mcrm := &types.MsgCancelReplaceMarketOrder{ + Owner: acc1.GetAddress().String(), + OrigClientOrderId: clientID, + NewClientOrderId: cid(), + TimeInForce: types.TimeInForce_GoodTillCancel, + Source: "gbp", + Destination: sdk.NewCoin("eur", sdk.NewInt(100)), + MaxSlippage: sdk.NewDecWithPrec(50, 2), + } + _, err = k.CancelReplaceMarketOrder(ctx, mcrm) + require.NoError(t, err) +} + func TestFillOrKillMarketOrder1(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) @@ -617,7 +676,90 @@ func TestCancelOrders1(t *testing.T) { require.Error(t, err) } -func TestCancelReplaceOrder(t *testing.T) { +func TestKeeperCancelReplaceLimitOrder(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + acc1 := createAccount(ctx, ak, bk, randomAddress(), "20000eur") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "45000usd") + + totalSupply := snapshotAccounts(ctx, bk) + + order1cid := cid() + order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), coin("1200usd"), acc1.GetAddress(), order1cid) + _, err := k.NewOrderSingle(ctx, order1) + require.NoError(t, err) + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + order2cid := cid() + order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), coin("17000usd"), acc1.GetAddress(), order2cid) + res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) + require.True(t, err == nil, res.Log) + require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) + + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + require.Equal(t, order2cid, orders[0].ClientOrderID) + require.Equal(t, coin("5000eur"), orders[0].Source) + require.Equal(t, coin("17000usd"), orders[0].Destination) + require.Equal(t, sdk.NewInt(5000), orders[0].SourceRemaining) + } + + order3, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), coin("1700usd"), acc1.GetAddress(), cid()) + // Wrong client order id for previous order submitted. + _, err = k.CancelReplaceLimitOrder(ctx, order3, order1cid) + require.True(t, types.ErrClientOrderIdNotFound.Is(err)) + + // Changing instrument of order + gasMeter = sdk.NewGasMeter(math.MaxUint64) + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) + require.True(t, types.ErrOrderInstrumentChanged.Is(err)) + require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) + + o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) + bal2 := bk.GetAllBalances(ctx, acc2.GetAddress()) + + require.Equal(t, int64(300), bal2.AmountOf("eur").Int64()) + require.Equal(t, int64(1020), bal1.AmountOf("usd").Int64()) + + filled := sdk.ZeroInt() + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + filled = orders[0].Source.Amount.Sub(orders[0].SourceRemaining) + } + + // CancelReplace and verify that previously filled amount is subtracted from the resulting order + order4cid := cid() + order4, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("35050usd"), acc1.GetAddress(), order4cid) + res, err = k.CancelReplaceLimitOrder(ctx, order4, order2cid) + require.True(t, err == nil, res.Log) + + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + require.Equal(t, order4cid, orders[0].ClientOrderID) + require.Equal(t, coin("10000eur"), orders[0].Source) + require.Equal(t, coin("35050usd"), orders[0].Destination) + require.Equal(t, sdk.NewInt(10000).Sub(filled), orders[0].SourceRemaining) + } + + // CancelReplace with an order that asks for a larger source than the replaced order has remaining + order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") + k.NewOrderSingle(ctx, order5) + require.True(t, err == nil, res.Log) + + order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") + _, err = k.CancelReplaceLimitOrder(ctx, order6, order4cid) + require.True(t, types.ErrNoSourceRemaining.Is(err)) + + require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) +} + +func TestKeeperCancelReplaceMarketOrder(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc1 := createAccount(ctx, ak, bk, randomAddress(), "20000eur") acc2 := createAccount(ctx, ak, bk, randomAddress(), "45000usd") @@ -632,7 +774,7 @@ func TestCancelReplaceOrder(t *testing.T) { gasMeter := sdk.NewGasMeter(math.MaxUint64) order2cid := cid() order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), coin("17000usd"), acc1.GetAddress(), order2cid) - res, err := k.CancelReplaceOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) + res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) @@ -647,12 +789,12 @@ func TestCancelReplaceOrder(t *testing.T) { order3, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), coin("1700usd"), acc1.GetAddress(), cid()) // Wrong client order id for previous order submitted. - _, err = k.CancelReplaceOrder(ctx, order3, order1cid) + _, err = k.CancelReplaceLimitOrder(ctx, order3, order1cid) require.True(t, types.ErrClientOrderIdNotFound.Is(err)) // Changing instrument of order gasMeter = sdk.NewGasMeter(math.MaxUint64) - _, err = k.CancelReplaceOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) require.True(t, types.ErrOrderInstrumentChanged.Is(err)) require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) @@ -676,7 +818,7 @@ func TestCancelReplaceOrder(t *testing.T) { // CancelReplace and verify that previously filled amount is subtracted from the resulting order order4cid := cid() order4, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("35050usd"), acc1.GetAddress(), order4cid) - res, err = k.CancelReplaceOrder(ctx, order4, order2cid) + res, err = k.CancelReplaceLimitOrder(ctx, order4, order2cid) require.True(t, err == nil, res.Log) { @@ -694,7 +836,7 @@ func TestCancelReplaceOrder(t *testing.T) { require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") - _, err = k.CancelReplaceOrder(ctx, order6, order4cid) + _, err = k.CancelReplaceLimitOrder(ctx, order6, order4cid) require.True(t, types.ErrNoSourceRemaining.Is(err)) require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index fc6256e4..9f034c91 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/e-money/em-ledger/x/market/types" @@ -13,7 +14,8 @@ type marketKeeper interface { NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) - CancelReplaceOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) + CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) + CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) } type msgServer struct { k marketKeeper @@ -93,7 +95,7 @@ func (m msgServer) CancelReplaceLimitOrder(c context.Context, msg *types.MsgCanc return nil, err } - result, err := m.k.CancelReplaceOrder(ctx, order, msg.OrigClientOrderId) + result, err := m.k.CancelReplaceLimitOrder(ctx, order, msg.OrigClientOrderId) if err != nil { return nil, err } @@ -102,3 +104,29 @@ func (m msgServer) CancelReplaceLimitOrder(c context.Context, msg *types.MsgCanc } return &types.MsgCancelReplaceLimitOrderResponse{}, nil } + +func (m msgServer) CancelReplaceMarketOrder(c context.Context, msg *types.MsgCancelReplaceMarketOrder) (*types.MsgCancelReplaceMarketOrderResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + _, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, fmt.Sprintf("invalid owner value:%s", msg.Owner)) + } + if msg.Destination.Amount.LTE(sdk.ZeroInt()) { + return nil, sdkerrors.Wrapf(types.ErrInvalidPrice, "Destination %s price is Zero or less: %s", msg.Destination.Denom, msg.Destination.Amount) + } + + if msg.TimeInForce <= types.TimeInForce_Unspecified || msg.TimeInForce > types.TimeInForce_FillOrKill { + return nil, sdkerrors.Wrapf(types.ErrUnknownTimeInForce, "Invalid Time In Force: %d", msg.TimeInForce) + } + + result, err := m.k.CancelReplaceMarketOrder(ctx, msg) + if err != nil { + return nil, err + } + for _, e := range result.Events { + ctx.EventManager().EmitEvent(sdk.Event(e)) + } + + return &types.MsgCancelReplaceMarketOrderResponse{}, nil +} diff --git a/x/market/keeper/msg_server_test.go b/x/market/keeper/msg_server_test.go index d841e06f..6da5372e 100644 --- a/x/market/keeper/msg_server_test.go +++ b/x/market/keeper/msg_server_test.go @@ -135,6 +135,7 @@ func TestAddMarketOrder(t *testing.T) { Owner: ownerAddr.String(), ClientOrderId: "myClientIOrderID", TimeInForce: types.TimeInForce_FillOrKill, + Source: "eur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, @@ -378,7 +379,7 @@ func TestCancelReplaceLimitOrder(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - keeper.CancelReplaceOrderFn = spec.mockFn + keeper.CancelReplaceLimitOrderFn = spec.mockFn eventManager := sdk.NewEventManager() ctx := sdk.Context{}.WithContext(context.Background()).WithEventManager(eventManager) _, gotErr := svr.CancelReplaceLimitOrder(sdk.WrapSDKContext(ctx), spec.req) @@ -394,11 +395,125 @@ func TestCancelReplaceLimitOrder(t *testing.T) { } } +func TestCancelReplaceMarketOrder(t *testing.T) { + var ( + ownerAddr = randomAccAddress() + gotMsg *types.MsgCancelReplaceMarketOrder + gotOrigClientOrderId string + ) + + keeper := marketKeeperMock{} + svr := NewMsgServerImpl(&keeper) + + specs := map[string]struct { + req *types.MsgCancelReplaceMarketOrder + mockFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) + expErr bool + expEvents sdk.Events + expMsg *types.MsgCancelReplaceMarketOrder + }{ + "all good": { + req: &types.MsgCancelReplaceMarketOrder{ + Owner: ownerAddr.String(), + OrigClientOrderId: "origClientID", + NewClientOrderId: "myNewClientID", + TimeInForce: types.TimeInForce_ImmediateOrCancel, + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + MaxSlippage: sdk.NewDec(10), + }, + mockFn: func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { + gotMsg, gotOrigClientOrderId = msg, msg.OrigClientOrderId + return &sdk.Result{ + Events: []abcitypes.Event{{ + Type: "testing", + Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}, + }}, + }, nil + }, + expEvents: sdk.Events{{ + Type: "testing", + Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}, + }}, + expMsg: &types.MsgCancelReplaceMarketOrder{ + Owner: ownerAddr.String(), + OrigClientOrderId: "origClientID", + NewClientOrderId: "myNewClientID", + TimeInForce: types.TimeInForce_ImmediateOrCancel, + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + MaxSlippage: sdk.NewDec(10), + }, + }, + "Time In Force invalid": { + req: &types.MsgCancelReplaceMarketOrder{ + Owner: ownerAddr.String(), + OrigClientOrderId: "origClientID", + NewClientOrderId: "myNewClientID", + TimeInForce: -1, + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + MaxSlippage: sdk.NewDec(10), + }, + expErr: true, + }, + "owner missing": { + req: &types.MsgCancelReplaceMarketOrder{ + OrigClientOrderId: "origClientID", + NewClientOrderId: "newClientID", + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + }, + expErr: true, + }, + "owner invalid": { + req: &types.MsgCancelReplaceMarketOrder{ + Owner: "invalid", + OrigClientOrderId: "origClientID", + NewClientOrderId: "newClientID", + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + }, + expErr: true, + }, + "processing failure": { + req: &types.MsgCancelReplaceMarketOrder{ + Owner: ownerAddr.String(), + OrigClientOrderId: "origClientID", + NewClientOrderId: "newClientID", + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + }, + mockFn: func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { + return nil, errors.New("testing") + }, + expErr: true, + }, + } + for name, spec := range specs { + t.Run(name, func(t *testing.T) { + keeper.CancelReplaceMarketOrderFn = spec.mockFn + eventManager := sdk.NewEventManager() + ctx := sdk.Context{}.WithContext(context.Background()).WithEventManager(eventManager) + _, gotErr := svr.CancelReplaceMarketOrder(sdk.WrapSDKContext(ctx), spec.req) + if spec.expErr { + require.Error(t, gotErr) + return + } + require.NoError(t, gotErr) + assert.Equal(t, spec.expEvents, eventManager.Events()) + assert.Equal(t, spec.expMsg, gotMsg) + assert.Equal(t, spec.req.OrigClientOrderId, gotOrigClientOrderId) + }) + } +} + type marketKeeperMock struct { NewMarketOrderWithSlippageFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) NewOrderSingleFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) CancelOrderFn func(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) - CancelReplaceOrderFn func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) + CancelReplaceLimitOrderFn func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) + CancelReplaceMarketOrderFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) } func (m marketKeeperMock) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { @@ -422,11 +537,18 @@ func (m marketKeeperMock) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, cli return m.CancelOrderFn(ctx, owner, clientOrderId) } -func (m marketKeeperMock) CancelReplaceOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { - if m.CancelReplaceOrderFn == nil { +func (m marketKeeperMock) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { + if m.CancelReplaceLimitOrderFn == nil { + panic("not expected to be called") + } + return m.CancelReplaceLimitOrderFn(ctx, newOrder, origClientOrderId) +} + +func (m marketKeeperMock) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { + if m.CancelReplaceMarketOrderFn == nil { panic("not expected to be called") } - return m.CancelReplaceOrderFn(ctx, newOrder, origClientOrderId) + return m.CancelReplaceMarketOrderFn(ctx, msg) } func randomAccAddress() sdk.AccAddress { diff --git a/x/market/types/msgs.go b/x/market/types/msgs.go index 8e2a83ce..25401692 100644 --- a/x/market/types/msgs.go +++ b/x/market/types/msgs.go @@ -16,6 +16,7 @@ var ( _ sdk.Msg = &MsgAddMarketOrder{} _ sdk.Msg = &MsgCancelOrder{} _ sdk.Msg = &MsgCancelReplaceLimitOrder{} + _ sdk.Msg = &MsgCancelReplaceMarketOrder{} ) func (m MsgAddMarketOrder) Route() string { @@ -184,3 +185,48 @@ func validateClientOrderID(id string) error { return nil } + +func (m MsgCancelReplaceMarketOrder) Route() string { + return RouterKey +} + +func (m MsgCancelReplaceMarketOrder) Type() string { + return "cancel_replace_market_order" +} + +func (m MsgCancelReplaceMarketOrder) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Owner); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid owner address (%s)", err) + } + + if !m.Destination.IsValid() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "destination amount is invalid: %v", m.Destination.String()) + } + + if err := sdk.ValidateDenom(m.Source); err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "source denomination is invalid: %v", m.Source) + } + + if m.Source == m.Destination.Denom { + return sdkerrors.Wrapf(ErrInvalidInstrument, "'%s/%s' is not a valid instrument", m.Source, m.Destination.Denom) + } + + err := validateClientOrderID(m.OrigClientOrderId) + if err != nil { + return err + } + + return validateClientOrderID(m.NewClientOrderId) +} + +func (m MsgCancelReplaceMarketOrder) GetSignBytes() []byte { + return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m)) +} + +func (m MsgCancelReplaceMarketOrder) GetSigners() []sdk.AccAddress { + from, err := sdk.AccAddressFromBech32(m.Owner) + if err != nil { + panic(err) + } + return []sdk.AccAddress{from} +} \ No newline at end of file diff --git a/x/market/types/tx.pb.go b/x/market/types/tx.pb.go index 34fe7669..96f33208 100644 --- a/x/market/types/tx.pb.go +++ b/x/market/types/tx.pb.go @@ -464,6 +464,127 @@ func (m *MsgCancelReplaceLimitOrderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCancelReplaceLimitOrderResponse proto.InternalMessageInfo +type MsgCancelReplaceMarketOrder struct { + Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + OrigClientOrderId string `protobuf:"bytes,2,opt,name=original_client_order_id,json=originalClientOrderId,proto3" json:"original_client_order_id,omitempty" yaml:"original_client_order_id"` + NewClientOrderId string `protobuf:"bytes,3,opt,name=new_client_order_id,json=newClientOrderId,proto3" json:"new_client_order_id,omitempty" yaml:"new_client_order_id"` + TimeInForce TimeInForce `protobuf:"varint,4,opt,name=time_in_force,json=timeInForce,proto3,enum=em.market.v1.TimeInForce" json:"time_in_force,omitempty" yaml:"time_in_force"` + Source string `protobuf:"bytes,5,opt,name=source,proto3" json:"source,omitempty" yaml:"source"` + Destination types.Coin `protobuf:"bytes,6,opt,name=destination,proto3" json:"destination" yaml:"destination"` + MaxSlippage github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=maximum_slippage,json=maximumSlippage,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"maximum_slippage" yaml:"maximum_slippage"` +} + +func (m *MsgCancelReplaceMarketOrder) Reset() { *m = MsgCancelReplaceMarketOrder{} } +func (m *MsgCancelReplaceMarketOrder) String() string { return proto.CompactTextString(m) } +func (*MsgCancelReplaceMarketOrder) ProtoMessage() {} +func (*MsgCancelReplaceMarketOrder) Descriptor() ([]byte, []int) { + return fileDescriptor_636272ab2288df51, []int{8} +} +func (m *MsgCancelReplaceMarketOrder) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCancelReplaceMarketOrder) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCancelReplaceMarketOrder.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCancelReplaceMarketOrder) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCancelReplaceMarketOrder.Merge(m, src) +} +func (m *MsgCancelReplaceMarketOrder) XXX_Size() int { + return m.Size() +} +func (m *MsgCancelReplaceMarketOrder) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCancelReplaceMarketOrder.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCancelReplaceMarketOrder proto.InternalMessageInfo + +func (m *MsgCancelReplaceMarketOrder) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *MsgCancelReplaceMarketOrder) GetOrigClientOrderId() string { + if m != nil { + return m.OrigClientOrderId + } + return "" +} + +func (m *MsgCancelReplaceMarketOrder) GetNewClientOrderId() string { + if m != nil { + return m.NewClientOrderId + } + return "" +} + +func (m *MsgCancelReplaceMarketOrder) GetTimeInForce() TimeInForce { + if m != nil { + return m.TimeInForce + } + return TimeInForce_Unspecified +} + +func (m *MsgCancelReplaceMarketOrder) GetSource() string { + if m != nil { + return m.Source + } + return "" +} + +func (m *MsgCancelReplaceMarketOrder) GetDestination() types.Coin { + if m != nil { + return m.Destination + } + return types.Coin{} +} + +type MsgCancelReplaceMarketOrderResponse struct { +} + +func (m *MsgCancelReplaceMarketOrderResponse) Reset() { *m = MsgCancelReplaceMarketOrderResponse{} } +func (m *MsgCancelReplaceMarketOrderResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCancelReplaceMarketOrderResponse) ProtoMessage() {} +func (*MsgCancelReplaceMarketOrderResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_636272ab2288df51, []int{9} +} +func (m *MsgCancelReplaceMarketOrderResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCancelReplaceMarketOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCancelReplaceMarketOrderResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCancelReplaceMarketOrderResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCancelReplaceMarketOrderResponse.Merge(m, src) +} +func (m *MsgCancelReplaceMarketOrderResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCancelReplaceMarketOrderResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCancelReplaceMarketOrderResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCancelReplaceMarketOrderResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgAddLimitOrder)(nil), "em.market.v1.MsgAddLimitOrder") proto.RegisterType((*MsgAddLimitOrderResponse)(nil), "em.market.v1.MsgAddLimitOrderResponse") @@ -473,58 +594,63 @@ func init() { proto.RegisterType((*MsgCancelOrderResponse)(nil), "em.market.v1.MsgCancelOrderResponse") proto.RegisterType((*MsgCancelReplaceLimitOrder)(nil), "em.market.v1.MsgCancelReplaceLimitOrder") proto.RegisterType((*MsgCancelReplaceLimitOrderResponse)(nil), "em.market.v1.MsgCancelReplaceLimitOrderResponse") + proto.RegisterType((*MsgCancelReplaceMarketOrder)(nil), "em.market.v1.MsgCancelReplaceMarketOrder") + proto.RegisterType((*MsgCancelReplaceMarketOrderResponse)(nil), "em.market.v1.MsgCancelReplaceMarketOrderResponse") } func init() { proto.RegisterFile("em/market/v1/tx.proto", fileDescriptor_636272ab2288df51) } var fileDescriptor_636272ab2288df51 = []byte{ - // 729 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x56, 0xcd, 0x6e, 0xd3, 0x4a, - 0x14, 0x8e, 0x9b, 0x36, 0x52, 0x27, 0xfd, 0x49, 0x7d, 0xfb, 0xe3, 0xf8, 0x5e, 0xd9, 0xd5, 0xa8, - 0xea, 0xcd, 0xd5, 0x55, 0x6d, 0x12, 0x36, 0x88, 0x1d, 0x29, 0x20, 0x2a, 0x11, 0x2a, 0x0c, 0x52, - 0x51, 0x37, 0x91, 0x63, 0x9f, 0x9a, 0x51, 0x3d, 0x9e, 0x60, 0x3b, 0x6d, 0x2a, 0xb1, 0x83, 0x07, - 0x60, 0xc5, 0x33, 0x75, 0xd9, 0x25, 0x62, 0x61, 0xa1, 0xf4, 0x0d, 0xb2, 0x64, 0x85, 0xec, 0x71, - 0x82, 0x93, 0x34, 0x2d, 0x42, 0x55, 0x17, 0xac, 0x92, 0xcc, 0xf7, 0x73, 0x8e, 0xbe, 0x99, 0x39, - 0x19, 0xb4, 0x06, 0x54, 0xa7, 0xa6, 0x7f, 0x0c, 0xa1, 0x7e, 0x52, 0xd5, 0xc3, 0xae, 0xd6, 0xf6, - 0x59, 0xc8, 0xc4, 0x05, 0xa0, 0x1a, 0x5f, 0xd6, 0x4e, 0xaa, 0xf2, 0xaa, 0xc3, 0x1c, 0x96, 0x00, - 0x7a, 0xfc, 0x8d, 0x73, 0x64, 0xc5, 0x62, 0x01, 0x65, 0x81, 0xde, 0x32, 0x03, 0xd0, 0x4f, 0xaa, - 0x2d, 0x08, 0xcd, 0xaa, 0x6e, 0x31, 0xe2, 0xa5, 0x78, 0x79, 0xc4, 0x3a, 0x75, 0xe3, 0x90, 0xea, - 0x30, 0xe6, 0xb8, 0xa0, 0x27, 0xbf, 0x5a, 0x9d, 0x23, 0x3d, 0x24, 0x14, 0x82, 0xd0, 0xa4, 0x6d, - 0x4e, 0xc0, 0xdf, 0x67, 0x50, 0xa9, 0x11, 0x38, 0x8f, 0x6c, 0xfb, 0x39, 0xa1, 0x24, 0xdc, 0xf7, - 0x6d, 0xf0, 0xc5, 0x6d, 0x34, 0xc7, 0x4e, 0x3d, 0xf0, 0x25, 0x61, 0x53, 0xa8, 0xcc, 0xd7, 0x4b, - 0xfd, 0x48, 0x5d, 0x38, 0x33, 0xa9, 0xfb, 0x10, 0x27, 0xcb, 0xd8, 0xe0, 0xb0, 0x58, 0x47, 0xcb, - 0x96, 0x4b, 0xc0, 0x0b, 0x9b, 0x2c, 0xd6, 0x35, 0x89, 0x2d, 0xcd, 0x24, 0x0a, 0xb9, 0x1f, 0xa9, - 0xeb, 0x5c, 0x31, 0x46, 0xc0, 0xc6, 0x22, 0x5f, 0x49, 0x2a, 0xed, 0xd9, 0xe2, 0x01, 0x5a, 0x8c, - 0x7b, 0x6a, 0x12, 0xaf, 0x79, 0xc4, 0x7c, 0x0b, 0xa4, 0xfc, 0xa6, 0x50, 0x59, 0xaa, 0x95, 0xb5, - 0x6c, 0x30, 0xda, 0x6b, 0x42, 0x61, 0xcf, 0x7b, 0x1a, 0x13, 0xea, 0x52, 0x3f, 0x52, 0x57, 0xb9, - 0xf9, 0x88, 0x12, 0x1b, 0xc5, 0xf0, 0x27, 0x4d, 0x7c, 0x86, 0x0a, 0x01, 0xeb, 0xc4, 0x8e, 0xb3, - 0x9b, 0x42, 0xa5, 0x58, 0x2b, 0x6b, 0x3c, 0x46, 0x2d, 0x8e, 0x51, 0x4b, 0x63, 0xd4, 0x76, 0x19, - 0xf1, 0xea, 0x6b, 0xe7, 0x91, 0x9a, 0xeb, 0x47, 0xea, 0x22, 0x77, 0xe5, 0x32, 0x6c, 0xa4, 0x7a, - 0xf1, 0x00, 0x15, 0x6d, 0x08, 0x42, 0xe2, 0x99, 0x21, 0x61, 0x9e, 0x34, 0x77, 0x93, 0x9d, 0x9c, - 0xda, 0x89, 0xdc, 0x2e, 0xa3, 0xc5, 0x46, 0xd6, 0x09, 0xcb, 0x48, 0x1a, 0xcf, 0xde, 0x80, 0xa0, - 0xcd, 0xbc, 0x00, 0x70, 0x2f, 0x8f, 0x56, 0x38, 0xd8, 0x48, 0x52, 0xf8, 0x83, 0x76, 0xe6, 0xbf, - 0x91, 0x9d, 0x99, 0xaf, 0xaf, 0xdc, 0x7d, 0xf4, 0xe2, 0x07, 0x01, 0x95, 0xa8, 0xd9, 0x25, 0xb4, - 0x43, 0x9b, 0x81, 0x4b, 0xda, 0x6d, 0xd3, 0x01, 0xa9, 0x90, 0xb4, 0xf3, 0x26, 0xf6, 0xf8, 0x1a, - 0xa9, 0xdb, 0x0e, 0x09, 0xdf, 0x76, 0x5a, 0x9a, 0xc5, 0xa8, 0x9e, 0xde, 0x40, 0xfe, 0xb1, 0x13, - 0xd8, 0xc7, 0x7a, 0x78, 0xd6, 0x86, 0x40, 0x7b, 0x0c, 0x56, 0x2f, 0x52, 0x8b, 0x0d, 0xb3, 0xfb, - 0x2a, 0x35, 0xe9, 0x47, 0xea, 0x06, 0x2f, 0x3e, 0x6e, 0x8f, 0x8d, 0xe5, 0x74, 0x69, 0xc0, 0xc5, - 0x7f, 0xa3, 0xf2, 0xc4, 0x1e, 0x0f, 0x4f, 0xc0, 0x7b, 0xb4, 0xd4, 0x08, 0x9c, 0x5d, 0xd3, 0xb3, - 0xc0, 0xbd, 0xf3, 0xdd, 0xc7, 0x12, 0x5a, 0x1f, 0xad, 0x3e, 0xec, 0xeb, 0xf3, 0x2c, 0x92, 0x87, - 0x90, 0x01, 0x6d, 0xd7, 0xb4, 0xe0, 0x37, 0x86, 0xc7, 0x3b, 0x24, 0x31, 0x9f, 0x38, 0xc4, 0x33, - 0xdd, 0xe6, 0xd5, 0xdd, 0x3e, 0xe8, 0x45, 0xea, 0xca, 0xbe, 0x4f, 0x9c, 0xdd, 0x6c, 0x67, 0xfd, - 0x48, 0x55, 0x53, 0xbf, 0x29, 0x72, 0x6c, 0xac, 0x0d, 0xa0, 0x11, 0xa5, 0x68, 0xa2, 0xbf, 0x3c, - 0x38, 0x9d, 0xa8, 0x96, 0x4f, 0xaa, 0xd5, 0x7a, 0x91, 0x5a, 0x7a, 0x01, 0xa7, 0xe3, 0xc5, 0x64, - 0x5e, 0xec, 0x0a, 0x21, 0x36, 0x4a, 0xde, 0x18, 0x7f, 0xf2, 0xd2, 0xcc, 0xde, 0xfa, 0x38, 0x9b, - 0xbb, 0xdd, 0x71, 0x56, 0xb8, 0xb5, 0x71, 0xb6, 0x85, 0xf0, 0xf4, 0x73, 0x31, 0x38, 0x3e, 0xb5, - 0x8f, 0x79, 0x94, 0x6f, 0x04, 0x4e, 0x9c, 0xd4, 0xe8, 0xbf, 0x8e, 0x32, 0x9a, 0xd1, 0xf8, 0x64, - 0x94, 0xb7, 0xaf, 0xc7, 0x07, 0x05, 0xc4, 0x43, 0xb4, 0x34, 0x36, 0x35, 0xd5, 0xab, 0x94, 0x19, - 0x82, 0xfc, 0xef, 0x0d, 0x84, 0xa1, 0xf7, 0x4b, 0x54, 0xcc, 0x5e, 0xc8, 0x7f, 0x26, 0x74, 0x19, - 0x54, 0xde, 0xba, 0x0e, 0x1d, 0x5a, 0x76, 0xd0, 0xc6, 0xb4, 0xab, 0x54, 0x99, 0x62, 0x30, 0xc1, - 0x94, 0xef, 0xfd, 0x2a, 0x73, 0x50, 0xb6, 0xfe, 0xe4, 0xbc, 0xa7, 0x08, 0x17, 0x3d, 0x45, 0xf8, - 0xd6, 0x53, 0x84, 0x4f, 0x97, 0x4a, 0xee, 0xe2, 0x52, 0xc9, 0x7d, 0xb9, 0x54, 0x72, 0x87, 0xff, - 0x67, 0xe6, 0x1e, 0xec, 0x50, 0xe6, 0xc1, 0x99, 0x0e, 0x74, 0xc7, 0x05, 0xdb, 0x01, 0x5f, 0xef, - 0x0e, 0x9e, 0x1a, 0xc9, 0x00, 0x6c, 0x15, 0x92, 0x67, 0xc4, 0xfd, 0x1f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x41, 0xad, 0x6b, 0x6e, 0xdf, 0x08, 0x00, 0x00, + // 780 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0x4d, 0x6f, 0xd3, 0x40, + 0x10, 0x8d, 0x9b, 0x0f, 0xd4, 0x4d, 0x3f, 0x52, 0xd3, 0x0f, 0xc7, 0x45, 0x76, 0x65, 0x4a, 0x49, + 0x85, 0x6a, 0x93, 0x70, 0x41, 0xdc, 0x48, 0x01, 0x51, 0x89, 0x50, 0x61, 0x90, 0x8a, 0x7a, 0x89, + 0x1c, 0x7b, 0x6b, 0x56, 0xf5, 0x7a, 0x83, 0xed, 0xb4, 0xa9, 0xc4, 0x8d, 0x3f, 0xc0, 0x89, 0xdf, + 0xd4, 0x63, 0x8f, 0x88, 0x83, 0x85, 0xd2, 0x7f, 0x90, 0x23, 0x87, 0x0a, 0xd9, 0xeb, 0x04, 0xc7, + 0x69, 0xd2, 0x52, 0x95, 0x1e, 0x10, 0xa7, 0x36, 0x3b, 0xef, 0xbd, 0x19, 0xcd, 0x8c, 0xdf, 0x2e, + 0x58, 0x80, 0x58, 0xc1, 0x9a, 0xb3, 0x0f, 0x3d, 0xe5, 0xa0, 0xac, 0x78, 0x6d, 0xb9, 0xe9, 0x10, + 0x8f, 0xb0, 0x53, 0x10, 0xcb, 0xf4, 0x58, 0x3e, 0x28, 0xf3, 0xf3, 0x26, 0x31, 0x49, 0x18, 0x50, + 0x82, 0xff, 0x28, 0x86, 0x17, 0x74, 0xe2, 0x62, 0xe2, 0x2a, 0x0d, 0xcd, 0x85, 0xca, 0x41, 0xb9, + 0x01, 0x3d, 0xad, 0xac, 0xe8, 0x04, 0xd9, 0x51, 0xbc, 0x38, 0x20, 0x1d, 0xa9, 0xd1, 0x90, 0x68, + 0x12, 0x62, 0x5a, 0x50, 0x09, 0x7f, 0x35, 0x5a, 0x7b, 0x8a, 0x87, 0x30, 0x74, 0x3d, 0x0d, 0x37, + 0x29, 0x40, 0xfa, 0x39, 0x01, 0x0a, 0x35, 0xd7, 0x7c, 0x6a, 0x18, 0xaf, 0x10, 0x46, 0xde, 0xb6, + 0x63, 0x40, 0x87, 0x5d, 0x03, 0x59, 0x72, 0x68, 0x43, 0x87, 0x63, 0x56, 0x98, 0xd2, 0x64, 0xb5, + 0xd0, 0xf5, 0xc5, 0xa9, 0x23, 0x0d, 0x5b, 0x4f, 0xa4, 0xf0, 0x58, 0x52, 0x69, 0x98, 0xad, 0x82, + 0x59, 0xdd, 0x42, 0xd0, 0xf6, 0xea, 0x24, 0xe0, 0xd5, 0x91, 0xc1, 0x4d, 0x84, 0x0c, 0xbe, 0xeb, + 0x8b, 0x8b, 0x94, 0x91, 0x00, 0x48, 0xea, 0x34, 0x3d, 0x09, 0x33, 0x6d, 0x19, 0xec, 0x0e, 0x98, + 0x0e, 0x6a, 0xaa, 0x23, 0xbb, 0xbe, 0x47, 0x1c, 0x1d, 0x72, 0xe9, 0x15, 0xa6, 0x34, 0x53, 0x29, + 0xca, 0xf1, 0xc6, 0xc8, 0xef, 0x10, 0x86, 0x5b, 0xf6, 0x8b, 0x00, 0x50, 0xe5, 0xba, 0xbe, 0x38, + 0x4f, 0xc5, 0x07, 0x98, 0x92, 0x9a, 0xf7, 0x7e, 0xc3, 0xd8, 0x97, 0x20, 0xe7, 0x92, 0x56, 0xa0, + 0x98, 0x59, 0x61, 0x4a, 0xf9, 0x4a, 0x51, 0xa6, 0x6d, 0x94, 0x83, 0x36, 0xca, 0x51, 0x1b, 0xe5, + 0x4d, 0x82, 0xec, 0xea, 0xc2, 0xb1, 0x2f, 0xa6, 0xba, 0xbe, 0x38, 0x4d, 0x55, 0x29, 0x4d, 0x52, + 0x23, 0x3e, 0xbb, 0x03, 0xf2, 0x06, 0x74, 0x3d, 0x64, 0x6b, 0x1e, 0x22, 0x36, 0x97, 0xbd, 0x48, + 0x8e, 0x8f, 0xe4, 0x58, 0x2a, 0x17, 0xe3, 0x4a, 0x6a, 0x5c, 0x49, 0xe2, 0x01, 0x97, 0xec, 0xbd, + 0x0a, 0xdd, 0x26, 0xb1, 0x5d, 0x28, 0x75, 0xd2, 0x60, 0x8e, 0x06, 0x6b, 0x61, 0x17, 0xfe, 0xa1, + 0xc9, 0xac, 0x0f, 0x4c, 0x66, 0xb2, 0x3a, 0x77, 0xf3, 0xad, 0x67, 0x3f, 0x33, 0xa0, 0x80, 0xb5, + 0x36, 0xc2, 0x2d, 0x5c, 0x77, 0x2d, 0xd4, 0x6c, 0x6a, 0x26, 0xe4, 0x72, 0x61, 0x39, 0xef, 0x03, + 0x8d, 0xef, 0xbe, 0xb8, 0x66, 0x22, 0xef, 0x43, 0xab, 0x21, 0xeb, 0x04, 0x2b, 0xd1, 0x17, 0x48, + 0xff, 0x6c, 0xb8, 0xc6, 0xbe, 0xe2, 0x1d, 0x35, 0xa1, 0x2b, 0x3f, 0x83, 0x7a, 0xc7, 0x17, 0xf3, + 0x35, 0xad, 0xfd, 0x36, 0x12, 0xe9, 0xfa, 0xe2, 0x12, 0x4d, 0x9e, 0x94, 0x97, 0xd4, 0xd9, 0xe8, + 0xa8, 0x87, 0x95, 0x96, 0x41, 0x71, 0x68, 0xc6, 0xfd, 0x0d, 0xf8, 0x04, 0x66, 0x6a, 0xae, 0xb9, + 0xa9, 0xd9, 0x3a, 0xb4, 0x6e, 0x7c, 0xfa, 0x12, 0x07, 0x16, 0x07, 0xb3, 0xf7, 0xeb, 0xfa, 0x9a, + 0x01, 0x7c, 0x3f, 0xa4, 0xc2, 0xa6, 0xa5, 0xe9, 0xf0, 0x0a, 0xe6, 0xf1, 0x11, 0x70, 0xc4, 0x41, + 0x26, 0xb2, 0x35, 0xab, 0x7e, 0x7e, 0xb5, 0x8f, 0x3b, 0xbe, 0x38, 0xb7, 0xed, 0x20, 0x73, 0x33, + 0x5e, 0x59, 0xd7, 0x17, 0xc5, 0x48, 0x6f, 0x04, 0x5d, 0x52, 0x17, 0x7a, 0xa1, 0x01, 0x26, 0xab, + 0x81, 0xdb, 0x36, 0x3c, 0x1c, 0xca, 0x96, 0x0e, 0xb3, 0x55, 0x3a, 0xbe, 0x58, 0x78, 0x0d, 0x0f, + 0x93, 0xc9, 0x78, 0x9a, 0xec, 0x1c, 0xa2, 0xa4, 0x16, 0xec, 0x04, 0x7e, 0xf8, 0xa3, 0xc9, 0x5c, + 0xbb, 0x9d, 0x65, 0xaf, 0xd7, 0xce, 0x72, 0xd7, 0x66, 0x67, 0xab, 0x40, 0x1a, 0xbd, 0x17, 0xfd, + 0xf5, 0x39, 0xcb, 0x80, 0xe5, 0x24, 0xec, 0x2a, 0x16, 0xf7, 0x7f, 0x7f, 0xae, 0x68, 0xba, 0xd9, + 0x3f, 0x34, 0xdd, 0xdc, 0xdf, 0x35, 0xdd, 0x5b, 0x37, 0x6d, 0xba, 0xf7, 0xc0, 0xdd, 0x31, 0xfb, + 0xd7, 0xdb, 0xd3, 0xca, 0x59, 0x1a, 0xa4, 0x6b, 0xae, 0x19, 0x4c, 0x64, 0xf0, 0x75, 0x24, 0x0c, + 0xce, 0x22, 0x79, 0x83, 0xf3, 0x6b, 0xe3, 0xe3, 0xbd, 0x04, 0xec, 0x2e, 0x98, 0x49, 0xdc, 0xee, + 0xe2, 0x79, 0xcc, 0x18, 0x80, 0xbf, 0x7f, 0x01, 0xa0, 0xaf, 0xfd, 0x06, 0xe4, 0xe3, 0x17, 0xc7, + 0x9d, 0x21, 0x5e, 0x2c, 0xca, 0xaf, 0x8e, 0x8b, 0xf6, 0x25, 0x5b, 0x60, 0x69, 0x94, 0xe5, 0x97, + 0x46, 0x08, 0x0c, 0x21, 0xf9, 0x87, 0x97, 0x45, 0xf6, 0xd3, 0xb6, 0x01, 0x37, 0xd2, 0x2a, 0xd6, + 0xc7, 0xab, 0xc5, 0x3b, 0x57, 0xbe, 0x34, 0xb4, 0x97, 0xb9, 0xfa, 0xfc, 0xb8, 0x23, 0x30, 0x27, + 0x1d, 0x81, 0xf9, 0xd1, 0x11, 0x98, 0x2f, 0xa7, 0x42, 0xea, 0xe4, 0x54, 0x48, 0x7d, 0x3b, 0x15, + 0x52, 0xbb, 0x0f, 0x62, 0x4b, 0x0a, 0x37, 0x30, 0xb1, 0xe1, 0x91, 0x02, 0xf1, 0x86, 0x05, 0x0d, + 0x13, 0x3a, 0x4a, 0xbb, 0xf7, 0x18, 0x0f, 0xb7, 0xb5, 0x91, 0x0b, 0x1f, 0xda, 0x8f, 0x7e, 0x05, + 0x00, 0x00, 0xff, 0xff, 0x7e, 0x1f, 0x6d, 0x63, 0x01, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -543,6 +669,7 @@ type MsgClient interface { AddMarketOrder(ctx context.Context, in *MsgAddMarketOrder, opts ...grpc.CallOption) (*MsgAddMarketOrderResponse, error) CancelOrder(ctx context.Context, in *MsgCancelOrder, opts ...grpc.CallOption) (*MsgCancelOrderResponse, error) CancelReplaceLimitOrder(ctx context.Context, in *MsgCancelReplaceLimitOrder, opts ...grpc.CallOption) (*MsgCancelReplaceLimitOrderResponse, error) + CancelReplaceMarketOrder(ctx context.Context, in *MsgCancelReplaceMarketOrder, opts ...grpc.CallOption) (*MsgCancelReplaceMarketOrderResponse, error) } type msgClient struct { @@ -589,12 +716,22 @@ func (c *msgClient) CancelReplaceLimitOrder(ctx context.Context, in *MsgCancelRe return out, nil } +func (c *msgClient) CancelReplaceMarketOrder(ctx context.Context, in *MsgCancelReplaceMarketOrder, opts ...grpc.CallOption) (*MsgCancelReplaceMarketOrderResponse, error) { + out := new(MsgCancelReplaceMarketOrderResponse) + err := c.cc.Invoke(ctx, "/em.market.v1.Msg/CancelReplaceMarketOrder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { AddLimitOrder(context.Context, *MsgAddLimitOrder) (*MsgAddLimitOrderResponse, error) AddMarketOrder(context.Context, *MsgAddMarketOrder) (*MsgAddMarketOrderResponse, error) CancelOrder(context.Context, *MsgCancelOrder) (*MsgCancelOrderResponse, error) CancelReplaceLimitOrder(context.Context, *MsgCancelReplaceLimitOrder) (*MsgCancelReplaceLimitOrderResponse, error) + CancelReplaceMarketOrder(context.Context, *MsgCancelReplaceMarketOrder) (*MsgCancelReplaceMarketOrderResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -613,6 +750,9 @@ func (*UnimplementedMsgServer) CancelOrder(ctx context.Context, req *MsgCancelOr func (*UnimplementedMsgServer) CancelReplaceLimitOrder(ctx context.Context, req *MsgCancelReplaceLimitOrder) (*MsgCancelReplaceLimitOrderResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CancelReplaceLimitOrder not implemented") } +func (*UnimplementedMsgServer) CancelReplaceMarketOrder(ctx context.Context, req *MsgCancelReplaceMarketOrder) (*MsgCancelReplaceMarketOrderResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CancelReplaceMarketOrder not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -690,6 +830,24 @@ func _Msg_CancelReplaceLimitOrder_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Msg_CancelReplaceMarketOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCancelReplaceMarketOrder) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CancelReplaceMarketOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/em.market.v1.Msg/CancelReplaceMarketOrder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CancelReplaceMarketOrder(ctx, req.(*MsgCancelReplaceMarketOrder)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "em.market.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -710,6 +868,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "CancelReplaceLimitOrder", Handler: _Msg_CancelReplaceLimitOrder_Handler, }, + { + MethodName: "CancelReplaceMarketOrder", + Handler: _Msg_CancelReplaceMarketOrder_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "em/market/v1/tx.proto", @@ -1044,6 +1206,105 @@ func (m *MsgCancelReplaceLimitOrderResponse) MarshalToSizedBuffer(dAtA []byte) ( return len(dAtA) - i, nil } +func (m *MsgCancelReplaceMarketOrder) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCancelReplaceMarketOrder) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCancelReplaceMarketOrder) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.MaxSlippage.Size() + i -= size + if _, err := m.MaxSlippage.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + { + size, err := m.Destination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + if len(m.Source) > 0 { + i -= len(m.Source) + copy(dAtA[i:], m.Source) + i = encodeVarintTx(dAtA, i, uint64(len(m.Source))) + i-- + dAtA[i] = 0x2a + } + if m.TimeInForce != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TimeInForce)) + i-- + dAtA[i] = 0x20 + } + if len(m.NewClientOrderId) > 0 { + i -= len(m.NewClientOrderId) + copy(dAtA[i:], m.NewClientOrderId) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewClientOrderId))) + i-- + dAtA[i] = 0x1a + } + if len(m.OrigClientOrderId) > 0 { + i -= len(m.OrigClientOrderId) + copy(dAtA[i:], m.OrigClientOrderId) + i = encodeVarintTx(dAtA, i, uint64(len(m.OrigClientOrderId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintTx(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCancelReplaceMarketOrderResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCancelReplaceMarketOrderResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCancelReplaceMarketOrderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -1188,6 +1449,47 @@ func (m *MsgCancelReplaceLimitOrderResponse) Size() (n int) { return n } +func (m *MsgCancelReplaceMarketOrder) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.OrigClientOrderId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.NewClientOrderId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.TimeInForce != 0 { + n += 1 + sovTx(uint64(m.TimeInForce)) + } + l = len(m.Source) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Destination.Size() + n += 1 + l + sovTx(uint64(l)) + l = m.MaxSlippage.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgCancelReplaceMarketOrderResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2170,6 +2472,320 @@ func (m *MsgCancelReplaceLimitOrderResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgCancelReplaceMarketOrder) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCancelReplaceMarketOrder: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCancelReplaceMarketOrder: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OrigClientOrderId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OrigClientOrderId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewClientOrderId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NewClientOrderId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeInForce", wireType) + } + m.TimeInForce = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeInForce |= TimeInForce(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Destination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Destination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxSlippage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaxSlippage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCancelReplaceMarketOrderResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCancelReplaceMarketOrderResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCancelReplaceMarketOrderResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From ffebfd4a32e65a604613f3bc5b9662a57426d10c Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 11 May 2021 10:44:25 +0300 Subject: [PATCH 04/41] Undo refactoring --- x/market/keeper/keeper.go | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 561d811d..aacaee5e 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -24,9 +24,6 @@ const ( gasPriceNewOrder = uint64(25000) gasPriceCancelReplaceOrder = uint64(25000) gasPriceCancelOrder = uint64(12500) - - gasCancelReplaceLimitOrder = "CancelReplaceMarketOrder" - gasCancelReplaceMarketOrder = "CancelReplaceMarketOrder" ) var _ marketKeeper = &Keeper{} @@ -406,38 +403,25 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, k.deleteOrder(ctx, origOrder) types.EmitExpireEvent(ctx, *origOrder) - setRemainingLimit(origOrder, &newOrder) - - resAdd, err := k.NewOrderSingle(ctx, newOrder) - if err != nil { - return nil, err - } - - evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) - return &sdk.Result{Events: evts}, nil -} - -func setRemainingLimit(origOrder *types.Order, newOrder *types.Order) { // Adjust remaining according to how much of the replaced order was filled: newOrder.SourceFilled = origOrder.SourceFilled newOrder.SourceRemaining = newOrder.Source.Amount.Sub(newOrder.SourceFilled) newOrder.DestinationFilled = origOrder.DestinationFilled newOrder.TimeInForce = origOrder.TimeInForce -} -func setRemainingMarket(origOrder *types.Order, newOrder *types.Order) { - // Adjust remaining according to how much of the replaced order was filled: - newOrder.SourceFilled = origOrder.SourceFilled - newOrder.SourceRemaining = newOrder.Source.Amount.Sub(newOrder.SourceFilled) - newOrder.DestinationFilled = origOrder.DestinationFilled + resAdd, err := k.NewOrderSingle(ctx, newOrder) + if err != nil { + return nil, err + } - newOrder.TimeInForce = origOrder.TimeInForce + evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) + return &sdk.Result{Events: evts}, nil } func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { // Use a fixed gas amount - ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, gasCancelReplaceMarketOrder) + ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, "CancelReplaceMarketOrder") ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) From 8a18f69f4fa99623440bbbc8eee51b388bea46e1 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 11 May 2021 16:39:11 +0300 Subject: [PATCH 05/41] Add keeper unit tests --- x/market/keeper/keeper_test.go | 138 ++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 12 deletions(-) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 87b63671..a6ca57b1 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -226,7 +226,7 @@ func TestMarketOrderSlippage1(t *testing.T) { require.True(t, types.ErrAccountBalanceInsufficient.Is(err)) } -func TestCancelReplaceMarketOrderSlippage1(t *testing.T) { +func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc1 := createAccount(ctx, ak, bk, randomAddress(), "500gbp") @@ -244,45 +244,159 @@ func TestCancelReplaceMarketOrderSlippage1(t *testing.T) { _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) - // Sell eur at various prices - o = order(ctx.BlockTime(), acc2, "50eur", "50gbp") - _, err = k.NewOrderSingle(ctx, o) + // Make a market order that allows slippage + clientID := cid() + slippage := sdk.NewDecWithPrec(100, 2) + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(100)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + clientID, + ) require.NoError(t, err) + foundOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), clientID, + ) + require.NotNil(t, foundOrder, "Market order should exist") + // 100% slippage to double source + require.True(t, foundOrder.Source.IsEqual(sdk.NewCoin("gbp", sdk.NewInt(200)))) - o = order(ctx.BlockTime(), acc2, "50eur", "75gbp") + // Gave 1 gbp and gained a eur + acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("1eur,499gbp").String(), acc1Bal.String()) + + newClientID := cid() + mcrm := &types.MsgCancelReplaceMarketOrder{ + Owner: acc1.GetAddress().String(), + OrigClientOrderId: clientID, + NewClientOrderId: newClientID, + TimeInForce: types.TimeInForce_GoodTillCancel, + Source: "gbp", + Destination: sdk.NewCoin("eur", sdk.NewInt(100)), + MaxSlippage: sdk.NewDecWithPrec(0, 2), + } + _, err = k.CancelReplaceMarketOrder(ctx, mcrm) + require.NoError(t, err) + + expOrder := &types.Order{ + ID: 3, + TimeInForce: types.TimeInForce_GoodTillCancel, + Owner: acc1.GetAddress().String(), + ClientOrderID: newClientID, + // Zero slippage same amount + Source: sdk.NewCoin(mcrm.Source, sdk.NewInt(100)), + SourceRemaining: sdk.NewInt(100), + SourceFilled: sdk.ZeroInt(), + Destination: mcrm.Destination, + DestinationFilled: sdk.ZeroInt(), + Created: ctx.BlockTime(), + } + require.NoError(t, err) + + origOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), clientID, + ) + require.Nil(t, origOrder, "Original market order should not exist") + + foundOrder = k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), newClientID, + ) + require.Equal(t, expOrder, foundOrder) + + // no impact + acc1Bal = bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("1eur,499gbp").String(), acc1Bal.String()) +} + +func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "100gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "100eur") + + var o types.Order + var err error + + // Establish market price by executing a 2:1 trade + o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) - o = order(ctx.BlockTime(), acc2, "50eur", "100gbp") + o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) + acc1b := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("20eur,90gbp").String(), acc1b.String()) // Make a market order that allows slippage - clientID := cid() - slippage := sdk.NewDecWithPrec(1, 2) + slippage := sdk.NewDecWithPrec(0, 2) _, err = k.NewMarketOrderWithSlippage( ctx, "gbp", - sdk.NewCoin("eur", sdk.NewInt(200)), + sdk.NewCoin("eur", sdk.NewInt(10)), slippage, acc1.GetAddress(), types.TimeInForce_GoodTillCancel, clientID, ) require.NoError(t, err) + acc1b = bk.GetAllBalances(ctx, acc1.GetAddress()) + // Gave 1 gbp and gained a eur + acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("20eur,90gbp").String(), acc1Bal.String()) + + foundOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), clientID, + ) + require.NotNil(t, foundOrder, "Market order should exist") + // 0% slippage same as ratio (1eur/2gbp) * 10 => 5gbp + require.True(t, foundOrder.Source.IsEqual(sdk.NewCoin("gbp", sdk.NewInt(5)))) + + newClientID := cid() mcrm := &types.MsgCancelReplaceMarketOrder{ Owner: acc1.GetAddress().String(), OrigClientOrderId: clientID, - NewClientOrderId: cid(), + NewClientOrderId: newClientID, TimeInForce: types.TimeInForce_GoodTillCancel, Source: "gbp", - Destination: sdk.NewCoin("eur", sdk.NewInt(100)), - MaxSlippage: sdk.NewDecWithPrec(50, 2), + Destination: sdk.NewCoin("eur", sdk.NewInt(10)), + MaxSlippage: sdk.NewDecWithPrec(100, 2), } _, err = k.CancelReplaceMarketOrder(ctx, mcrm) require.NoError(t, err) + expOrder := &types.Order{ + ID: 3, + TimeInForce: types.TimeInForce_GoodTillCancel, + Owner: acc1.GetAddress().String(), + ClientOrderID: newClientID, + // 100 % slippage should result 2 * (1/2) => 10 gbp -> 10 eur + Source: sdk.NewCoin(mcrm.Source, sdk.NewInt(10)), + SourceRemaining: sdk.NewInt(10), + SourceFilled: sdk.ZeroInt(), + Destination: mcrm.Destination, + DestinationFilled: sdk.ZeroInt(), + Created: ctx.BlockTime(), + } + require.NoError(t, err) + + origOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), clientID, + ) + require.Nil(t, origOrder, "Original market order should not exist") + + foundOrder = k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), newClientID, + ) + require.Equal(t, expOrder, foundOrder) + + // no impact + acc1Bal = bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("20eur,90gbp").String(), acc1Bal.String()) } func TestFillOrKillMarketOrder1(t *testing.T) { From d76e843fa0327e0c30532ed80cdd82dd21ef79fe Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 11 May 2021 17:06:20 +0300 Subject: [PATCH 06/41] Add documentation --- x/market/spec/02_messages.md | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/x/market/spec/02_messages.md b/x/market/spec/02_messages.md index 01b0651a..55595806 100644 --- a/x/market/spec/02_messages.md +++ b/x/market/spec/02_messages.md @@ -88,3 +88,45 @@ newOrder.SourceFilled = origOrder.SourceFilled newOrder.SourceRemaining = newOrder.Source.Amount.Sub(newOrder.SourceFilled) newOrder.DestinationFilled = origOrder.DestinationFilled ``` + +## MsgCancelReplaceMarketOrder + +The MsgCancelReplaceMarketOrder message is helpful to adjust prices and slippage for previous market orders while +remaining in the market. Please note, The new Market order is converted to limit order on receipt: The limit price is +determined using the last traded price of its instrument, with the *adjusted* slippage value applied resulting in the +updated limit price. + +```go +// MsgCancelReplaceMarketOrder represents a message to cancel an existing order and replace it with a market order. +MsgCancelReplaceMarketOrder struct { + Owner sdk.AccAddress `json:"owner" yaml:"owner"` + OrigClientOrderId string `json:"original_client_order_id" yaml:"original_client_order_id"` + NewClientOrderId string `json:"new_client_order_id" yaml:"new_client_order_id"` + TimeInForce string `json:"time_in_force" yaml:"time_in_force"` + Source string `protobuf:"bytes,5,opt,name=source,proto3" json:"source,omitempty" yaml:"source"` + Destination sdk.Coin `json:"destination" yaml:"destination"` + MaxSlippage sdk.Dec `protobuf:"bytes,7,opt,name=maximum_slippage,json=maximumSlippage,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"maximum_slippage" yaml:"maximum_slippage"` +} +``` + +The unfilled part of the original order is canceled and replaced with a new market order, taking into consideration how +much of the original order was filled: + +```go +// Has the previous order already achieved the goal on the source side? +if origOrder.SourceFilled.GTE(newOrder.Source.Amount) { + return nil, sdkerrors.Wrap(types.ErrNoSourceRemaining, "") +} +if origOrder.DestinationFilled.GTE(msg.Destination.Amount) { + return nil, sdkerrors.Wrap( + types.ErrNoSourceRemaining, fmt.Sprintf("has already been filled filled:%s >= %s", + origOrder.Destination.Amount.String(), msg.Destination.Amount.String()), + ) +} +[...] + +// Adjust remaining according to how much of the replaced order was filled: +destinationFilled := origOrder.DestinationFilled +dstRemaining := msg.Destination.Amount.Sub(destinationFilled) +remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) +``` From 99a8031e15e6f970d261ce77df3fd6c302f5074a Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Wed, 12 May 2021 15:13:11 +0300 Subject: [PATCH 07/41] Add proto msg type --- docs/proto/em/proto-docs.md | 36 +++ proto/em/market/v1/tx.proto | 46 ++++ x/market/types/tx.pb.go | 430 +++++++++++++++++++++++++++++++----- 3 files changed, 452 insertions(+), 60 deletions(-) diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index 8f71d408..436f9266 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -122,6 +122,9 @@ - [MsgCancelReplaceLimitOrderResponse](#em.market.v1.MsgCancelReplaceLimitOrderResponse) - [MsgCancelReplaceMarketOrder](#em.market.v1.MsgCancelReplaceMarketOrder) - [MsgCancelReplaceMarketOrderResponse](#em.market.v1.MsgCancelReplaceMarketOrderResponse) + - [TxParam](#em.market.v1.TxParam) + + - [TxMessageType](#em.market.v1.TxMessageType) - [Msg](#em.market.v1.Msg) @@ -1458,8 +1461,41 @@ + + + +### TxParam + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `trx_fee` | [string](#string) | | default fee for a market transaction. | +| `liquid_trx_fee` | [string](#string) | | Valid liquidity adding orders are free or adjusted to a minimum nominal/fee | +| `liquidity_rebate_minutes_span` | [int64](#int64) | | Minutes interval for the liquidity rebate to apply. For the liquidity rebate to apply, the running transaction should occur x minutes after the signers' last liquid trx. | + + + + + + + + +### TxMessageType + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| DEFAULT_TX_MSG | 0 | Tx fallback for fees etc. | +| ADD_LIMIT_ORDER | 1 | | +| ADD_MARKET_ORDER | 2 | | +| CANCEL_REPLACE_LIMIT_ORDER | 3 | | +| CANCEL_REPLACE_MARKET_ORDER | 4 | | +| CANCEL_ORDER | 5 | | + + diff --git a/proto/em/market/v1/tx.proto b/proto/em/market/v1/tx.proto index 0af5c221..0690c79c 100644 --- a/proto/em/market/v1/tx.proto +++ b/proto/em/market/v1/tx.proto @@ -20,6 +20,52 @@ service Msg { returns (MsgCancelReplaceMarketOrderResponse); } +enum TxMessageType { + option (gogoproto.goproto_enum_stringer) = true; + + // Tx fallback for fees etc. + DEFAULT_TX_MSG = 0 + [ (gogoproto.enumvalue_customname) = "DefaultTxMsg" ]; + + ADD_LIMIT_ORDER = 1 + [ (gogoproto.enumvalue_customname) = "AddLimitOrder" ]; + + ADD_MARKET_ORDER = 2 + [ (gogoproto.enumvalue_customname) = "AddMarketOrder" ]; + + CANCEL_REPLACE_LIMIT_ORDER = 3 + [ (gogoproto.enumvalue_customname) = "CancelReplaceLimitOrder" ]; + + CANCEL_REPLACE_MARKET_ORDER = 4 + [ (gogoproto.enumvalue_customname) = "CancelReplaceMarketOrder" ]; + + CANCEL_ORDER = 5 + [ (gogoproto.enumvalue_customname) = "CancelOrder" ]; +} + +message TxParam { + // default fee for a market transaction. + string trx_fee = 1 [ + (gogoproto.moretags) = "yaml:\"trx_fee\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee + string liquid_trx_fee = 2 [ + (gogoproto.moretags) = "yaml:\"liquid_trx_fee\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", + (gogoproto.nullable) = false + ]; + + // Minutes interval for the liquidity rebate to apply. For the liquidity + // rebate to apply, the running transaction should occur x minutes + // after the signers' last liquid trx. + int64 liquidity_rebate_minutes_span = 3 [ + (gogoproto.moretags) = "yaml:\"liquidity_rebate_minutes_span\"" + ]; +} + message MsgAddLimitOrder { string owner = 1 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; diff --git a/x/market/types/tx.pb.go b/x/market/types/tx.pb.go index 96f33208..c9c1eafb 100644 --- a/x/market/types/tx.pb.go +++ b/x/market/types/tx.pb.go @@ -31,6 +31,95 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type TxMessageType int32 + +const ( + // Tx fallback for fees etc. + TxMessageType_DefaultTxMsg TxMessageType = 0 + TxMessageType_AddLimitOrder TxMessageType = 1 + TxMessageType_AddMarketOrder TxMessageType = 2 + TxMessageType_CancelReplaceLimitOrder TxMessageType = 3 + TxMessageType_CancelReplaceMarketOrder TxMessageType = 4 + TxMessageType_CancelOrder TxMessageType = 5 +) + +var TxMessageType_name = map[int32]string{ + 0: "DEFAULT_TX_MSG", + 1: "ADD_LIMIT_ORDER", + 2: "ADD_MARKET_ORDER", + 3: "CANCEL_REPLACE_LIMIT_ORDER", + 4: "CANCEL_REPLACE_MARKET_ORDER", + 5: "CANCEL_ORDER", +} + +var TxMessageType_value = map[string]int32{ + "DEFAULT_TX_MSG": 0, + "ADD_LIMIT_ORDER": 1, + "ADD_MARKET_ORDER": 2, + "CANCEL_REPLACE_LIMIT_ORDER": 3, + "CANCEL_REPLACE_MARKET_ORDER": 4, + "CANCEL_ORDER": 5, +} + +func (x TxMessageType) String() string { + return proto.EnumName(TxMessageType_name, int32(x)) +} + +func (TxMessageType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_636272ab2288df51, []int{0} +} + +type TxParam struct { + // default fee for a market transaction. + TrxFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=trx_fee,json=trxFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"trx_fee" yaml:"trx_fee"` + // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee + LiquidTrxFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=liquid_trx_fee,json=liquidTrxFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_trx_fee" yaml:"liquid_trx_fee"` + // Minutes interval for the liquidity rebate to apply. For the liquidity + // rebate to apply, the running transaction should occur x minutes + // after the signers' last liquid trx. + LiquidityRebateMinutesSpan int64 `protobuf:"varint,3,opt,name=liquidity_rebate_minutes_span,json=liquidityRebateMinutesSpan,proto3" json:"liquidity_rebate_minutes_span,omitempty" yaml:"liquidity_rebate_minutes_span"` +} + +func (m *TxParam) Reset() { *m = TxParam{} } +func (m *TxParam) String() string { return proto.CompactTextString(m) } +func (*TxParam) ProtoMessage() {} +func (*TxParam) Descriptor() ([]byte, []int) { + return fileDescriptor_636272ab2288df51, []int{0} +} +func (m *TxParam) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TxParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TxParam.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TxParam) XXX_Merge(src proto.Message) { + xxx_messageInfo_TxParam.Merge(m, src) +} +func (m *TxParam) XXX_Size() int { + return m.Size() +} +func (m *TxParam) XXX_DiscardUnknown() { + xxx_messageInfo_TxParam.DiscardUnknown(m) +} + +var xxx_messageInfo_TxParam proto.InternalMessageInfo + +func (m *TxParam) GetLiquidityRebateMinutesSpan() int64 { + if m != nil { + return m.LiquidityRebateMinutesSpan + } + return 0 +} + type MsgAddLimitOrder struct { Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` ClientOrderId string `protobuf:"bytes,2,opt,name=client_order_id,json=clientOrderId,proto3" json:"client_order_id,omitempty" yaml:"client_order_id"` @@ -43,7 +132,7 @@ func (m *MsgAddLimitOrder) Reset() { *m = MsgAddLimitOrder{} } func (m *MsgAddLimitOrder) String() string { return proto.CompactTextString(m) } func (*MsgAddLimitOrder) ProtoMessage() {} func (*MsgAddLimitOrder) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{0} + return fileDescriptor_636272ab2288df51, []int{1} } func (m *MsgAddLimitOrder) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -114,7 +203,7 @@ func (m *MsgAddLimitOrderResponse) Reset() { *m = MsgAddLimitOrderRespon func (m *MsgAddLimitOrderResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddLimitOrderResponse) ProtoMessage() {} func (*MsgAddLimitOrderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{1} + return fileDescriptor_636272ab2288df51, []int{2} } func (m *MsgAddLimitOrderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -156,7 +245,7 @@ func (m *MsgAddMarketOrder) Reset() { *m = MsgAddMarketOrder{} } func (m *MsgAddMarketOrder) String() string { return proto.CompactTextString(m) } func (*MsgAddMarketOrder) ProtoMessage() {} func (*MsgAddMarketOrder) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{2} + return fileDescriptor_636272ab2288df51, []int{3} } func (m *MsgAddMarketOrder) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -227,7 +316,7 @@ func (m *MsgAddMarketOrderResponse) Reset() { *m = MsgAddMarketOrderResp func (m *MsgAddMarketOrderResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddMarketOrderResponse) ProtoMessage() {} func (*MsgAddMarketOrderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{3} + return fileDescriptor_636272ab2288df51, []int{4} } func (m *MsgAddMarketOrderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -265,7 +354,7 @@ func (m *MsgCancelOrder) Reset() { *m = MsgCancelOrder{} } func (m *MsgCancelOrder) String() string { return proto.CompactTextString(m) } func (*MsgCancelOrder) ProtoMessage() {} func (*MsgCancelOrder) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{4} + return fileDescriptor_636272ab2288df51, []int{5} } func (m *MsgCancelOrder) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -315,7 +404,7 @@ func (m *MsgCancelOrderResponse) Reset() { *m = MsgCancelOrderResponse{} func (m *MsgCancelOrderResponse) String() string { return proto.CompactTextString(m) } func (*MsgCancelOrderResponse) ProtoMessage() {} func (*MsgCancelOrderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{5} + return fileDescriptor_636272ab2288df51, []int{6} } func (m *MsgCancelOrderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -357,7 +446,7 @@ func (m *MsgCancelReplaceLimitOrder) Reset() { *m = MsgCancelReplaceLimi func (m *MsgCancelReplaceLimitOrder) String() string { return proto.CompactTextString(m) } func (*MsgCancelReplaceLimitOrder) ProtoMessage() {} func (*MsgCancelReplaceLimitOrder) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{6} + return fileDescriptor_636272ab2288df51, []int{7} } func (m *MsgCancelReplaceLimitOrder) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -435,7 +524,7 @@ func (m *MsgCancelReplaceLimitOrderResponse) Reset() { *m = MsgCancelRep func (m *MsgCancelReplaceLimitOrderResponse) String() string { return proto.CompactTextString(m) } func (*MsgCancelReplaceLimitOrderResponse) ProtoMessage() {} func (*MsgCancelReplaceLimitOrderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{7} + return fileDescriptor_636272ab2288df51, []int{8} } func (m *MsgCancelReplaceLimitOrderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -478,7 +567,7 @@ func (m *MsgCancelReplaceMarketOrder) Reset() { *m = MsgCancelReplaceMar func (m *MsgCancelReplaceMarketOrder) String() string { return proto.CompactTextString(m) } func (*MsgCancelReplaceMarketOrder) ProtoMessage() {} func (*MsgCancelReplaceMarketOrder) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{8} + return fileDescriptor_636272ab2288df51, []int{9} } func (m *MsgCancelReplaceMarketOrder) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +645,7 @@ func (m *MsgCancelReplaceMarketOrderResponse) Reset() { *m = MsgCancelRe func (m *MsgCancelReplaceMarketOrderResponse) String() string { return proto.CompactTextString(m) } func (*MsgCancelReplaceMarketOrderResponse) ProtoMessage() {} func (*MsgCancelReplaceMarketOrderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{9} + return fileDescriptor_636272ab2288df51, []int{10} } func (m *MsgCancelReplaceMarketOrderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -586,6 +675,8 @@ func (m *MsgCancelReplaceMarketOrderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCancelReplaceMarketOrderResponse proto.InternalMessageInfo func init() { + proto.RegisterEnum("em.market.v1.TxMessageType", TxMessageType_name, TxMessageType_value) + proto.RegisterType((*TxParam)(nil), "em.market.v1.TxParam") proto.RegisterType((*MsgAddLimitOrder)(nil), "em.market.v1.MsgAddLimitOrder") proto.RegisterType((*MsgAddLimitOrderResponse)(nil), "em.market.v1.MsgAddLimitOrderResponse") proto.RegisterType((*MsgAddMarketOrder)(nil), "em.market.v1.MsgAddMarketOrder") @@ -601,56 +692,74 @@ func init() { func init() { proto.RegisterFile("em/market/v1/tx.proto", fileDescriptor_636272ab2288df51) } var fileDescriptor_636272ab2288df51 = []byte{ - // 780 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0x4d, 0x6f, 0xd3, 0x40, - 0x10, 0x8d, 0x9b, 0x0f, 0xd4, 0x4d, 0x3f, 0x52, 0xd3, 0x0f, 0xc7, 0x45, 0x76, 0x65, 0x4a, 0x49, - 0x85, 0x6a, 0x93, 0x70, 0x41, 0xdc, 0x48, 0x01, 0x51, 0x89, 0x50, 0x61, 0x90, 0x8a, 0x7a, 0x89, - 0x1c, 0x7b, 0x6b, 0x56, 0xf5, 0x7a, 0x83, 0xed, 0xb4, 0xa9, 0xc4, 0x8d, 0x3f, 0xc0, 0x89, 0xdf, - 0xd4, 0x63, 0x8f, 0x88, 0x83, 0x85, 0xd2, 0x7f, 0x90, 0x23, 0x87, 0x0a, 0xd9, 0xeb, 0x04, 0xc7, - 0x69, 0xd2, 0x52, 0x95, 0x1e, 0x10, 0xa7, 0x36, 0x3b, 0xef, 0xbd, 0x19, 0xcd, 0x8c, 0xdf, 0x2e, - 0x58, 0x80, 0x58, 0xc1, 0x9a, 0xb3, 0x0f, 0x3d, 0xe5, 0xa0, 0xac, 0x78, 0x6d, 0xb9, 0xe9, 0x10, - 0x8f, 0xb0, 0x53, 0x10, 0xcb, 0xf4, 0x58, 0x3e, 0x28, 0xf3, 0xf3, 0x26, 0x31, 0x49, 0x18, 0x50, - 0x82, 0xff, 0x28, 0x86, 0x17, 0x74, 0xe2, 0x62, 0xe2, 0x2a, 0x0d, 0xcd, 0x85, 0xca, 0x41, 0xb9, - 0x01, 0x3d, 0xad, 0xac, 0xe8, 0x04, 0xd9, 0x51, 0xbc, 0x38, 0x20, 0x1d, 0xa9, 0xd1, 0x90, 0x68, - 0x12, 0x62, 0x5a, 0x50, 0x09, 0x7f, 0x35, 0x5a, 0x7b, 0x8a, 0x87, 0x30, 0x74, 0x3d, 0x0d, 0x37, - 0x29, 0x40, 0xfa, 0x39, 0x01, 0x0a, 0x35, 0xd7, 0x7c, 0x6a, 0x18, 0xaf, 0x10, 0x46, 0xde, 0xb6, - 0x63, 0x40, 0x87, 0x5d, 0x03, 0x59, 0x72, 0x68, 0x43, 0x87, 0x63, 0x56, 0x98, 0xd2, 0x64, 0xb5, - 0xd0, 0xf5, 0xc5, 0xa9, 0x23, 0x0d, 0x5b, 0x4f, 0xa4, 0xf0, 0x58, 0x52, 0x69, 0x98, 0xad, 0x82, - 0x59, 0xdd, 0x42, 0xd0, 0xf6, 0xea, 0x24, 0xe0, 0xd5, 0x91, 0xc1, 0x4d, 0x84, 0x0c, 0xbe, 0xeb, - 0x8b, 0x8b, 0x94, 0x91, 0x00, 0x48, 0xea, 0x34, 0x3d, 0x09, 0x33, 0x6d, 0x19, 0xec, 0x0e, 0x98, - 0x0e, 0x6a, 0xaa, 0x23, 0xbb, 0xbe, 0x47, 0x1c, 0x1d, 0x72, 0xe9, 0x15, 0xa6, 0x34, 0x53, 0x29, - 0xca, 0xf1, 0xc6, 0xc8, 0xef, 0x10, 0x86, 0x5b, 0xf6, 0x8b, 0x00, 0x50, 0xe5, 0xba, 0xbe, 0x38, - 0x4f, 0xc5, 0x07, 0x98, 0x92, 0x9a, 0xf7, 0x7e, 0xc3, 0xd8, 0x97, 0x20, 0xe7, 0x92, 0x56, 0xa0, - 0x98, 0x59, 0x61, 0x4a, 0xf9, 0x4a, 0x51, 0xa6, 0x6d, 0x94, 0x83, 0x36, 0xca, 0x51, 0x1b, 0xe5, - 0x4d, 0x82, 0xec, 0xea, 0xc2, 0xb1, 0x2f, 0xa6, 0xba, 0xbe, 0x38, 0x4d, 0x55, 0x29, 0x4d, 0x52, - 0x23, 0x3e, 0xbb, 0x03, 0xf2, 0x06, 0x74, 0x3d, 0x64, 0x6b, 0x1e, 0x22, 0x36, 0x97, 0xbd, 0x48, - 0x8e, 0x8f, 0xe4, 0x58, 0x2a, 0x17, 0xe3, 0x4a, 0x6a, 0x5c, 0x49, 0xe2, 0x01, 0x97, 0xec, 0xbd, - 0x0a, 0xdd, 0x26, 0xb1, 0x5d, 0x28, 0x75, 0xd2, 0x60, 0x8e, 0x06, 0x6b, 0x61, 0x17, 0xfe, 0xa1, - 0xc9, 0xac, 0x0f, 0x4c, 0x66, 0xb2, 0x3a, 0x77, 0xf3, 0xad, 0x67, 0x3f, 0x33, 0xa0, 0x80, 0xb5, - 0x36, 0xc2, 0x2d, 0x5c, 0x77, 0x2d, 0xd4, 0x6c, 0x6a, 0x26, 0xe4, 0x72, 0x61, 0x39, 0xef, 0x03, - 0x8d, 0xef, 0xbe, 0xb8, 0x66, 0x22, 0xef, 0x43, 0xab, 0x21, 0xeb, 0x04, 0x2b, 0xd1, 0x17, 0x48, - 0xff, 0x6c, 0xb8, 0xc6, 0xbe, 0xe2, 0x1d, 0x35, 0xa1, 0x2b, 0x3f, 0x83, 0x7a, 0xc7, 0x17, 0xf3, - 0x35, 0xad, 0xfd, 0x36, 0x12, 0xe9, 0xfa, 0xe2, 0x12, 0x4d, 0x9e, 0x94, 0x97, 0xd4, 0xd9, 0xe8, - 0xa8, 0x87, 0x95, 0x96, 0x41, 0x71, 0x68, 0xc6, 0xfd, 0x0d, 0xf8, 0x04, 0x66, 0x6a, 0xae, 0xb9, - 0xa9, 0xd9, 0x3a, 0xb4, 0x6e, 0x7c, 0xfa, 0x12, 0x07, 0x16, 0x07, 0xb3, 0xf7, 0xeb, 0xfa, 0x9a, - 0x01, 0x7c, 0x3f, 0xa4, 0xc2, 0xa6, 0xa5, 0xe9, 0xf0, 0x0a, 0xe6, 0xf1, 0x11, 0x70, 0xc4, 0x41, - 0x26, 0xb2, 0x35, 0xab, 0x7e, 0x7e, 0xb5, 0x8f, 0x3b, 0xbe, 0x38, 0xb7, 0xed, 0x20, 0x73, 0x33, - 0x5e, 0x59, 0xd7, 0x17, 0xc5, 0x48, 0x6f, 0x04, 0x5d, 0x52, 0x17, 0x7a, 0xa1, 0x01, 0x26, 0xab, - 0x81, 0xdb, 0x36, 0x3c, 0x1c, 0xca, 0x96, 0x0e, 0xb3, 0x55, 0x3a, 0xbe, 0x58, 0x78, 0x0d, 0x0f, - 0x93, 0xc9, 0x78, 0x9a, 0xec, 0x1c, 0xa2, 0xa4, 0x16, 0xec, 0x04, 0x7e, 0xf8, 0xa3, 0xc9, 0x5c, - 0xbb, 0x9d, 0x65, 0xaf, 0xd7, 0xce, 0x72, 0xd7, 0x66, 0x67, 0xab, 0x40, 0x1a, 0xbd, 0x17, 0xfd, - 0xf5, 0x39, 0xcb, 0x80, 0xe5, 0x24, 0xec, 0x2a, 0x16, 0xf7, 0x7f, 0x7f, 0xae, 0x68, 0xba, 0xd9, - 0x3f, 0x34, 0xdd, 0xdc, 0xdf, 0x35, 0xdd, 0x5b, 0x37, 0x6d, 0xba, 0xf7, 0xc0, 0xdd, 0x31, 0xfb, - 0xd7, 0xdb, 0xd3, 0xca, 0x59, 0x1a, 0xa4, 0x6b, 0xae, 0x19, 0x4c, 0x64, 0xf0, 0x75, 0x24, 0x0c, - 0xce, 0x22, 0x79, 0x83, 0xf3, 0x6b, 0xe3, 0xe3, 0xbd, 0x04, 0xec, 0x2e, 0x98, 0x49, 0xdc, 0xee, - 0xe2, 0x79, 0xcc, 0x18, 0x80, 0xbf, 0x7f, 0x01, 0xa0, 0xaf, 0xfd, 0x06, 0xe4, 0xe3, 0x17, 0xc7, - 0x9d, 0x21, 0x5e, 0x2c, 0xca, 0xaf, 0x8e, 0x8b, 0xf6, 0x25, 0x5b, 0x60, 0x69, 0x94, 0xe5, 0x97, - 0x46, 0x08, 0x0c, 0x21, 0xf9, 0x87, 0x97, 0x45, 0xf6, 0xd3, 0xb6, 0x01, 0x37, 0xd2, 0x2a, 0xd6, - 0xc7, 0xab, 0xc5, 0x3b, 0x57, 0xbe, 0x34, 0xb4, 0x97, 0xb9, 0xfa, 0xfc, 0xb8, 0x23, 0x30, 0x27, - 0x1d, 0x81, 0xf9, 0xd1, 0x11, 0x98, 0x2f, 0xa7, 0x42, 0xea, 0xe4, 0x54, 0x48, 0x7d, 0x3b, 0x15, - 0x52, 0xbb, 0x0f, 0x62, 0x4b, 0x0a, 0x37, 0x30, 0xb1, 0xe1, 0x91, 0x02, 0xf1, 0x86, 0x05, 0x0d, - 0x13, 0x3a, 0x4a, 0xbb, 0xf7, 0x18, 0x0f, 0xb7, 0xb5, 0x91, 0x0b, 0x1f, 0xda, 0x8f, 0x7e, 0x05, - 0x00, 0x00, 0xff, 0xff, 0x7e, 0x1f, 0x6d, 0x63, 0x01, 0x0c, 0x00, 0x00, + // 1064 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0xcd, 0x6f, 0xe3, 0x44, + 0x14, 0xaf, 0x9b, 0x34, 0xd5, 0x4e, 0x9b, 0x34, 0x35, 0xdb, 0xdd, 0xd4, 0x5d, 0xe2, 0x60, 0x4a, + 0xc9, 0x82, 0x6a, 0x93, 0x72, 0x41, 0x20, 0x24, 0xf2, 0xd5, 0x25, 0x22, 0xde, 0x2e, 0x6e, 0x50, + 0x97, 0xbd, 0x58, 0x4e, 0x32, 0x35, 0xa3, 0xfa, 0x23, 0x6b, 0x4f, 0x5a, 0x47, 0xe2, 0xc6, 0x2d, + 0x27, 0x4e, 0xdc, 0x72, 0xe3, 0xc0, 0x81, 0x3f, 0x82, 0xe3, 0x1e, 0xf7, 0x88, 0x38, 0x58, 0x28, + 0xfd, 0x0f, 0x72, 0xe4, 0xb0, 0x42, 0xf6, 0x38, 0xc1, 0x71, 0x9a, 0xee, 0xb6, 0x2a, 0x3d, 0x20, + 0x4e, 0x6d, 0xe6, 0xfd, 0x3e, 0x66, 0xde, 0x7b, 0xf3, 0x6c, 0x83, 0x0d, 0xa8, 0x0b, 0xba, 0x62, + 0x9d, 0x40, 0x2c, 0x9c, 0x16, 0x04, 0xec, 0xf0, 0x1d, 0xcb, 0xc4, 0x26, 0xbd, 0x0a, 0x75, 0x9e, + 0x2c, 0xf3, 0xa7, 0x05, 0xe6, 0xae, 0x6a, 0xaa, 0xa6, 0x1f, 0x10, 0xbc, 0xff, 0x08, 0x86, 0xc9, + 0xb6, 0x4c, 0x5b, 0x37, 0x6d, 0xa1, 0xa9, 0xd8, 0x50, 0x38, 0x2d, 0x34, 0x21, 0x56, 0x0a, 0x42, + 0xcb, 0x44, 0x46, 0x10, 0xdf, 0x9c, 0x92, 0x0e, 0xd4, 0x48, 0x88, 0x55, 0x4d, 0x53, 0xd5, 0xa0, + 0xe0, 0xff, 0x6a, 0x76, 0x8f, 0x05, 0x8c, 0x74, 0x68, 0x63, 0x45, 0xef, 0x10, 0x00, 0xf7, 0xdb, + 0x22, 0x58, 0x6e, 0x38, 0x4f, 0x14, 0x4b, 0xd1, 0xe9, 0x6f, 0xc1, 0x32, 0xb6, 0x1c, 0xf9, 0x18, + 0xc2, 0x0c, 0x95, 0xa3, 0xf2, 0x77, 0x4a, 0x5f, 0xbc, 0x70, 0xd9, 0x85, 0x3f, 0x5c, 0x76, 0x47, + 0x45, 0xf8, 0xbb, 0x6e, 0x93, 0x6f, 0x99, 0xba, 0x10, 0xec, 0x85, 0xfc, 0xd9, 0xb5, 0xdb, 0x27, + 0x02, 0xee, 0x75, 0xa0, 0xcd, 0xd7, 0x0c, 0x3c, 0x72, 0xd9, 0x54, 0x4f, 0xd1, 0xb5, 0x4f, 0xb9, + 0x40, 0x86, 0x93, 0x12, 0xd8, 0x72, 0xf6, 0x21, 0xa4, 0x75, 0x90, 0xd2, 0xd0, 0xf3, 0x2e, 0x6a, + 0xcb, 0x63, 0x87, 0x45, 0xdf, 0xe1, 0xd1, 0x95, 0x1d, 0x36, 0x88, 0xc3, 0xb4, 0x1a, 0x27, 0xad, + 0x92, 0x85, 0x06, 0xb1, 0x3b, 0x01, 0x6f, 0x93, 0xdf, 0x08, 0xf7, 0x64, 0x0b, 0x36, 0x15, 0x0c, + 0x65, 0x1d, 0x19, 0x5d, 0x0c, 0x6d, 0xd9, 0xee, 0x28, 0x46, 0x26, 0x96, 0xa3, 0xf2, 0xb1, 0x52, + 0x7e, 0xe4, 0xb2, 0xdb, 0x61, 0xbd, 0x39, 0x70, 0x4e, 0x62, 0x26, 0x71, 0xc9, 0x0f, 0x8b, 0x24, + 0x7a, 0xe8, 0x05, 0xff, 0x5a, 0x04, 0x69, 0xd1, 0x56, 0x8b, 0xed, 0x76, 0x1d, 0xe9, 0x08, 0x1f, + 0x58, 0x6d, 0x68, 0xd1, 0x3b, 0x60, 0xc9, 0x3c, 0x33, 0xa0, 0x15, 0x64, 0x32, 0x3d, 0x72, 0xd9, + 0x55, 0xe2, 0xe4, 0x2f, 0x73, 0x12, 0x09, 0xd3, 0x25, 0xb0, 0xd6, 0xd2, 0x10, 0x34, 0xb0, 0x6c, + 0x7a, 0x3c, 0x19, 0xb5, 0x83, 0xcc, 0x30, 0x23, 0x97, 0xbd, 0x47, 0x18, 0x11, 0x00, 0x27, 0x25, + 0xc9, 0x8a, 0xef, 0x54, 0x6b, 0xd3, 0x47, 0x20, 0xe9, 0x95, 0x55, 0x46, 0x86, 0x7c, 0x6c, 0x5a, + 0x2d, 0xe8, 0x9f, 0x2e, 0xb5, 0xb7, 0xc9, 0x87, 0x7b, 0x8b, 0x6f, 0x20, 0x1d, 0xd6, 0x8c, 0x7d, + 0x0f, 0x50, 0xca, 0x8c, 0x5c, 0xf6, 0x6e, 0x50, 0xaa, 0x30, 0x93, 0x93, 0x56, 0xf0, 0x3f, 0x30, + 0xfa, 0x4b, 0x90, 0xb0, 0xcd, 0xae, 0xa7, 0x18, 0xcf, 0x51, 0xf9, 0x95, 0xbd, 0x4d, 0x9e, 0x14, + 0x85, 0xf7, 0x3a, 0x91, 0x0f, 0x3a, 0x91, 0x2f, 0x9b, 0xc8, 0x28, 0x6d, 0x78, 0x85, 0x1c, 0xb9, + 0x6c, 0x92, 0xa8, 0x12, 0x1a, 0x27, 0x05, 0x7c, 0xfa, 0x08, 0xac, 0xb4, 0xa1, 0x8d, 0x91, 0xa1, + 0x60, 0x64, 0x1a, 0x99, 0xa5, 0xd7, 0xc9, 0x31, 0x81, 0x1c, 0x4d, 0xe4, 0x42, 0x5c, 0x4e, 0x0a, + 0x2b, 0x71, 0x0c, 0xc8, 0x44, 0x73, 0x2f, 0x41, 0xbb, 0x63, 0x1a, 0x36, 0xe4, 0x86, 0x31, 0xb0, + 0x4e, 0x82, 0xa2, 0x9f, 0x85, 0xff, 0x50, 0x65, 0x1e, 0x4e, 0x55, 0xe6, 0x4e, 0x69, 0xfd, 0xf6, + 0x53, 0x4f, 0xff, 0x40, 0x81, 0xb4, 0xae, 0x38, 0x48, 0xef, 0xea, 0xb2, 0xad, 0xa1, 0x4e, 0x47, + 0x51, 0x61, 0x26, 0xe1, 0x6f, 0xe7, 0xe9, 0x15, 0xae, 0x75, 0x05, 0xb6, 0x86, 0x2e, 0xbb, 0x22, + 0x2a, 0xce, 0x61, 0x20, 0x32, 0x72, 0xd9, 0xfb, 0xc4, 0x3c, 0x2a, 0xcf, 0x49, 0x6b, 0xc1, 0xd2, + 0x18, 0xcb, 0x6d, 0x81, 0xcd, 0x99, 0x1a, 0x4f, 0x3a, 0xe0, 0x7b, 0x90, 0x12, 0x6d, 0xb5, 0xac, + 0x18, 0x2d, 0xa8, 0xdd, 0x7a, 0xf5, 0xb9, 0x0c, 0xb8, 0x37, 0xed, 0x3e, 0xd9, 0xd7, 0x4f, 0x71, + 0xc0, 0x4c, 0x42, 0x12, 0xec, 0x68, 0x4a, 0x0b, 0x5e, 0x63, 0x78, 0x3c, 0x07, 0x19, 0xd3, 0x42, + 0x2a, 0x32, 0x14, 0x4d, 0xbe, 0x78, 0xb7, 0x9f, 0x0c, 0x5d, 0x76, 0xfd, 0xc0, 0x42, 0x6a, 0x39, + 0xbc, 0xb3, 0x91, 0xcb, 0xb2, 0x81, 0xde, 0x1c, 0x3a, 0x27, 0x6d, 0x8c, 0x43, 0x53, 0x4c, 0x5a, + 0x01, 0x6f, 0x19, 0xf0, 0x6c, 0xc6, 0x2d, 0xe6, 0xbb, 0xed, 0x0d, 0x5d, 0x36, 0xfd, 0x18, 0x9e, + 0x45, 0xcd, 0x18, 0x62, 0x76, 0x01, 0x91, 0x93, 0xd2, 0x46, 0x04, 0x3f, 0x7b, 0x69, 0xe2, 0x37, + 0x3e, 0xce, 0x96, 0x6e, 0x76, 0x9c, 0x25, 0x6e, 0x6c, 0x9c, 0x6d, 0x03, 0x6e, 0x7e, 0x5f, 0x4c, + 0xda, 0xe7, 0x55, 0x1c, 0x6c, 0x45, 0x61, 0xd7, 0x19, 0x71, 0xff, 0xf7, 0xcf, 0x35, 0x87, 0xee, + 0xd2, 0x15, 0x87, 0x6e, 0xe2, 0xdf, 0x1d, 0xba, 0xcb, 0xb7, 0x3d, 0x74, 0xdf, 0x03, 0xef, 0x5e, + 0xd2, 0x7f, 0xe3, 0x3e, 0xfd, 0xe0, 0xd7, 0x45, 0x90, 0x6c, 0x38, 0x22, 0xb4, 0x6d, 0x45, 0x85, + 0x8d, 0x5e, 0x07, 0xd2, 0xdb, 0x20, 0x55, 0xa9, 0xee, 0x17, 0xbf, 0xa9, 0x37, 0xe4, 0xc6, 0x53, + 0x59, 0x3c, 0x7c, 0x94, 0x5e, 0x60, 0xd2, 0xfd, 0x41, 0x6e, 0xb5, 0x02, 0x8f, 0x95, 0xae, 0x86, + 0x1b, 0x8e, 0x68, 0xab, 0xf4, 0x0e, 0x58, 0x2b, 0x56, 0x2a, 0x72, 0xbd, 0x26, 0xd6, 0x1a, 0xf2, + 0x81, 0x54, 0xa9, 0x4a, 0x69, 0x8a, 0x59, 0xef, 0x0f, 0x72, 0xc9, 0xe9, 0x97, 0xac, 0x3c, 0x48, + 0x7b, 0x38, 0xb1, 0x28, 0x7d, 0x55, 0x1d, 0x03, 0x17, 0x19, 0xba, 0x3f, 0xc8, 0xa5, 0x22, 0x0f, + 0xfd, 0xcf, 0x00, 0x53, 0x2e, 0x3e, 0x2e, 0x57, 0xeb, 0xb2, 0x54, 0x7d, 0x52, 0x2f, 0x96, 0xab, + 0x53, 0xe2, 0x31, 0x66, 0xab, 0x3f, 0xc8, 0xdd, 0x9f, 0x37, 0x8e, 0x3f, 0x07, 0x5b, 0x11, 0xf2, + 0x94, 0x63, 0x9c, 0x79, 0xd0, 0x1f, 0xe4, 0x32, 0x73, 0x6f, 0xe3, 0x3b, 0x60, 0x35, 0xa0, 0x13, + 0xfc, 0x12, 0xb3, 0xd6, 0x1f, 0xe4, 0x56, 0x42, 0xcf, 0x05, 0x26, 0xfe, 0xcb, 0xcf, 0x59, 0x6a, + 0xef, 0x55, 0x0c, 0xc4, 0xbc, 0xe3, 0x1f, 0x81, 0xc8, 0x39, 0xb3, 0xd3, 0xad, 0x1b, 0x7d, 0xe1, + 0x61, 0x76, 0x2e, 0x8f, 0x8f, 0xeb, 0x41, 0x3f, 0x03, 0xd1, 0xbc, 0xb0, 0x17, 0x31, 0x43, 0x00, + 0xe6, 0xfd, 0xd7, 0x00, 0x26, 0xda, 0x5f, 0x83, 0xf0, 0x89, 0xe8, 0x07, 0x33, 0xbc, 0xf0, 0x79, + 0xb7, 0x2f, 0x8b, 0x4e, 0x24, 0xbb, 0x60, 0x6e, 0x49, 0xf2, 0x73, 0x04, 0x66, 0x90, 0xcc, 0x47, + 0x6f, 0x8a, 0x9c, 0xd8, 0x3a, 0x60, 0x7e, 0x2d, 0x1f, 0x5e, 0xae, 0x16, 0xce, 0x5c, 0xe1, 0x8d, + 0xa1, 0x63, 0xe7, 0x52, 0xf5, 0xc5, 0x30, 0x4b, 0xbd, 0x1c, 0x66, 0xa9, 0x3f, 0x87, 0x59, 0xea, + 0xc7, 0xf3, 0xec, 0xc2, 0xcb, 0xf3, 0xec, 0xc2, 0xef, 0xe7, 0xd9, 0x85, 0x67, 0x1f, 0x86, 0xee, + 0x34, 0xdc, 0xd5, 0x4d, 0x03, 0xf6, 0x04, 0xa8, 0xef, 0x6a, 0xb0, 0xad, 0x42, 0x4b, 0x70, 0xc6, + 0x9f, 0x7f, 0xfe, 0xe5, 0x6e, 0x26, 0xfc, 0x4f, 0xbb, 0x8f, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, + 0x71, 0xf7, 0xac, 0x3e, 0x73, 0x0e, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -877,6 +986,54 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Metadata: "em/market/v1/tx.proto", } +func (m *TxParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxParam) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TxParam) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LiquidityRebateMinutesSpan != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.LiquidityRebateMinutesSpan)) + i-- + dAtA[i] = 0x18 + } + { + size := m.LiquidTrxFee.Size() + i -= size + if _, err := m.LiquidTrxFee.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.TrxFee.Size() + i -= size + if _, err := m.TrxFee.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *MsgAddLimitOrder) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1316,6 +1473,22 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *TxParam) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.TrxFee.Size() + n += 1 + l + sovTx(uint64(l)) + l = m.LiquidTrxFee.Size() + n += 1 + l + sovTx(uint64(l)) + if m.LiquidityRebateMinutesSpan != 0 { + n += 1 + sovTx(uint64(m.LiquidityRebateMinutesSpan)) + } + return n +} + func (m *MsgAddLimitOrder) Size() (n int) { if m == nil { return 0 @@ -1496,6 +1669,143 @@ func sovTx(x uint64) (n int) { func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *TxParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrxFee", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TrxFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidTrxFee", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LiquidTrxFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LiquidityRebateMinutesSpan", wireType) + } + m.LiquidityRebateMinutesSpan = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LiquidityRebateMinutesSpan |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *MsgAddLimitOrder) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From 42d695b62080c768fe50925841e07403f886d1e7 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Wed, 12 May 2021 18:18:57 +0300 Subject: [PATCH 08/41] Add Params --- app.go | 3 ++- x/market/keeper/keeper.go | 38 ++++++++++++++++++++++++++++++++--- x/market/keeper/msg_server.go | 4 ++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/app.go b/app.go index 53318b9b..b526b4be 100644 --- a/app.go +++ b/app.go @@ -344,7 +344,7 @@ func NewApp( app.lpKeeper = liquidityprovider.NewKeeper(app.accountKeeper, app.bankKeeper) app.issuerKeeper = issuer.NewKeeper(app.appCodec, keys[issuer.StoreKey], app.lpKeeper, app.inflationKeeper) app.authorityKeeper = authority.NewKeeper(app.appCodec, keys[authority.StoreKey], app.issuerKeeper, app.bankKeeper, app) - app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], keys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper, app.authorityKeeper) + app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], keys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper, app.authorityKeeper, app.paramsKeeper.Subspace(market.ModuleName)) app.buybackKeeper = buyback.NewKeeper(app.appCodec, keys[buyback.StoreKey], app.marketKeeper, app.accountKeeper, app.stakingKeeper, app.bankKeeper) app.bep3Keeper = bep3.NewKeeper(app.appCodec, keys[bep3.StoreKey], app.bankKeeper, app.accountKeeper, app.paramsKeeper.Subspace(bep3.ModuleName), GetMaccs()) @@ -624,6 +624,7 @@ func initParamsKeeper(appCodec codec.BinaryMarshaler, legacyAmino *codec.LegacyA paramsKeeper.Subspace(distrtypes.ModuleName) paramsKeeper.Subspace(emslashing.ModuleName) paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable()) + paramsKeeper.Subspace(market.ModuleName) paramsKeeper.Subspace(crisistypes.ModuleName) paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibchost.ModuleName) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index aacaee5e..1cc1defe 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -7,6 +7,7 @@ package keeper import ( "fmt" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" types2 "github.com/e-money/em-ledger/x/authority/types" "math" "sync" @@ -37,19 +38,30 @@ type Keeper struct { bk types.BankKeeper authorityk types.RestrictedKeeper + paramSubspace paramtypes.Subspace + // accountOrders types.Orders appstateInit *sync.Once restrictedDenoms types2.RestrictedDenoms } -func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey, keyIndices sdk.StoreKey, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, authorityKeeper types.RestrictedKeeper) *Keeper { +func NewKeeper( + cdc codec.BinaryMarshaler, + key sdk.StoreKey, + keyIndices sdk.StoreKey, + authKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + authorityKeeper types.RestrictedKeeper, + params paramtypes.Subspace, +) *Keeper { k := &Keeper{ cdc: cdc, key: key, keyIndices: keyIndices, ak: authKeeper, bk: bankKeeper, + paramSubspace: params, appstateInit: new(sync.Once), @@ -135,11 +147,31 @@ func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, ds return k.NewOrderSingle(ctx, order) } -func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { +func postOrderSingle( + ctx sdk.Context, + order types.Order, + messageType types.TxMessageType, commitTrade func(), +) { + // recover -> save recError + + // if !rebate applies // Use a fixed gas amount ctx.GasMeter().ConsumeGas(gasPriceNewOrder, "NewOrderSingle") ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + // else !rebate applies and out of gas error + // panic(recError) + + // else apply full or partial rebate + // check partial rebate and whether panic still applied + + commitTrade() +} + +func (k *Keeper) NewOrderSingle( + ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType, +) (*sdk.Result, error) { + // Set this to true to roll back any state changes made by the aggressive order. Used for FillOrKill orders. KillOrder := false ctx, commitTrade := ctx.CacheContext() @@ -149,7 +181,7 @@ func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (* return } - commitTrade() + postOrderSingle(ctx, aggressiveOrder, messageType, commitTrade) }() if err := aggressiveOrder.IsValid(); err != nil { diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index 9f034c91..c0d890eb 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -12,7 +12,7 @@ var _ types.MsgServer = msgServer{} type marketKeeper interface { NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) - NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) + NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType) (*sdk.Result, error) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) @@ -37,7 +37,7 @@ func (m msgServer) AddLimitOrder(c context.Context, msg *types.MsgAddLimitOrder) return nil, err } - result, err := m.k.NewOrderSingle(ctx, order) + result, err := m.k.NewOrderSingle(ctx, order, ) if err != nil { return nil, err } From 7a5041e755a63a83d8b87e52aa6284300ae029f4 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 13 May 2021 16:24:39 +0300 Subject: [PATCH 09/41] Add trx params --- docs/proto/em/proto-docs.md | 10 +- proto/em/market/v1/tx.proto | 20 +- x/market/keeper/keeper.go | 13 +- x/market/keeper/keeper_test.go | 10 + x/market/keeper/params.go | 63 +++++++ x/market/keeper/params_test.go | 25 +++ x/market/types/tx.pb.go | 310 ++++++++++++++----------------- x/market/types/tx_params.go | 109 +++++++++++ x/market/types/tx_params_test.go | 29 +++ 9 files changed, 400 insertions(+), 189 deletions(-) create mode 100644 x/market/keeper/params.go create mode 100644 x/market/keeper/params_test.go create mode 100644 x/market/types/tx_params.go create mode 100644 x/market/types/tx_params_test.go diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index 436f9266..a7719189 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -122,7 +122,7 @@ - [MsgCancelReplaceLimitOrderResponse](#em.market.v1.MsgCancelReplaceLimitOrderResponse) - [MsgCancelReplaceMarketOrder](#em.market.v1.MsgCancelReplaceMarketOrder) - [MsgCancelReplaceMarketOrderResponse](#em.market.v1.MsgCancelReplaceMarketOrderResponse) - - [TxParam](#em.market.v1.TxParam) + - [TxParams](#em.market.v1.TxParams) - [TxMessageType](#em.market.v1.TxMessageType) @@ -1462,16 +1462,16 @@ - + -### TxParam +### TxParams | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| `trx_fee` | [string](#string) | | default fee for a market transaction. | -| `liquid_trx_fee` | [string](#string) | | Valid liquidity adding orders are free or adjusted to a minimum nominal/fee | +| `trx_fee` | [uint64](#uint64) | | default fee for a market transaction. | +| `liquid_trx_fee` | [uint64](#uint64) | | Valid liquidity adding orders are free or adjusted to a minimum nominal/fee | | `liquidity_rebate_minutes_span` | [int64](#int64) | | Minutes interval for the liquidity rebate to apply. For the liquidity rebate to apply, the running transaction should occur x minutes after the signers' last liquid trx. | diff --git a/proto/em/market/v1/tx.proto b/proto/em/market/v1/tx.proto index 0690c79c..96737ffb 100644 --- a/proto/em/market/v1/tx.proto +++ b/proto/em/market/v1/tx.proto @@ -43,24 +43,16 @@ enum TxMessageType { [ (gogoproto.enumvalue_customname) = "CancelOrder" ]; } -message TxParam { +message TxParams { // default fee for a market transaction. - string trx_fee = 1 [ - (gogoproto.moretags) = "yaml:\"trx_fee\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; + uint64 trx_fee = 1 [(gogoproto.moretags) = "yaml:\"trx_fee\""]; // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee - string liquid_trx_fee = 2 [ - (gogoproto.moretags) = "yaml:\"liquid_trx_fee\"", - (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", - (gogoproto.nullable) = false - ]; + uint64 liquid_trx_fee = 2 [(gogoproto.moretags) = "yaml:\"liquid_trx_fee\""]; - // Minutes interval for the liquidity rebate to apply. For the liquidity - // rebate to apply, the running transaction should occur x minutes - // after the signers' last liquid trx. + // Minutes interval for eligible liquidity transactions to qualify for + // the rebate. For the rebate to apply, the running transaction + // should occur x minutes after the signers' last liquid trx. int64 liquidity_rebate_minutes_span = 3 [ (gogoproto.moretags) = "yaml:\"liquidity_rebate_minutes_span\"" ]; diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 1cc1defe..f32351ef 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -38,7 +38,7 @@ type Keeper struct { bk types.BankKeeper authorityk types.RestrictedKeeper - paramSubspace paramtypes.Subspace + paramStore paramtypes.Subspace // accountOrders types.Orders appstateInit *sync.Once @@ -53,15 +53,20 @@ func NewKeeper( authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, authorityKeeper types.RestrictedKeeper, - params paramtypes.Subspace, + paramStore paramtypes.Subspace, ) *Keeper { + // set params map + if !paramStore.HasKeyTable() { + paramStore = paramStore.WithKeyTable(types.ParamKeyTable()) + } + k := &Keeper{ cdc: cdc, key: key, keyIndices: keyIndices, ak: authKeeper, bk: bankKeeper, - paramSubspace: params, + paramStore: paramStore, appstateInit: new(sync.Once), @@ -377,6 +382,8 @@ func (k *Keeper) NewOrderSingle( func (k *Keeper) initializeFromStore(ctx sdk.Context) { k.appstateInit.Do(func() { + k.InitParamsStore(ctx) + // Load the restricted denominations from the authority module k.restrictedDenoms = k.authorityk.GetRestrictedDenoms(ctx) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index a6ca57b1..b1e1cf34 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -26,6 +26,7 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" embank "github.com/e-money/em-ledger/hooks/bank" emtypes "github.com/e-money/em-ledger/types" emauthtypes "github.com/e-money/em-ledger/x/authority/types" @@ -1452,6 +1453,7 @@ func createTestComponentsWithEncoding(t *testing.T, encConfig simappparams.Encod ms.MountStoreWithDB(keyAuthCap, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(keyBank, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) err := ms.LoadLatestVersion() require.Nil(t, err) @@ -1470,8 +1472,16 @@ func createTestComponentsWithEncoding(t *testing.T, encConfig simappparams.Encod wrappedBank = embank.Wrap(bk, embank.RestrictedKeeperFunc(func(ctx sdk.Context) emauthtypes.RestrictedDenoms { return emauthtypes.RestrictedDenoms{} // allow all })) + + marketKeeper = NewKeeper( + encConfig.Marshaler, keyMarket, keyIndices, ak, wrappedBank, + dummyAuthority{}, + pk.Subspace(types.ModuleName), + ) ) + marketKeeper.InitParamsStore(ctx) + bk.SetSupply(ctx, banktypes.NewSupply(coins("1eur,1usd,1chf,1jpy,1gbp,1ngm"))) marketKeeper := NewKeeper(encConfig.Marshaler, keyMarket, keyIndices, ak, wrappedBank, dummyAuthority{}) diff --git a/x/market/keeper/params.go b/x/market/keeper/params.go new file mode 100644 index 00000000..a3a55238 --- /dev/null +++ b/x/market/keeper/params.go @@ -0,0 +1,63 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/e-money/em-ledger/x/market/types" +) + +// InitParamsStore initializes param store +func (k Keeper) InitParamsStore(ctx sdk.Context) uint64 { + defaultSet := types.DefaultTxParams() + var trxFee uint64 + if !k.paramStore.Has(ctx, types.KeyTrxFee) { + k.paramStore.Set(ctx, types.KeyTrxFee, defaultSet.TrxFee) + } + if !k.paramStore.Has(ctx, types.KeyLiquidTrxFee) { + k.paramStore.Set(ctx, types.KeyLiquidTrxFee, defaultSet.LiquidTrxFee) + } + if !k.paramStore.Has(ctx, types.KeyLiquidityRebateMinutesSpan) { + k.paramStore.Set( + ctx, types.KeyLiquidityRebateMinutesSpan, + defaultSet.LiquidityRebateMinutesSpan, + ) + } + + return trxFee +} + +// GetTrxFee retrieves the trx fee from the paramStore +func (k Keeper) GetTrxFee(ctx sdk.Context) uint64 { + var trxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &trxFee) + + return trxFee +} + +// GetLiquidTrxFee retrieves the liquid trx fee from the paramStore +func (k Keeper) GetLiquidTrxFee(ctx sdk.Context) uint64 { + var liqTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liqTrxFee) + + return liqTrxFee +} + +// GetLiquidityRebateMinutesSpan retrieves the default market order fee from the +// paramStore +func (k Keeper) GetLiquidityRebateMinutesSpan(ctx sdk.Context) int64 { + var liqTrxFee int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &liqTrxFee) + + return liqTrxFee +} + +// GetParams returns the total set of Trx parameters. +func (k Keeper) GetParams(ctx sdk.Context) types.TxParams { + return types.NewTxParams(k.GetTrxFee(ctx), k.GetLiquidTrxFee(ctx), + k.GetLiquidityRebateMinutesSpan(ctx)) +} + +// SetParams sets the total set of ibc-transfer parameters. +func (k Keeper) SetParams(ctx sdk.Context, params types.TxParams) { + k.paramStore.SetParamSet(ctx, ¶ms) +} + diff --git a/x/market/keeper/params_test.go b/x/market/keeper/params_test.go new file mode 100644 index 00000000..841d78ed --- /dev/null +++ b/x/market/keeper/params_test.go @@ -0,0 +1,25 @@ +package keeper + +import ( + "github.com/e-money/em-ledger/x/market/types" + "github.com/stretchr/testify/require" + "testing" +) + +func TestParams(t *testing.T) { + ctx, k, _, _ := createTestComponents(t) + expParams := types.DefaultTxParams() + + params := k.GetParams(ctx) + require.Equal(t, expParams, params) + + expParams.TrxFee = 100_000 + expParams.LiquidTrxFee = 250 + expParams.LiquidityRebateMinutesSpan = 10 + + k.SetParams(ctx, expParams) + params = k.GetParams(ctx) + + require.Equal(t, expParams, params) +} + diff --git a/x/market/types/tx.pb.go b/x/market/types/tx.pb.go index c9c1eafb..a9b0dd01 100644 --- a/x/market/types/tx.pb.go +++ b/x/market/types/tx.pb.go @@ -69,53 +69,67 @@ func (TxMessageType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_636272ab2288df51, []int{0} } -type TxParam struct { +type TxParams struct { // default fee for a market transaction. - TrxFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=trx_fee,json=trxFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"trx_fee" yaml:"trx_fee"` + TrxFee uint64 `protobuf:"varint,1,opt,name=trx_fee,json=trxFee,proto3" json:"trx_fee,omitempty" yaml:"trx_fee"` // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee - LiquidTrxFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=liquid_trx_fee,json=liquidTrxFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"liquid_trx_fee" yaml:"liquid_trx_fee"` + LiquidTrxFee uint64 `protobuf:"varint,2,opt,name=liquid_trx_fee,json=liquidTrxFee,proto3" json:"liquid_trx_fee,omitempty" yaml:"liquid_trx_fee"` // Minutes interval for the liquidity rebate to apply. For the liquidity // rebate to apply, the running transaction should occur x minutes // after the signers' last liquid trx. LiquidityRebateMinutesSpan int64 `protobuf:"varint,3,opt,name=liquidity_rebate_minutes_span,json=liquidityRebateMinutesSpan,proto3" json:"liquidity_rebate_minutes_span,omitempty" yaml:"liquidity_rebate_minutes_span"` } -func (m *TxParam) Reset() { *m = TxParam{} } -func (m *TxParam) String() string { return proto.CompactTextString(m) } -func (*TxParam) ProtoMessage() {} -func (*TxParam) Descriptor() ([]byte, []int) { +func (p *TxParams) Reset() { *p = TxParams{} } +func (p *TxParams) String() string { return proto.CompactTextString(p) } +func (*TxParams) ProtoMessage() {} +func (*TxParams) Descriptor() ([]byte, []int) { return fileDescriptor_636272ab2288df51, []int{0} } -func (m *TxParam) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) +func (p *TxParams) XXX_Unmarshal(b []byte) error { + return p.Unmarshal(b) } -func (m *TxParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (p *TxParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_TxParam.Marshal(b, m, deterministic) + return xxx_messageInfo_TxParams.Marshal(b, p, deterministic) } else { b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) + n, err := p.MarshalToSizedBuffer(b) if err != nil { return nil, err } return b[:n], nil } } -func (m *TxParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxParam.Merge(m, src) +func (p *TxParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_TxParams.Merge(p, src) } -func (m *TxParam) XXX_Size() int { - return m.Size() +func (p *TxParams) XXX_Size() int { + return p.Size() } -func (m *TxParam) XXX_DiscardUnknown() { - xxx_messageInfo_TxParam.DiscardUnknown(m) +func (p *TxParams) XXX_DiscardUnknown() { + xxx_messageInfo_TxParams.DiscardUnknown(p) } -var xxx_messageInfo_TxParam proto.InternalMessageInfo +var xxx_messageInfo_TxParams proto.InternalMessageInfo -func (m *TxParam) GetLiquidityRebateMinutesSpan() int64 { - if m != nil { - return m.LiquidityRebateMinutesSpan +func (p *TxParams) GetTrxFee() uint64 { + if p != nil { + return p.TrxFee + } + return 0 +} + +func (p *TxParams) GetLiquidTrxFee() uint64 { + if p != nil { + return p.LiquidTrxFee + } + return 0 +} + +func (p *TxParams) GetLiquidityRebateMinutesSpan() int64 { + if p != nil { + return p.LiquidityRebateMinutesSpan } return 0 } @@ -676,7 +690,7 @@ var xxx_messageInfo_MsgCancelReplaceMarketOrderResponse proto.InternalMessageInf func init() { proto.RegisterEnum("em.market.v1.TxMessageType", TxMessageType_name, TxMessageType_value) - proto.RegisterType((*TxParam)(nil), "em.market.v1.TxParam") + proto.RegisterType((*TxParams)(nil), "em.market.v1.TxParams") proto.RegisterType((*MsgAddLimitOrder)(nil), "em.market.v1.MsgAddLimitOrder") proto.RegisterType((*MsgAddLimitOrderResponse)(nil), "em.market.v1.MsgAddLimitOrderResponse") proto.RegisterType((*MsgAddMarketOrder)(nil), "em.market.v1.MsgAddMarketOrder") @@ -692,74 +706,74 @@ func init() { func init() { proto.RegisterFile("em/market/v1/tx.proto", fileDescriptor_636272ab2288df51) } var fileDescriptor_636272ab2288df51 = []byte{ - // 1064 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0xcd, 0x6f, 0xe3, 0x44, - 0x14, 0xaf, 0x9b, 0x34, 0xd5, 0x4e, 0x9b, 0x34, 0x35, 0xdb, 0xdd, 0xd4, 0x5d, 0xe2, 0x60, 0x4a, - 0xc9, 0x82, 0x6a, 0x93, 0x72, 0x41, 0x20, 0x24, 0xf2, 0xd5, 0x25, 0x22, 0xde, 0x2e, 0x6e, 0x50, - 0x97, 0xbd, 0x58, 0x4e, 0x32, 0x35, 0xa3, 0xfa, 0x23, 0x6b, 0x4f, 0x5a, 0x47, 0xe2, 0xc6, 0x2d, - 0x27, 0x4e, 0xdc, 0x72, 0xe3, 0xc0, 0x81, 0x3f, 0x82, 0xe3, 0x1e, 0xf7, 0x88, 0x38, 0x58, 0x28, - 0xfd, 0x0f, 0x72, 0xe4, 0xb0, 0x42, 0xf6, 0x38, 0xc1, 0x71, 0x9a, 0xee, 0xb6, 0x2a, 0x3d, 0x20, - 0x4e, 0x6d, 0xe6, 0xfd, 0x3e, 0x66, 0xde, 0x7b, 0xf3, 0x6c, 0x83, 0x0d, 0xa8, 0x0b, 0xba, 0x62, - 0x9d, 0x40, 0x2c, 0x9c, 0x16, 0x04, 0xec, 0xf0, 0x1d, 0xcb, 0xc4, 0x26, 0xbd, 0x0a, 0x75, 0x9e, - 0x2c, 0xf3, 0xa7, 0x05, 0xe6, 0xae, 0x6a, 0xaa, 0xa6, 0x1f, 0x10, 0xbc, 0xff, 0x08, 0x86, 0xc9, - 0xb6, 0x4c, 0x5b, 0x37, 0x6d, 0xa1, 0xa9, 0xd8, 0x50, 0x38, 0x2d, 0x34, 0x21, 0x56, 0x0a, 0x42, - 0xcb, 0x44, 0x46, 0x10, 0xdf, 0x9c, 0x92, 0x0e, 0xd4, 0x48, 0x88, 0x55, 0x4d, 0x53, 0xd5, 0xa0, - 0xe0, 0xff, 0x6a, 0x76, 0x8f, 0x05, 0x8c, 0x74, 0x68, 0x63, 0x45, 0xef, 0x10, 0x00, 0xf7, 0xdb, - 0x22, 0x58, 0x6e, 0x38, 0x4f, 0x14, 0x4b, 0xd1, 0xe9, 0x6f, 0xc1, 0x32, 0xb6, 0x1c, 0xf9, 0x18, - 0xc2, 0x0c, 0x95, 0xa3, 0xf2, 0x77, 0x4a, 0x5f, 0xbc, 0x70, 0xd9, 0x85, 0x3f, 0x5c, 0x76, 0x47, - 0x45, 0xf8, 0xbb, 0x6e, 0x93, 0x6f, 0x99, 0xba, 0x10, 0xec, 0x85, 0xfc, 0xd9, 0xb5, 0xdb, 0x27, - 0x02, 0xee, 0x75, 0xa0, 0xcd, 0xd7, 0x0c, 0x3c, 0x72, 0xd9, 0x54, 0x4f, 0xd1, 0xb5, 0x4f, 0xb9, - 0x40, 0x86, 0x93, 0x12, 0xd8, 0x72, 0xf6, 0x21, 0xa4, 0x75, 0x90, 0xd2, 0xd0, 0xf3, 0x2e, 0x6a, - 0xcb, 0x63, 0x87, 0x45, 0xdf, 0xe1, 0xd1, 0x95, 0x1d, 0x36, 0x88, 0xc3, 0xb4, 0x1a, 0x27, 0xad, - 0x92, 0x85, 0x06, 0xb1, 0x3b, 0x01, 0x6f, 0x93, 0xdf, 0x08, 0xf7, 0x64, 0x0b, 0x36, 0x15, 0x0c, - 0x65, 0x1d, 0x19, 0x5d, 0x0c, 0x6d, 0xd9, 0xee, 0x28, 0x46, 0x26, 0x96, 0xa3, 0xf2, 0xb1, 0x52, - 0x7e, 0xe4, 0xb2, 0xdb, 0x61, 0xbd, 0x39, 0x70, 0x4e, 0x62, 0x26, 0x71, 0xc9, 0x0f, 0x8b, 0x24, - 0x7a, 0xe8, 0x05, 0xff, 0x5a, 0x04, 0x69, 0xd1, 0x56, 0x8b, 0xed, 0x76, 0x1d, 0xe9, 0x08, 0x1f, - 0x58, 0x6d, 0x68, 0xd1, 0x3b, 0x60, 0xc9, 0x3c, 0x33, 0xa0, 0x15, 0x64, 0x32, 0x3d, 0x72, 0xd9, - 0x55, 0xe2, 0xe4, 0x2f, 0x73, 0x12, 0x09, 0xd3, 0x25, 0xb0, 0xd6, 0xd2, 0x10, 0x34, 0xb0, 0x6c, - 0x7a, 0x3c, 0x19, 0xb5, 0x83, 0xcc, 0x30, 0x23, 0x97, 0xbd, 0x47, 0x18, 0x11, 0x00, 0x27, 0x25, - 0xc9, 0x8a, 0xef, 0x54, 0x6b, 0xd3, 0x47, 0x20, 0xe9, 0x95, 0x55, 0x46, 0x86, 0x7c, 0x6c, 0x5a, - 0x2d, 0xe8, 0x9f, 0x2e, 0xb5, 0xb7, 0xc9, 0x87, 0x7b, 0x8b, 0x6f, 0x20, 0x1d, 0xd6, 0x8c, 0x7d, - 0x0f, 0x50, 0xca, 0x8c, 0x5c, 0xf6, 0x6e, 0x50, 0xaa, 0x30, 0x93, 0x93, 0x56, 0xf0, 0x3f, 0x30, - 0xfa, 0x4b, 0x90, 0xb0, 0xcd, 0xae, 0xa7, 0x18, 0xcf, 0x51, 0xf9, 0x95, 0xbd, 0x4d, 0x9e, 0x14, - 0x85, 0xf7, 0x3a, 0x91, 0x0f, 0x3a, 0x91, 0x2f, 0x9b, 0xc8, 0x28, 0x6d, 0x78, 0x85, 0x1c, 0xb9, - 0x6c, 0x92, 0xa8, 0x12, 0x1a, 0x27, 0x05, 0x7c, 0xfa, 0x08, 0xac, 0xb4, 0xa1, 0x8d, 0x91, 0xa1, - 0x60, 0x64, 0x1a, 0x99, 0xa5, 0xd7, 0xc9, 0x31, 0x81, 0x1c, 0x4d, 0xe4, 0x42, 0x5c, 0x4e, 0x0a, - 0x2b, 0x71, 0x0c, 0xc8, 0x44, 0x73, 0x2f, 0x41, 0xbb, 0x63, 0x1a, 0x36, 0xe4, 0x86, 0x31, 0xb0, - 0x4e, 0x82, 0xa2, 0x9f, 0x85, 0xff, 0x50, 0x65, 0x1e, 0x4e, 0x55, 0xe6, 0x4e, 0x69, 0xfd, 0xf6, - 0x53, 0x4f, 0xff, 0x40, 0x81, 0xb4, 0xae, 0x38, 0x48, 0xef, 0xea, 0xb2, 0xad, 0xa1, 0x4e, 0x47, - 0x51, 0x61, 0x26, 0xe1, 0x6f, 0xe7, 0xe9, 0x15, 0xae, 0x75, 0x05, 0xb6, 0x86, 0x2e, 0xbb, 0x22, - 0x2a, 0xce, 0x61, 0x20, 0x32, 0x72, 0xd9, 0xfb, 0xc4, 0x3c, 0x2a, 0xcf, 0x49, 0x6b, 0xc1, 0xd2, - 0x18, 0xcb, 0x6d, 0x81, 0xcd, 0x99, 0x1a, 0x4f, 0x3a, 0xe0, 0x7b, 0x90, 0x12, 0x6d, 0xb5, 0xac, - 0x18, 0x2d, 0xa8, 0xdd, 0x7a, 0xf5, 0xb9, 0x0c, 0xb8, 0x37, 0xed, 0x3e, 0xd9, 0xd7, 0x4f, 0x71, - 0xc0, 0x4c, 0x42, 0x12, 0xec, 0x68, 0x4a, 0x0b, 0x5e, 0x63, 0x78, 0x3c, 0x07, 0x19, 0xd3, 0x42, - 0x2a, 0x32, 0x14, 0x4d, 0xbe, 0x78, 0xb7, 0x9f, 0x0c, 0x5d, 0x76, 0xfd, 0xc0, 0x42, 0x6a, 0x39, - 0xbc, 0xb3, 0x91, 0xcb, 0xb2, 0x81, 0xde, 0x1c, 0x3a, 0x27, 0x6d, 0x8c, 0x43, 0x53, 0x4c, 0x5a, - 0x01, 0x6f, 0x19, 0xf0, 0x6c, 0xc6, 0x2d, 0xe6, 0xbb, 0xed, 0x0d, 0x5d, 0x36, 0xfd, 0x18, 0x9e, - 0x45, 0xcd, 0x18, 0x62, 0x76, 0x01, 0x91, 0x93, 0xd2, 0x46, 0x04, 0x3f, 0x7b, 0x69, 0xe2, 0x37, - 0x3e, 0xce, 0x96, 0x6e, 0x76, 0x9c, 0x25, 0x6e, 0x6c, 0x9c, 0x6d, 0x03, 0x6e, 0x7e, 0x5f, 0x4c, - 0xda, 0xe7, 0x55, 0x1c, 0x6c, 0x45, 0x61, 0xd7, 0x19, 0x71, 0xff, 0xf7, 0xcf, 0x35, 0x87, 0xee, - 0xd2, 0x15, 0x87, 0x6e, 0xe2, 0xdf, 0x1d, 0xba, 0xcb, 0xb7, 0x3d, 0x74, 0xdf, 0x03, 0xef, 0x5e, - 0xd2, 0x7f, 0xe3, 0x3e, 0xfd, 0xe0, 0xd7, 0x45, 0x90, 0x6c, 0x38, 0x22, 0xb4, 0x6d, 0x45, 0x85, - 0x8d, 0x5e, 0x07, 0xd2, 0xdb, 0x20, 0x55, 0xa9, 0xee, 0x17, 0xbf, 0xa9, 0x37, 0xe4, 0xc6, 0x53, - 0x59, 0x3c, 0x7c, 0x94, 0x5e, 0x60, 0xd2, 0xfd, 0x41, 0x6e, 0xb5, 0x02, 0x8f, 0x95, 0xae, 0x86, - 0x1b, 0x8e, 0x68, 0xab, 0xf4, 0x0e, 0x58, 0x2b, 0x56, 0x2a, 0x72, 0xbd, 0x26, 0xd6, 0x1a, 0xf2, - 0x81, 0x54, 0xa9, 0x4a, 0x69, 0x8a, 0x59, 0xef, 0x0f, 0x72, 0xc9, 0xe9, 0x97, 0xac, 0x3c, 0x48, - 0x7b, 0x38, 0xb1, 0x28, 0x7d, 0x55, 0x1d, 0x03, 0x17, 0x19, 0xba, 0x3f, 0xc8, 0xa5, 0x22, 0x0f, - 0xfd, 0xcf, 0x00, 0x53, 0x2e, 0x3e, 0x2e, 0x57, 0xeb, 0xb2, 0x54, 0x7d, 0x52, 0x2f, 0x96, 0xab, - 0x53, 0xe2, 0x31, 0x66, 0xab, 0x3f, 0xc8, 0xdd, 0x9f, 0x37, 0x8e, 0x3f, 0x07, 0x5b, 0x11, 0xf2, - 0x94, 0x63, 0x9c, 0x79, 0xd0, 0x1f, 0xe4, 0x32, 0x73, 0x6f, 0xe3, 0x3b, 0x60, 0x35, 0xa0, 0x13, - 0xfc, 0x12, 0xb3, 0xd6, 0x1f, 0xe4, 0x56, 0x42, 0xcf, 0x05, 0x26, 0xfe, 0xcb, 0xcf, 0x59, 0x6a, - 0xef, 0x55, 0x0c, 0xc4, 0xbc, 0xe3, 0x1f, 0x81, 0xc8, 0x39, 0xb3, 0xd3, 0xad, 0x1b, 0x7d, 0xe1, - 0x61, 0x76, 0x2e, 0x8f, 0x8f, 0xeb, 0x41, 0x3f, 0x03, 0xd1, 0xbc, 0xb0, 0x17, 0x31, 0x43, 0x00, - 0xe6, 0xfd, 0xd7, 0x00, 0x26, 0xda, 0x5f, 0x83, 0xf0, 0x89, 0xe8, 0x07, 0x33, 0xbc, 0xf0, 0x79, - 0xb7, 0x2f, 0x8b, 0x4e, 0x24, 0xbb, 0x60, 0x6e, 0x49, 0xf2, 0x73, 0x04, 0x66, 0x90, 0xcc, 0x47, - 0x6f, 0x8a, 0x9c, 0xd8, 0x3a, 0x60, 0x7e, 0x2d, 0x1f, 0x5e, 0xae, 0x16, 0xce, 0x5c, 0xe1, 0x8d, - 0xa1, 0x63, 0xe7, 0x52, 0xf5, 0xc5, 0x30, 0x4b, 0xbd, 0x1c, 0x66, 0xa9, 0x3f, 0x87, 0x59, 0xea, - 0xc7, 0xf3, 0xec, 0xc2, 0xcb, 0xf3, 0xec, 0xc2, 0xef, 0xe7, 0xd9, 0x85, 0x67, 0x1f, 0x86, 0xee, - 0x34, 0xdc, 0xd5, 0x4d, 0x03, 0xf6, 0x04, 0xa8, 0xef, 0x6a, 0xb0, 0xad, 0x42, 0x4b, 0x70, 0xc6, - 0x9f, 0x7f, 0xfe, 0xe5, 0x6e, 0x26, 0xfc, 0x4f, 0xbb, 0x8f, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, - 0x71, 0xf7, 0xac, 0x3e, 0x73, 0x0e, 0x00, 0x00, + // 1061 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0xcb, 0x6f, 0xe3, 0x44, + 0x18, 0x8f, 0x9b, 0xc7, 0xd2, 0xc9, 0xa3, 0xa9, 0xd9, 0xee, 0x26, 0xee, 0x12, 0x07, 0x53, 0x4a, + 0x96, 0x55, 0x6d, 0x52, 0x2e, 0x08, 0x84, 0x50, 0x5e, 0x85, 0x8a, 0x78, 0xbb, 0xb8, 0x41, 0x5d, + 0xed, 0xc5, 0x72, 0x92, 0xa9, 0x19, 0xd5, 0x8f, 0xac, 0xed, 0xb4, 0x8e, 0xc4, 0x8d, 0x5b, 0x4e, + 0x9c, 0xb8, 0xe5, 0xc6, 0x81, 0x03, 0x7f, 0xc8, 0x1e, 0xf7, 0x88, 0x38, 0x58, 0x28, 0x15, 0xff, + 0x40, 0x8e, 0x1c, 0x56, 0xc8, 0x1e, 0x27, 0x38, 0x4e, 0xd3, 0x2d, 0x55, 0xe9, 0x01, 0xed, 0xa9, + 0xcd, 0xfc, 0x1e, 0xdf, 0xcc, 0xf7, 0x7d, 0xf3, 0xd9, 0x06, 0x1b, 0x50, 0xe5, 0x54, 0xc9, 0x38, + 0x81, 0x16, 0x77, 0x5a, 0xe6, 0x2c, 0x9b, 0xed, 0x19, 0xba, 0xa5, 0x93, 0x29, 0xa8, 0xb2, 0x78, + 0x99, 0x3d, 0x2d, 0x53, 0x77, 0x65, 0x5d, 0xd6, 0x3d, 0x80, 0x73, 0xff, 0xc3, 0x1c, 0xaa, 0xd0, + 0xd1, 0x4d, 0x55, 0x37, 0xb9, 0xb6, 0x64, 0x42, 0xee, 0xb4, 0xdc, 0x86, 0x96, 0x54, 0xe6, 0x3a, + 0x3a, 0xd2, 0x7c, 0x3c, 0x3f, 0x67, 0xed, 0xbb, 0x61, 0x88, 0x96, 0x75, 0x5d, 0x56, 0x20, 0xe7, + 0xfd, 0x6a, 0xf7, 0x8f, 0x39, 0x0b, 0xa9, 0xd0, 0xb4, 0x24, 0xb5, 0x87, 0x09, 0xcc, 0x9f, 0x04, + 0x78, 0xab, 0x65, 0x3f, 0x91, 0x0c, 0x49, 0x35, 0xc9, 0x47, 0xe0, 0x8e, 0x65, 0xd8, 0xe2, 0x31, + 0x84, 0x39, 0xa2, 0x48, 0x94, 0x62, 0x55, 0x72, 0xe2, 0xd0, 0x99, 0x81, 0xa4, 0x2a, 0x9f, 0x32, + 0x3e, 0xc0, 0x08, 0x09, 0xcb, 0xb0, 0xf7, 0x20, 0x24, 0xbf, 0x00, 0x19, 0x05, 0x3d, 0xef, 0xa3, + 0xae, 0x38, 0xd5, 0xac, 0x78, 0x9a, 0xfc, 0xc4, 0xa1, 0x37, 0xb0, 0x66, 0x1e, 0x67, 0x84, 0x14, + 0x5e, 0x68, 0x61, 0x83, 0x13, 0xf0, 0x0e, 0xfe, 0x8d, 0xac, 0x81, 0x68, 0xc0, 0xb6, 0x64, 0x41, + 0x51, 0x45, 0x5a, 0xdf, 0x82, 0xa6, 0x68, 0xf6, 0x24, 0x2d, 0x17, 0x2d, 0x12, 0xa5, 0x68, 0xb5, + 0x34, 0x71, 0xe8, 0xad, 0xa0, 0xdf, 0x12, 0x3a, 0x23, 0x50, 0x33, 0x5c, 0xf0, 0x60, 0x1e, 0xa3, + 0x87, 0x2e, 0xf8, 0xd7, 0x0a, 0xc8, 0xf2, 0xa6, 0x5c, 0xe9, 0x76, 0x9b, 0x48, 0x45, 0xd6, 0x81, + 0xd1, 0x85, 0x06, 0xb9, 0x0d, 0xe2, 0xfa, 0x99, 0x06, 0x0d, 0xef, 0xb4, 0xab, 0xd5, 0xec, 0xc4, + 0xa1, 0x53, 0x38, 0x92, 0xb7, 0xcc, 0x08, 0x18, 0x26, 0xab, 0x60, 0xad, 0xa3, 0x20, 0xa8, 0x59, + 0xa2, 0xee, 0xea, 0x44, 0xd4, 0xf5, 0xce, 0xba, 0x5a, 0xa5, 0x26, 0x0e, 0x7d, 0x0f, 0x2b, 0x42, + 0x04, 0x46, 0x48, 0xe3, 0x15, 0x2f, 0xd2, 0x7e, 0x97, 0x3c, 0x02, 0x69, 0x37, 0xf7, 0x22, 0xd2, + 0xc4, 0x63, 0xdd, 0xe8, 0x40, 0xef, 0x74, 0x99, 0xdd, 0x3c, 0x1b, 0x6c, 0x00, 0xb6, 0x85, 0x54, + 0xb8, 0xaf, 0xed, 0xb9, 0x84, 0x6a, 0x6e, 0xe2, 0xd0, 0x77, 0xfd, 0xe4, 0x07, 0x95, 0x8c, 0x90, + 0xb4, 0xfe, 0xa1, 0x91, 0x5f, 0x81, 0x84, 0xa9, 0xf7, 0x5d, 0xc7, 0x58, 0x91, 0x28, 0x25, 0x77, + 0xf3, 0x2c, 0x6e, 0x17, 0xd6, 0x6d, 0x17, 0xd6, 0x6f, 0x17, 0xb6, 0xa6, 0x23, 0xad, 0xba, 0xf1, + 0xc2, 0xa1, 0x23, 0x13, 0x87, 0x4e, 0x63, 0x57, 0x2c, 0x63, 0x04, 0x5f, 0x4f, 0x1e, 0x81, 0x64, + 0x17, 0x9a, 0x16, 0xd2, 0x24, 0x0b, 0xe9, 0x5a, 0x2e, 0xfe, 0x3a, 0x3b, 0xca, 0xb7, 0x23, 0xb1, + 0x5d, 0x40, 0xcb, 0x08, 0x41, 0x27, 0x86, 0x02, 0xb9, 0x70, 0xee, 0x05, 0x68, 0xf6, 0x74, 0xcd, + 0x84, 0xcc, 0x38, 0x0a, 0xd6, 0x31, 0xc8, 0x7b, 0x59, 0xf8, 0x1f, 0x55, 0xe6, 0xe1, 0x5c, 0x65, + 0x56, 0xab, 0xeb, 0xb7, 0x9f, 0x7a, 0xf2, 0x07, 0x02, 0x64, 0x55, 0xc9, 0x46, 0x6a, 0x5f, 0x15, + 0x4d, 0x05, 0xf5, 0x7a, 0x92, 0x0c, 0x73, 0x09, 0x6f, 0x3b, 0x4f, 0x5d, 0x8f, 0xdf, 0x1d, 0x7a, + 0x5b, 0x46, 0xd6, 0x77, 0xfd, 0x36, 0xdb, 0xd1, 0x55, 0xce, 0x9f, 0x34, 0xf8, 0xcf, 0x8e, 0xd9, + 0x3d, 0xe1, 0xac, 0x41, 0x0f, 0x9a, 0x6c, 0x1d, 0x76, 0xc6, 0x0e, 0x9d, 0xe4, 0x25, 0xfb, 0xd0, + 0x37, 0x99, 0x38, 0xf4, 0x7d, 0x1c, 0x3c, 0x6c, 0xcf, 0x08, 0x6b, 0xfe, 0xd2, 0x94, 0xcb, 0x6c, + 0x82, 0xfc, 0x42, 0x8d, 0x67, 0x1d, 0xf0, 0x3d, 0xc8, 0xf0, 0xa6, 0x5c, 0x93, 0xb4, 0x0e, 0x54, + 0x6e, 0xbd, 0xfa, 0x4c, 0x0e, 0xdc, 0x9b, 0x8f, 0x3e, 0xdb, 0xd7, 0x4f, 0x31, 0x40, 0xcd, 0x20, + 0x01, 0xf6, 0x14, 0xa9, 0x03, 0xaf, 0x31, 0x3c, 0x9e, 0x83, 0x9c, 0x6e, 0x20, 0x19, 0x69, 0x92, + 0x22, 0x5e, 0xbc, 0xdb, 0x4f, 0xc6, 0x0e, 0xbd, 0x7e, 0x60, 0x20, 0xb9, 0x16, 0xdc, 0xd9, 0xc4, + 0xa1, 0x69, 0xdf, 0x6f, 0x89, 0x9c, 0x11, 0x36, 0xa6, 0xd0, 0x9c, 0x92, 0x94, 0xc0, 0xdb, 0x1a, + 0x3c, 0x5b, 0x88, 0x16, 0xf5, 0xa2, 0xed, 0x8e, 0x1d, 0x3a, 0xfb, 0x18, 0x9e, 0x85, 0x83, 0x51, + 0x38, 0xd8, 0x05, 0x42, 0x46, 0xc8, 0x6a, 0x21, 0xfe, 0xe2, 0xa5, 0x89, 0xdd, 0xf8, 0x38, 0x8b, + 0xdf, 0xec, 0x38, 0x4b, 0xdc, 0xd8, 0x38, 0xdb, 0x02, 0xcc, 0xf2, 0xbe, 0x98, 0xb5, 0xcf, 0xab, + 0x18, 0xd8, 0x0c, 0xd3, 0xae, 0x33, 0xe2, 0xde, 0xf4, 0xcf, 0x35, 0x87, 0x6e, 0xfc, 0x5f, 0x0e, + 0xdd, 0xc4, 0x7f, 0x3b, 0x74, 0xef, 0xdc, 0xf6, 0xd0, 0x7d, 0x1f, 0xbc, 0x77, 0x49, 0xff, 0x4d, + 0xfb, 0xf4, 0xc3, 0x5f, 0x57, 0x40, 0xba, 0x65, 0xf3, 0xd0, 0x34, 0x25, 0x19, 0xb6, 0x06, 0x3d, + 0x48, 0x6e, 0x81, 0x4c, 0xbd, 0xb1, 0x57, 0xf9, 0xb6, 0xd9, 0x12, 0x5b, 0x4f, 0x45, 0xfe, 0xf0, + 0xcb, 0x6c, 0x84, 0xca, 0x0e, 0x47, 0xc5, 0x54, 0x1d, 0x1e, 0x4b, 0x7d, 0xc5, 0x6a, 0xd9, 0xbc, + 0x29, 0x93, 0xdb, 0x60, 0xad, 0x52, 0xaf, 0x8b, 0xcd, 0x7d, 0x7e, 0xbf, 0x25, 0x1e, 0x08, 0xf5, + 0x86, 0x90, 0x25, 0xa8, 0xf5, 0xe1, 0xa8, 0x98, 0x9e, 0x7f, 0xc9, 0x2a, 0x81, 0xac, 0xcb, 0xe3, + 0x2b, 0xc2, 0xd7, 0x8d, 0x29, 0x71, 0x85, 0x22, 0x87, 0xa3, 0x62, 0x26, 0xf4, 0xd0, 0xff, 0x0c, + 0x50, 0xb5, 0xca, 0xe3, 0x5a, 0xa3, 0x29, 0x0a, 0x8d, 0x27, 0xcd, 0x4a, 0xad, 0x31, 0x67, 0x1e, + 0xa5, 0x36, 0x87, 0xa3, 0xe2, 0xfd, 0x65, 0xe3, 0xf8, 0x73, 0xb0, 0x19, 0x12, 0xcf, 0x45, 0x8c, + 0x51, 0x0f, 0x86, 0xa3, 0x62, 0x6e, 0xe9, 0x6d, 0x7c, 0x17, 0xa4, 0x7c, 0x39, 0xe6, 0xc7, 0xa9, + 0xb5, 0xe1, 0xa8, 0x98, 0x0c, 0x3c, 0x17, 0xa8, 0xd8, 0x2f, 0x3f, 0x17, 0x88, 0xdd, 0x57, 0x51, + 0x10, 0x75, 0x8f, 0x7f, 0x04, 0x42, 0xe7, 0x2c, 0xcc, 0xb7, 0x6e, 0xf8, 0x85, 0x87, 0xda, 0xbe, + 0x1c, 0x9f, 0xd6, 0x83, 0x7c, 0x06, 0xc2, 0x79, 0xa1, 0x2f, 0x52, 0x06, 0x08, 0xd4, 0x07, 0xaf, + 0x21, 0xcc, 0xbc, 0xbf, 0x01, 0xc1, 0x13, 0x91, 0x0f, 0x16, 0x74, 0xc1, 0xf3, 0x6e, 0x5d, 0x86, + 0xce, 0x2c, 0xfb, 0x60, 0x69, 0x49, 0x4a, 0x4b, 0x0c, 0x16, 0x98, 0xd4, 0x47, 0x57, 0x65, 0xce, + 0xc2, 0xda, 0x60, 0x79, 0x2d, 0x1f, 0x5e, 0xee, 0x16, 0xcc, 0x5c, 0xf9, 0xca, 0xd4, 0x69, 0xe4, + 0x6a, 0xe3, 0xc5, 0xb8, 0x40, 0xbc, 0x1c, 0x17, 0x88, 0x3f, 0xc6, 0x05, 0xe2, 0xc7, 0xf3, 0x42, + 0xe4, 0xe5, 0x79, 0x21, 0xf2, 0xdb, 0x79, 0x21, 0xf2, 0xec, 0x51, 0xe0, 0x4e, 0xc3, 0x1d, 0x55, + 0xd7, 0xe0, 0x80, 0x83, 0xea, 0x8e, 0x02, 0xbb, 0x32, 0x34, 0x38, 0x7b, 0xfa, 0x8d, 0xe6, 0x5d, + 0xee, 0x76, 0xc2, 0xfb, 0xfe, 0xfa, 0xf8, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd6, 0xf0, 0xc2, + 0x4b, 0x18, 0x0e, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -986,51 +1000,41 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Metadata: "em/market/v1/tx.proto", } -func (m *TxParam) Marshal() (dAtA []byte, err error) { - size := m.Size() +func (p *TxParams) Marshal() (dAtA []byte, err error) { + size := p.Size() dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) + n, err := p.MarshalToSizedBuffer(dAtA[:size]) if err != nil { return nil, err } return dAtA[:n], nil } -func (m *TxParam) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (p *TxParams) MarshalTo(dAtA []byte) (int, error) { + size := p.Size() + return p.MarshalToSizedBuffer(dAtA[:size]) } -func (m *TxParam) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (p *TxParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.LiquidityRebateMinutesSpan != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.LiquidityRebateMinutesSpan)) + if p.LiquidityRebateMinutesSpan != 0 { + i = encodeVarintTx(dAtA, i, uint64(p.LiquidityRebateMinutesSpan)) i-- dAtA[i] = 0x18 } - { - size := m.LiquidTrxFee.Size() - i -= size - if _, err := m.LiquidTrxFee.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTx(dAtA, i, uint64(size)) + if p.LiquidTrxFee != 0 { + i = encodeVarintTx(dAtA, i, uint64(p.LiquidTrxFee)) + i-- + dAtA[i] = 0x10 } - i-- - dAtA[i] = 0x12 - { - size := m.TrxFee.Size() - i -= size - if _, err := m.TrxFee.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTx(dAtA, i, uint64(size)) + if p.TrxFee != 0 { + i = encodeVarintTx(dAtA, i, uint64(p.TrxFee)) + i-- + dAtA[i] = 0x8 } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -1473,18 +1477,20 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *TxParam) Size() (n int) { - if m == nil { +func (p *TxParams) Size() (n int) { + if p == nil { return 0 } var l int _ = l - l = m.TrxFee.Size() - n += 1 + l + sovTx(uint64(l)) - l = m.LiquidTrxFee.Size() - n += 1 + l + sovTx(uint64(l)) - if m.LiquidityRebateMinutesSpan != 0 { - n += 1 + sovTx(uint64(m.LiquidityRebateMinutesSpan)) + if p.TrxFee != 0 { + n += 1 + sovTx(uint64(p.TrxFee)) + } + if p.LiquidTrxFee != 0 { + n += 1 + sovTx(uint64(p.LiquidTrxFee)) + } + if p.LiquidityRebateMinutesSpan != 0 { + n += 1 + sovTx(uint64(p.LiquidityRebateMinutesSpan)) } return n } @@ -1669,7 +1675,7 @@ func sovTx(x uint64) (n int) { func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *TxParam) Unmarshal(dAtA []byte) error { +func (p *TxParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1692,17 +1698,17 @@ func (m *TxParam) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: TxParam: wiretype end group for non-group") + return fmt.Errorf("proto: TxParams: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: TxParam: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: TxParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field TrxFee", wireType) } - var stringLen uint64 + p.TrxFee = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1712,31 +1718,16 @@ func (m *TxParam) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + p.TrxFee |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.TrxFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 2: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LiquidTrxFee", wireType) } - var stringLen uint64 + p.LiquidTrxFee = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1746,31 +1737,16 @@ func (m *TxParam) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + p.LiquidTrxFee |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.LiquidTrxFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LiquidityRebateMinutesSpan", wireType) } - m.LiquidityRebateMinutesSpan = 0 + p.LiquidityRebateMinutesSpan = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1780,7 +1756,7 @@ func (m *TxParam) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.LiquidityRebateMinutesSpan |= int64(b&0x7F) << shift + p.LiquidityRebateMinutesSpan |= int64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/market/types/tx_params.go b/x/market/types/tx_params.go new file mode 100644 index 00000000..0e2996b9 --- /dev/null +++ b/x/market/types/tx_params.go @@ -0,0 +1,109 @@ +package types + +import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/pkg/errors" +) + +const ( + defaultTrxFee = 25000 + defaultLiquidMinutesSpan = 5 +) + +var ( + // DefaultLiquidTrxFee zero by default + DefaultLiquidTrxFee = sdk.ZeroInt() + + // KeyTrxFee is store's key for TrxFee Param + KeyTrxFee = []byte("TrxFee") + // KeyLiquidTrxFee is store's key for the LiquidTrxFee + KeyLiquidTrxFee = []byte("LiquidTrxFee") + // KeyLiquidityRebateMinutesSpan is store's key for the + // LiquidityRebateMinutesSpan + KeyLiquidityRebateMinutesSpan = []byte("LiquidityRebateMinutesSpan") +) + +// ParamKeyTable for bank module. +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&TxParams{}) +} + +// ParamSetPairs implements params.ParamSet +func (p *TxParams) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyTrxFee, &p.TrxFee, validateIsUInt), + paramtypes.NewParamSetPair(KeyLiquidTrxFee, &p.LiquidTrxFee, validateIsUInt), + paramtypes.NewParamSetPair( + KeyLiquidityRebateMinutesSpan, &p.LiquidityRebateMinutesSpan, + validateTimeSpan, + ), + } +} + +// NewTxParams creates a new parameter configuration for the bank module +func NewTxParams(trxFee, liquidTrxFee uint64, liquidityRebateMinutes int64) TxParams { + return TxParams{ + TrxFee: trxFee, + LiquidTrxFee: liquidTrxFee, + LiquidityRebateMinutesSpan: liquidityRebateMinutes, + } +} + +// DefaultTxParams are the default Trx market parameters. +func DefaultTxParams() TxParams { + return TxParams{ + TrxFee: defaultTrxFee, + LiquidTrxFee: 0, + LiquidityRebateMinutesSpan: defaultLiquidMinutesSpan, + } +} + +// Validate all Tx Market Params parameters +func (p TxParams) Validate() error { + if err := validateIsNonZeroUInt(p.TrxFee); err != nil { + return err + } + + if err := validateIsUInt(p.LiquidTrxFee); err != nil { + return err + } + + return validateTimeSpan(p.LiquidityRebateMinutesSpan) +} + +func validateTimeSpan(i interface{}) error { + m, ok := i.(int64) + + if !ok { + return fmt.Errorf("invalid minutes parameter type: %T", i) + } + + if m < 0 { + return fmt.Errorf("minutes parameter cannot be < 0: %d", m) + } + + return nil +} + +func validateIsUInt(u interface{}) error { + _, ok := u.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", u) + } + + return nil +} + +func validateIsNonZeroUInt(u interface{}) error { + v, ok := u.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", u) + } + if v == 0 { + return errors.New("cannot be 0") + } + + return nil +} diff --git a/x/market/types/tx_params_test.go b/x/market/types/tx_params_test.go new file mode 100644 index 00000000..87499f90 --- /dev/null +++ b/x/market/types/tx_params_test.go @@ -0,0 +1,29 @@ +package types + +import ( + "github.com/stretchr/testify/require" + "testing" +) + +func Test_ParamsEqual(t *testing.T) { + paramsA := NewTxParams(1, 0, 1) + err := paramsA.Validate() + require.NoError(t, err) + paramsB := NewTxParams(1, 0, 1) + err = paramsB.Validate() + require.NoError(t, err) + paramsC := NewTxParams(1, 1, 1) + err = paramsC.Validate() + require.NoError(t, err) + + require.True(t, paramsA.String() == paramsB.String()) + + require.False(t, paramsA.String() == paramsC.String()) +} + +func TestValidateParams(t *testing.T) { + require.NoError(t, DefaultTxParams().Validate()) + require.NoError(t, NewTxParams(1, 0, 5).Validate()) + require.Error(t, NewTxParams(0, 0, 5).Validate()) + require.Error(t, NewTxParams(0, 0, -1).Validate()) +} \ No newline at end of file From 9c895907ce40d4d1b5d72ccb2a615c6455d8f5fe Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 13 May 2021 20:29:13 +0300 Subject: [PATCH 10/41] Add trx type in orders --- x/buyback/internal/keeper/expected_keepers.go | 2 +- x/buyback/internal/keeper/keeper.go | 2 +- x/market/keeper/grpc_query_test.go | 4 +- x/market/keeper/keeper.go | 26 +-- x/market/keeper/keeper_fuzzing_test.go | 2 +- x/market/keeper/keeper_test.go | 197 ++++++++++-------- x/market/keeper/msg_server.go | 2 +- x/market/keeper/msg_server_test.go | 12 +- x/market/keeper/querier_test.go | 36 ++-- x/market/types/tx_params.go | 2 +- 10 files changed, 156 insertions(+), 129 deletions(-) diff --git a/x/buyback/internal/keeper/expected_keepers.go b/x/buyback/internal/keeper/expected_keepers.go index cb4a602d..31e811ae 100644 --- a/x/buyback/internal/keeper/expected_keepers.go +++ b/x/buyback/internal/keeper/expected_keepers.go @@ -7,7 +7,7 @@ import ( type ( MarketKeeper interface { - NewOrderSingle(ctx sdk.Context, order market.Order) (*sdk.Result, error) + NewOrderSingle(ctx sdk.Context, order market.Order, messageType market.TxMessageType) (*sdk.Result, error) GetOrdersByOwner(ctx sdk.Context, owner sdk.AccAddress) []*market.Order GetInstruments(ctx sdk.Context) (instrs []market.MarketData) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) diff --git a/x/buyback/internal/keeper/keeper.go b/x/buyback/internal/keeper/keeper.go index 2f8ccebc..aa982d32 100644 --- a/x/buyback/internal/keeper/keeper.go +++ b/x/buyback/internal/keeper/keeper.go @@ -50,7 +50,7 @@ func (k Keeper) CancelCurrentModuleOrders(ctx sdk.Context) { } func (k Keeper) SendOrderToMarket(ctx sdk.Context, order market.Order) (*sdk.Result, error) { - return k.marketKeeper.NewOrderSingle(ctx, order) + return k.marketKeeper.NewOrderSingle(ctx, order, market.TxMessageType_AddLimitOrder) } func (k Keeper) GetMarketData(ctx sdk.Context) []market.MarketData { diff --git a/x/market/keeper/grpc_query_test.go b/x/market/keeper/grpc_query_test.go index 7789aa6e..82728841 100644 --- a/x/market/keeper/grpc_query_test.go +++ b/x/market/keeper/grpc_query_test.go @@ -129,13 +129,13 @@ func TestInstrument(t *testing.T) { acc := createAccount(ctx, ak, bk, randomAddress(), "1000usd") o := order(ctx.BlockTime(), acc, "100usd", "100chf") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) oPlusOne := order( ctx.BlockTime().Add(time.Second), acc, "100usd", "100gbp", ) - _, err = k.NewOrderSingle(ctx, oPlusOne) + _, err = k.NewOrderSingle(ctx, oPlusOne, types.TxMessageType_AddLimitOrder) require.NoError(t, err) specs := map[string]struct { diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index f32351ef..9d7fce83 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -149,10 +149,11 @@ func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, ds return nil, err } - return k.NewOrderSingle(ctx, order) + // treat ReplaceMarketOrder and AddMarketOrders costing same gas + return k.NewOrderSingle(ctx, order, types.TxMessageType_AddMarketOrder) } -func postOrderSingle( +func postOrder( ctx sdk.Context, order types.Order, messageType types.TxMessageType, commitTrade func(), @@ -170,24 +171,20 @@ func postOrderSingle( // else apply full or partial rebate // check partial rebate and whether panic still applied + // Roll back any state changes made by the aggressive FillOrKill order. + if order.TimeInForce == types.TimeInForce_FillOrKill { + return + } + commitTrade() } func (k *Keeper) NewOrderSingle( ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType, ) (*sdk.Result, error) { - - // Set this to true to roll back any state changes made by the aggressive order. Used for FillOrKill orders. - KillOrder := false ctx, commitTrade := ctx.CacheContext() - defer func() { - if KillOrder { - return - } - - postOrderSingle(ctx, aggressiveOrder, messageType, commitTrade) - }() + defer postOrder(ctx, aggressiveOrder, messageType, commitTrade) if err := aggressiveOrder.IsValid(); err != nil { return nil, err @@ -363,7 +360,6 @@ func (k *Keeper) NewOrderSingle( addToBook = false types.EmitExpireEvent(ctx, aggressiveOrder) case types.TimeInForce_FillOrKill: - KillOrder = true ctx = ctx.WithEventManager(sdk.NewEventManager()) types.EmitExpireEvent(ctx, aggressiveOrder) } @@ -420,7 +416,7 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { // Use a fixed gas amount - ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, "CancelReplaceOrder") + ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, "CancelReplaceLimitOrder") ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, newOrder.Owner, origClientOrderId) @@ -449,7 +445,7 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, newOrder.TimeInForce = origOrder.TimeInForce - resAdd, err := k.NewOrderSingle(ctx, newOrder) + resAdd, err := k.NewOrderSingle(ctx, newOrder, types.TxMessageType_CancelReplaceLimitOrder) if err != nil { return nil, err } diff --git a/x/market/keeper/keeper_fuzzing_test.go b/x/market/keeper/keeper_fuzzing_test.go index 539a5523..83a11fd1 100644 --- a/x/market/keeper/keeper_fuzzing_test.go +++ b/x/market/keeper/keeper_fuzzing_test.go @@ -88,7 +88,7 @@ func TestFuzzing1(t *testing.T) { }) for _, order := range allOrders { - _, err := k.NewOrderSingle(ctx, order) + _, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) if order.IsFilled() { fmt.Println("Order is filled on creation. Ignoring.", order) continue diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index b1e1cf34..9aab2555 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -58,7 +58,8 @@ func TestBasicTrade(t *testing.T) { gasmeter := sdk.NewGasMeter(math.MaxUint64) src1, dst1 := "eur", "usd" order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order1) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order1, + types.TxMessageType_AddLimitOrder) require.NoError(t, err) require.Equal(t, gasPriceNewOrder, gasmeter.GasConsumed()) require.Equal(t, ctx.BlockTime(), order1.Created) @@ -73,7 +74,8 @@ func TestBasicTrade(t *testing.T) { gasmeter = sdk.NewGasMeter(math.MaxUint64) src2, dst2 := dst1, src1 order2 := order(ctx.BlockTime(), acc2, "60"+src2, "50"+dst2) - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order2) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order2, + types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Ensure that the trade has been correctly registered in market data. @@ -126,11 +128,11 @@ func TestBasicTrade2(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) order1 := order(ctx.BlockTime(), acc1, "888eur", "1121usd") - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc2, "1120usd", "890eur") - res, err := k.NewOrderSingle(ctx, order2) + res, err := k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) @@ -146,16 +148,16 @@ func TestBasicTrade3(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) order1 := order(ctx.BlockTime(), acc2, "888850eur", "22807162chf") - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc3, "12chf", "4usd") - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order3 := order(ctx.BlockTime(), acc1, "227156usd", "24971eur") - _, err = k.NewOrderSingle(ctx, order3) + _, err = k.NewOrderSingle(ctx, order3, types.TxMessageType_AddLimitOrder) require.NoError(t, err) require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) @@ -172,24 +174,24 @@ func TestMarketOrderSlippage1(t *testing.T) { // Establish market price by executing a 1:1 trade o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) // Sell eur at various prices o = order(ctx.BlockTime(), acc2, "50eur", "50gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "50eur", "75gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "50eur", "100gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) // Make a market order that allows slippage @@ -238,11 +240,11 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { // Establish market price by executing a 1:1 trade o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Make a market order that allows slippage @@ -323,11 +325,11 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { // Establish market price by executing a 2:1 trade o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) acc1b := bk.GetAllBalances(ctx, acc1.GetAddress()) require.Equal(t, coins("20eur,90gbp").String(), acc1b.String()) @@ -413,16 +415,16 @@ func TestFillOrKillMarketOrder1(t *testing.T) { // Establish market price by executing a 1:1 trade o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Create a market for eur o = order(ctx.BlockTime(), acc2, "100eur", "100gbp") - res, err := k.NewOrderSingle(ctx, o) + res, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) require.Equal( t, "accept", @@ -467,12 +469,12 @@ func TestFillOrKillLimitOrder1(t *testing.T) { // Create a tiny market for eur o := order(ctx.BlockTime(), acc2, "100eur", "100gbp") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc1, "200gbp", "200eur") order2.TimeInForce = types.TimeInForce_FillOrKill - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Order must fail completely due to not being fillable @@ -499,13 +501,13 @@ func TestImmediateOrCancel(t *testing.T) { var err error o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "2gbp", "2eur") o.TimeInForce = types.TimeInForce_ImmediateOrCancel cid := o.ClientOrderID - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) require.Equal(t, o.Created, ctx.BlockTime()) @@ -526,7 +528,10 @@ func TestInsufficientGas(t *testing.T) { gasMeter := sdk.NewGasMeter(gasPriceNewOrder - 5000) require.Panics(t, func() { - k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) + k.NewOrderSingle( + ctx.WithGasMeter(gasMeter), order1, + types.TxMessageType_AddLimitOrder, + ) }) } @@ -540,18 +545,18 @@ func TestMultipleOrders(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) // Add two orders that draw on the same balance. - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd")) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), types.TxMessageType_AddLimitOrder) require.NoError(t, err) - _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf")) + _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Len(t, k.instruments, 2) - res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur")) + res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur")) + res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -568,7 +573,10 @@ func TestCancelZeroRemainingOrders(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc := createAccount(ctx, ak, bk, randomAddress(), "10000eur") - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc, "10000eur", "11000usd")) + _, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc, "10000eur", "11000usd"), + types.TxMessageType_AddLimitOrder, + ) require.NoError(t, err) err = bk.SendCoins(ctx, acc.GetAddress(), sdk.AccAddress([]byte("void")), coins("10000eur")) @@ -588,7 +596,7 @@ func TestInsufficientBalance1(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "300eur", "360usd") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Modify account balance to be below order source @@ -596,7 +604,7 @@ func TestInsufficientBalance1(t *testing.T) { require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "360usd", "300eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -616,11 +624,11 @@ func Test2(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "121usd", "100eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Empty(t, k.instruments) @@ -638,16 +646,16 @@ func TestAllInstruments(t *testing.T) { acc3 := createAccount(ctx, ak, bk, randomAddress(), "2200chf") // Add two orders that draw on the same balance. - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd")) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), types.TxMessageType_AddLimitOrder) require.NoError(t, err) - _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf")) + _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), types.TxMessageType_AddLimitOrder) require.NoError(t, err) - res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur")) + res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur")) + res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -691,12 +699,12 @@ func Test3(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - k.NewOrderSingle(ctx, o) + k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) gasMeter := sdk.NewGasMeter(math.MaxUint64) for i := 0; i < 4; i++ { o = order(ctx.BlockTime(), acc2, "30usd", "25eur") - k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) + k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) } require.Equal(t, 4*gasPriceNewOrder, gasMeter.GasConsumed()) @@ -717,11 +725,11 @@ func TestDeleteOrder(t *testing.T) { cid := cid() order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), coin("120usd"), acc1.GetAddress(), cid) - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), coin("77chf"), acc1.GetAddress(), cid) - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.Error(t, err) // Verify that client order ids cannot be duplicated. // require.Len(t, k.instruments, 1) // Ensure that the eur->chf pair was not added. @@ -739,13 +747,13 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { for i := 0; i < 5; i++ { order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5eur"), coin("12usd"), acc1.GetAddress(), cid()) - _, err := k.NewOrderSingle(ctx, order) + _, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) require.NoError(t, err) } for i := 0; i < 5; i++ { order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("7usd"), coin("3chf"), acc2.GetAddress(), cid()) - res, err := k.NewOrderSingle(ctx, order) + res, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) } @@ -754,7 +762,7 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { { order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("12usd"), coin("5eur"), acc2.GetAddress(), cid()) - res, err := k.NewOrderSingle(ctx, order) + res, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) } @@ -800,7 +808,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), coin("1200usd"), acc1.GetAddress(), order1cid) - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) gasMeter := sdk.NewGasMeter(math.MaxUint64) @@ -831,7 +839,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -864,7 +872,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { // CancelReplace with an order that asks for a larger source than the replaced order has remaining order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") - k.NewOrderSingle(ctx, order5) + k.NewOrderSingle(ctx, order5, types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") @@ -883,7 +891,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), coin("1200usd"), acc1.GetAddress(), order1cid) - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) gasMeter := sdk.NewGasMeter(math.MaxUint64) @@ -914,7 +922,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -947,7 +955,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { // CancelReplace with an order that asks for a larger source than the replaced order has remaining order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") - k.NewOrderSingle(ctx, order5) + k.NewOrderSingle(ctx, order5, types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") @@ -963,14 +971,14 @@ func TestOrdersChangeWithAccountBalance(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "11000chf,100000eur") order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("1000usd"), acc.GetAddress(), cid()) - _, err := k.NewOrderSingle(ctx, order) + _, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) require.NoError(t, err) { // Partially fill the order above acc2 := createAccount(ctx, ak, bk, randomAddress(), "900000usd") order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("400usd"), coin("4000eur"), acc2.GetAddress(), cid()) - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.NoError(t, err) } @@ -1013,7 +1021,7 @@ func TestUnknownAsset(t *testing.T) { // Make an order with a destination that is not known by the supply module o := order(ctx.BlockTime(), acc1, "1000eur", "1200nok") - _, err := k1.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) + _, err := k1.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) require.True(t, types.ErrUnknownAsset.Is(err)) require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) } @@ -1026,11 +1034,11 @@ func TestLoadFromStore(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "7400usd") o := order(ctx.BlockTime(), acc1, "1000eur", "1200usd") - _, err := k1.NewOrderSingle(ctx, o) + _, err := k1.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "5000usd", "3500chf") - _, err = k1.NewOrderSingle(ctx, o) + _, err = k1.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) _, k2, _, _ := createTestComponents(t) @@ -1054,7 +1062,10 @@ func TestVestingAccount(t *testing.T) { vestingAcc := vestingtypes.NewDelayedVestingAccount(account.(*authtypes.BaseAccount), amount, math.MaxInt64) ak.SetAccount(ctx, vestingAcc) - _, err := keeper.NewOrderSingle(ctx, order(ctx.BlockTime(), vestingAcc, "5000eur", "4700chf")) + _, err := keeper.NewOrderSingle( + ctx, order(ctx.BlockTime(), vestingAcc, "5000eur", "4700chf"), + types.TxMessageType_AddLimitOrder, + ) require.True(t, types.ErrAccountBalanceInsufficient.Is(err)) } @@ -1074,7 +1085,7 @@ func TestInvalidInstrument(t *testing.T) { TimeInForce: types.TimeInForce_GoodTillCancel, } - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.True(t, types.ErrInvalidInstrument.Is(err)) } @@ -1095,38 +1106,38 @@ func TestRestrictedDenominations1(t *testing.T) { { // Verify that acc2 can't create a passive gbp order o := order(ctx.BlockTime(), acc2, "500gbp", "542eur") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Empty(t, k.instruments) o = order(ctx.BlockTime(), acc2, "542usd", "500gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Empty(t, k.instruments) } { // Verify that acc1 can create a passive gbp order o := order(ctx.BlockTime(), acc1, "542eur", "500gbp") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Len(t, k.instruments, 1) o = order(ctx.BlockTime(), acc1, "200gbp", "333usd") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Len(t, k.instruments, 2) } { // Verify that acc2 managed to sell its gbp to a passive order o := order(ctx.BlockTime(), acc2, "500gbp", "542eur") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) balance := bk.GetAllBalances(ctx, acc2.GetAddress()) require.Equal(t, "542", balance.AmountOf("eur").String()) o = order(ctx.BlockTime(), acc2, "333usd", "200gbp") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) balance = bk.GetAllBalances(ctx, acc2.GetAddress()) require.Equal(t, "900", balance.AmountOf("gbp").String()) @@ -1152,13 +1163,13 @@ func TestRestrictedDenominations2(t *testing.T) { gasMeter := sdk.NewGasMeter(math.MaxUint64) // Ensure that no orders can be created, even though acc1 is allowed to create usd orders o := order(ctx.BlockTime(), acc1, "542usd", "500gbp") - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Empty(t, k.instruments) require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) o = order(ctx.BlockTime(), acc1, "500gbp", "542usd") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // require.Empty(t, k.instruments) } @@ -1172,26 +1183,26 @@ func TestSyntheticInstruments1(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "1000eur", "1114usd") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "500eur", "542chf") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc3, "1000chf", "1028usd") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err) gasMeter := sdk.NewGasMeter(math.MaxUint64) o = order(ctx.BlockTime(), acc2, "5000usd", "4485eur") - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) - require.NoError(t, err) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) + require.NoError(t, err, types.TxMessageType_AddLimitOrder) require.Equal(t, gasMeter.GasConsumed(), gasPriceNewOrder) // Matches several orders, but should pay only the fixed fee // Ensure acc2 received at least some euro acc2Balance := bk.GetAllBalances(ctx, acc2.GetAddress()) - require.True(t, acc2Balance.AmountOf("eur").IsPositive()) + require.True(t, acc2Balance.AmountOf("eur").IsPositive(), types.TxMessageType_AddLimitOrder) // Ensure acc2 did not receive any CHF, which is used in the synthetic instrument require.True(t, acc2Balance.AmountOf("chf").IsZero()) @@ -1208,9 +1219,15 @@ func TestNonMatchingOrders(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "100000usd") acc2 := createAccount(ctx, ak, bk, randomAddress(), "240000eur") - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "20000usd", "20000eur")) + _, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "20000usd", "20000eur"), + types.TxMessageType_AddLimitOrder, + ) require.NoError(t, err) - _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "20000eur", "50000usd")) + _, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc2, "20000eur", "50000usd"), + types.TxMessageType_AddLimitOrder, + ) require.NoError(t, err) acc1Orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) @@ -1249,13 +1266,16 @@ func TestSyntheticInstruments2(t *testing.T) { } for _, o := range passiveOrders { - res, err := k.NewOrderSingle(ctx, o) + res, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) require.NoError(t, err, res.Log) } gasMeter := sdk.NewGasMeter(math.MaxUint64) monsterOrder := order(ctx.BlockTime(), acc3, "3700000eur", "4000000usd") - res, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), monsterOrder) + res, err := k.NewOrderSingle( + ctx.WithGasMeter(gasMeter), monsterOrder, + types.TxMessageType_AddLimitOrder, + ) require.NoError(t, err, res.Log) require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) @@ -1279,11 +1299,11 @@ func TestDestinationCapacity(t *testing.T) { order1.SourceFilled = sdk.NewInt(618000000) order1.DestinationFilled = sdk.NewInt(645161290) - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc2, "471096868463eur", "500182000000usd") - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.NoError(t, err) } @@ -1301,15 +1321,15 @@ func TestDestinationCapacity2(t *testing.T) { order1.SourceFilled = sdk.NewInt(618000000) order1.DestinationFilled = sdk.NewInt(645161290) - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc3, "130000000000chf", "800000000usd") - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.NoError(t, err) aggressiveOrder := order(ctx.BlockTime(), acc2, "471096868463eur", "120000000000chf") - _, err = k.NewOrderSingle(ctx, aggressiveOrder) + _, err = k.NewOrderSingle(ctx, aggressiveOrder, types.TxMessageType_AddLimitOrder) require.NoError(t, err) } @@ -1319,17 +1339,17 @@ func TestPreventPhantomLiquidity(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "10000eur") order1 := order(ctx.BlockTime(), acc1, "8000eur", "9000usd") - _, err := k.NewOrderSingle(ctx, order1) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Cannot sell more than the balance in the same instrument order2 := order(ctx.BlockTime(), acc1, "8000eur", "9000usd") - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) require.Error(t, err) // Can sell the balance in another instrument order3 := order(ctx.BlockTime(), acc1, "8000eur", "6000chf") - _, err = k.NewOrderSingle(ctx, order3) + _, err = k.NewOrderSingle(ctx, order3, types.TxMessageType_AddLimitOrder) require.NoError(t, err) } @@ -1358,7 +1378,7 @@ func TestListInstruments(t *testing.T) { ) order := order(ctx.BlockTime(), acc, s, d) - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order, types.TxMessageType_AddLimitOrder) require.NoError(t, err) } } @@ -1435,12 +1455,12 @@ func createTestComponentsWithEncoding(t *testing.T, encConfig simappparams.Encod t.Helper() var ( - keyMarket = sdk.NewKVStoreKey(types.ModuleName) + keyMarket = sdk.NewKVStoreKey(types.StoreKey) keyIndices = sdk.NewKVStoreKey(types.StoreKeyIdx) keyAuthCap = sdk.NewKVStoreKey("authCapKey") - keyParams = sdk.NewKVStoreKey("params") - keyBank = sdk.NewKVStoreKey(banktypes.ModuleName) - tkeyParams = sdk.NewTransientStoreKey("transient_params") + keyParams = sdk.NewKVStoreKey(paramstypes.StoreKey) + keyBank = sdk.NewKVStoreKey(banktypes.StoreKey) + tkeyParams = sdk.NewTransientStoreKey(paramstypes.TStoreKey) blockedAddr = make(map[string]bool) maccPerms = map[string][]string{} @@ -1484,7 +1504,6 @@ func createTestComponentsWithEncoding(t *testing.T, encConfig simappparams.Encod bk.SetSupply(ctx, banktypes.NewSupply(coins("1eur,1usd,1chf,1jpy,1gbp,1ngm"))) - marketKeeper := NewKeeper(encConfig.Marshaler, keyMarket, keyIndices, ak, wrappedBank, dummyAuthority{}) return ctx, marketKeeper, ak, wrappedBank } diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index c0d890eb..3bd6aa38 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -37,7 +37,7 @@ func (m msgServer) AddLimitOrder(c context.Context, msg *types.MsgAddLimitOrder) return nil, err } - result, err := m.k.NewOrderSingle(ctx, order, ) + result, err := m.k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) if err != nil { return nil, err } diff --git a/x/market/keeper/msg_server_test.go b/x/market/keeper/msg_server_test.go index 6da5372e..de8b848c 100644 --- a/x/market/keeper/msg_server_test.go +++ b/x/market/keeper/msg_server_test.go @@ -23,7 +23,7 @@ func TestAddLimitOrder(t *testing.T) { specs := map[string]struct { req *types.MsgAddLimitOrder - mockFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) + mockFn func(ctx sdk.Context, aggressiveOrder types.Order, msgType types.TxMessageType) (*sdk.Result, error) expErr bool expEvents sdk.Events expOrder types.Order @@ -36,7 +36,7 @@ func TestAddLimitOrder(t *testing.T) { Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, - mockFn: func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { + mockFn: func(ctx sdk.Context, aggressiveOrder types.Order, msgType types.TxMessageType) (*sdk.Result, error) { gotOrder = aggressiveOrder return &sdk.Result{ Events: []abcitypes.Event{{ @@ -87,7 +87,7 @@ func TestAddLimitOrder(t *testing.T) { Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, - mockFn: func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { + mockFn: func(ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType) (*sdk.Result, error) { return nil, errors.New("testing") }, expErr: true, @@ -510,7 +510,7 @@ func TestCancelReplaceMarketOrder(t *testing.T) { type marketKeeperMock struct { NewMarketOrderWithSlippageFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) - NewOrderSingleFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) + NewOrderSingleFn func(ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType) (*sdk.Result, error) CancelOrderFn func(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrderFn func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) CancelReplaceMarketOrderFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) @@ -523,11 +523,11 @@ func (m marketKeeperMock) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom s return m.NewMarketOrderWithSlippageFn(ctx, srcDenom, dst, maxSlippage, owner, timeInForce, clientOrderId) } -func (m marketKeeperMock) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { +func (m marketKeeperMock) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order, msgType types.TxMessageType) (*sdk.Result, error) { if m.NewOrderSingleFn == nil { panic("not expected to be called") } - return m.NewOrderSingleFn(ctx, aggressiveOrder) + return m.NewOrderSingleFn(ctx, aggressiveOrder, msgType) } func (m marketKeeperMock) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) { diff --git a/x/market/keeper/querier_test.go b/x/market/keeper/querier_test.go index b68316ce..fd434274 100644 --- a/x/market/keeper/querier_test.go +++ b/x/market/keeper/querier_test.go @@ -25,23 +25,23 @@ func TestQryGetAllInstrumentsWithNonZeroBestPrices(t *testing.T) { // generate passive order o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) // generate passive order o = order(ctx.BlockTime(), acc1, "72eur", "1213jpy") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) // generate passive order of half balances o = order(ctx.BlockTime(), acc1, "72chf", "312usd") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) // Execute an order // fulfilled o = order(ctx.BlockTime(), acc2, "156usd", "36chf") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) { @@ -81,16 +81,28 @@ func TestQryGetAllInstrumentsWithNilBestPrices(t *testing.T) { acc3 := createAccount(ctx, ak, bk, randomAddress(), "2200chf") // generate passive order - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd")) + _, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), + types.TxMessageType_AddMarketOrder, + ) require.NoError(t, err) - _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf")) + _, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), + types.TxMessageType_AddMarketOrder, + ) require.NoError(t, err) - res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur")) + res, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), + types.TxMessageType_AddMarketOrder, + ) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur")) + res, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), + types.TxMessageType_AddMarketOrder, + ) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -136,20 +148,20 @@ func TestQuerier1(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "1000usd") o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - _, err := k.NewOrderSingle(ctx, o) + _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "72eur", "1213jpy") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "72chf", "312usd") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) // Execute an order o = order(ctx.BlockTime(), acc2, "156usd", "36chf") - _, err = k.NewOrderSingle(ctx, o) + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) require.NoError(t, err) { diff --git a/x/market/types/tx_params.go b/x/market/types/tx_params.go index 0e2996b9..6fa223f7 100644 --- a/x/market/types/tx_params.go +++ b/x/market/types/tx_params.go @@ -1,10 +1,10 @@ package types import ( + "errors" "fmt" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/pkg/errors" ) const ( From bbd27af8430700f324dcfd254a426c8cc421eba3 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 14 May 2021 10:35:31 +0300 Subject: [PATCH 11/41] Fix subspace init --- app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.go b/app.go index b526b4be..d2ecfe71 100644 --- a/app.go +++ b/app.go @@ -344,7 +344,7 @@ func NewApp( app.lpKeeper = liquidityprovider.NewKeeper(app.accountKeeper, app.bankKeeper) app.issuerKeeper = issuer.NewKeeper(app.appCodec, keys[issuer.StoreKey], app.lpKeeper, app.inflationKeeper) app.authorityKeeper = authority.NewKeeper(app.appCodec, keys[authority.StoreKey], app.issuerKeeper, app.bankKeeper, app) - app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], keys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper, app.authorityKeeper, app.paramsKeeper.Subspace(market.ModuleName)) + app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], keys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper, app.authorityKeeper, app.GetSubspace(market.ModuleName)) app.buybackKeeper = buyback.NewKeeper(app.appCodec, keys[buyback.StoreKey], app.marketKeeper, app.accountKeeper, app.stakingKeeper, app.bankKeeper) app.bep3Keeper = bep3.NewKeeper(app.appCodec, keys[bep3.StoreKey], app.bankKeeper, app.accountKeeper, app.paramsKeeper.Subspace(bep3.ModuleName), GetMaccs()) From 6862b28137ffd450891aff5157850bd8562c1721 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 14 May 2021 13:37:49 +0300 Subject: [PATCH 12/41] Fix tests --- x/buyback/abci_test.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/x/buyback/abci_test.go b/x/buyback/abci_test.go index 90077c84..1acd89a1 100644 --- a/x/buyback/abci_test.go +++ b/x/buyback/abci_test.go @@ -13,6 +13,7 @@ import ( bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" embank "github.com/e-money/em-ledger/hooks/bank" types2 "github.com/e-money/em-ledger/x/authority/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -141,10 +142,10 @@ func TestBuyback3(t *testing.T) { acc1 = createAccount(ctx, accountKeeper, bankKeeper, randomAddress(), "5000000pesos") acc2 = createAccount(ctx, accountKeeper, bankKeeper, randomAddress(), "10000ungm") ) - _, err := market.NewOrderSingle(ctx, order(acc1, "4000000pesos", "1ungm")) + _, err := market.NewOrderSingle(ctx, order(acc1, "4000000pesos", "1ungm"), types.TxMessageType_AddLimitOrder) require.NoError(t, err) - _, err = market.NewOrderSingle(ctx, order(acc2, "1ungm", "4000000pesos")) + _, err = market.NewOrderSingle(ctx, order(acc2, "1ungm", "4000000pesos"), types.TxMessageType_AddLimitOrder) require.NoError(t, err) // Attempt to create a position using the meager pesos balance of the module @@ -200,10 +201,10 @@ func generateMarketActivity(ctx sdk.Context, marketKeeper *market.Keeper, ak ban acc2 = createAccount(ctx, ak, bk, randomAddress(), "150000eur,290000chf") ) - marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "10000eur")) - marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "20000chf")) - marketKeeper.NewOrderSingle(ctx, order(acc2, "10000eur", "5000ungm")) - marketKeeper.NewOrderSingle(ctx, order(acc2, "20000chf", "5000ungm")) + marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "10000eur"), types.TxMessageType_AddLimitOrder) + marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "20000chf"), types.TxMessageType_AddLimitOrder) + marketKeeper.NewOrderSingle(ctx, order(acc2, "10000eur", "5000ungm"), types.TxMessageType_AddLimitOrder) + marketKeeper.NewOrderSingle(ctx, order(acc2, "20000chf", "5000ungm"), types.TxMessageType_AddLimitOrder) } func order(account authtypes.AccountI, src, dst string) types.Order { @@ -231,7 +232,7 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee encConfig := MakeTestEncodingConfig() var ( - keyMarket = sdk.NewKVStoreKey(types.ModuleName) + keyMarket = sdk.NewKVStoreKey(types.StoreKey) keyIndices = sdk.NewKVStoreKey(types.StoreKeyIdx) authCapKey = sdk.NewKVStoreKey("authCapKey") keyParams = sdk.NewKVStoreKey("params") @@ -239,7 +240,7 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee buybackKey = sdk.NewKVStoreKey("buyback") bankKey = sdk.NewKVStoreKey(banktypes.ModuleName) - tkeyParams = sdk.NewTransientStoreKey("transient_params") + tkeyParams = sdk.NewTransientStoreKey(paramstypes.TStoreKey) blockedAddr = make(map[string]bool) maccPerms = map[string][]string{ @@ -255,6 +256,7 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee ms.MountStoreWithDB(keyIndices, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(buybackKey, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) err := ms.LoadLatestVersion() require.Nil(t, err) @@ -276,7 +278,10 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee initialSupply := coins(fmt.Sprintf("1000000eur,1000000usd,1000000chf,1000000jpy,1000000gbp,1000000%v,500000000pesos", stakingDenom)) bk.SetSupply(ctx, banktypes.NewSupply(initialSupply)) - marketKeeper := market.NewKeeper(encConfig.Marshaler, keyMarket, keyIndices, ak, bk, mockAuthority{}) + marketKeeper := market.NewKeeper( + encConfig.Marshaler, keyMarket, keyIndices, ak, bk, mockAuthority{}, + pk.Subspace(types.ModuleName), + ) keeper := NewKeeper(encConfig.Marshaler, buybackKey, marketKeeper, ak, mockStakingKeeper{}, bk) keeper.SetUpdateInterval(ctx, time.Hour) From 1621211783e7a571176661190853bdb41d4bfddb Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 14 May 2021 13:53:51 +0300 Subject: [PATCH 13/41] Add validation --- x/market/types/tx_params.go | 7 +++++++ x/market/types/tx_params_test.go | 2 ++ 2 files changed, 9 insertions(+) diff --git a/x/market/types/tx_params.go b/x/market/types/tx_params.go index 6fa223f7..d62b858b 100644 --- a/x/market/types/tx_params.go +++ b/x/market/types/tx_params.go @@ -70,6 +70,13 @@ func (p TxParams) Validate() error { return err } + if p.TrxFee < p.LiquidTrxFee { + return fmt.Errorf( + "standard fee:%d is less than liquid trx fee:%d", p.TrxFee, + p.LiquidTrxFee, + ) + } + return validateTimeSpan(p.LiquidityRebateMinutesSpan) } diff --git a/x/market/types/tx_params_test.go b/x/market/types/tx_params_test.go index 87499f90..960ead32 100644 --- a/x/market/types/tx_params_test.go +++ b/x/market/types/tx_params_test.go @@ -24,6 +24,8 @@ func Test_ParamsEqual(t *testing.T) { func TestValidateParams(t *testing.T) { require.NoError(t, DefaultTxParams().Validate()) require.NoError(t, NewTxParams(1, 0, 5).Validate()) + require.NoError(t, NewTxParams(1, 1, 5).Validate()) + require.Error(t, NewTxParams(1, 2, 5).Validate()) require.Error(t, NewTxParams(0, 0, 5).Validate()) require.Error(t, NewTxParams(0, 0, -1).Validate()) } \ No newline at end of file From 504821bbc7b6b5a4447f2077d126280d82ea287d Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 14 May 2021 16:57:37 +0300 Subject: [PATCH 14/41] Add Implementation --- x/market/keeper/keeper.go | 164 ++++++++++++++++++++++++++++----- x/market/keeper/keeper_test.go | 1 + 2 files changed, 141 insertions(+), 24 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 9d7fce83..d1dc07b3 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -134,42 +134,129 @@ func (k *Keeper) createExecutionPlan(ctx sdk.Context, SourceDenom, DestinationDe } func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { + return k.createMarketOrder( + ctx, + srcDenom, + dst, + maxSlippage, + owner, + timeInForce, + clientOrderId, + types.TxMessageType_AddMarketOrder, + ) +} + +// createMarketOrder creates a new market order by setting the message type +// whether it is a new (Add) or replacement. +func (k *Keeper) createMarketOrder( + ctx sdk.Context, + srcDenom string, dst sdk.Coin, + maxSlippage sdk.Dec, + owner sdk.AccAddress, + timeInForce types.TimeInForce, + clientOrderId string, + msgType types.TxMessageType, +) (*sdk.Result, error) { // If the order allows for slippage, adjust the source amount accordingly. md := k.GetInstrument(ctx, srcDenom, dst.Denom) if md == nil || md.LastPrice == nil { - return nil, sdkerrors.Wrapf(types.ErrNoMarketDataAvailable, "%v/%v", srcDenom, dst.Denom) + return nil, sdkerrors.Wrapf( + types.ErrNoMarketDataAvailable, "%v/%v", srcDenom, dst.Denom, + ) } source := dst.Amount.ToDec().Quo(*md.LastPrice) source = source.Mul(sdk.NewDec(1).Add(maxSlippage)) slippageSource := sdk.NewCoin(srcDenom, source.RoundInt()) - order, err := types.NewOrder(ctx.BlockTime(), timeInForce, slippageSource, dst, owner, clientOrderId) + order, err := types.NewOrder( + ctx.BlockTime(), timeInForce, slippageSource, dst, owner, clientOrderId, + ) if err != nil { return nil, err } - // treat ReplaceMarketOrder and AddMarketOrders costing same gas - return k.NewOrderSingle(ctx, order, types.TxMessageType_AddMarketOrder) + return k.NewOrderSingle(ctx, order, msgType) +} + +func calcRebate(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { + if dstFilled.Equal(sdk.ZeroInt()) { + // 0% fill -> 100% rebate + return liquidFee + } + + // remaining / total amount => % + rebatePct := dstAmount.Sub(dstFilled).ToDec().Quo(dstAmount.ToDec()) + + // rebate amount = Std fee - Liquid fee(likely 0) + rebate := sdk.NewIntFromUint64(stdFee).Sub(sdk.NewIntFromUint64(liquidFee)) + + return rebatePct.Mul(rebate.ToDec()).RoundInt().Uint64() +} + +func (k *Keeper) calcOrderGas( + ctx sdk.Context, dstFilled, dstAmount sdk.Int, + messageType types.TxMessageType, lastOrderTm time.Time, +) sdk.Gas { + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + // Standard trx fee + if messageType == types.TxMessageType_CancelOrder { + return stdTrxFee + } + + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyTrxFee, &qualificationMin) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + switch messageType { + case types.TxMessageType_AddLimitOrder, + types.TxMessageType_AddMarketOrder: + + return calcRebate(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) + + case types.TxMessageType_CancelReplaceLimitOrder, + types.TxMessageType_CancelReplaceMarketOrder: + + if lastOrderTm.Equal(time.Unix(0, 0)) || + ctx.BlockTime().Sub(lastOrderTm).Minutes() >= float64(qualificationMin) { + return calcRebate(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) + } + + default: + // mis/uncategorized trx + return stdTrxFee + } + + return stdTrxFee } -func postOrder( +func (k *Keeper) SpendNewOrderGas( + ctx sdk.Context, orderGasMeter sdk.GasMeter, owner sdk.AccAddress, + order types.Order, messageType types.TxMessageType, +) { + orderGas := k.calcOrderGas( + ctx, order.DestinationFilled, order.Destination.Amount, messageType, + time.Time{}, + ) + orderGasMeter.ConsumeGas(orderGas, messageType.String()) +} + +func (k *Keeper) postOrder( ctx sdk.Context, + orderGasMeter sdk.GasMeter, + owner sdk.AccAddress, order types.Order, messageType types.TxMessageType, commitTrade func(), ) { - // recover -> save recError - - // if !rebate applies - // Use a fixed gas amount - ctx.GasMeter().ConsumeGas(gasPriceNewOrder, "NewOrderSingle") - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - - // else !rebate applies and out of gas error - // panic(recError) + if messageType != types.TxMessageType_AddLimitOrder && + messageType != types.TxMessageType_CancelReplaceMarketOrder { - // else apply full or partial rebate - // check partial rebate and whether panic still applied + k.SpendNewOrderGas(ctx, orderGasMeter, owner, order, messageType) + } // Roll back any state changes made by the aggressive FillOrKill order. if order.TimeInForce == types.TimeInForce_FillOrKill { @@ -184,7 +271,16 @@ func (k *Keeper) NewOrderSingle( ) (*sdk.Result, error) { ctx, commitTrade := ctx.CacheContext() - defer postOrder(ctx, aggressiveOrder, messageType, commitTrade) + trxGasMeter := ctx.GasMeter() + // impostor meter that would not panic + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + + owner, err := sdk.AccAddressFromBech32(aggressiveOrder.Owner) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") + } + + defer k.postOrder(ctx, trxGasMeter, owner, aggressiveOrder, messageType, commitTrade) if err := aggressiveOrder.IsValid(); err != nil { return nil, err @@ -194,10 +290,6 @@ func (k *Keeper) NewOrderSingle( return nil, sdkerrors.Wrapf(types.ErrInvalidPrice, "Order price is invalid: %s -> %s", aggressiveOrder.Source, aggressiveOrder.Destination) } - owner, err := sdk.AccAddressFromBech32(aggressiveOrder.Owner) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") - } spendableCoins := k.bk.SpendableCoins(ctx, owner) // Verify account balance @@ -445,11 +537,21 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, newOrder.TimeInForce = origOrder.TimeInForce + orderGasMeter := ctx.GasMeter() + resAdd, err := k.NewOrderSingle(ctx, newOrder, types.TxMessageType_CancelReplaceLimitOrder) if err != nil { return nil, err } + orderGas := k.calcOrderGas( + ctx, newOrder.DestinationFilled, newOrder.Destination.Amount, + types.TxMessageType_CancelReplaceLimitOrder, + origOrder.Created, + ) + + orderGasMeter.ConsumeGas(orderGas, types.TxMessageType_CancelReplaceLimitOrder.String()) + evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) return &sdk.Result{Events: evts}, nil } @@ -496,14 +598,28 @@ func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelR dstRemaining := msg.Destination.Amount.Sub(destinationFilled) remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) - resAdd, err := k.NewMarketOrderWithSlippage( - ctx, msg.Source, remDstCoin, msg.MaxSlippage, ownerAddr, - msg.TimeInForce, msg.NewClientOrderId, + orderGasMeter := ctx.GasMeter() + + resAdd, err := k.createMarketOrder( + ctx, + msg.Source, + remDstCoin, + msg.MaxSlippage, + ownerAddr, + msg.TimeInForce, + msg.NewClientOrderId, + types.TxMessageType_CancelReplaceMarketOrder, ) if err != nil { return nil, err } + orderGas := k.calcOrderGas( + ctx, destinationFilled, msg.Destination.Amount, types.TxMessageType_CancelReplaceMarketOrder, + origOrder.Created, + ) + orderGasMeter.ConsumeGas(orderGas, types.TxMessageType_CancelReplaceMarketOrder.String()) + evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) return &sdk.Result{Events: evts}, nil diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 9aab2555..311b2bf5 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -1042,6 +1042,7 @@ func TestLoadFromStore(t *testing.T) { require.NoError(t, err) _, k2, _, _ := createTestComponents(t) + k2.paramStore = k1.paramStore k2.key = k1.key // Create new keeper and let it inherit the store of the previous keeper From f9c6aa5800f9a9791e49c19140e28d3f39a800b0 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Sat, 15 May 2021 17:12:18 +0300 Subject: [PATCH 15/41] Add liquid tests, fixes --- x/market/keeper/keeper.go | 96 +++++++++++++++--------- x/market/keeper/keeper_test.go | 131 +++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+), 36 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index d1dc07b3..21a5d9bd 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -180,6 +180,8 @@ func (k *Keeper) createMarketOrder( } func calcRebate(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { + // TODO is destination sufficient to evaluate the total filling impact + // for limit/market orders? if dstFilled.Equal(sdk.ZeroInt()) { // 0% fill -> 100% rebate return liquidFee @@ -194,68 +196,86 @@ func calcRebate(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas return rebatePct.Mul(rebate.ToDec()).RoundInt().Uint64() } -func (k *Keeper) calcOrderGas( +func (k *Keeper) calcReplacementGas( ctx sdk.Context, dstFilled, dstAmount sdk.Int, messageType types.TxMessageType, lastOrderTm time.Time, ) sdk.Gas { var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - // Standard trx fee - if messageType == types.TxMessageType_CancelOrder { - return stdTrxFee - } - - var qualificationMin int64 - k.paramStore.Get(ctx, types.KeyTrxFee, &qualificationMin) - var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) switch messageType { - case types.TxMessageType_AddLimitOrder, - types.TxMessageType_AddMarketOrder: - - return calcRebate(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) - case types.TxMessageType_CancelReplaceLimitOrder, types.TxMessageType_CancelReplaceMarketOrder: + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + + lastOrderTmMinutes := ctx.BlockTime().Sub(lastOrderTm).Minutes() + if lastOrderTm.Equal(time.Unix(0, 0)) || - ctx.BlockTime().Sub(lastOrderTm).Minutes() >= float64(qualificationMin) { + lastOrderTmMinutes >= float64(qualificationMin) { return calcRebate(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) } + } - default: - // mis/uncategorized trx + // mis/uncategorized trx + return stdTrxFee +} + +// calcNewOrderGas applies to New orders. +func (k *Keeper) calcNewOrderGas( + ctx sdk.Context, + order types.Order, + messageType types.TxMessageType, +) sdk.Gas { + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + if order.IsFilled() { return stdTrxFee } + switch messageType { + case types.TxMessageType_AddLimitOrder, + types.TxMessageType_AddMarketOrder: + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + return calcRebate(order.DestinationFilled, order.Destination.Amount, + stdTrxFee, liquidTrxFee) + } + + // mis/uncategorized trx return stdTrxFee } +// SpendNewOrderGas applies to Cancel, New non-replacement orders. func (k *Keeper) SpendNewOrderGas( - ctx sdk.Context, orderGasMeter sdk.GasMeter, owner sdk.AccAddress, - order types.Order, messageType types.TxMessageType, + ctx sdk.Context, + orderGasMeter sdk.GasMeter, + order types.Order, + messageType types.TxMessageType, ) { - orderGas := k.calcOrderGas( - ctx, order.DestinationFilled, order.Destination.Amount, messageType, - time.Time{}, - ) + orderGas := k.calcNewOrderGas(ctx, order, messageType) orderGasMeter.ConsumeGas(orderGas, messageType.String()) } +// postOrder does not affect replacement orders' gas consumption. func (k *Keeper) postOrder( ctx sdk.Context, orderGasMeter sdk.GasMeter, - owner sdk.AccAddress, order types.Order, messageType types.TxMessageType, commitTrade func(), ) { - if messageType != types.TxMessageType_AddLimitOrder && + if messageType != types.TxMessageType_CancelReplaceLimitOrder && messageType != types.TxMessageType_CancelReplaceMarketOrder { - k.SpendNewOrderGas(ctx, orderGasMeter, owner, order, messageType) + // Cancel && New Orders + k.SpendNewOrderGas(ctx, orderGasMeter, order, messageType) } // Roll back any state changes made by the aggressive FillOrKill order. @@ -275,12 +295,7 @@ func (k *Keeper) NewOrderSingle( // impostor meter that would not panic ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - owner, err := sdk.AccAddressFromBech32(aggressiveOrder.Owner) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") - } - - defer k.postOrder(ctx, trxGasMeter, owner, aggressiveOrder, messageType, commitTrade) + defer k.postOrder(ctx, trxGasMeter, aggressiveOrder, messageType, commitTrade) if err := aggressiveOrder.IsValid(); err != nil { return nil, err @@ -290,6 +305,10 @@ func (k *Keeper) NewOrderSingle( return nil, sdkerrors.Wrapf(types.ErrInvalidPrice, "Order price is invalid: %s -> %s", aggressiveOrder.Source, aggressiveOrder.Destination) } + owner, err := sdk.AccAddressFromBech32(aggressiveOrder.Owner) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") + } spendableCoins := k.bk.SpendableCoins(ctx, owner) // Verify account balance @@ -544,7 +563,7 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, return nil, err } - orderGas := k.calcOrderGas( + orderGas := k.calcReplacementGas( ctx, newOrder.DestinationFilled, newOrder.Destination.Amount, types.TxMessageType_CancelReplaceLimitOrder, origOrder.Created, @@ -614,7 +633,7 @@ func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelR return nil, err } - orderGas := k.calcOrderGas( + orderGas := k.calcReplacementGas( ctx, destinationFilled, msg.Destination.Amount, types.TxMessageType_CancelReplaceMarketOrder, origOrder.Created, ) @@ -645,10 +664,15 @@ func (k *Keeper) GetOrderByOwnerAndClientOrderId(ctx sdk.Context, owner, clientO } func (k *Keeper) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) { - // Use a fixed gas amount - ctx.GasMeter().ConsumeGas(gasPriceCancelOrder, "CancelOrder") + trxGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + // Use a fixed gas amount + trxGasMeter.ConsumeGas(stdTrxFee, "CancelOrder") + // orders := k.accountOrders.GetAllOrders(owner) order := k.GetOrderByOwnerAndClientOrderId(ctx, owner.String(), clientOrderId) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 311b2bf5..8d8f1d57 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -535,6 +535,137 @@ func TestInsufficientGas(t *testing.T) { }) } +func TestLiquidNewLimit0Gas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + src1, dst1 := "eur", "usd" + order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, + types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) +} + +func TestLiquidNewMarket0Gas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + order1 := order(ctx.BlockTime(), acc1, "100gbp", "120eur") + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, + types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + order2 := order(ctx.BlockTime(), acc2, "120eur", "100gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2, + types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + slippage := sdk.NewDecWithPrec(50, 2) + cid := cid() + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(200)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + cid, + ) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) +} + +func TestCancelNewLimitFullGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + src1, dst1 := "eur", "usd" + order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, + types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + order := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, order, 1) + + cid := order[0].ClientOrderID + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + _, err = k.CancelOrder(ctx, acc1.GetAddress(), cid) + require.NoError(t, err) + require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) +} + +func TestCancelNewMarketFullGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + order1 := order(ctx.BlockTime(), acc1, "100gbp", "120eur") + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, + types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + order2 := order(ctx.BlockTime(), acc2, "120eur", "100gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2, + types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + slippage := sdk.NewDecWithPrec(50, 2) + cid := cid() + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(200)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + cid, + ) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + _, err = k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), cid) + require.NoError(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) +} + func TestMultipleOrders(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) From bd9a33f792a9eb3ccf1b2adcc2209e4c7517e2ae Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Sun, 16 May 2021 14:34:44 +0300 Subject: [PATCH 16/41] Fix test, refactor, documentation. --- x/market/keeper/keeper.go | 52 ++++++++++++++++------------------ x/market/keeper/keeper_test.go | 8 +++++- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 21a5d9bd..8afbda97 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -146,8 +146,8 @@ func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, ds ) } -// createMarketOrder creates a new market order by setting the message type -// whether it is a new (Add) or replacement. +// createMarketOrder creates a new market order allowing to set the message type +// to new (Add) or Replacement. func (k *Keeper) createMarketOrder( ctx sdk.Context, srcDenom string, dst sdk.Coin, @@ -179,7 +179,11 @@ func (k *Keeper) createMarketOrder( return k.NewOrderSingle(ctx, order, msgType) } -func calcRebate(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { +// getOrderGas calculates the gas for an order. The liquid fee applies to liquid +// unfilled orders. If an order is not liquid the full fee applies. If filled +// partially then the difference between the full fee - liquid fee is applied +// proportionally. +func getOrderGas(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { // TODO is destination sufficient to evaluate the total filling impact // for limit/market orders? if dstFilled.Equal(sdk.ZeroInt()) { @@ -196,7 +200,7 @@ func calcRebate(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas return rebatePct.Mul(rebate.ToDec()).RoundInt().Uint64() } -func (k *Keeper) calcReplacementGas( +func (k *Keeper) getReplacedOrderGas( ctx sdk.Context, dstFilled, dstAmount sdk.Int, messageType types.TxMessageType, lastOrderTm time.Time, ) sdk.Gas { @@ -217,7 +221,7 @@ func (k *Keeper) calcReplacementGas( if lastOrderTm.Equal(time.Unix(0, 0)) || lastOrderTmMinutes >= float64(qualificationMin) { - return calcRebate(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) + return getOrderGas(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) } } @@ -225,10 +229,9 @@ func (k *Keeper) calcReplacementGas( return stdTrxFee } -// calcNewOrderGas applies to New orders. -func (k *Keeper) calcNewOrderGas( +func (k *Keeper) getNewOrderGas( ctx sdk.Context, - order types.Order, + order *types.Order, messageType types.TxMessageType, ) sdk.Gas { var stdTrxFee uint64 @@ -245,7 +248,7 @@ func (k *Keeper) calcNewOrderGas( var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - return calcRebate(order.DestinationFilled, order.Destination.Amount, + return getOrderGas(order.DestinationFilled, order.Destination.Amount, stdTrxFee, liquidTrxFee) } @@ -253,29 +256,20 @@ func (k *Keeper) calcNewOrderGas( return stdTrxFee } -// SpendNewOrderGas applies to Cancel, New non-replacement orders. -func (k *Keeper) SpendNewOrderGas( +// postNewOrderSingle spends gas on new orders and adds non-fill-or-kill orders to the +// order-book. +func (k *Keeper) postNewOrderSingle( ctx sdk.Context, orderGasMeter sdk.GasMeter, - order types.Order, - messageType types.TxMessageType, -) { - orderGas := k.calcNewOrderGas(ctx, order, messageType) - orderGasMeter.ConsumeGas(orderGas, messageType.String()) -} - -// postOrder does not affect replacement orders' gas consumption. -func (k *Keeper) postOrder( - ctx sdk.Context, - orderGasMeter sdk.GasMeter, - order types.Order, + order *types.Order, messageType types.TxMessageType, commitTrade func(), ) { if messageType != types.TxMessageType_CancelReplaceLimitOrder && messageType != types.TxMessageType_CancelReplaceMarketOrder { - // Cancel && New Orders - k.SpendNewOrderGas(ctx, orderGasMeter, order, messageType) + // New Orders + orderGas := k.getNewOrderGas(ctx, order, messageType) + orderGasMeter.ConsumeGas(orderGas, messageType.String()) } // Roll back any state changes made by the aggressive FillOrKill order. @@ -295,7 +289,9 @@ func (k *Keeper) NewOrderSingle( // impostor meter that would not panic ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - defer k.postOrder(ctx, trxGasMeter, aggressiveOrder, messageType, commitTrade) + defer k.postNewOrderSingle( + ctx, trxGasMeter, &aggressiveOrder, messageType, commitTrade, + ) if err := aggressiveOrder.IsValid(); err != nil { return nil, err @@ -563,7 +559,7 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, return nil, err } - orderGas := k.calcReplacementGas( + orderGas := k.getReplacedOrderGas( ctx, newOrder.DestinationFilled, newOrder.Destination.Amount, types.TxMessageType_CancelReplaceLimitOrder, origOrder.Created, @@ -633,7 +629,7 @@ func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelR return nil, err } - orderGas := k.calcReplacementGas( + orderGas := k.getReplacedOrderGas( ctx, destinationFilled, msg.Destination.Amount, types.TxMessageType_CancelReplaceMarketOrder, origOrder.Created, ) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 8d8f1d57..a81002dd 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -527,9 +527,15 @@ func TestInsufficientGas(t *testing.T) { gasMeter := sdk.NewGasMeter(gasPriceNewOrder - 5000) + _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + + acc2 := createAccount(ctx, ak, bk, randomAddress(), "1121usd") + order2 := order(ctx.BlockTime(), acc2, "1121usd", "888eur") + require.Panics(t, func() { k.NewOrderSingle( - ctx.WithGasMeter(gasMeter), order1, + ctx.WithGasMeter(gasMeter), order2, types.TxMessageType_AddLimitOrder, ) }) From e0f74cccb587e1ee0a30edfe54204a2b2621aedc Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Sun, 16 May 2021 23:42:24 +0300 Subject: [PATCH 17/41] Test, Fix Cancel, Replacement orders --- x/market/keeper/keeper.go | 58 +++++++----- x/market/keeper/keeper_test.go | 162 +++++++++++++++++++++++++++++++-- 2 files changed, 187 insertions(+), 33 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 8afbda97..44ee3ee7 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -179,11 +179,11 @@ func (k *Keeper) createMarketOrder( return k.NewOrderSingle(ctx, order, msgType) } -// getOrderGas calculates the gas for an order. The liquid fee applies to liquid -// unfilled orders. If an order is not liquid the full fee applies. If filled -// partially then the difference between the full fee - liquid fee is applied -// proportionally. -func getOrderGas(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { +// calcOrderGas calculates the gas for an order. The liquid fee applies to +// liquid unfilled orders. If an order is not liquid the full fee applies. If +// filled partially then the difference between the full fee - liquid fee is +// applied proportionally. +func calcOrderGas(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { // TODO is destination sufficient to evaluate the total filling impact // for limit/market orders? if dstFilled.Equal(sdk.ZeroInt()) { @@ -217,11 +217,11 @@ func (k *Keeper) getReplacedOrderGas( var qualificationMin int64 k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) - lastOrderTmMinutes := ctx.BlockTime().Sub(lastOrderTm).Minutes() - - if lastOrderTm.Equal(time.Unix(0, 0)) || - lastOrderTmMinutes >= float64(qualificationMin) { - return getOrderGas(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) + // check at least LiquidityRebateMinutesSpan elapsed from replaced + // order + if lastOrderTm.IsZero() || + ctx.BlockTime().Sub(lastOrderTm).Minutes() >= float64(qualificationMin) { + return calcOrderGas(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) } } @@ -248,7 +248,7 @@ func (k *Keeper) getNewOrderGas( var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - return getOrderGas(order.DestinationFilled, order.Destination.Amount, + return calcOrderGas(order.DestinationFilled, order.Destination.Amount, stdTrxFee, liquidTrxFee) } @@ -521,11 +521,22 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { return total.AmountOf(asset.Denom).GT(sdk.ZeroInt()) } +func postReplaceOrder(orderGasMeter sdk.GasMeter, gas *sdk.Gas, desc string) { + + orderGasMeter.ConsumeGas(*gas, desc) +} + func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { - // Use a fixed gas amount - ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, "CancelReplaceLimitOrder") + orderGasMeter := ctx.GasMeter() + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + desc := types.TxMessageType_CancelReplaceMarketOrder.String() + orderGas := new(sdk.Gas) + k.paramStore.Get(ctx, types.KeyTrxFee, orderGas) + + defer postReplaceOrder(orderGasMeter, orderGas, desc) + origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, newOrder.Owner, origClientOrderId) if origOrder == nil { @@ -552,30 +563,32 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, newOrder.TimeInForce = origOrder.TimeInForce - orderGasMeter := ctx.GasMeter() - resAdd, err := k.NewOrderSingle(ctx, newOrder, types.TxMessageType_CancelReplaceLimitOrder) if err != nil { return nil, err } - orderGas := k.getReplacedOrderGas( + *orderGas = k.getReplacedOrderGas( ctx, newOrder.DestinationFilled, newOrder.Destination.Amount, types.TxMessageType_CancelReplaceLimitOrder, origOrder.Created, ) - orderGasMeter.ConsumeGas(orderGas, types.TxMessageType_CancelReplaceLimitOrder.String()) - evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) return &sdk.Result{Events: evts}, nil } func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { - // Use a fixed gas amount - ctx.GasMeter().ConsumeGas(gasPriceCancelReplaceOrder, "CancelReplaceMarketOrder") + orderGasMeter := ctx.GasMeter() + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + desc := types.TxMessageType_CancelReplaceMarketOrder.String() + orderGas := new(sdk.Gas) + k.paramStore.Get(ctx, types.KeyTrxFee, orderGas) + + defer postReplaceOrder(orderGasMeter, orderGas, desc) + origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) if origOrder == nil { @@ -613,8 +626,6 @@ func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelR dstRemaining := msg.Destination.Amount.Sub(destinationFilled) remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) - orderGasMeter := ctx.GasMeter() - resAdd, err := k.createMarketOrder( ctx, msg.Source, @@ -629,11 +640,10 @@ func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelR return nil, err } - orderGas := k.getReplacedOrderGas( + *orderGas = k.getReplacedOrderGas( ctx, destinationFilled, msg.Destination.Amount, types.TxMessageType_CancelReplaceMarketOrder, origOrder.Created, ) - orderGasMeter.ConsumeGas(orderGas, types.TxMessageType_CancelReplaceMarketOrder.String()) evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index a81002dd..465a56b6 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -281,8 +281,16 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { Destination: sdk.NewCoin("eur", sdk.NewInt(100)), MaxSlippage: sdk.NewDecWithPrec(0, 2), } + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + gasMeter := sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) _, err = k.CancelReplaceMarketOrder(ctx, mcrm) require.NoError(t, err) + t.Log(ctx.GasMeter().String()) + require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) expOrder := &types.Order{ ID: 3, @@ -402,6 +410,92 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { require.Equal(t, coins("20eur,90gbp").String(), acc1Bal.String()) } +func TestCancelReplaceMarketOrder0GasFee(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "100gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "100eur") + + var o types.Order + var err error + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + gasMeter := sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + + // Establish market price by executing a 2:1 trade + o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed(), "Liquid Trx are discounted") + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + + o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") + _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + require.NoError(t, err) + require.Equalf( + t, stdTrxFee, ctx.GasMeter().GasConsumed(), "Filled order costs std fee", + ) + + acc1b := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("20eur,90gbp").String(), acc1b.String()) + + // Make a market order that allows slippage + clientID := cid() + slippage := sdk.NewDecWithPrec(0, 2) + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(10)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + clientID, + ) + require.NoError(t, err) + acc1b = bk.GetAllBalances(ctx, acc1.GetAddress()) + + foundOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), clientID, + ) + require.NotNil(t, foundOrder, "Market order should exist") + // 0% slippage same as ratio (1eur/2gbp) * 10 => 5gbp + require.True(t, foundOrder.Source.IsEqual(sdk.NewCoin("gbp", sdk.NewInt(5)))) + + newClientID := cid() + mcrm := &types.MsgCancelReplaceMarketOrder{ + Owner: acc1.GetAddress().String(), + OrigClientOrderId: clientID, + NewClientOrderId: newClientID, + TimeInForce: types.TimeInForce_GoodTillCancel, + Source: "gbp", + Destination: sdk.NewCoin("eur", sdk.NewInt(10)), + MaxSlippage: sdk.NewDecWithPrec(100, 2), + } + + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + + _, err = k.CancelReplaceMarketOrder( + ctx.WithGasMeter(gasMeter).WithBlockTime( + ctx.BlockTime(). + Add(time.Duration(qualificationMin)*time.Minute), + ), mcrm, + ) + require.NoError(t, err) + require.Equalf(t, liquidTrxFee, ctx.GasMeter().GasConsumed(), "Not filled and liquid are discounted") +} + func TestFillOrKillMarketOrder1(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) @@ -525,15 +619,21 @@ func TestInsufficientGas(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "888eur") order1 := order(ctx.BlockTime(), acc1, "888eur", "1121usd") - gasMeter := sdk.NewGasMeter(gasPriceNewOrder - 5000) - + // Free: it adds liquidity _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) acc2 := createAccount(ctx, ak, bk, randomAddress(), "1121usd") order2 := order(ctx.BlockTime(), acc2, "1121usd", "888eur") + var fullTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &fullTrxFee) + + // bummer missing 1 micro + gasMeter := sdk.NewGasMeter(fullTrxFee - 1) + require.Panics(t, func() { + // Taking away liquidity not enough to cover the full Trx fee k.NewOrderSingle( ctx.WithGasMeter(gasMeter), order2, types.TxMessageType_AddLimitOrder, @@ -906,15 +1006,19 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { allOrders2 := k.GetOrdersByOwner(ctx, acc1.GetAddress()) require.Len(t, allOrders2, 4) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + cid := allOrders2[2].ClientOrderID gasMeter := sdk.NewGasMeter(math.MaxUint64) _, err := k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), cid) require.NoError(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) _, err = k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), cid) require.Error(t, err) - require.Equal(t, 2*gasPriceCancelOrder, gasMeter.GasConsumed()) + require.Equal(t, 2*stdTrxFee, gasMeter.GasConsumed()) allOrders3 := k.GetOrdersByOwner(ctx, acc1.GetAddress()) require.Len(t, allOrders3, 3) @@ -932,8 +1036,15 @@ func TestCancelOrders1(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc := createAccount(ctx, ak, bk, randomAddress(), "100eur") - _, err := k.CancelOrder(ctx, acc.GetAddress(), "abcde") + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + gasMeter := sdk.NewInfiniteGasMeter() + _, err := k.CancelOrder( + ctx.WithGasMeter(gasMeter), acc.GetAddress(), "abcde", + ) require.Error(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) } func TestKeeperCancelReplaceLimitOrder(t *testing.T) { @@ -948,12 +1059,15 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) require.NoError(t, err) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) order2cid := cid() order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), coin("17000usd"), acc1.GetAddress(), order2cid) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) - require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) { orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) @@ -973,7 +1087,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { gasMeter = sdk.NewGasMeter(math.MaxUint64) _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) require.True(t, types.ErrOrderInstrumentChanged.Is(err)) - require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) @@ -992,11 +1106,31 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { filled = orders[0].Source.Amount.Sub(orders[0].SourceRemaining) } + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + // CancelReplace and verify that previously filled amount is subtracted from the resulting order order4cid := cid() + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) order4, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("35050usd"), acc1.GetAddress(), order4cid) - res, err = k.CancelReplaceLimitOrder(ctx, order4, order2cid) + res, err = k.CancelReplaceLimitOrder( + ctx.WithBlockTime(ctx.BlockTime().Add( + time.Duration(qualificationMin)*time.Minute)), + order4, order2cid, + ) require.True(t, err == nil, res.Log) + require.Lessf( + t, gasMeter.GasConsumed(), stdTrxFee, + "Gas consumed for partial filled should be less than stdTrxFee", + ) + require.Greaterf( + t, gasMeter.GasConsumed(), liquidTrxFee, + "Gas consumed should filled should be greater than LiquidTrxFee", + ) { orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) @@ -1009,12 +1143,22 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { // CancelReplace with an order that asks for a larger source than the replaced order has remaining order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") - k.NewOrderSingle(ctx, order5, types.TxMessageType_AddLimitOrder) + res, err = k.NewOrderSingle(ctx, order5, types.TxMessageType_AddLimitOrder) require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") - _, err = k.CancelReplaceLimitOrder(ctx, order6, order4cid) + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + _, err = k.CancelReplaceLimitOrder( + ctx.WithBlockTime(ctx.BlockTime().Add( + time.Duration(qualificationMin)*time.Minute)), + order6, order4cid, + ) require.True(t, types.ErrNoSourceRemaining.Is(err)) + require.Equalf( + t, stdTrxFee, gasMeter.GasConsumed(), + "Erred orders should incur full fees", + ) require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) } From 7e0c45daa83baf0c26abf36ec50dc29a96e70ddf Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Mon, 17 May 2021 23:46:14 +0300 Subject: [PATCH 18/41] Refactor --- docs/proto/em/proto-docs.md | 21 +- proto/em/market/v1/market.proto | 8 + proto/em/market/v1/tx.proto | 29 +- x/buyback/abci.go | 10 +- x/buyback/abci_test.go | 17 +- x/buyback/internal/keeper/expected_keepers.go | 2 +- x/buyback/internal/keeper/keeper.go | 2 +- x/market/keeper/grpc_query_test.go | 12 +- x/market/keeper/keeper.go | 256 ++++++------ x/market/keeper/keeper_fuzzing_test.go | 2 +- x/market/keeper/keeper_test.go | 365 +++++++++++------- x/market/keeper/msg_server.go | 16 +- x/market/keeper/msg_server_test.go | 12 +- x/market/keeper/querier_test.go | 20 +- x/market/types/market.pb.go | 179 ++++++--- x/market/types/tx.pb.go | 271 ++++++------- x/market/types/types.go | 12 +- x/market/types/types_test.go | 26 +- 18 files changed, 680 insertions(+), 580 deletions(-) diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index a7719189..d71dcae2 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -124,8 +124,6 @@ - [MsgCancelReplaceMarketOrderResponse](#em.market.v1.MsgCancelReplaceMarketOrderResponse) - [TxParams](#em.market.v1.TxParams) - - [TxMessageType](#em.market.v1.TxMessageType) - - [Msg](#em.market.v1.Msg) - [em/queries/v1/query.proto](#em/queries/v1/query.proto) @@ -1125,6 +1123,7 @@ | `destination` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | | | `destination_filled` | [string](#string) | | | | `created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | | +| `orig_order_created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | applicable to CancelReplace orders: the creation timestamp of the order this order replaces. | @@ -1472,7 +1471,7 @@ | ----- | ---- | ----- | ----------- | | `trx_fee` | [uint64](#uint64) | | default fee for a market transaction. | | `liquid_trx_fee` | [uint64](#uint64) | | Valid liquidity adding orders are free or adjusted to a minimum nominal/fee | -| `liquidity_rebate_minutes_span` | [int64](#int64) | | Minutes interval for the liquidity rebate to apply. For the liquidity rebate to apply, the running transaction should occur x minutes after the signers' last liquid trx. | +| `liquidity_rebate_minutes_span` | [int64](#int64) | | Minutes interval for eligible replacing liquidity transactions to qualify for the rebate. For the rebate to apply, the replacing transaction should occur x minutes after the signer's original trx. | @@ -1480,22 +1479,6 @@ - - - -### TxMessageType - - -| Name | Number | Description | -| ---- | ------ | ----------- | -| DEFAULT_TX_MSG | 0 | Tx fallback for fees etc. | -| ADD_LIMIT_ORDER | 1 | | -| ADD_MARKET_ORDER | 2 | | -| CANCEL_REPLACE_LIMIT_ORDER | 3 | | -| CANCEL_REPLACE_MARKET_ORDER | 4 | | -| CANCEL_ORDER | 5 | | - - diff --git a/proto/em/market/v1/market.proto b/proto/em/market/v1/market.proto index c0c2970d..4f17f046 100644 --- a/proto/em/market/v1/market.proto +++ b/proto/em/market/v1/market.proto @@ -77,6 +77,14 @@ message Order { (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + + // applicable to CancelReplace orders: the creation timestamp of the order + // this order replaces. + google.protobuf.Timestamp orig_order_created = 11 [ + (gogoproto.moretags) = "yaml:\"orig_order_created\"", + (gogoproto.nullable) = false, + (gogoproto.stdtime) = true + ]; } message ExecutionPlan { diff --git a/proto/em/market/v1/tx.proto b/proto/em/market/v1/tx.proto index 96737ffb..318ebed4 100644 --- a/proto/em/market/v1/tx.proto +++ b/proto/em/market/v1/tx.proto @@ -20,29 +20,6 @@ service Msg { returns (MsgCancelReplaceMarketOrderResponse); } -enum TxMessageType { - option (gogoproto.goproto_enum_stringer) = true; - - // Tx fallback for fees etc. - DEFAULT_TX_MSG = 0 - [ (gogoproto.enumvalue_customname) = "DefaultTxMsg" ]; - - ADD_LIMIT_ORDER = 1 - [ (gogoproto.enumvalue_customname) = "AddLimitOrder" ]; - - ADD_MARKET_ORDER = 2 - [ (gogoproto.enumvalue_customname) = "AddMarketOrder" ]; - - CANCEL_REPLACE_LIMIT_ORDER = 3 - [ (gogoproto.enumvalue_customname) = "CancelReplaceLimitOrder" ]; - - CANCEL_REPLACE_MARKET_ORDER = 4 - [ (gogoproto.enumvalue_customname) = "CancelReplaceMarketOrder" ]; - - CANCEL_ORDER = 5 - [ (gogoproto.enumvalue_customname) = "CancelOrder" ]; -} - message TxParams { // default fee for a market transaction. uint64 trx_fee = 1 [(gogoproto.moretags) = "yaml:\"trx_fee\""]; @@ -50,9 +27,9 @@ message TxParams { // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee uint64 liquid_trx_fee = 2 [(gogoproto.moretags) = "yaml:\"liquid_trx_fee\""]; - // Minutes interval for eligible liquidity transactions to qualify for - // the rebate. For the rebate to apply, the running transaction - // should occur x minutes after the signers' last liquid trx. + // Minutes interval for eligible replacing liquidity transactions to qualify + // for the rebate. For the rebate to apply, the replacing transaction should + // occur x minutes after the signer's original trx. int64 liquidity_rebate_minutes_span = 3 [ (gogoproto.moretags) = "yaml:\"liquidity_rebate_minutes_span\"" ]; diff --git a/x/buyback/abci.go b/x/buyback/abci.go index 61dccbea..df481510 100644 --- a/x/buyback/abci.go +++ b/x/buyback/abci.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/e-money/em-ledger/x/buyback/internal/types" markettypes "github.com/e-money/em-ledger/x/market/types" + "time" ) func BeginBlocker(ctx sdk.Context, k Keeper, bk types.BankKeeper) { @@ -40,12 +41,9 @@ func BeginBlocker(ctx sdk.Context, k Keeper, bk types.BankKeeper) { } order, err := markettypes.NewOrder( - ctx.BlockTime(), - markettypes.TimeInForce_GoodTillCancel, - balance, - sdk.NewCoin(stakingDenom, destinationAmount), - account, - generateClientOrderId(ctx, balance), + ctx.BlockTime(), markettypes.TimeInForce_GoodTillCancel, balance, + sdk.NewCoin(stakingDenom, destinationAmount), account, + generateClientOrderId(ctx, balance), time.Time{}, ) if err != nil { diff --git a/x/buyback/abci_test.go b/x/buyback/abci_test.go index 1acd89a1..b80b1217 100644 --- a/x/buyback/abci_test.go +++ b/x/buyback/abci_test.go @@ -142,10 +142,10 @@ func TestBuyback3(t *testing.T) { acc1 = createAccount(ctx, accountKeeper, bankKeeper, randomAddress(), "5000000pesos") acc2 = createAccount(ctx, accountKeeper, bankKeeper, randomAddress(), "10000ungm") ) - _, err := market.NewOrderSingle(ctx, order(acc1, "4000000pesos", "1ungm"), types.TxMessageType_AddLimitOrder) + _, err := market.NewOrderSingle(ctx, order(acc1, "4000000pesos", "1ungm")) require.NoError(t, err) - _, err = market.NewOrderSingle(ctx, order(acc2, "1ungm", "4000000pesos"), types.TxMessageType_AddLimitOrder) + _, err = market.NewOrderSingle(ctx, order(acc2, "1ungm", "4000000pesos")) require.NoError(t, err) // Attempt to create a position using the meager pesos balance of the module @@ -201,16 +201,19 @@ func generateMarketActivity(ctx sdk.Context, marketKeeper *market.Keeper, ak ban acc2 = createAccount(ctx, ak, bk, randomAddress(), "150000eur,290000chf") ) - marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "10000eur"), types.TxMessageType_AddLimitOrder) - marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "20000chf"), types.TxMessageType_AddLimitOrder) - marketKeeper.NewOrderSingle(ctx, order(acc2, "10000eur", "5000ungm"), types.TxMessageType_AddLimitOrder) - marketKeeper.NewOrderSingle(ctx, order(acc2, "20000chf", "5000ungm"), types.TxMessageType_AddLimitOrder) + marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "10000eur")) + marketKeeper.NewOrderSingle(ctx, order(acc1, "5000ungm", "20000chf")) + marketKeeper.NewOrderSingle(ctx, order(acc2, "10000eur", "5000ungm")) + marketKeeper.NewOrderSingle(ctx, order(acc2, "20000chf", "5000ungm")) } func order(account authtypes.AccountI, src, dst string) types.Order { s, _ := sdk.ParseCoinNormalized(src) d, _ := sdk.ParseCoinNormalized(dst) - o, err := types.NewOrder(time.Now(), types.TimeInForce_GoodTillCancel, s, d, account.GetAddress(), tmrand.Str(10)) + o, err := types.NewOrder( + time.Now(), types.TimeInForce_GoodTillCancel, s, d, + account.GetAddress(), tmrand.Str(10), time.Time{}, + ) if err != nil { panic(err) } diff --git a/x/buyback/internal/keeper/expected_keepers.go b/x/buyback/internal/keeper/expected_keepers.go index 31e811ae..6e39200b 100644 --- a/x/buyback/internal/keeper/expected_keepers.go +++ b/x/buyback/internal/keeper/expected_keepers.go @@ -7,7 +7,7 @@ import ( type ( MarketKeeper interface { - NewOrderSingle(ctx sdk.Context, order market.Order, messageType market.TxMessageType) (*sdk.Result, error) + NewOrderSingle(ctx sdk.Context, aggressiveOrder market.Order) (*sdk.Result, error) GetOrdersByOwner(ctx sdk.Context, owner sdk.AccAddress) []*market.Order GetInstruments(ctx sdk.Context) (instrs []market.MarketData) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) diff --git a/x/buyback/internal/keeper/keeper.go b/x/buyback/internal/keeper/keeper.go index aa982d32..2f8ccebc 100644 --- a/x/buyback/internal/keeper/keeper.go +++ b/x/buyback/internal/keeper/keeper.go @@ -50,7 +50,7 @@ func (k Keeper) CancelCurrentModuleOrders(ctx sdk.Context) { } func (k Keeper) SendOrderToMarket(ctx sdk.Context, order market.Order) (*sdk.Result, error) { - return k.marketKeeper.NewOrderSingle(ctx, order, market.TxMessageType_AddLimitOrder) + return k.marketKeeper.NewOrderSingle(ctx, order) } func (k Keeper) GetMarketData(ctx sdk.Context) []market.MarketData { diff --git a/x/market/keeper/grpc_query_test.go b/x/market/keeper/grpc_query_test.go index 82728841..ef9acf9f 100644 --- a/x/market/keeper/grpc_query_test.go +++ b/x/market/keeper/grpc_query_test.go @@ -21,11 +21,9 @@ func TestQueryByAccount(t *testing.T) { types.RegisterQueryServer(queryHelper, k) queryClient := types.NewQueryClient(queryHelper) o, err := types.NewOrder( - ctx.BlockTime(), - types.TimeInForce_GoodTillCancel, - sdk.NewCoin("alx", sdk.OneInt()), - sdk.NewCoin("blx", sdk.OneInt()), - myAddress, "myOrderID", + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, + sdk.NewCoin("alx", sdk.OneInt()), sdk.NewCoin("blx", sdk.OneInt()), + myAddress, "myOrderID", time.Time{}, ) require.NoError(t, err) k.setOrder(ctx, &o) @@ -129,13 +127,13 @@ func TestInstrument(t *testing.T) { acc := createAccount(ctx, ak, bk, randomAddress(), "1000usd") o := order(ctx.BlockTime(), acc, "100usd", "100chf") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) oPlusOne := order( ctx.BlockTime().Add(time.Second), acc, "100usd", "100gbp", ) - _, err = k.NewOrderSingle(ctx, oPlusOne, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, oPlusOne) require.NoError(t, err) specs := map[string]struct { diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 44ee3ee7..2674dd82 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -134,7 +134,7 @@ func (k *Keeper) createExecutionPlan(ctx sdk.Context, SourceDenom, DestinationDe } func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { - return k.createMarketOrder( + _, res, err := k.createMarketOrder( ctx, srcDenom, dst, @@ -142,8 +142,10 @@ func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, ds owner, timeInForce, clientOrderId, - types.TxMessageType_AddMarketOrder, + time.Time{}, ) + + return res, err } // createMarketOrder creates a new market order allowing to set the message type @@ -155,12 +157,12 @@ func (k *Keeper) createMarketOrder( owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string, - msgType types.TxMessageType, -) (*sdk.Result, error) { + origOrderCreated time.Time, +) (*types.Order, *sdk.Result, error) { // If the order allows for slippage, adjust the source amount accordingly. - md := k.GetInstrument(ctx, srcDenom, dst.Denom) + md := k.GetInstrument(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()), srcDenom, dst.Denom) if md == nil || md.LastPrice == nil { - return nil, sdkerrors.Wrapf( + return nil, nil, sdkerrors.Wrapf( types.ErrNoMarketDataAvailable, "%v/%v", srcDenom, dst.Denom, ) } @@ -171,107 +173,86 @@ func (k *Keeper) createMarketOrder( slippageSource := sdk.NewCoin(srcDenom, source.RoundInt()) order, err := types.NewOrder( ctx.BlockTime(), timeInForce, slippageSource, dst, owner, clientOrderId, + origOrderCreated, ) if err != nil { - return nil, err + return nil, nil, err } - return k.NewOrderSingle(ctx, order, msgType) + res, err := k.NewOrderSingle(ctx, order) + return &order, res, err } -// calcOrderGas calculates the gas for an order. The liquid fee applies to -// liquid unfilled orders. If an order is not liquid the full fee applies. If -// filled partially then the difference between the full fee - liquid fee is -// applied proportionally. -func calcOrderGas(dstFilled, dstAmount sdk.Int, stdFee, liquidFee sdk.Gas) sdk.Gas { +// calcOrderGas calculates the order rebate. The liquid fee applies to liquid +// unfilled orders. If filled partially, the difference between the full fee +// minus (-) liquid fee is applied proportionally. +func (k *Keeper) calcOrderGas( + ctx sdk.Context, stdTrxFee sdk.Gas, dstFilled, dstAmount sdk.Int, +) sdk.Gas { + var liquidTrxFee sdk.Gas + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + // TODO is destination sufficient to evaluate the total filling impact // for limit/market orders? - if dstFilled.Equal(sdk.ZeroInt()) { - // 0% fill -> 100% rebate - return liquidFee + if dstFilled.IsZero() { + // 0% fill -> 100% totalRebate + return liquidTrxFee } - // remaining / total amount => % - rebatePct := dstAmount.Sub(dstFilled).ToDec().Quo(dstAmount.ToDec()) - - // rebate amount = Std fee - Liquid fee(likely 0) - rebate := sdk.NewIntFromUint64(stdFee).Sub(sdk.NewIntFromUint64(liquidFee)) - - return rebatePct.Mul(rebate.ToDec()).RoundInt().Uint64() -} - -func (k *Keeper) getReplacedOrderGas( - ctx sdk.Context, dstFilled, dstAmount sdk.Int, - messageType types.TxMessageType, lastOrderTm time.Time, -) sdk.Gas { - var stdTrxFee uint64 - k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - - var liquidTrxFee uint64 - k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - - switch messageType { - case types.TxMessageType_CancelReplaceLimitOrder, - types.TxMessageType_CancelReplaceMarketOrder: + dstRemaining := dstAmount.Sub(dstFilled) + if dstRemaining.IsZero() { + // 100% fill -> no rebate + return stdTrxFee + } - var qualificationMin int64 - k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + // totalRebate amount = Std fee - Liquid fee + totalRebate := sdk.NewIntFromUint64(stdTrxFee). + Sub(sdk.NewIntFromUint64(liquidTrxFee)) - // check at least LiquidityRebateMinutesSpan elapsed from replaced - // order - if lastOrderTm.IsZero() || - ctx.BlockTime().Sub(lastOrderTm).Minutes() >= float64(qualificationMin) { - return calcOrderGas(dstFilled, dstAmount, stdTrxFee, liquidTrxFee) - } - } + payPct := dstFilled.ToDec().Quo(dstAmount.ToDec()) + payGas := payPct.Mul(totalRebate.ToDec()) - // mis/uncategorized trx - return stdTrxFee + return payGas.RoundInt().Uint64() } -func (k *Keeper) getNewOrderGas( - ctx sdk.Context, - order *types.Order, - messageType types.TxMessageType, +// calcReplaceOrderGas computes gas for replacement orders. Because it needs +// the original order's creation time, this func acts is a precondition for +// calcOrderGas(). +func (k *Keeper) calcReplaceOrderGas( + ctx sdk.Context, dstFilled, dstAmount sdk.Int, lastOrderTm time.Time, ) sdk.Gas { var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - if order.IsFilled() { - return stdTrxFee - } - - switch messageType { - case types.TxMessageType_AddLimitOrder, - types.TxMessageType_AddMarketOrder: + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) - var liquidTrxFee uint64 - k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - - return calcOrderGas(order.DestinationFilled, order.Destination.Amount, - stdTrxFee, liquidTrxFee) + // check at least LiquidityRebateMinutesSpan elapsed from replaced order + if ctx.BlockTime().Sub(lastOrderTm).Minutes() >= float64(qualificationMin) { + return k.calcOrderGas(ctx, stdTrxFee, dstFilled, dstAmount) } - // mis/uncategorized trx return stdTrxFee } -// postNewOrderSingle spends gas on new orders and adds non-fill-or-kill orders to the -// order-book. +// postNewOrderSingle is a deferred function for NewOrderSingle. It spends gas +// on any order and adds non fill-or-kill orders to the order-book. func (k *Keeper) postNewOrderSingle( - ctx sdk.Context, - orderGasMeter sdk.GasMeter, - order *types.Order, - messageType types.TxMessageType, commitTrade func(), + ctx sdk.Context, orderGasMeter sdk.GasMeter, order *types.Order, + commitTrade func(), callerErr *error, ) { - if messageType != types.TxMessageType_CancelReplaceLimitOrder && - messageType != types.TxMessageType_CancelReplaceMarketOrder { - - // New Orders - orderGas := k.getNewOrderGas(ctx, order, messageType) - orderGasMeter.ConsumeGas(orderGas, messageType.String()) + if orderErr := recover(); orderErr != nil { + *callerErr = fmt.Errorf("%s", orderErr) } + defer func() { + if gasErr := recover(); gasErr != nil { + *callerErr = fmt.Errorf("out of Gas:%s", gasErr) + } + }() + + k.postOrderSpendGas(ctx, order, orderGasMeter, callerErr) + // Roll back any state changes made by the aggressive FillOrKill order. if order.TimeInForce == types.TimeInForce_FillOrKill { return @@ -281,17 +262,15 @@ func (k *Keeper) postNewOrderSingle( } func (k *Keeper) NewOrderSingle( - ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType, -) (*sdk.Result, error) { + ctx sdk.Context, aggressiveOrder types.Order, +) (res *sdk.Result, err error) { ctx, commitTrade := ctx.CacheContext() - trxGasMeter := ctx.GasMeter() + orderGasMeter := ctx.GasMeter() // impostor meter that would not panic ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - defer k.postNewOrderSingle( - ctx, trxGasMeter, &aggressiveOrder, messageType, commitTrade, - ) + defer k.postNewOrderSingle(ctx, orderGasMeter, &aggressiveOrder, commitTrade, &err) if err := aggressiveOrder.IsValid(); err != nil { return nil, err @@ -521,23 +500,68 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { return total.AmountOf(asset.Denom).GT(sdk.ZeroInt()) } -func postReplaceOrder(orderGasMeter sdk.GasMeter, gas *sdk.Gas, desc string) { +// postOrderSpendGas is a deferred function from Order processing +// NewSingleOrder, NewCancelReplace functions to charge the StdFee for canonical +// and exceptional cases. +func (k *Keeper) postOrderSpendGas( + ctx sdk.Context, order *types.Order, orderGasMeter sdk.GasMeter, callerErr *error, +) { + var stdTrxFee sdk.Gas + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - orderGasMeter.ConsumeGas(*gas, desc) + // Order failed + if *callerErr != nil || order == nil || order.IsValid() != nil { + orderGasMeter.ConsumeGas( + stdTrxFee, + fmt.Sprintf("cannot cover the erred order %d gas", stdTrxFee), + ) + return + } + + if order.IsFilled() { + orderGasMeter.ConsumeGas( + stdTrxFee, + fmt.Sprintf("cannot cover the standand order %d gas", stdTrxFee), + ) + return + } + // Rebate candidate + var orderGas sdk.Gas + + if order.OrigOrderCreated.IsZero() { + orderGas = k.calcOrderGas( + ctx, stdTrxFee, order.DestinationFilled, + order.Destination.Amount, + ) + } else { + orderGas = k.calcReplaceOrderGas( + ctx, order.DestinationFilled, order.Destination.Amount, + order.OrigOrderCreated, + ) + } + + orderGasMeter.ConsumeGas( + orderGas, fmt.Sprintf("cannot cover order %d gas", orderGas), + ) } -func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { +func (k *Keeper) CancelReplaceLimitOrder( + ctx sdk.Context, newOrder types.Order, origClientOrderId string, +) (res *sdk.Result, err error) { orderGasMeter := ctx.GasMeter() - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - desc := types.TxMessageType_CancelReplaceMarketOrder.String() - orderGas := new(sdk.Gas) - k.paramStore.Get(ctx, types.KeyTrxFee, orderGas) - - defer postReplaceOrder(orderGasMeter, orderGas, desc) + defer func() { + // consume gas if did not enter NewSingleOrder() + if err != nil && orderGasMeter.GasConsumed() == 0 { + k.postOrderSpendGas(ctx, &newOrder, orderGasMeter, &err) + } + }() - origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, newOrder.Owner, origClientOrderId) + origOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, newOrder.Owner, + origClientOrderId, + ) if origOrder == nil { return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, origClientOrderId) @@ -562,32 +586,31 @@ func (k *Keeper) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, newOrder.DestinationFilled = origOrder.DestinationFilled newOrder.TimeInForce = origOrder.TimeInForce + newOrder.OrigOrderCreated = origOrder.Created - resAdd, err := k.NewOrderSingle(ctx, newOrder, types.TxMessageType_CancelReplaceLimitOrder) + resAdd, err := k.NewOrderSingle(ctx.WithGasMeter(orderGasMeter), newOrder) if err != nil { return nil, err } - *orderGas = k.getReplacedOrderGas( - ctx, newOrder.DestinationFilled, newOrder.Destination.Amount, - types.TxMessageType_CancelReplaceLimitOrder, - origOrder.Created, - ) - evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) return &sdk.Result{Events: evts}, nil } -func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { - orderGasMeter := ctx.GasMeter() +func (k *Keeper) CancelReplaceMarketOrder( + ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder, +) (res *sdk.Result, err error) { + var newOrder *types.Order + orderGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - desc := types.TxMessageType_CancelReplaceMarketOrder.String() - orderGas := new(sdk.Gas) - k.paramStore.Get(ctx, types.KeyTrxFee, orderGas) - - defer postReplaceOrder(orderGasMeter, orderGas, desc) + defer func() { + // consume gas if did not enter NewSingleOrder() + if err != nil && orderGasMeter.GasConsumed() == 0 { + k.postOrderSpendGas(ctx, newOrder, orderGasMeter, &err) + } + }() origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) @@ -626,26 +649,21 @@ func (k *Keeper) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelR dstRemaining := msg.Destination.Amount.Sub(destinationFilled) remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) - resAdd, err := k.createMarketOrder( - ctx, + newOrder, res, err = k.createMarketOrder( + ctx.WithGasMeter(orderGasMeter), msg.Source, remDstCoin, msg.MaxSlippage, ownerAddr, msg.TimeInForce, msg.NewClientOrderId, - types.TxMessageType_CancelReplaceMarketOrder, + origOrder.Created, ) if err != nil { return nil, err } - *orderGas = k.getReplacedOrderGas( - ctx, destinationFilled, msg.Destination.Amount, types.TxMessageType_CancelReplaceMarketOrder, - origOrder.Created, - ) - - evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) + evts := append(ctx.EventManager().ABCIEvents(), res.Events...) return &sdk.Result{Events: evts}, nil } @@ -670,14 +688,14 @@ func (k *Keeper) GetOrderByOwnerAndClientOrderId(ctx sdk.Context, owner, clientO } func (k *Keeper) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) { - trxGasMeter := ctx.GasMeter() + cancelGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) // Use a fixed gas amount - trxGasMeter.ConsumeGas(stdTrxFee, "CancelOrder") + cancelGasMeter.ConsumeGas(stdTrxFee, "CancelOrder") // orders := k.accountOrders.GetAllOrders(owner) order := k.GetOrderByOwnerAndClientOrderId(ctx, owner.String(), clientOrderId) diff --git a/x/market/keeper/keeper_fuzzing_test.go b/x/market/keeper/keeper_fuzzing_test.go index 83a11fd1..539a5523 100644 --- a/x/market/keeper/keeper_fuzzing_test.go +++ b/x/market/keeper/keeper_fuzzing_test.go @@ -88,7 +88,7 @@ func TestFuzzing1(t *testing.T) { }) for _, order := range allOrders { - _, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order) if order.IsFilled() { fmt.Println("Order is filled on creation. Ignoring.", order) continue diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 465a56b6..949f189c 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -55,13 +55,18 @@ func TestBasicTrade(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + gasmeter := sdk.NewGasMeter(math.MaxUint64) src1, dst1 := "eur", "usd" order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order1, - types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order1) require.NoError(t, err) - require.Equal(t, gasPriceNewOrder, gasmeter.GasConsumed()) + require.Equal(t, liquidTrxFee, gasmeter.GasConsumed(), "Liquid non-filled") require.Equal(t, ctx.BlockTime(), order1.Created) // Ensure that the instrument was registered @@ -74,8 +79,7 @@ func TestBasicTrade(t *testing.T) { gasmeter = sdk.NewGasMeter(math.MaxUint64) src2, dst2 := dst1, src1 order2 := order(ctx.BlockTime(), acc2, "60"+src2, "50"+dst2) - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order2, - types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order2) require.NoError(t, err) // Ensure that the trade has been correctly registered in market data. @@ -128,11 +132,11 @@ func TestBasicTrade2(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) order1 := order(ctx.BlockTime(), acc1, "888eur", "1121usd") - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc2, "1120usd", "890eur") - res, err := k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + res, err := k.NewOrderSingle(ctx, order2) require.True(t, err == nil, res.Log) require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) @@ -148,16 +152,16 @@ func TestBasicTrade3(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) order1 := order(ctx.BlockTime(), acc2, "888850eur", "22807162chf") - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc3, "12chf", "4usd") - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order2) require.NoError(t, err) order3 := order(ctx.BlockTime(), acc1, "227156usd", "24971eur") - _, err = k.NewOrderSingle(ctx, order3, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order3) require.NoError(t, err) require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) @@ -174,24 +178,24 @@ func TestMarketOrderSlippage1(t *testing.T) { // Establish market price by executing a 1:1 trade o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // Sell eur at various prices o = order(ctx.BlockTime(), acc2, "50eur", "50gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "50eur", "75gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "50eur", "100gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // Make a market order that allows slippage @@ -240,11 +244,11 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { // Establish market price by executing a 1:1 trade o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // Make a market order that allows slippage @@ -289,7 +293,6 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { ctx = ctx.WithGasMeter(gasMeter) _, err = k.CancelReplaceMarketOrder(ctx, mcrm) require.NoError(t, err) - t.Log(ctx.GasMeter().String()) require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) expOrder := &types.Order{ @@ -304,6 +307,7 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { Destination: mcrm.Destination, DestinationFilled: sdk.ZeroInt(), Created: ctx.BlockTime(), + OrigOrderCreated: foundOrder.Created, } require.NoError(t, err) @@ -333,11 +337,11 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { // Establish market price by executing a 2:1 trade o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) acc1b := bk.GetAllBalances(ctx, acc1.GetAddress()) require.Equal(t, coins("20eur,90gbp").String(), acc1b.String()) @@ -392,6 +396,7 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { Destination: mcrm.Destination, DestinationFilled: sdk.ZeroInt(), Created: ctx.BlockTime(), + OrigOrderCreated: foundOrder.Created, } require.NoError(t, err) @@ -427,7 +432,7 @@ func TestCancelReplaceMarketOrder0GasFee(t *testing.T) { // Establish market price by executing a 2:1 trade o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed(), "Liquid Trx are discounted") @@ -438,9 +443,9 @@ func TestCancelReplaceMarketOrder0GasFee(t *testing.T) { ctx = ctx.WithGasMeter(gasMeter) o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) - require.Equalf( + require.Equal( t, stdTrxFee, ctx.GasMeter().GasConsumed(), "Filled order costs std fee", ) @@ -493,7 +498,10 @@ func TestCancelReplaceMarketOrder0GasFee(t *testing.T) { ), mcrm, ) require.NoError(t, err) - require.Equalf(t, liquidTrxFee, ctx.GasMeter().GasConsumed(), "Not filled and liquid are discounted") + require.Equal( + t, liquidTrxFee, ctx.GasMeter().GasConsumed(), + "Unfilled/liquid are discounted", + ) } func TestFillOrKillMarketOrder1(t *testing.T) { @@ -509,16 +517,16 @@ func TestFillOrKillMarketOrder1(t *testing.T) { // Establish market price by executing a 1:1 trade o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // Create a market for eur o = order(ctx.BlockTime(), acc2, "100eur", "100gbp") - res, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + res, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) require.Equal( t, "accept", @@ -563,12 +571,12 @@ func TestFillOrKillLimitOrder1(t *testing.T) { // Create a tiny market for eur o := order(ctx.BlockTime(), acc2, "100eur", "100gbp") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc1, "200gbp", "200eur") order2.TimeInForce = types.TimeInForce_FillOrKill - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order2) require.NoError(t, err) // Order must fail completely due to not being fillable @@ -595,13 +603,13 @@ func TestImmediateOrCancel(t *testing.T) { var err error o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "2gbp", "2eur") o.TimeInForce = types.TimeInForce_ImmediateOrCancel cid := o.ClientOrderID - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) require.Equal(t, o.Created, ctx.BlockTime()) @@ -620,7 +628,7 @@ func TestInsufficientGas(t *testing.T) { order1 := order(ctx.BlockTime(), acc1, "888eur", "1121usd") // Free: it adds liquidity - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) acc2 := createAccount(ctx, ak, bk, randomAddress(), "1121usd") @@ -632,13 +640,9 @@ func TestInsufficientGas(t *testing.T) { // bummer missing 1 micro gasMeter := sdk.NewGasMeter(fullTrxFee - 1) - require.Panics(t, func() { - // Taking away liquidity not enough to cover the full Trx fee - k.NewOrderSingle( - ctx.WithGasMeter(gasMeter), order2, - types.TxMessageType_AddLimitOrder, - ) - }) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.Error(t, err) + require.True(t, strings.Contains(strings.ToLower(err.Error()), "gas")) } func TestLiquidNewLimit0Gas(t *testing.T) { @@ -653,8 +657,7 @@ func TestLiquidNewLimit0Gas(t *testing.T) { src1, dst1 := "eur", "usd" order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, - types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) } @@ -667,23 +670,26 @@ func TestLiquidNewMarket0Gas(t *testing.T) { gasMeter := sdk.NewGasMeter(math.MaxUint64) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) order1 := order(ctx.BlockTime(), acc1, "100gbp", "120eur") - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, - types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) order2 := order(ctx.BlockTime(), acc2, "120eur", "100gbp") - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2, - types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) require.NoError(t, err) - require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + gasMeter = sdk.NewInfiniteGasMeter() slippage := sdk.NewDecWithPrec(50, 2) cid := cid() + ctx = ctx.WithGasMeter(gasMeter) _, err = k.NewMarketOrderWithSlippage( ctx, "gbp", @@ -694,7 +700,7 @@ func TestLiquidNewMarket0Gas(t *testing.T) { cid, ) require.NoError(t, err) - require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed()) } func TestCancelNewLimitFullGas(t *testing.T) { @@ -712,8 +718,7 @@ func TestCancelNewLimitFullGas(t *testing.T) { src1, dst1 := "eur", "usd" order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, - types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) @@ -742,17 +747,16 @@ func TestCancelNewMarketFullGas(t *testing.T) { k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) order1 := order(ctx.BlockTime(), acc1, "100gbp", "120eur") - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1, - types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) - require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed(), "Liquid trx") order2 := order(ctx.BlockTime(), acc2, "120eur", "100gbp") - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2, - types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) require.NoError(t, err) - require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed(), "Filled, non-liquid") + gasMeter = sdk.NewGasMeter(math.MaxUint64) slippage := sdk.NewDecWithPrec(50, 2) cid := cid() _, err = k.NewMarketOrderWithSlippage( @@ -765,11 +769,11 @@ func TestCancelNewMarketFullGas(t *testing.T) { cid, ) require.NoError(t, err) - require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed(), "Non-filled-Liquid") _, err = k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), cid) require.NoError(t, err) - require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed(), "Cancel pays std fee") } func TestMultipleOrders(t *testing.T) { @@ -782,18 +786,26 @@ func TestMultipleOrders(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) // Add two orders that draw on the same balance. - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), + ) require.NoError(t, err) - _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), + ) require.NoError(t, err) // require.Len(t, k.instruments, 2) - res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), types.TxMessageType_AddLimitOrder) + res, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), + ) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), types.TxMessageType_AddLimitOrder) + res, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), + ) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -812,7 +824,6 @@ func TestCancelZeroRemainingOrders(t *testing.T) { acc := createAccount(ctx, ak, bk, randomAddress(), "10000eur") _, err := k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc, "10000eur", "11000usd"), - types.TxMessageType_AddLimitOrder, ) require.NoError(t, err) @@ -833,7 +844,7 @@ func TestInsufficientBalance1(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "300eur", "360usd") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) // Modify account balance to be below order source @@ -841,7 +852,7 @@ func TestInsufficientBalance1(t *testing.T) { require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "360usd", "300eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -861,11 +872,11 @@ func Test2(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "121usd", "100eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // require.Empty(t, k.instruments) @@ -883,16 +894,24 @@ func TestAllInstruments(t *testing.T) { acc3 := createAccount(ctx, ak, bk, randomAddress(), "2200chf") // Add two orders that draw on the same balance. - _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), + ) require.NoError(t, err) - _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), + ) require.NoError(t, err) - res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), types.TxMessageType_AddLimitOrder) + res, err := k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), + ) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), types.TxMessageType_AddLimitOrder) + res, err = k.NewOrderSingle( + ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), + ) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -936,12 +955,12 @@ func Test3(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + k.NewOrderSingle(ctx, o) gasMeter := sdk.NewGasMeter(math.MaxUint64) for i := 0; i < 4; i++ { o = order(ctx.BlockTime(), acc2, "30usd", "25eur") - k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) + k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) } require.Equal(t, 4*gasPriceNewOrder, gasMeter.GasConsumed()) @@ -961,12 +980,18 @@ func TestDeleteOrder(t *testing.T) { cid := cid() - order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), coin("120usd"), acc1.GetAddress(), cid) - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + order1, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), + coin("120usd"), acc1.GetAddress(), cid, time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) - order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), coin("77chf"), acc1.GetAddress(), cid) - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + order2, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), + coin("77chf"), acc1.GetAddress(), cid, time.Time{}, + ) + _, err = k.NewOrderSingle(ctx, order2) require.Error(t, err) // Verify that client order ids cannot be duplicated. // require.Len(t, k.instruments, 1) // Ensure that the eur->chf pair was not added. @@ -983,14 +1008,20 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "120usd") for i := 0; i < 5; i++ { - order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5eur"), coin("12usd"), acc1.GetAddress(), cid()) - _, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) + order, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5eur"), + coin("12usd"), acc1.GetAddress(), cid(), time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order) require.NoError(t, err) } for i := 0; i < 5; i++ { - order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("7usd"), coin("3chf"), acc2.GetAddress(), cid()) - res, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) + order, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("7usd"), + coin("3chf"), acc2.GetAddress(), cid(), time.Time{}, + ) + res, err := k.NewOrderSingle(ctx, order) require.True(t, err == nil, res.Log) } @@ -998,8 +1029,11 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { require.Len(t, allOrders1, 5) { - order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("12usd"), coin("5eur"), acc2.GetAddress(), cid()) - res, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) + order, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("12usd"), + coin("5eur"), acc2.GetAddress(), cid(), time.Time{}, + ) + res, err := k.NewOrderSingle(ctx, order) require.True(t, err == nil, res.Log) } @@ -1055,8 +1089,11 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) order1cid := cid() - order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), coin("1200usd"), acc1.GetAddress(), order1cid) - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + order1, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), + coin("1200usd"), acc1.GetAddress(), order1cid, time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) var stdTrxFee uint64 @@ -1064,7 +1101,10 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { gasMeter := sdk.NewGasMeter(math.MaxUint64) order2cid := cid() - order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), coin("17000usd"), acc1.GetAddress(), order2cid) + order2, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), + coin("17000usd"), acc1.GetAddress(), order2cid, time.Time{}, + ) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) @@ -1078,7 +1118,10 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { require.Equal(t, sdk.NewInt(5000), orders[0].SourceRemaining) } - order3, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), coin("1700usd"), acc1.GetAddress(), cid()) + order3, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), + coin("1700usd"), acc1.GetAddress(), cid(), time.Time{}, + ) // Wrong client order id for previous order submitted. _, err = k.CancelReplaceLimitOrder(ctx, order3, order1cid) require.True(t, types.ErrClientOrderIdNotFound.Is(err)) @@ -1090,7 +1133,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -1116,7 +1159,10 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { order4cid := cid() gasMeter = sdk.NewInfiniteGasMeter() ctx = ctx.WithGasMeter(gasMeter) - order4, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("35050usd"), acc1.GetAddress(), order4cid) + order4, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), + coin("35050usd"), acc1.GetAddress(), order4cid, time.Time{}, + ) res, err = k.CancelReplaceLimitOrder( ctx.WithBlockTime(ctx.BlockTime().Add( time.Duration(qualificationMin)*time.Minute)), @@ -1143,7 +1189,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { // CancelReplace with an order that asks for a larger source than the replaced order has remaining order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") - res, err = k.NewOrderSingle(ctx, order5, types.TxMessageType_AddLimitOrder) + res, err = k.NewOrderSingle(ctx, order5) require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") @@ -1155,7 +1201,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { order6, order4cid, ) require.True(t, types.ErrNoSourceRemaining.Is(err)) - require.Equalf( + require.Equal( t, stdTrxFee, gasMeter.GasConsumed(), "Erred orders should incur full fees", ) @@ -1171,13 +1217,19 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) order1cid := cid() - order1, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), coin("1200usd"), acc1.GetAddress(), order1cid) - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + order1, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), + coin("1200usd"), acc1.GetAddress(), order1cid, time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) gasMeter := sdk.NewGasMeter(math.MaxUint64) order2cid := cid() - order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), coin("17000usd"), acc1.GetAddress(), order2cid) + order2, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), + coin("17000usd"), acc1.GetAddress(), order2cid, time.Time{}, + ) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) @@ -1191,7 +1243,10 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { require.Equal(t, sdk.NewInt(5000), orders[0].SourceRemaining) } - order3, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), coin("1700usd"), acc1.GetAddress(), cid()) + order3, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), + coin("1700usd"), acc1.GetAddress(), cid(), time.Time{}, + ) // Wrong client order id for previous order submitted. _, err = k.CancelReplaceLimitOrder(ctx, order3, order1cid) require.True(t, types.ErrClientOrderIdNotFound.Is(err)) @@ -1203,7 +1258,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -1221,7 +1276,10 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { // CancelReplace and verify that previously filled amount is subtracted from the resulting order order4cid := cid() - order4, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("35050usd"), acc1.GetAddress(), order4cid) + order4, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), + coin("35050usd"), acc1.GetAddress(), order4cid, time.Time{}, + ) res, err = k.CancelReplaceLimitOrder(ctx, order4, order2cid) require.True(t, err == nil, res.Log) @@ -1236,7 +1294,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { // CancelReplace with an order that asks for a larger source than the replaced order has remaining order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") - k.NewOrderSingle(ctx, order5, types.TxMessageType_AddLimitOrder) + k.NewOrderSingle(ctx, order5) require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") @@ -1251,15 +1309,21 @@ func TestOrdersChangeWithAccountBalance(t *testing.T) { acc := createAccount(ctx, ak, bk, randomAddress(), "15000eur") acc2 := createAccount(ctx, ak, bk, randomAddress(), "11000chf,100000eur") - order, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), coin("1000usd"), acc.GetAddress(), cid()) - _, err := k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) + order, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), + coin("1000usd"), acc.GetAddress(), cid(), time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order) require.NoError(t, err) { // Partially fill the order above acc2 := createAccount(ctx, ak, bk, randomAddress(), "900000usd") - order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("400usd"), coin("4000eur"), acc2.GetAddress(), cid()) - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + order2, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("400usd"), + coin("4000eur"), acc2.GetAddress(), cid(), time.Time{}, + ) + _, err = k.NewOrderSingle(ctx, order2) require.NoError(t, err) } @@ -1298,13 +1362,16 @@ func TestUnknownAsset(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + var stdTrxFee sdk.Gas + k1.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) // Make an order with a destination that is not known by the supply module o := order(ctx.BlockTime(), acc1, "1000eur", "1200nok") - _, err := k1.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) + _, err := k1.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) require.True(t, types.ErrUnknownAsset.Is(err)) - require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed(), "Liquid non-filled") } func TestLoadFromStore(t *testing.T) { @@ -1315,11 +1382,11 @@ func TestLoadFromStore(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "7400usd") o := order(ctx.BlockTime(), acc1, "1000eur", "1200usd") - _, err := k1.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k1.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc2, "5000usd", "3500chf") - _, err = k1.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k1.NewOrderSingle(ctx, o) require.NoError(t, err) _, k2, _, _ := createTestComponents(t) @@ -1346,7 +1413,6 @@ func TestVestingAccount(t *testing.T) { _, err := keeper.NewOrderSingle( ctx, order(ctx.BlockTime(), vestingAcc, "5000eur", "4700chf"), - types.TxMessageType_AddLimitOrder, ) require.True(t, types.ErrAccountBalanceInsufficient.Is(err)) } @@ -1367,7 +1433,7 @@ func TestInvalidInstrument(t *testing.T) { TimeInForce: types.TimeInForce_GoodTillCancel, } - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.True(t, types.ErrInvalidInstrument.Is(err)) } @@ -1388,38 +1454,38 @@ func TestRestrictedDenominations1(t *testing.T) { { // Verify that acc2 can't create a passive gbp order o := order(ctx.BlockTime(), acc2, "500gbp", "542eur") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) // require.Empty(t, k.instruments) o = order(ctx.BlockTime(), acc2, "542usd", "500gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // require.Empty(t, k.instruments) } { // Verify that acc1 can create a passive gbp order o := order(ctx.BlockTime(), acc1, "542eur", "500gbp") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) // require.Len(t, k.instruments, 1) o = order(ctx.BlockTime(), acc1, "200gbp", "333usd") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // require.Len(t, k.instruments, 2) } { // Verify that acc2 managed to sell its gbp to a passive order o := order(ctx.BlockTime(), acc2, "500gbp", "542eur") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) balance := bk.GetAllBalances(ctx, acc2.GetAddress()) require.Equal(t, "542", balance.AmountOf("eur").String()) o = order(ctx.BlockTime(), acc2, "333usd", "200gbp") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) balance = bk.GetAllBalances(ctx, acc2.GetAddress()) require.Equal(t, "900", balance.AmountOf("gbp").String()) @@ -1442,16 +1508,19 @@ func TestRestrictedDenominations2(t *testing.T) { k.initializeFromStore(ctx) + var liquidTrxFee sdk.Gas + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) // Ensure that no orders can be created, even though acc1 is allowed to create usd orders o := order(ctx.BlockTime(), acc1, "542usd", "500gbp") - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) require.NoError(t, err) // require.Empty(t, k.instruments) - require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) o = order(ctx.BlockTime(), acc1, "500gbp", "542usd") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // require.Empty(t, k.instruments) } @@ -1465,26 +1534,33 @@ func TestSyntheticInstruments1(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) o := order(ctx.BlockTime(), acc1, "1000eur", "1114usd") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "500eur", "542chf") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc3, "1000chf", "1028usd") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee sdk.Gas + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) o = order(ctx.BlockTime(), acc2, "5000usd", "4485eur") - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o, types.TxMessageType_AddLimitOrder) - require.NoError(t, err, types.TxMessageType_AddLimitOrder) - require.Equal(t, gasMeter.GasConsumed(), gasPriceNewOrder) // Matches several orders, but should pay only the fixed fee + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) + require.NoError(t, err) + require.Greater(t, gasMeter.GasConsumed(), liquidTrxFee) // Matches several orders, but should pay only the fixed fee + require.Less(t, gasMeter.GasConsumed(), stdTrxFee) // Matches several orders, but should pay only the fixed fee // Ensure acc2 received at least some euro acc2Balance := bk.GetAllBalances(ctx, acc2.GetAddress()) - require.True(t, acc2Balance.AmountOf("eur").IsPositive(), types.TxMessageType_AddLimitOrder) + require.True(t, acc2Balance.AmountOf("eur").IsPositive()) // Ensure acc2 did not receive any CHF, which is used in the synthetic instrument require.True(t, acc2Balance.AmountOf("chf").IsZero()) @@ -1503,12 +1579,10 @@ func TestNonMatchingOrders(t *testing.T) { _, err := k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc1, "20000usd", "20000eur"), - types.TxMessageType_AddLimitOrder, ) require.NoError(t, err) _, err = k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc2, "20000eur", "50000usd"), - types.TxMessageType_AddLimitOrder, ) require.NoError(t, err) @@ -1548,16 +1622,13 @@ func TestSyntheticInstruments2(t *testing.T) { } for _, o := range passiveOrders { - res, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddLimitOrder) + res, err := k.NewOrderSingle(ctx, o) require.NoError(t, err, res.Log) } gasMeter := sdk.NewGasMeter(math.MaxUint64) monsterOrder := order(ctx.BlockTime(), acc3, "3700000eur", "4000000usd") - res, err := k.NewOrderSingle( - ctx.WithGasMeter(gasMeter), monsterOrder, - types.TxMessageType_AddLimitOrder, - ) + res, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), monsterOrder) require.NoError(t, err, res.Log) require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) @@ -1581,11 +1652,11 @@ func TestDestinationCapacity(t *testing.T) { order1.SourceFilled = sdk.NewInt(618000000) order1.DestinationFilled = sdk.NewInt(645161290) - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc2, "471096868463eur", "500182000000usd") - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order2) require.NoError(t, err) } @@ -1603,15 +1674,15 @@ func TestDestinationCapacity2(t *testing.T) { order1.SourceFilled = sdk.NewInt(618000000) order1.DestinationFilled = sdk.NewInt(645161290) - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) order2 := order(ctx.BlockTime(), acc3, "130000000000chf", "800000000usd") - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order2) require.NoError(t, err) aggressiveOrder := order(ctx.BlockTime(), acc2, "471096868463eur", "120000000000chf") - _, err = k.NewOrderSingle(ctx, aggressiveOrder, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, aggressiveOrder) require.NoError(t, err) } @@ -1621,17 +1692,17 @@ func TestPreventPhantomLiquidity(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "10000eur") order1 := order(ctx.BlockTime(), acc1, "8000eur", "9000usd") - _, err := k.NewOrderSingle(ctx, order1, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) // Cannot sell more than the balance in the same instrument order2 := order(ctx.BlockTime(), acc1, "8000eur", "9000usd") - _, err = k.NewOrderSingle(ctx, order2, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order2) require.Error(t, err) // Can sell the balance in another instrument order3 := order(ctx.BlockTime(), acc1, "8000eur", "6000chf") - _, err = k.NewOrderSingle(ctx, order3, types.TxMessageType_AddLimitOrder) + _, err = k.NewOrderSingle(ctx, order3) require.NoError(t, err) } @@ -1660,7 +1731,7 @@ func TestListInstruments(t *testing.T) { ) order := order(ctx.BlockTime(), acc, s, d) - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order, types.TxMessageType_AddLimitOrder) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasmeter), order) require.NoError(t, err) } } @@ -1841,9 +1912,21 @@ func coins(s string) sdk.Coins { } func order(createdTm time.Time, account authtypes.AccountI, src, dst string) types.Order { + return orderReplacement(createdTm, account, src, dst, time.Time{}) +} + +func orderReplacement( + createdTm time.Time, account authtypes.AccountI, src, dst string, + origOrderTm time.Time, +) types.Order { o, err := types.NewOrder( - createdTm, types.TimeInForce_GoodTillCancel, coin(src), coin(dst), - account.GetAddress(), cid(), + createdTm, + types.TimeInForce_GoodTillCancel, + coin(src), + coin(dst), + account.GetAddress(), + cid(), + origOrderTm, ) if err != nil { panic(err) diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index 3bd6aa38..f37627f5 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -6,13 +6,14 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/e-money/em-ledger/x/market/types" + "time" ) var _ types.MsgServer = msgServer{} type marketKeeper interface { NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) - NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType) (*sdk.Result, error) + NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) @@ -32,12 +33,16 @@ func (m msgServer) AddLimitOrder(c context.Context, msg *types.MsgAddLimitOrder) return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") } - order, err := types.NewOrder(ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, msg.ClientOrderId) + order, err := types.NewOrder( + ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, + msg.ClientOrderId, time.Time{}, + ) + if err != nil { return nil, err } - result, err := m.k.NewOrderSingle(ctx, order, types.TxMessageType_AddLimitOrder) + result, err := m.k.NewOrderSingle(ctx, order) if err != nil { return nil, err } @@ -90,7 +95,10 @@ func (m msgServer) CancelReplaceLimitOrder(c context.Context, msg *types.MsgCanc if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") } - order, err := types.NewOrder(ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, msg.NewClientOrderId) + order, err := types.NewOrder( + ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, + msg.NewClientOrderId, time.Time{}, + ) if err != nil { return nil, err } diff --git a/x/market/keeper/msg_server_test.go b/x/market/keeper/msg_server_test.go index de8b848c..6da5372e 100644 --- a/x/market/keeper/msg_server_test.go +++ b/x/market/keeper/msg_server_test.go @@ -23,7 +23,7 @@ func TestAddLimitOrder(t *testing.T) { specs := map[string]struct { req *types.MsgAddLimitOrder - mockFn func(ctx sdk.Context, aggressiveOrder types.Order, msgType types.TxMessageType) (*sdk.Result, error) + mockFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) expErr bool expEvents sdk.Events expOrder types.Order @@ -36,7 +36,7 @@ func TestAddLimitOrder(t *testing.T) { Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, - mockFn: func(ctx sdk.Context, aggressiveOrder types.Order, msgType types.TxMessageType) (*sdk.Result, error) { + mockFn: func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { gotOrder = aggressiveOrder return &sdk.Result{ Events: []abcitypes.Event{{ @@ -87,7 +87,7 @@ func TestAddLimitOrder(t *testing.T) { Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, - mockFn: func(ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType) (*sdk.Result, error) { + mockFn: func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { return nil, errors.New("testing") }, expErr: true, @@ -510,7 +510,7 @@ func TestCancelReplaceMarketOrder(t *testing.T) { type marketKeeperMock struct { NewMarketOrderWithSlippageFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) - NewOrderSingleFn func(ctx sdk.Context, aggressiveOrder types.Order, messageType types.TxMessageType) (*sdk.Result, error) + NewOrderSingleFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) CancelOrderFn func(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrderFn func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) CancelReplaceMarketOrderFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) @@ -523,11 +523,11 @@ func (m marketKeeperMock) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom s return m.NewMarketOrderWithSlippageFn(ctx, srcDenom, dst, maxSlippage, owner, timeInForce, clientOrderId) } -func (m marketKeeperMock) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order, msgType types.TxMessageType) (*sdk.Result, error) { +func (m marketKeeperMock) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { if m.NewOrderSingleFn == nil { panic("not expected to be called") } - return m.NewOrderSingleFn(ctx, aggressiveOrder, msgType) + return m.NewOrderSingleFn(ctx, aggressiveOrder) } func (m marketKeeperMock) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) { diff --git a/x/market/keeper/querier_test.go b/x/market/keeper/querier_test.go index fd434274..308cb33d 100644 --- a/x/market/keeper/querier_test.go +++ b/x/market/keeper/querier_test.go @@ -25,23 +25,23 @@ func TestQryGetAllInstrumentsWithNonZeroBestPrices(t *testing.T) { // generate passive order o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) // generate passive order o = order(ctx.BlockTime(), acc1, "72eur", "1213jpy") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // generate passive order of half balances o = order(ctx.BlockTime(), acc1, "72chf", "312usd") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // Execute an order // fulfilled o = order(ctx.BlockTime(), acc2, "156usd", "36chf") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) { @@ -83,25 +83,21 @@ func TestQryGetAllInstrumentsWithNilBestPrices(t *testing.T) { // generate passive order _, err := k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), - types.TxMessageType_AddMarketOrder, ) require.NoError(t, err) _, err = k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), - types.TxMessageType_AddMarketOrder, ) require.NoError(t, err) res, err := k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), - types.TxMessageType_AddMarketOrder, ) require.True(t, err == nil, res.Log) res, err = k.NewOrderSingle( ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), - types.TxMessageType_AddMarketOrder, ) require.True(t, err == nil, res.Log) @@ -148,20 +144,20 @@ func TestQuerier1(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "1000usd") o := order(ctx.BlockTime(), acc1, "100eur", "120usd") - _, err := k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "72eur", "1213jpy") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) o = order(ctx.BlockTime(), acc1, "72chf", "312usd") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) // Execute an order o = order(ctx.BlockTime(), acc2, "156usd", "36chf") - _, err = k.NewOrderSingle(ctx, o, types.TxMessageType_AddMarketOrder) + _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) { diff --git a/x/market/types/market.pb.go b/x/market/types/market.pb.go index 4bcf72b3..42174a4d 100644 --- a/x/market/types/market.pb.go +++ b/x/market/types/market.pb.go @@ -123,6 +123,9 @@ type Order struct { Destination types.Coin `protobuf:"bytes,8,opt,name=destination,proto3" json:"destination" yaml:"destination"` DestinationFilled github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,9,opt,name=destination_filled,json=destinationFilled,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"destination_filled" yaml:"destination_filled"` Created time.Time `protobuf:"bytes,10,opt,name=created,proto3,stdtime" json:"created" yaml:"created"` + // applicable to CancelReplace orders: the creation timestamp of the order + // this order replaces. + OrigOrderCreated time.Time `protobuf:"bytes,11,opt,name=orig_order_created,json=origOrderCreated,proto3,stdtime" json:"orig_order_created" yaml:"orig_order_created"` } func (m *Order) Reset() { *m = Order{} } @@ -206,6 +209,13 @@ func (m *Order) GetCreated() time.Time { return time.Time{} } +func (m *Order) GetOrigOrderCreated() time.Time { + if m != nil { + return m.OrigOrderCreated + } + return time.Time{} +} + type ExecutionPlan struct { Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price"` FirstOrder *Order `protobuf:"bytes,2,opt,name=first_order,json=firstOrder,proto3" json:"first_order,omitempty"` @@ -330,63 +340,65 @@ func init() { func init() { proto.RegisterFile("em/market/v1/market.proto", fileDescriptor_888ec7fc0f7580e2) } var fileDescriptor_888ec7fc0f7580e2 = []byte{ - // 896 bytes of a gzipped FileDescriptorProto + // 923 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x3f, 0x6f, 0xdb, 0x46, - 0x14, 0x17, 0x6d, 0xd9, 0x8e, 0x4f, 0x96, 0xad, 0x5c, 0x9d, 0x54, 0xe2, 0x40, 0xaa, 0x1c, 0x82, - 0x20, 0x81, 0x49, 0xd8, 0x0d, 0x32, 0x04, 0x45, 0x81, 0x48, 0xa2, 0x52, 0xc2, 0xb2, 0x65, 0x30, - 0x0a, 0x02, 0x74, 0x21, 0x28, 0xf2, 0xa4, 0x1e, 0x4c, 0xde, 0x09, 0xe4, 0xc9, 0x8d, 0xfb, 0x11, - 0x3c, 0x65, 0xec, 0x62, 0xa0, 0x43, 0x87, 0x7e, 0x94, 0x74, 0x73, 0xb7, 0xa2, 0x03, 0x5b, 0xc8, - 0x53, 0x87, 0x2e, 0xfa, 0x04, 0x05, 0xef, 0x28, 0x99, 0x6c, 0xd1, 0x16, 0xea, 0xa4, 0x7b, 0x7f, - 0x7e, 0xef, 0xbd, 0xdf, 0xfb, 0x43, 0x81, 0x06, 0x0a, 0x8d, 0xd0, 0x8d, 0xce, 0x11, 0x33, 0x2e, - 0x0e, 0xb3, 0x97, 0x3e, 0x89, 0x28, 0xa3, 0x70, 0x07, 0x85, 0x7a, 0xa6, 0xb8, 0x38, 0x94, 0xf7, - 0xc7, 0x74, 0x4c, 0xb9, 0xc1, 0x48, 0x5f, 0xc2, 0x47, 0x56, 0xc7, 0x94, 0x8e, 0x03, 0x64, 0x70, - 0x69, 0x38, 0x1d, 0x19, 0x0c, 0x87, 0x28, 0x66, 0x6e, 0x38, 0xc9, 0x1c, 0x14, 0x8f, 0xc6, 0x21, - 0x8d, 0x8d, 0xa1, 0x1b, 0x23, 0xe3, 0xe2, 0x70, 0x88, 0x98, 0x7b, 0x68, 0x78, 0x14, 0x13, 0x61, - 0xd7, 0xba, 0x00, 0x58, 0x24, 0x66, 0xd1, 0x34, 0x44, 0x84, 0xc1, 0x87, 0x60, 0x33, 0xa6, 0xd3, - 0xc8, 0x43, 0x75, 0xa9, 0x29, 0x3d, 0xde, 0xb6, 0x33, 0x09, 0x36, 0x41, 0xc5, 0x47, 0x31, 0xc3, - 0xc4, 0x65, 0x98, 0x92, 0xfa, 0x1a, 0x37, 0xe6, 0x55, 0xda, 0x1f, 0x9b, 0x60, 0xa3, 0x1f, 0xf9, - 0x28, 0x82, 0xcf, 0xc0, 0x3d, 0x9a, 0x3e, 0x1c, 0xec, 0xf3, 0x28, 0xe5, 0x56, 0x63, 0x96, 0xa8, - 0x6b, 0x56, 0x67, 0x9e, 0xa8, 0x7b, 0x97, 0x6e, 0x18, 0xbc, 0xd0, 0x16, 0x76, 0xcd, 0xde, 0xe2, - 0x4f, 0xcb, 0x87, 0x6f, 0x41, 0x35, 0x2d, 0xdd, 0xc1, 0xc4, 0x19, 0xd1, 0xb4, 0x80, 0x34, 0xc7, - 0xee, 0x51, 0x43, 0xcf, 0x37, 0x41, 0x1f, 0xe0, 0x10, 0x59, 0xa4, 0x9b, 0x3a, 0xb4, 0xea, 0xf3, - 0x44, 0xdd, 0x17, 0xf1, 0x0a, 0x48, 0xcd, 0xae, 0xb0, 0x3b, 0x37, 0xf8, 0x08, 0x6c, 0xd0, 0xaf, - 0x09, 0x8a, 0xea, 0xeb, 0x69, 0xd1, 0xad, 0xda, 0x3c, 0x51, 0x77, 0xb2, 0x2a, 0x52, 0xb5, 0x66, - 0x0b, 0x33, 0x7c, 0x0d, 0xf6, 0xbc, 0x00, 0x23, 0xc2, 0x9c, 0x65, 0xf5, 0x65, 0x8e, 0x78, 0x3a, - 0x4b, 0xd4, 0x6a, 0x9b, 0x9b, 0x38, 0x41, 0x4e, 0xe4, 0xa1, 0x08, 0xf1, 0x17, 0x84, 0x66, 0x57, - 0xbd, 0x9c, 0xa3, 0x0f, 0xbf, 0x58, 0xf6, 0x73, 0xa3, 0x29, 0x3d, 0xae, 0x1c, 0x35, 0x74, 0x31, - 0x0e, 0x3d, 0x1d, 0x87, 0x9e, 0x8d, 0x43, 0x6f, 0x53, 0x4c, 0x5a, 0x0f, 0x3e, 0x24, 0x6a, 0x69, - 0x9e, 0xa8, 0x55, 0x11, 0x59, 0xc0, 0xb4, 0xe5, 0x04, 0x18, 0xa8, 0x89, 0x97, 0x13, 0xa1, 0xd0, - 0xc5, 0x04, 0x93, 0x71, 0x7d, 0x93, 0xd7, 0x67, 0xa5, 0xc0, 0x5f, 0x12, 0xf5, 0xd1, 0x18, 0xb3, - 0xaf, 0xa6, 0x43, 0xdd, 0xa3, 0xa1, 0x91, 0x0d, 0x5d, 0xfc, 0x1c, 0xc4, 0xfe, 0xb9, 0xc1, 0x2e, - 0x27, 0x28, 0xd6, 0x2d, 0xc2, 0xe6, 0x89, 0xfa, 0x71, 0x3e, 0xc5, 0x5d, 0x3c, 0xcd, 0xde, 0x13, - 0x2a, 0x7b, 0xa1, 0x81, 0xe7, 0xa0, 0x9a, 0x79, 0x8d, 0x70, 0x10, 0x20, 0xbf, 0xbe, 0xc5, 0x53, - 0x76, 0x57, 0x4e, 0xb9, 0x5f, 0x48, 0x29, 0x82, 0x69, 0xf6, 0x8e, 0x90, 0xbb, 0x5c, 0x84, 0x6f, - 0x8b, 0x4b, 0x76, 0xef, 0xbf, 0x3a, 0x26, 0x67, 0x1d, 0x83, 0x22, 0x76, 0x7e, 0x1b, 0x0b, 0xbb, - 0x09, 0xbf, 0x01, 0x30, 0x27, 0x2e, 0xa8, 0x6c, 0x73, 0x2a, 0xc7, 0x2b, 0x53, 0x69, 0xfc, 0x2d, - 0xdd, 0x92, 0xcf, 0xfd, 0x9c, 0x32, 0x23, 0x75, 0x06, 0xb6, 0xbc, 0x08, 0xb9, 0x0c, 0xf9, 0x75, - 0xc0, 0x09, 0xc9, 0xba, 0x38, 0x59, 0x7d, 0x71, 0xb2, 0x7c, 0xa9, 0xf9, 0xc9, 0x2e, 0x19, 0xed, - 0x66, 0xdb, 0x25, 0x80, 0xda, 0xfb, 0x5f, 0x55, 0xc9, 0x5e, 0x84, 0x79, 0x51, 0xfe, 0xf6, 0x3b, - 0xb5, 0xa4, 0xfd, 0x28, 0x81, 0xaa, 0xf9, 0x0e, 0x79, 0xd3, 0x34, 0xd7, 0x59, 0xe0, 0x12, 0xd8, - 0x01, 0x1b, 0x93, 0x08, 0x2f, 0x4e, 0xb7, 0xa5, 0xaf, 0x40, 0xac, 0x83, 0x3c, 0x5b, 0x80, 0xe1, - 0x33, 0x50, 0x19, 0xe1, 0x28, 0xce, 0x76, 0x9a, 0x5f, 0x61, 0xe5, 0xe8, 0xa3, 0xe2, 0x15, 0xf2, - 0xed, 0xb6, 0x01, 0xf7, 0x13, 0x37, 0xff, 0x1c, 0xec, 0xc4, 0xc8, 0xa3, 0xc4, 0xcf, 0x60, 0xeb, - 0xff, 0x0c, 0xab, 0x08, 0x47, 0x2e, 0x64, 0x5c, 0x7e, 0x92, 0x00, 0x38, 0xe1, 0x6e, 0x1d, 0x97, - 0xb9, 0xff, 0xff, 0x23, 0x04, 0x2d, 0x00, 0x02, 0x37, 0x66, 0x8e, 0xe8, 0x83, 0x38, 0xf8, 0x27, - 0x2b, 0xf4, 0x60, 0x3b, 0x45, 0x9f, 0xf1, 0x3e, 0x7c, 0x0e, 0xb6, 0x97, 0x9f, 0x52, 0xfe, 0x21, - 0xf8, 0xf7, 0xc9, 0x95, 0xf9, 0x8c, 0xee, 0x20, 0x4f, 0x7e, 0x97, 0x40, 0x25, 0xf7, 0xb5, 0x82, - 0x3a, 0x68, 0x0c, 0xac, 0x13, 0xd3, 0xb1, 0x4e, 0x9d, 0x6e, 0xdf, 0x6e, 0x9b, 0xce, 0x9b, 0xd3, - 0xd7, 0x67, 0x66, 0xdb, 0xea, 0x5a, 0x66, 0xa7, 0x56, 0x92, 0xf7, 0xae, 0xae, 0x9b, 0x95, 0x37, - 0x24, 0x9e, 0x20, 0x0f, 0x8f, 0x30, 0xf2, 0xe1, 0x73, 0xa0, 0x14, 0xfd, 0x5f, 0xf5, 0xfb, 0x1d, - 0x67, 0x60, 0xf5, 0x7a, 0x4e, 0xfb, 0xe5, 0x69, 0xdb, 0xec, 0xd5, 0x24, 0x19, 0x5e, 0x5d, 0x37, - 0x77, 0x5f, 0x51, 0xea, 0x0f, 0x70, 0x10, 0xb4, 0x5d, 0xe2, 0xa1, 0x00, 0x7e, 0x06, 0x3e, 0x29, - 0xe2, 0xac, 0x93, 0x13, 0xb3, 0x63, 0xbd, 0x1c, 0x98, 0x4e, 0xdf, 0x5e, 0x40, 0xd7, 0xe4, 0x07, - 0x57, 0xd7, 0xcd, 0xfb, 0x56, 0x18, 0x22, 0x1f, 0xbb, 0x0c, 0xf5, 0xa3, 0x0c, 0xad, 0x03, 0xb9, - 0x88, 0xee, 0xa6, 0x09, 0xfb, 0xb6, 0x73, 0x6c, 0xf5, 0x7a, 0xb5, 0x75, 0x79, 0xf7, 0xea, 0xba, - 0x09, 0xd2, 0xcd, 0xee, 0x47, 0xc7, 0x38, 0x08, 0xe4, 0xf2, 0x0f, 0xdf, 0x2b, 0x52, 0xcb, 0xfc, - 0x30, 0x53, 0xa4, 0x9b, 0x99, 0x22, 0xfd, 0x36, 0x53, 0xa4, 0xf7, 0xb7, 0x4a, 0xe9, 0xe6, 0x56, - 0x29, 0xfd, 0x7c, 0xab, 0x94, 0xbe, 0x7c, 0x9a, 0x6b, 0x3c, 0x3a, 0x08, 0x29, 0x41, 0x97, 0x06, - 0x0a, 0x0f, 0x02, 0xe4, 0x8f, 0x51, 0x64, 0xbc, 0x5b, 0xfc, 0xf3, 0xf1, 0x09, 0x0c, 0x37, 0x79, - 0x5f, 0x3f, 0xfd, 0x33, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x22, 0xa6, 0x88, 0x13, 0x07, 0x00, 0x00, + 0x14, 0x17, 0xfd, 0x37, 0x3e, 0x5a, 0xb6, 0x72, 0x75, 0x52, 0x89, 0x03, 0xa9, 0x12, 0x68, 0x10, + 0x24, 0x30, 0x09, 0xbb, 0x41, 0x86, 0xa0, 0x28, 0x10, 0x49, 0x54, 0x4a, 0x58, 0xb6, 0x0c, 0x46, + 0x41, 0x80, 0x2e, 0x04, 0x45, 0x9e, 0xd4, 0x83, 0xc9, 0x3b, 0x81, 0x3c, 0xb9, 0x71, 0x3f, 0x82, + 0xa7, 0x8c, 0x5d, 0x0c, 0x74, 0xe8, 0xd0, 0x8f, 0x92, 0x6e, 0xe9, 0x56, 0x74, 0x60, 0x0b, 0x79, + 0xea, 0xaa, 0x4f, 0x50, 0xf0, 0x8e, 0x94, 0xa9, 0x14, 0x6d, 0xe0, 0x4e, 0xbc, 0xf7, 0xe7, 0xf7, + 0xfe, 0xbf, 0x47, 0xd0, 0x40, 0x91, 0x19, 0x79, 0xf1, 0x19, 0x62, 0xe6, 0xf9, 0x41, 0xfe, 0x32, + 0x26, 0x31, 0x65, 0x14, 0x6e, 0xa3, 0xc8, 0xc8, 0x19, 0xe7, 0x07, 0xca, 0xde, 0x98, 0x8e, 0x29, + 0x17, 0x98, 0xd9, 0x4b, 0xe8, 0x28, 0xda, 0x98, 0xd2, 0x71, 0x88, 0x4c, 0x4e, 0x0d, 0xa7, 0x23, + 0x93, 0xe1, 0x08, 0x25, 0xcc, 0x8b, 0x26, 0xb9, 0x82, 0xea, 0xd3, 0x24, 0xa2, 0x89, 0x39, 0xf4, + 0x12, 0x64, 0x9e, 0x1f, 0x0c, 0x11, 0xf3, 0x0e, 0x4c, 0x9f, 0x62, 0x22, 0xe4, 0x7a, 0x17, 0x00, + 0x9b, 0x24, 0x2c, 0x9e, 0x46, 0x88, 0x30, 0x78, 0x1f, 0x6c, 0x24, 0x74, 0x1a, 0xfb, 0xa8, 0x2e, + 0x35, 0xa5, 0x87, 0x5b, 0x4e, 0x4e, 0xc1, 0x26, 0x90, 0x03, 0x94, 0x30, 0x4c, 0x3c, 0x86, 0x29, + 0xa9, 0xaf, 0x70, 0x61, 0x99, 0xa5, 0xa7, 0x9b, 0x60, 0xbd, 0x1f, 0x07, 0x28, 0x86, 0x4f, 0xc0, + 0x1d, 0x9a, 0x3d, 0x5c, 0x1c, 0x70, 0x2b, 0x6b, 0xad, 0xc6, 0x2c, 0xd5, 0x56, 0xec, 0xce, 0x3c, + 0xd5, 0x76, 0x2f, 0xbc, 0x28, 0x7c, 0xa6, 0x17, 0x72, 0xdd, 0xd9, 0xe4, 0x4f, 0x3b, 0x80, 0xaf, + 0x41, 0x35, 0x0b, 0xdd, 0xc5, 0xc4, 0x1d, 0xd1, 0x2c, 0x80, 0xcc, 0xc7, 0xce, 0x61, 0xc3, 0x28, + 0x17, 0xc1, 0x18, 0xe0, 0x08, 0xd9, 0xa4, 0x9b, 0x29, 0xb4, 0xea, 0xf3, 0x54, 0xdb, 0x13, 0xf6, + 0x96, 0x90, 0xba, 0x23, 0xb3, 0x1b, 0x35, 0xf8, 0x00, 0xac, 0xd3, 0xef, 0x08, 0x8a, 0xeb, 0xab, + 0x59, 0xd0, 0xad, 0xda, 0x3c, 0xd5, 0xb6, 0xf3, 0x28, 0x32, 0xb6, 0xee, 0x08, 0x31, 0x7c, 0x09, + 0x76, 0xfd, 0x10, 0x23, 0xc2, 0xdc, 0x45, 0xf4, 0x6b, 0x1c, 0xf1, 0x78, 0x96, 0x6a, 0xd5, 0x36, + 0x17, 0xf1, 0x04, 0x79, 0x22, 0xf7, 0x85, 0x89, 0x0f, 0x10, 0xba, 0x53, 0xf5, 0x4b, 0x8a, 0x01, + 0xfc, 0x7a, 0x51, 0xcf, 0xf5, 0xa6, 0xf4, 0x50, 0x3e, 0x6c, 0x18, 0xa2, 0x1d, 0x46, 0xd6, 0x0e, + 0x23, 0x6f, 0x87, 0xd1, 0xa6, 0x98, 0xb4, 0xee, 0xbd, 0x4b, 0xb5, 0xca, 0x3c, 0xd5, 0xaa, 0xc2, + 0xb2, 0x80, 0xe9, 0x8b, 0x0e, 0x30, 0x50, 0x13, 0x2f, 0x37, 0x46, 0x91, 0x87, 0x09, 0x26, 0xe3, + 0xfa, 0x06, 0x8f, 0xcf, 0xce, 0x80, 0xbf, 0xa7, 0xda, 0x83, 0x31, 0x66, 0xdf, 0x4e, 0x87, 0x86, + 0x4f, 0x23, 0x33, 0x6f, 0xba, 0xf8, 0xec, 0x27, 0xc1, 0x99, 0xc9, 0x2e, 0x26, 0x28, 0x31, 0x6c, + 0xc2, 0xe6, 0xa9, 0xf6, 0x69, 0xd9, 0xc5, 0x8d, 0x3d, 0xdd, 0xd9, 0x15, 0x2c, 0xa7, 0xe0, 0xc0, + 0x33, 0x50, 0xcd, 0xb5, 0x46, 0x38, 0x0c, 0x51, 0x50, 0xdf, 0xe4, 0x2e, 0xbb, 0xb7, 0x76, 0xb9, + 0xb7, 0xe4, 0x52, 0x18, 0xd3, 0x9d, 0x6d, 0x41, 0x77, 0x39, 0x09, 0x5f, 0x2f, 0x0f, 0xd9, 0x9d, + 0x8f, 0x55, 0x4c, 0xc9, 0x2b, 0x06, 0x85, 0xed, 0xf2, 0x34, 0x2e, 0xcd, 0x26, 0xfc, 0x1e, 0xc0, + 0x12, 0x59, 0xa4, 0xb2, 0xc5, 0x53, 0x39, 0xba, 0x75, 0x2a, 0x8d, 0x7f, 0xb8, 0x5b, 0xe4, 0x73, + 0xb7, 0xc4, 0xcc, 0x93, 0x3a, 0x05, 0x9b, 0x7e, 0x8c, 0x3c, 0x86, 0x82, 0x3a, 0xe0, 0x09, 0x29, + 0x86, 0x58, 0x59, 0xa3, 0x58, 0x59, 0x3e, 0xd4, 0x7c, 0x65, 0x17, 0x19, 0xed, 0xe4, 0xd3, 0x25, + 0x80, 0xfa, 0xdb, 0x3f, 0x34, 0xc9, 0x29, 0xcc, 0x40, 0x0a, 0x20, 0x8d, 0xf1, 0x38, 0x1f, 0xba, + 0xc2, 0xb8, 0xfc, 0x51, 0xe3, 0x9f, 0xe7, 0xc6, 0x1b, 0xc5, 0x0e, 0x7e, 0x68, 0x43, 0xf8, 0xa9, + 0x65, 0x02, 0x3e, 0xbf, 0x6d, 0xc1, 0x7e, 0xb6, 0xf6, 0xc3, 0x8f, 0x5a, 0x45, 0xff, 0x45, 0x02, + 0x55, 0xeb, 0x0d, 0xf2, 0xa7, 0x59, 0x72, 0xa7, 0xa1, 0x47, 0x60, 0x07, 0xac, 0x4f, 0x62, 0x5c, + 0xdc, 0x8a, 0x96, 0x71, 0x8b, 0x4a, 0x76, 0x90, 0xef, 0x08, 0x30, 0x7c, 0x02, 0xe4, 0x11, 0x8e, + 0x93, 0x7c, 0x89, 0xf8, 0xda, 0xcb, 0x87, 0x9f, 0x2c, 0xaf, 0x3d, 0x0f, 0xc7, 0x01, 0x5c, 0x4f, + 0x1c, 0x99, 0xa7, 0x60, 0x3b, 0x41, 0x3e, 0x25, 0x41, 0x0e, 0x5b, 0xfd, 0x77, 0x98, 0x2c, 0x14, + 0x39, 0x91, 0xe7, 0xf2, 0xab, 0x04, 0xc0, 0x31, 0x57, 0xeb, 0x78, 0xcc, 0xfb, 0xff, 0x57, 0x0f, + 0xda, 0x00, 0x84, 0x5e, 0xc2, 0x5c, 0x51, 0x07, 0x71, 0x61, 0x1e, 0xdd, 0xa2, 0x06, 0x5b, 0x19, + 0xfa, 0x94, 0xd7, 0xe1, 0x2b, 0xb0, 0xb5, 0xb8, 0xdd, 0xfc, 0xf2, 0xfc, 0x77, 0x37, 0xd7, 0x78, + 0xb3, 0x6e, 0x20, 0x8f, 0xfe, 0x92, 0x80, 0x5c, 0x3a, 0x8f, 0xd0, 0x00, 0x8d, 0x81, 0x7d, 0x6c, + 0xb9, 0xf6, 0x89, 0xdb, 0xed, 0x3b, 0x6d, 0xcb, 0x7d, 0x75, 0xf2, 0xf2, 0xd4, 0x6a, 0xdb, 0x5d, + 0xdb, 0xea, 0xd4, 0x2a, 0xca, 0xee, 0xe5, 0x55, 0x53, 0x7e, 0x45, 0x92, 0x09, 0xf2, 0xf1, 0x08, + 0xa3, 0x00, 0x3e, 0x05, 0xea, 0xb2, 0xfe, 0x8b, 0x7e, 0xbf, 0xe3, 0x0e, 0xec, 0x5e, 0xcf, 0x6d, + 0x3f, 0x3f, 0x69, 0x5b, 0xbd, 0x9a, 0xa4, 0xc0, 0xcb, 0xab, 0xe6, 0xce, 0x0b, 0x4a, 0x83, 0x01, + 0x0e, 0xc3, 0xb6, 0x47, 0x7c, 0x14, 0xc2, 0x2f, 0xc1, 0x67, 0xcb, 0x38, 0xfb, 0xf8, 0xd8, 0xea, + 0xd8, 0xcf, 0x07, 0x96, 0xdb, 0x77, 0x0a, 0xe8, 0x8a, 0x72, 0xef, 0xf2, 0xaa, 0x79, 0xd7, 0x8e, + 0x22, 0x14, 0x60, 0x8f, 0xa1, 0x7e, 0x9c, 0xa3, 0x0d, 0xa0, 0x2c, 0xa3, 0xbb, 0x99, 0xc3, 0xbe, + 0xe3, 0x1e, 0xd9, 0xbd, 0x5e, 0x6d, 0x55, 0xd9, 0xb9, 0xbc, 0x6a, 0x82, 0x6c, 0x95, 0xfa, 0xf1, + 0x11, 0x0e, 0x43, 0x65, 0xed, 0xe7, 0x9f, 0x54, 0xa9, 0x65, 0xbd, 0x9b, 0xa9, 0xd2, 0xfb, 0x99, + 0x2a, 0xfd, 0x39, 0x53, 0xa5, 0xb7, 0xd7, 0x6a, 0xe5, 0xfd, 0xb5, 0x5a, 0xf9, 0xed, 0x5a, 0xad, + 0x7c, 0xf3, 0xb8, 0x54, 0x78, 0xb4, 0x1f, 0x51, 0x82, 0x2e, 0x4c, 0x14, 0xed, 0x87, 0x28, 0x18, + 0xa3, 0xd8, 0x7c, 0x53, 0xfc, 0x6a, 0x79, 0x07, 0x86, 0x1b, 0xbc, 0xae, 0x5f, 0xfc, 0x1d, 0x00, + 0x00, 0xff, 0xff, 0x8f, 0xfc, 0x7b, 0x76, 0x84, 0x07, 0x00, 0x00, } func (m *Instrument) Marshal() (dAtA []byte, err error) { @@ -446,13 +458,21 @@ func (m *Order) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.OrigOrderCreated, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.OrigOrderCreated):]) if err1 != nil { return 0, err1 } i -= n1 i = encodeVarintMarket(dAtA, i, uint64(n1)) i-- + dAtA[i] = 0x5a + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) + if err2 != nil { + return 0, err2 + } + i -= n2 + i = encodeVarintMarket(dAtA, i, uint64(n2)) + i-- dAtA[i] = 0x52 { size := m.DestinationFilled.Size() @@ -609,12 +629,12 @@ func (m *MarketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l if m.Timestamp != nil { - n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Timestamp):]) - if err6 != nil { - return 0, err6 + n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Timestamp):]) + if err7 != nil { + return 0, err7 } - i -= n6 - i = encodeVarintMarket(dAtA, i, uint64(n6)) + i -= n7 + i = encodeVarintMarket(dAtA, i, uint64(n7)) i-- dAtA[i] = 0x22 } @@ -707,6 +727,8 @@ func (m *Order) Size() (n int) { n += 1 + l + sovMarket(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Created) n += 1 + l + sovMarket(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.OrigOrderCreated) + n += 1 + l + sovMarket(uint64(l)) return n } @@ -1206,6 +1228,39 @@ func (m *Order) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OrigOrderCreated", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMarket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMarket + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMarket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.OrigOrderCreated, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMarket(dAtA[iNdEx:]) diff --git a/x/market/types/tx.pb.go b/x/market/types/tx.pb.go index a9b0dd01..1c104475 100644 --- a/x/market/types/tx.pb.go +++ b/x/market/types/tx.pb.go @@ -31,105 +31,67 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type TxMessageType int32 - -const ( - // Tx fallback for fees etc. - TxMessageType_DefaultTxMsg TxMessageType = 0 - TxMessageType_AddLimitOrder TxMessageType = 1 - TxMessageType_AddMarketOrder TxMessageType = 2 - TxMessageType_CancelReplaceLimitOrder TxMessageType = 3 - TxMessageType_CancelReplaceMarketOrder TxMessageType = 4 - TxMessageType_CancelOrder TxMessageType = 5 -) - -var TxMessageType_name = map[int32]string{ - 0: "DEFAULT_TX_MSG", - 1: "ADD_LIMIT_ORDER", - 2: "ADD_MARKET_ORDER", - 3: "CANCEL_REPLACE_LIMIT_ORDER", - 4: "CANCEL_REPLACE_MARKET_ORDER", - 5: "CANCEL_ORDER", -} - -var TxMessageType_value = map[string]int32{ - "DEFAULT_TX_MSG": 0, - "ADD_LIMIT_ORDER": 1, - "ADD_MARKET_ORDER": 2, - "CANCEL_REPLACE_LIMIT_ORDER": 3, - "CANCEL_REPLACE_MARKET_ORDER": 4, - "CANCEL_ORDER": 5, -} - -func (x TxMessageType) String() string { - return proto.EnumName(TxMessageType_name, int32(x)) -} - -func (TxMessageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_636272ab2288df51, []int{0} -} - type TxParams struct { // default fee for a market transaction. TrxFee uint64 `protobuf:"varint,1,opt,name=trx_fee,json=trxFee,proto3" json:"trx_fee,omitempty" yaml:"trx_fee"` // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee LiquidTrxFee uint64 `protobuf:"varint,2,opt,name=liquid_trx_fee,json=liquidTrxFee,proto3" json:"liquid_trx_fee,omitempty" yaml:"liquid_trx_fee"` - // Minutes interval for the liquidity rebate to apply. For the liquidity - // rebate to apply, the running transaction should occur x minutes - // after the signers' last liquid trx. + // Minutes interval for eligible replacing liquidity transactions to qualify + // for the rebate. For the rebate to apply, the replacing transaction should + // occur x minutes after the signer's original trx. LiquidityRebateMinutesSpan int64 `protobuf:"varint,3,opt,name=liquidity_rebate_minutes_span,json=liquidityRebateMinutesSpan,proto3" json:"liquidity_rebate_minutes_span,omitempty" yaml:"liquidity_rebate_minutes_span"` } -func (p *TxParams) Reset() { *p = TxParams{} } -func (p *TxParams) String() string { return proto.CompactTextString(p) } +func (m *TxParams) Reset() { *m = TxParams{} } +func (m *TxParams) String() string { return proto.CompactTextString(m) } func (*TxParams) ProtoMessage() {} func (*TxParams) Descriptor() ([]byte, []int) { return fileDescriptor_636272ab2288df51, []int{0} } -func (p *TxParams) XXX_Unmarshal(b []byte) error { - return p.Unmarshal(b) +func (m *TxParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } -func (p *TxParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *TxParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_TxParams.Marshal(b, p, deterministic) + return xxx_messageInfo_TxParams.Marshal(b, m, deterministic) } else { b = b[:cap(b)] - n, err := p.MarshalToSizedBuffer(b) + n, err := m.MarshalToSizedBuffer(b) if err != nil { return nil, err } return b[:n], nil } } -func (p *TxParams) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxParams.Merge(p, src) +func (m *TxParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_TxParams.Merge(m, src) } -func (p *TxParams) XXX_Size() int { - return p.Size() +func (m *TxParams) XXX_Size() int { + return m.Size() } -func (p *TxParams) XXX_DiscardUnknown() { - xxx_messageInfo_TxParams.DiscardUnknown(p) +func (m *TxParams) XXX_DiscardUnknown() { + xxx_messageInfo_TxParams.DiscardUnknown(m) } var xxx_messageInfo_TxParams proto.InternalMessageInfo -func (p *TxParams) GetTrxFee() uint64 { - if p != nil { - return p.TrxFee +func (m *TxParams) GetTrxFee() uint64 { + if m != nil { + return m.TrxFee } return 0 } -func (p *TxParams) GetLiquidTrxFee() uint64 { - if p != nil { - return p.LiquidTrxFee +func (m *TxParams) GetLiquidTrxFee() uint64 { + if m != nil { + return m.LiquidTrxFee } return 0 } -func (p *TxParams) GetLiquidityRebateMinutesSpan() int64 { - if p != nil { - return p.LiquidityRebateMinutesSpan +func (m *TxParams) GetLiquidityRebateMinutesSpan() int64 { + if m != nil { + return m.LiquidityRebateMinutesSpan } return 0 } @@ -689,7 +651,6 @@ func (m *MsgCancelReplaceMarketOrderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCancelReplaceMarketOrderResponse proto.InternalMessageInfo func init() { - proto.RegisterEnum("em.market.v1.TxMessageType", TxMessageType_name, TxMessageType_value) proto.RegisterType((*TxParams)(nil), "em.market.v1.TxParams") proto.RegisterType((*MsgAddLimitOrder)(nil), "em.market.v1.MsgAddLimitOrder") proto.RegisterType((*MsgAddLimitOrderResponse)(nil), "em.market.v1.MsgAddLimitOrderResponse") @@ -706,74 +667,64 @@ func init() { func init() { proto.RegisterFile("em/market/v1/tx.proto", fileDescriptor_636272ab2288df51) } var fileDescriptor_636272ab2288df51 = []byte{ - // 1061 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0xcb, 0x6f, 0xe3, 0x44, - 0x18, 0x8f, 0x9b, 0xc7, 0xd2, 0xc9, 0xa3, 0xa9, 0xd9, 0xee, 0x26, 0xee, 0x12, 0x07, 0x53, 0x4a, - 0x96, 0x55, 0x6d, 0x52, 0x2e, 0x08, 0x84, 0x50, 0x5e, 0x85, 0x8a, 0x78, 0xbb, 0xb8, 0x41, 0x5d, - 0xed, 0xc5, 0x72, 0x92, 0xa9, 0x19, 0xd5, 0x8f, 0xac, 0xed, 0xb4, 0x8e, 0xc4, 0x8d, 0x5b, 0x4e, - 0x9c, 0xb8, 0xe5, 0xc6, 0x81, 0x03, 0x7f, 0xc8, 0x1e, 0xf7, 0x88, 0x38, 0x58, 0x28, 0x15, 0xff, - 0x40, 0x8e, 0x1c, 0x56, 0xc8, 0x1e, 0x27, 0x38, 0x4e, 0xd3, 0x2d, 0x55, 0xe9, 0x01, 0xed, 0xa9, - 0xcd, 0xfc, 0x1e, 0xdf, 0xcc, 0xf7, 0x7d, 0xf3, 0xd9, 0x06, 0x1b, 0x50, 0xe5, 0x54, 0xc9, 0x38, - 0x81, 0x16, 0x77, 0x5a, 0xe6, 0x2c, 0x9b, 0xed, 0x19, 0xba, 0xa5, 0x93, 0x29, 0xa8, 0xb2, 0x78, - 0x99, 0x3d, 0x2d, 0x53, 0x77, 0x65, 0x5d, 0xd6, 0x3d, 0x80, 0x73, 0xff, 0xc3, 0x1c, 0xaa, 0xd0, - 0xd1, 0x4d, 0x55, 0x37, 0xb9, 0xb6, 0x64, 0x42, 0xee, 0xb4, 0xdc, 0x86, 0x96, 0x54, 0xe6, 0x3a, - 0x3a, 0xd2, 0x7c, 0x3c, 0x3f, 0x67, 0xed, 0xbb, 0x61, 0x88, 0x96, 0x75, 0x5d, 0x56, 0x20, 0xe7, - 0xfd, 0x6a, 0xf7, 0x8f, 0x39, 0x0b, 0xa9, 0xd0, 0xb4, 0x24, 0xb5, 0x87, 0x09, 0xcc, 0x9f, 0x04, - 0x78, 0xab, 0x65, 0x3f, 0x91, 0x0c, 0x49, 0x35, 0xc9, 0x47, 0xe0, 0x8e, 0x65, 0xd8, 0xe2, 0x31, - 0x84, 0x39, 0xa2, 0x48, 0x94, 0x62, 0x55, 0x72, 0xe2, 0xd0, 0x99, 0x81, 0xa4, 0x2a, 0x9f, 0x32, - 0x3e, 0xc0, 0x08, 0x09, 0xcb, 0xb0, 0xf7, 0x20, 0x24, 0xbf, 0x00, 0x19, 0x05, 0x3d, 0xef, 0xa3, - 0xae, 0x38, 0xd5, 0xac, 0x78, 0x9a, 0xfc, 0xc4, 0xa1, 0x37, 0xb0, 0x66, 0x1e, 0x67, 0x84, 0x14, - 0x5e, 0x68, 0x61, 0x83, 0x13, 0xf0, 0x0e, 0xfe, 0x8d, 0xac, 0x81, 0x68, 0xc0, 0xb6, 0x64, 0x41, - 0x51, 0x45, 0x5a, 0xdf, 0x82, 0xa6, 0x68, 0xf6, 0x24, 0x2d, 0x17, 0x2d, 0x12, 0xa5, 0x68, 0xb5, - 0x34, 0x71, 0xe8, 0xad, 0xa0, 0xdf, 0x12, 0x3a, 0x23, 0x50, 0x33, 0x5c, 0xf0, 0x60, 0x1e, 0xa3, - 0x87, 0x2e, 0xf8, 0xd7, 0x0a, 0xc8, 0xf2, 0xa6, 0x5c, 0xe9, 0x76, 0x9b, 0x48, 0x45, 0xd6, 0x81, - 0xd1, 0x85, 0x06, 0xb9, 0x0d, 0xe2, 0xfa, 0x99, 0x06, 0x0d, 0xef, 0xb4, 0xab, 0xd5, 0xec, 0xc4, - 0xa1, 0x53, 0x38, 0x92, 0xb7, 0xcc, 0x08, 0x18, 0x26, 0xab, 0x60, 0xad, 0xa3, 0x20, 0xa8, 0x59, - 0xa2, 0xee, 0xea, 0x44, 0xd4, 0xf5, 0xce, 0xba, 0x5a, 0xa5, 0x26, 0x0e, 0x7d, 0x0f, 0x2b, 0x42, - 0x04, 0x46, 0x48, 0xe3, 0x15, 0x2f, 0xd2, 0x7e, 0x97, 0x3c, 0x02, 0x69, 0x37, 0xf7, 0x22, 0xd2, - 0xc4, 0x63, 0xdd, 0xe8, 0x40, 0xef, 0x74, 0x99, 0xdd, 0x3c, 0x1b, 0x6c, 0x00, 0xb6, 0x85, 0x54, - 0xb8, 0xaf, 0xed, 0xb9, 0x84, 0x6a, 0x6e, 0xe2, 0xd0, 0x77, 0xfd, 0xe4, 0x07, 0x95, 0x8c, 0x90, - 0xb4, 0xfe, 0xa1, 0x91, 0x5f, 0x81, 0x84, 0xa9, 0xf7, 0x5d, 0xc7, 0x58, 0x91, 0x28, 0x25, 0x77, - 0xf3, 0x2c, 0x6e, 0x17, 0xd6, 0x6d, 0x17, 0xd6, 0x6f, 0x17, 0xb6, 0xa6, 0x23, 0xad, 0xba, 0xf1, - 0xc2, 0xa1, 0x23, 0x13, 0x87, 0x4e, 0x63, 0x57, 0x2c, 0x63, 0x04, 0x5f, 0x4f, 0x1e, 0x81, 0x64, - 0x17, 0x9a, 0x16, 0xd2, 0x24, 0x0b, 0xe9, 0x5a, 0x2e, 0xfe, 0x3a, 0x3b, 0xca, 0xb7, 0x23, 0xb1, - 0x5d, 0x40, 0xcb, 0x08, 0x41, 0x27, 0x86, 0x02, 0xb9, 0x70, 0xee, 0x05, 0x68, 0xf6, 0x74, 0xcd, - 0x84, 0xcc, 0x38, 0x0a, 0xd6, 0x31, 0xc8, 0x7b, 0x59, 0xf8, 0x1f, 0x55, 0xe6, 0xe1, 0x5c, 0x65, - 0x56, 0xab, 0xeb, 0xb7, 0x9f, 0x7a, 0xf2, 0x07, 0x02, 0x64, 0x55, 0xc9, 0x46, 0x6a, 0x5f, 0x15, - 0x4d, 0x05, 0xf5, 0x7a, 0x92, 0x0c, 0x73, 0x09, 0x6f, 0x3b, 0x4f, 0x5d, 0x8f, 0xdf, 0x1d, 0x7a, - 0x5b, 0x46, 0xd6, 0x77, 0xfd, 0x36, 0xdb, 0xd1, 0x55, 0xce, 0x9f, 0x34, 0xf8, 0xcf, 0x8e, 0xd9, - 0x3d, 0xe1, 0xac, 0x41, 0x0f, 0x9a, 0x6c, 0x1d, 0x76, 0xc6, 0x0e, 0x9d, 0xe4, 0x25, 0xfb, 0xd0, - 0x37, 0x99, 0x38, 0xf4, 0x7d, 0x1c, 0x3c, 0x6c, 0xcf, 0x08, 0x6b, 0xfe, 0xd2, 0x94, 0xcb, 0x6c, - 0x82, 0xfc, 0x42, 0x8d, 0x67, 0x1d, 0xf0, 0x3d, 0xc8, 0xf0, 0xa6, 0x5c, 0x93, 0xb4, 0x0e, 0x54, - 0x6e, 0xbd, 0xfa, 0x4c, 0x0e, 0xdc, 0x9b, 0x8f, 0x3e, 0xdb, 0xd7, 0x4f, 0x31, 0x40, 0xcd, 0x20, - 0x01, 0xf6, 0x14, 0xa9, 0x03, 0xaf, 0x31, 0x3c, 0x9e, 0x83, 0x9c, 0x6e, 0x20, 0x19, 0x69, 0x92, - 0x22, 0x5e, 0xbc, 0xdb, 0x4f, 0xc6, 0x0e, 0xbd, 0x7e, 0x60, 0x20, 0xb9, 0x16, 0xdc, 0xd9, 0xc4, - 0xa1, 0x69, 0xdf, 0x6f, 0x89, 0x9c, 0x11, 0x36, 0xa6, 0xd0, 0x9c, 0x92, 0x94, 0xc0, 0xdb, 0x1a, - 0x3c, 0x5b, 0x88, 0x16, 0xf5, 0xa2, 0xed, 0x8e, 0x1d, 0x3a, 0xfb, 0x18, 0x9e, 0x85, 0x83, 0x51, - 0x38, 0xd8, 0x05, 0x42, 0x46, 0xc8, 0x6a, 0x21, 0xfe, 0xe2, 0xa5, 0x89, 0xdd, 0xf8, 0x38, 0x8b, - 0xdf, 0xec, 0x38, 0x4b, 0xdc, 0xd8, 0x38, 0xdb, 0x02, 0xcc, 0xf2, 0xbe, 0x98, 0xb5, 0xcf, 0xab, - 0x18, 0xd8, 0x0c, 0xd3, 0xae, 0x33, 0xe2, 0xde, 0xf4, 0xcf, 0x35, 0x87, 0x6e, 0xfc, 0x5f, 0x0e, - 0xdd, 0xc4, 0x7f, 0x3b, 0x74, 0xef, 0xdc, 0xf6, 0xd0, 0x7d, 0x1f, 0xbc, 0x77, 0x49, 0xff, 0x4d, - 0xfb, 0xf4, 0xc3, 0x5f, 0x57, 0x40, 0xba, 0x65, 0xf3, 0xd0, 0x34, 0x25, 0x19, 0xb6, 0x06, 0x3d, - 0x48, 0x6e, 0x81, 0x4c, 0xbd, 0xb1, 0x57, 0xf9, 0xb6, 0xd9, 0x12, 0x5b, 0x4f, 0x45, 0xfe, 0xf0, - 0xcb, 0x6c, 0x84, 0xca, 0x0e, 0x47, 0xc5, 0x54, 0x1d, 0x1e, 0x4b, 0x7d, 0xc5, 0x6a, 0xd9, 0xbc, - 0x29, 0x93, 0xdb, 0x60, 0xad, 0x52, 0xaf, 0x8b, 0xcd, 0x7d, 0x7e, 0xbf, 0x25, 0x1e, 0x08, 0xf5, - 0x86, 0x90, 0x25, 0xa8, 0xf5, 0xe1, 0xa8, 0x98, 0x9e, 0x7f, 0xc9, 0x2a, 0x81, 0xac, 0xcb, 0xe3, - 0x2b, 0xc2, 0xd7, 0x8d, 0x29, 0x71, 0x85, 0x22, 0x87, 0xa3, 0x62, 0x26, 0xf4, 0xd0, 0xff, 0x0c, - 0x50, 0xb5, 0xca, 0xe3, 0x5a, 0xa3, 0x29, 0x0a, 0x8d, 0x27, 0xcd, 0x4a, 0xad, 0x31, 0x67, 0x1e, - 0xa5, 0x36, 0x87, 0xa3, 0xe2, 0xfd, 0x65, 0xe3, 0xf8, 0x73, 0xb0, 0x19, 0x12, 0xcf, 0x45, 0x8c, - 0x51, 0x0f, 0x86, 0xa3, 0x62, 0x6e, 0xe9, 0x6d, 0x7c, 0x17, 0xa4, 0x7c, 0x39, 0xe6, 0xc7, 0xa9, - 0xb5, 0xe1, 0xa8, 0x98, 0x0c, 0x3c, 0x17, 0xa8, 0xd8, 0x2f, 0x3f, 0x17, 0x88, 0xdd, 0x57, 0x51, - 0x10, 0x75, 0x8f, 0x7f, 0x04, 0x42, 0xe7, 0x2c, 0xcc, 0xb7, 0x6e, 0xf8, 0x85, 0x87, 0xda, 0xbe, - 0x1c, 0x9f, 0xd6, 0x83, 0x7c, 0x06, 0xc2, 0x79, 0xa1, 0x2f, 0x52, 0x06, 0x08, 0xd4, 0x07, 0xaf, - 0x21, 0xcc, 0xbc, 0xbf, 0x01, 0xc1, 0x13, 0x91, 0x0f, 0x16, 0x74, 0xc1, 0xf3, 0x6e, 0x5d, 0x86, - 0xce, 0x2c, 0xfb, 0x60, 0x69, 0x49, 0x4a, 0x4b, 0x0c, 0x16, 0x98, 0xd4, 0x47, 0x57, 0x65, 0xce, - 0xc2, 0xda, 0x60, 0x79, 0x2d, 0x1f, 0x5e, 0xee, 0x16, 0xcc, 0x5c, 0xf9, 0xca, 0xd4, 0x69, 0xe4, - 0x6a, 0xe3, 0xc5, 0xb8, 0x40, 0xbc, 0x1c, 0x17, 0x88, 0x3f, 0xc6, 0x05, 0xe2, 0xc7, 0xf3, 0x42, - 0xe4, 0xe5, 0x79, 0x21, 0xf2, 0xdb, 0x79, 0x21, 0xf2, 0xec, 0x51, 0xe0, 0x4e, 0xc3, 0x1d, 0x55, - 0xd7, 0xe0, 0x80, 0x83, 0xea, 0x8e, 0x02, 0xbb, 0x32, 0x34, 0x38, 0x7b, 0xfa, 0x8d, 0xe6, 0x5d, - 0xee, 0x76, 0xc2, 0xfb, 0xfe, 0xfa, 0xf8, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd6, 0xf0, 0xc2, - 0x4b, 0x18, 0x0e, 0x00, 0x00, + // 898 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0xcf, 0x6f, 0xdb, 0x54, + 0x1c, 0xaf, 0x97, 0x34, 0xa3, 0x2f, 0x6d, 0x96, 0x9a, 0x75, 0x73, 0x3c, 0x88, 0xab, 0x47, 0x29, + 0x99, 0xa6, 0xda, 0xa4, 0x5c, 0x10, 0x17, 0x84, 0x0b, 0x13, 0x93, 0x08, 0x03, 0xaf, 0xd2, 0xd0, + 0x2e, 0x96, 0x13, 0x7f, 0x6b, 0x9e, 0x6a, 0xfb, 0x65, 0x7e, 0x2f, 0x6d, 0x2a, 0x71, 0xe3, 0x1f, + 0xe0, 0xc4, 0xdf, 0xb4, 0xe3, 0x8e, 0x88, 0x83, 0x85, 0x52, 0xf1, 0x0f, 0xf8, 0xc8, 0x61, 0x42, + 0xf6, 0x73, 0x82, 0x93, 0x34, 0xd9, 0xa8, 0x4a, 0x0f, 0x68, 0xa7, 0xc4, 0xef, 0xf3, 0xe3, 0xfb, + 0xfc, 0xbe, 0xdf, 0x7c, 0x1c, 0xa3, 0x2d, 0x08, 0x8c, 0xc0, 0x89, 0x8e, 0x81, 0x1b, 0x27, 0x6d, + 0x83, 0x0f, 0xf5, 0x7e, 0x44, 0x39, 0x95, 0xd7, 0x21, 0xd0, 0xc5, 0xb2, 0x7e, 0xd2, 0x56, 0x6f, + 0x7b, 0xd4, 0xa3, 0x19, 0x60, 0xa4, 0xdf, 0x04, 0x47, 0x6d, 0xf6, 0x28, 0x0b, 0x28, 0x33, 0xba, + 0x0e, 0x03, 0xe3, 0xa4, 0xdd, 0x05, 0xee, 0xb4, 0x8d, 0x1e, 0x25, 0x61, 0x8e, 0x37, 0xa6, 0xac, + 0x73, 0x37, 0x01, 0x69, 0x1e, 0xa5, 0x9e, 0x0f, 0x46, 0x76, 0xd5, 0x1d, 0x1c, 0x19, 0x9c, 0x04, + 0xc0, 0xb8, 0x13, 0xf4, 0x05, 0x01, 0xff, 0x29, 0xa1, 0x77, 0x0e, 0x87, 0xdf, 0x39, 0x91, 0x13, + 0x30, 0xf9, 0x01, 0xba, 0xc9, 0xa3, 0xa1, 0x7d, 0x04, 0xa0, 0x48, 0xdb, 0x52, 0xab, 0x6c, 0xca, + 0x49, 0xac, 0xd5, 0xce, 0x9c, 0xc0, 0xff, 0x0c, 0xe7, 0x00, 0xb6, 0x2a, 0x3c, 0x1a, 0x3e, 0x04, + 0x90, 0x3f, 0x47, 0x35, 0x9f, 0x3c, 0x1f, 0x10, 0xd7, 0x1e, 0x6b, 0x6e, 0x64, 0x9a, 0x46, 0x12, + 0x6b, 0x5b, 0x42, 0x33, 0x8d, 0x63, 0x6b, 0x5d, 0x2c, 0x1c, 0x0a, 0x83, 0x63, 0xf4, 0xbe, 0xb8, + 0x26, 0xfc, 0xcc, 0x8e, 0xa0, 0xeb, 0x70, 0xb0, 0x03, 0x12, 0x0e, 0x38, 0x30, 0x9b, 0xf5, 0x9d, + 0x50, 0x29, 0x6d, 0x4b, 0xad, 0x92, 0xd9, 0x4a, 0x62, 0x6d, 0xa7, 0xe8, 0xb7, 0x80, 0x8e, 0x2d, + 0x75, 0x82, 0x5b, 0x19, 0xdc, 0x11, 0xe8, 0x93, 0x14, 0xfc, 0xeb, 0x06, 0xaa, 0x77, 0x98, 0xf7, + 0x85, 0xeb, 0x7e, 0x43, 0x02, 0xc2, 0x1f, 0x47, 0x2e, 0x44, 0xf2, 0x2e, 0x5a, 0xa5, 0xa7, 0x21, + 0x44, 0xd9, 0xdd, 0xae, 0x99, 0xf5, 0x24, 0xd6, 0xd6, 0x45, 0xa5, 0x6c, 0x19, 0x5b, 0x02, 0x96, + 0x4d, 0x74, 0xab, 0xe7, 0x13, 0x08, 0xb9, 0x4d, 0x53, 0x9d, 0x4d, 0xdc, 0xec, 0x5e, 0xd7, 0x4c, + 0x35, 0x89, 0xb5, 0x3b, 0x42, 0x31, 0x43, 0xc0, 0xd6, 0x86, 0x58, 0xc9, 0x2a, 0x3d, 0x72, 0xe5, + 0xa7, 0x68, 0x23, 0x3d, 0x7b, 0x9b, 0x84, 0xf6, 0x11, 0x8d, 0x7a, 0x90, 0xdd, 0x5d, 0x6d, 0xbf, + 0xa1, 0x17, 0x07, 0x40, 0x3f, 0x24, 0x01, 0x3c, 0x0a, 0x1f, 0xa6, 0x04, 0x53, 0x49, 0x62, 0xed, + 0x76, 0x7e, 0xf8, 0x45, 0x25, 0xb6, 0xaa, 0xfc, 0x1f, 0x9a, 0xfc, 0x35, 0xaa, 0x30, 0x3a, 0x48, + 0x1d, 0xcb, 0xdb, 0x52, 0xab, 0xba, 0xdf, 0xd0, 0xc5, 0xb8, 0xe8, 0xe9, 0xb8, 0xe8, 0xf9, 0xb8, + 0xe8, 0x07, 0x94, 0x84, 0xe6, 0xd6, 0x8b, 0x58, 0x5b, 0x49, 0x62, 0x6d, 0x43, 0xb8, 0x0a, 0x19, + 0xb6, 0x72, 0xbd, 0xfc, 0x14, 0x55, 0x5d, 0x60, 0x9c, 0x84, 0x0e, 0x27, 0x34, 0x54, 0x56, 0x5f, + 0x67, 0xa7, 0xe6, 0x76, 0xb2, 0xb0, 0x2b, 0x68, 0xb1, 0x55, 0x74, 0xc2, 0x2a, 0x52, 0x66, 0xcf, + 0xde, 0x02, 0xd6, 0xa7, 0x21, 0x03, 0x3c, 0x2a, 0xa1, 0x4d, 0x01, 0x76, 0xb2, 0x53, 0xf8, 0x1f, + 0x75, 0xe6, 0xfe, 0x54, 0x67, 0xd6, 0xcc, 0xcd, 0xeb, 0x3f, 0x7a, 0xf9, 0x67, 0x09, 0xd5, 0x03, + 0x67, 0x48, 0x82, 0x41, 0x60, 0x33, 0x9f, 0xf4, 0xfb, 0x8e, 0x07, 0x4a, 0x25, 0xdb, 0xce, 0x0f, + 0xa9, 0xc7, 0xef, 0xb1, 0xb6, 0xeb, 0x11, 0xfe, 0xe3, 0xa0, 0xab, 0xf7, 0x68, 0x60, 0xe4, 0x49, + 0x23, 0x3e, 0xf6, 0x98, 0x7b, 0x6c, 0xf0, 0xb3, 0x3e, 0x30, 0xfd, 0x4b, 0xe8, 0x8d, 0x62, 0xad, + 0xda, 0x71, 0x86, 0x4f, 0x72, 0x93, 0x24, 0xd6, 0xee, 0x8a, 0xe2, 0xb3, 0xf6, 0xd8, 0xba, 0x95, + 0x2f, 0x8d, 0xb9, 0xf8, 0x1e, 0x6a, 0xcc, 0xf5, 0x78, 0x32, 0x01, 0x3f, 0xa1, 0x5a, 0x87, 0x79, + 0x07, 0x4e, 0xd8, 0x03, 0xff, 0xda, 0xbb, 0x8f, 0x15, 0x74, 0x67, 0xba, 0xfa, 0x64, 0x5f, 0xbf, + 0x96, 0x91, 0x3a, 0x81, 0x2c, 0xe8, 0xfb, 0x4e, 0x0f, 0x2e, 0x11, 0x1e, 0xcf, 0x91, 0x42, 0x23, + 0xe2, 0x91, 0xd0, 0xf1, 0xed, 0x8b, 0x77, 0xfb, 0xe9, 0x28, 0xd6, 0x36, 0x1f, 0x47, 0xc4, 0x3b, + 0x28, 0xee, 0x2c, 0x89, 0x35, 0x2d, 0xf7, 0x5b, 0x20, 0xc7, 0xd6, 0xd6, 0x18, 0x9a, 0x52, 0xca, + 0x0e, 0x7a, 0x37, 0x84, 0xd3, 0xb9, 0x6a, 0xa5, 0xac, 0xda, 0xfe, 0x28, 0xd6, 0xea, 0xdf, 0xc2, + 0xe9, 0x6c, 0x31, 0x55, 0x14, 0xbb, 0x40, 0x88, 0xad, 0x7a, 0x38, 0xc3, 0x9f, 0xff, 0xd1, 0x94, + 0xaf, 0x3c, 0xce, 0x56, 0xaf, 0x36, 0xce, 0x2a, 0x57, 0x16, 0x67, 0x3b, 0x08, 0x2f, 0x9e, 0x8b, + 0xc9, 0xf8, 0xbc, 0x2a, 0xa3, 0x7b, 0xb3, 0xb4, 0xcb, 0x44, 0xdc, 0xdb, 0xf9, 0xb9, 0x64, 0xe8, + 0xae, 0xfe, 0xcb, 0xd0, 0xad, 0xfc, 0xb7, 0xa1, 0x7b, 0xf3, 0xba, 0x43, 0xf7, 0x43, 0xf4, 0xc1, + 0x92, 0xf9, 0x1b, 0xcf, 0xe9, 0xfe, 0xab, 0x12, 0x2a, 0x75, 0x98, 0x97, 0x76, 0x64, 0xfa, 0xdf, + 0x51, 0x73, 0xba, 0x17, 0xb3, 0x4f, 0x70, 0x75, 0x77, 0x39, 0x3e, 0x2e, 0x20, 0x3f, 0x43, 0xb5, + 0x99, 0xa7, 0xbb, 0x76, 0x91, 0xb2, 0x40, 0x50, 0x3f, 0x7a, 0x0d, 0x61, 0xe2, 0xfd, 0x3d, 0xaa, + 0x16, 0x1f, 0x1c, 0xef, 0xcd, 0xe9, 0x0a, 0xa8, 0xba, 0xb3, 0x0c, 0x9d, 0x58, 0x0e, 0xd0, 0xdd, + 0x45, 0x91, 0xdf, 0x5a, 0x60, 0x30, 0xc7, 0x54, 0x3f, 0x7e, 0x53, 0xe6, 0xa4, 0xec, 0x10, 0x29, + 0x0b, 0xa3, 0xe2, 0xfe, 0x72, 0xb7, 0xe2, 0xc9, 0xb5, 0xdf, 0x98, 0x3a, 0xae, 0x6c, 0x7e, 0xf5, + 0x62, 0xd4, 0x94, 0x5e, 0x8e, 0x9a, 0xd2, 0x1f, 0xa3, 0xa6, 0xf4, 0xcb, 0x79, 0x73, 0xe5, 0xe5, + 0x79, 0x73, 0xe5, 0xb7, 0xf3, 0xe6, 0xca, 0xb3, 0x07, 0x85, 0x21, 0x85, 0xbd, 0x80, 0x86, 0x70, + 0x66, 0x40, 0xb0, 0xe7, 0x83, 0xeb, 0x41, 0x64, 0x0c, 0xc7, 0x2f, 0x1d, 0xd9, 0xb4, 0x76, 0x2b, + 0xd9, 0x0b, 0xc5, 0x27, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x64, 0x77, 0xc4, 0x23, 0xe9, 0x0c, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1000,38 +951,38 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Metadata: "em/market/v1/tx.proto", } -func (p *TxParams) Marshal() (dAtA []byte, err error) { - size := p.Size() +func (m *TxParams) Marshal() (dAtA []byte, err error) { + size := m.Size() dAtA = make([]byte, size) - n, err := p.MarshalToSizedBuffer(dAtA[:size]) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) if err != nil { return nil, err } return dAtA[:n], nil } -func (p *TxParams) MarshalTo(dAtA []byte) (int, error) { - size := p.Size() - return p.MarshalToSizedBuffer(dAtA[:size]) +func (m *TxParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (p *TxParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *TxParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if p.LiquidityRebateMinutesSpan != 0 { - i = encodeVarintTx(dAtA, i, uint64(p.LiquidityRebateMinutesSpan)) + if m.LiquidityRebateMinutesSpan != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.LiquidityRebateMinutesSpan)) i-- dAtA[i] = 0x18 } - if p.LiquidTrxFee != 0 { - i = encodeVarintTx(dAtA, i, uint64(p.LiquidTrxFee)) + if m.LiquidTrxFee != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.LiquidTrxFee)) i-- dAtA[i] = 0x10 } - if p.TrxFee != 0 { - i = encodeVarintTx(dAtA, i, uint64(p.TrxFee)) + if m.TrxFee != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TrxFee)) i-- dAtA[i] = 0x8 } @@ -1477,20 +1428,20 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (p *TxParams) Size() (n int) { - if p == nil { +func (m *TxParams) Size() (n int) { + if m == nil { return 0 } var l int _ = l - if p.TrxFee != 0 { - n += 1 + sovTx(uint64(p.TrxFee)) + if m.TrxFee != 0 { + n += 1 + sovTx(uint64(m.TrxFee)) } - if p.LiquidTrxFee != 0 { - n += 1 + sovTx(uint64(p.LiquidTrxFee)) + if m.LiquidTrxFee != 0 { + n += 1 + sovTx(uint64(m.LiquidTrxFee)) } - if p.LiquidityRebateMinutesSpan != 0 { - n += 1 + sovTx(uint64(p.LiquidityRebateMinutesSpan)) + if m.LiquidityRebateMinutesSpan != 0 { + n += 1 + sovTx(uint64(m.LiquidityRebateMinutesSpan)) } return n } @@ -1675,7 +1626,7 @@ func sovTx(x uint64) (n int) { func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (p *TxParams) Unmarshal(dAtA []byte) error { +func (m *TxParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1708,7 +1659,7 @@ func (p *TxParams) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field TrxFee", wireType) } - p.TrxFee = 0 + m.TrxFee = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1718,7 +1669,7 @@ func (p *TxParams) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - p.TrxFee |= uint64(b&0x7F) << shift + m.TrxFee |= uint64(b&0x7F) << shift if b < 0x80 { break } @@ -1727,7 +1678,7 @@ func (p *TxParams) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LiquidTrxFee", wireType) } - p.LiquidTrxFee = 0 + m.LiquidTrxFee = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1737,7 +1688,7 @@ func (p *TxParams) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - p.LiquidTrxFee |= uint64(b&0x7F) << shift + m.LiquidTrxFee |= uint64(b&0x7F) << shift if b < 0x80 { break } @@ -1746,7 +1697,7 @@ func (p *TxParams) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LiquidityRebateMinutesSpan", wireType) } - p.LiquidityRebateMinutesSpan = 0 + m.LiquidityRebateMinutesSpan = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1756,7 +1707,7 @@ func (p *TxParams) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - p.LiquidityRebateMinutesSpan |= int64(b&0x7F) << shift + m.LiquidityRebateMinutesSpan |= int64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/market/types/types.go b/x/market/types/types.go index f3c9caff..a502d0ad 100644 --- a/x/market/types/types.go +++ b/x/market/types/types.go @@ -31,7 +31,9 @@ func (o Order) MarshalJSON() ([]byte, error) { "denom": "%v", "amount": "%v" }, - "destination_filled": "%v" + "destination_filled": "%v", + "created": "%v", + "orig_order_created": "%v" } `, o.ID, @@ -46,6 +48,8 @@ func (o Order) MarshalJSON() ([]byte, error) { o.Destination.Denom, o.Destination.Amount, o.DestinationFilled, + o.Created, + o.OrigOrderCreated, ) return []byte(s), nil @@ -83,7 +87,7 @@ func (o Order) Price() sdk.Dec { } func (o Order) String() string { - return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner) + return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\nReplacementOrder:%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created, o.OrigOrderCreated) } func (ep ExecutionPlan) DestinationCapacity() sdk.Dec { @@ -130,7 +134,8 @@ func NewOrder( timeInForce TimeInForce, src, dst sdk.Coin, seller sdk.AccAddress, - clientOrderId string) (Order, error) { + clientOrderId string, + origOrderCreated time.Time) (Order, error) { if src.Amount.LTE(sdk.ZeroInt()) || dst.Amount.LTE(sdk.ZeroInt()) { return Order{}, sdkerrors.Wrapf(ErrInvalidPrice, "Order price is invalid: %s -> %s", src.Amount, dst.Amount) @@ -148,6 +153,7 @@ func NewOrder( Destination: dst, DestinationFilled: sdk.ZeroInt(), Created: createdTm, + OrigOrderCreated: origOrderCreated, } if err := o.IsValid(); err != nil { diff --git a/x/market/types/types_test.go b/x/market/types/types_test.go index 7a2874d9..902b6779 100644 --- a/x/market/types/types_test.go +++ b/x/market/types/types_test.go @@ -15,7 +15,10 @@ import ( func TestSerialization(t *testing.T) { // Verify that non-public fields survive de-/serialization tm := time.Now() - order1, _ := NewOrder(tm, TimeInForce_GoodTillCancel, coin("100eur"), coin("120usd"), []byte("acc1"), "A") + order1, _ := NewOrder( + tm, TimeInForce_GoodTillCancel, coin("100eur"), coin("120usd"), + []byte("acc1"), "A", time.Time{}, + ) order1.ID = 3123 order1.SourceRemaining = sdk.NewInt(50) order1.SourceFilled = sdk.NewInt(10) @@ -51,19 +54,29 @@ func TestSerialization(t *testing.T) { require.Equal(t, order1.TimeInForce, order2.TimeInForce) require.True(t, order1.Created.Equal(order2.Created)) + require.Equal(t, order1.OrigOrderCreated, order2.OrigOrderCreated) } func TestInvalidOrder(t *testing.T) { // 0 amount source - _, err := NewOrder(time.Now(), TimeInForce_GoodTillCancel, coin("0eur"), coin("120usd"), []byte("acc"), "A") + _, err := NewOrder( + time.Now(), TimeInForce_GoodTillCancel, coin("0eur"), coin("120usd"), + []byte("acc"), "A", time.Time{}, + ) require.Error(t, err) // 0 amount destination - _, err = NewOrder(time.Now(), TimeInForce_GoodTillCancel, coin("120eur"), coin("0usd"), []byte("acc"), "A") + _, err = NewOrder( + time.Now(), TimeInForce_GoodTillCancel, coin("120eur"), coin("0usd"), + []byte("acc"), "A", time.Time{}, + ) require.Error(t, err) // Same denomination - _, err = NewOrder(time.Now(), TimeInForce_GoodTillCancel, coin("1000eur"), coin("850eur"), []byte("acc"), "A") + _, err = NewOrder( + time.Now(), TimeInForce_GoodTillCancel, coin("1000eur"), coin("850eur"), + []byte("acc"), "A", time.Time{}, + ) require.Error(t, err) c := sdk.Coin{ @@ -72,7 +85,10 @@ func TestInvalidOrder(t *testing.T) { } // Negative source - _, err = NewOrder(time.Now(), TimeInForce_GoodTillCancel, c, coin("120usd"), []byte("acc"), "B") + _, err = NewOrder( + time.Now(), TimeInForce_GoodTillCancel, c, coin("120usd"), + []byte("acc"), "B", time.Time{}, + ) require.Error(t, err) } From 5c0ba3395c17aeacf31d81189527435e439264c6 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 11:00:09 +0300 Subject: [PATCH 19/41] Add params initialization --- x/buyback/abci_test.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/x/buyback/abci_test.go b/x/buyback/abci_test.go index b80b1217..54c04004 100644 --- a/x/buyback/abci_test.go +++ b/x/buyback/abci_test.go @@ -253,6 +253,7 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee db := dbm.NewMemDB() ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(authCapKey, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(stakingKey, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(keyMarket, sdk.StoreTypeIAVL, db) @@ -276,15 +277,17 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee bk = embank.Wrap(bankkeeper.NewBaseKeeper( encConfig.Marshaler, bankKey, ak, pk.Subspace(banktypes.ModuleName), blockedAddr, ), allowAllDenoms) + + marketKeeper = market.NewKeeper( + encConfig.Marshaler, keyMarket, keyIndices, ak, bk, mockAuthority{}, + pk.Subspace(market.ModuleName), + ) ) initialSupply := coins(fmt.Sprintf("1000000eur,1000000usd,1000000chf,1000000jpy,1000000gbp,1000000%v,500000000pesos", stakingDenom)) bk.SetSupply(ctx, banktypes.NewSupply(initialSupply)) - marketKeeper := market.NewKeeper( - encConfig.Marshaler, keyMarket, keyIndices, ak, bk, mockAuthority{}, - pk.Subspace(types.ModuleName), - ) + marketKeeper.InitParamsStore(ctx) keeper := NewKeeper(encConfig.Marshaler, buybackKey, marketKeeper, ak, mockStakingKeeper{}, bk) keeper.SetUpdateInterval(ctx, time.Hour) From b8553e9961138a59fe3680b2c382634e507c3d8e Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 11:01:32 +0300 Subject: [PATCH 20/41] Add panic stack trace --- x/market/keeper/keeper.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 2674dd82..d1612551 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -10,14 +10,14 @@ import ( paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" types2 "github.com/e-money/em-ledger/x/authority/types" "math" + "runtime/debug" "sync" "time" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/e-money/em-ledger/x/market/types" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/e-money/em-ledger/x/market/types" ) const ( @@ -247,7 +247,9 @@ func (k *Keeper) postNewOrderSingle( defer func() { if gasErr := recover(); gasErr != nil { - *callerErr = fmt.Errorf("out of Gas:%s", gasErr) + *callerErr = fmt.Errorf("%v", gasErr) + fmt.Println(gasErr) + fmt.Println(string(debug.Stack())) } }() From 8e687ed7a99e4c3fdb5d3b4a72cff59e166f85ed Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 12:16:09 +0300 Subject: [PATCH 21/41] Formatting, documentation --- docs/proto/em/proto-docs.md | 4 +- proto/em/market/v1/market.proto | 4 +- proto/em/market/v1/tx.proto | 6 +- x/buyback/abci.go | 10 ++- x/buyback/abci_test.go | 8 ++- x/buyback/internal/keeper/expected_keepers.go | 2 +- x/market/keeper/grpc_query_test.go | 9 ++- x/market/keeper/keeper.go | 47 +++++++------- x/market/keeper/keeper_test.go | 64 ++++--------------- x/market/keeper/params.go | 12 ++-- x/market/keeper/querier_test.go | 16 ++--- x/market/types/market.pb.go | 4 +- x/market/types/tx.pb.go | 6 +- x/market/types/tx_params.go | 4 +- x/market/types/types.go | 2 +- 15 files changed, 85 insertions(+), 113 deletions(-) diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index d71dcae2..d12e13e7 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -1123,7 +1123,7 @@ | `destination` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | | | `destination_filled` | [string](#string) | | | | `created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | | -| `orig_order_created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | applicable to CancelReplace orders: the creation timestamp of the order this order replaces. | +| `orig_order_created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | applicable to CancelReplace orders: the creation timestamp of the original order. | @@ -1471,7 +1471,7 @@ | ----- | ---- | ----- | ----------- | | `trx_fee` | [uint64](#uint64) | | default fee for a market transaction. | | `liquid_trx_fee` | [uint64](#uint64) | | Valid liquidity adding orders are free or adjusted to a minimum nominal/fee | -| `liquidity_rebate_minutes_span` | [int64](#int64) | | Minutes interval for eligible replacing liquidity transactions to qualify for the rebate. For the rebate to apply, the replacing transaction should occur x minutes after the signer's original trx. | +| `liquidity_rebate_minutes_span` | [int64](#int64) | | Minutes interval for eligible replacing transactions to receive a rebate. For a rebate to apply, the replacing transaction should occur these minutes after the signer's original trx. | diff --git a/proto/em/market/v1/market.proto b/proto/em/market/v1/market.proto index 4f17f046..324afd73 100644 --- a/proto/em/market/v1/market.proto +++ b/proto/em/market/v1/market.proto @@ -78,8 +78,8 @@ message Order { (gogoproto.stdtime) = true ]; - // applicable to CancelReplace orders: the creation timestamp of the order - // this order replaces. + // applicable to CancelReplace orders: the creation timestamp of the original + // order. google.protobuf.Timestamp orig_order_created = 11 [ (gogoproto.moretags) = "yaml:\"orig_order_created\"", (gogoproto.nullable) = false, diff --git a/proto/em/market/v1/tx.proto b/proto/em/market/v1/tx.proto index 318ebed4..4c75dcdd 100644 --- a/proto/em/market/v1/tx.proto +++ b/proto/em/market/v1/tx.proto @@ -27,9 +27,9 @@ message TxParams { // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee uint64 liquid_trx_fee = 2 [(gogoproto.moretags) = "yaml:\"liquid_trx_fee\""]; - // Minutes interval for eligible replacing liquidity transactions to qualify - // for the rebate. For the rebate to apply, the replacing transaction should - // occur x minutes after the signer's original trx. + // Minutes interval for eligible replacing transactions to receive a rebate. + // For a rebate to apply, the replacing transaction should occur these minutes + // after the signer's original trx. int64 liquidity_rebate_minutes_span = 3 [ (gogoproto.moretags) = "yaml:\"liquidity_rebate_minutes_span\"" ]; diff --git a/x/buyback/abci.go b/x/buyback/abci.go index df481510..15494d6d 100644 --- a/x/buyback/abci.go +++ b/x/buyback/abci.go @@ -41,9 +41,13 @@ func BeginBlocker(ctx sdk.Context, k Keeper, bk types.BankKeeper) { } order, err := markettypes.NewOrder( - ctx.BlockTime(), markettypes.TimeInForce_GoodTillCancel, balance, - sdk.NewCoin(stakingDenom, destinationAmount), account, - generateClientOrderId(ctx, balance), time.Time{}, + ctx.BlockTime(), + markettypes.TimeInForce_GoodTillCancel, + balance, + sdk.NewCoin(stakingDenom, destinationAmount), + account, + generateClientOrderId(ctx, balance), + time.Time{}, ) if err != nil { diff --git a/x/buyback/abci_test.go b/x/buyback/abci_test.go index 54c04004..f1647ca6 100644 --- a/x/buyback/abci_test.go +++ b/x/buyback/abci_test.go @@ -211,8 +211,12 @@ func order(account authtypes.AccountI, src, dst string) types.Order { s, _ := sdk.ParseCoinNormalized(src) d, _ := sdk.ParseCoinNormalized(dst) o, err := types.NewOrder( - time.Now(), types.TimeInForce_GoodTillCancel, s, d, - account.GetAddress(), tmrand.Str(10), time.Time{}, + time.Now(), + types.TimeInForce_GoodTillCancel, + s, d, + account.GetAddress(), + tmrand.Str(10), + time.Time{}, ) if err != nil { panic(err) diff --git a/x/buyback/internal/keeper/expected_keepers.go b/x/buyback/internal/keeper/expected_keepers.go index 6e39200b..cb4a602d 100644 --- a/x/buyback/internal/keeper/expected_keepers.go +++ b/x/buyback/internal/keeper/expected_keepers.go @@ -7,7 +7,7 @@ import ( type ( MarketKeeper interface { - NewOrderSingle(ctx sdk.Context, aggressiveOrder market.Order) (*sdk.Result, error) + NewOrderSingle(ctx sdk.Context, order market.Order) (*sdk.Result, error) GetOrdersByOwner(ctx sdk.Context, owner sdk.AccAddress) []*market.Order GetInstruments(ctx sdk.Context) (instrs []market.MarketData) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) diff --git a/x/market/keeper/grpc_query_test.go b/x/market/keeper/grpc_query_test.go index ef9acf9f..79994bdf 100644 --- a/x/market/keeper/grpc_query_test.go +++ b/x/market/keeper/grpc_query_test.go @@ -21,9 +21,12 @@ func TestQueryByAccount(t *testing.T) { types.RegisterQueryServer(queryHelper, k) queryClient := types.NewQueryClient(queryHelper) o, err := types.NewOrder( - ctx.BlockTime(), types.TimeInForce_GoodTillCancel, - sdk.NewCoin("alx", sdk.OneInt()), sdk.NewCoin("blx", sdk.OneInt()), - myAddress, "myOrderID", time.Time{}, + ctx.BlockTime(), + types.TimeInForce_GoodTillCancel, + sdk.NewCoin("alx", sdk.OneInt()), + sdk.NewCoin("blx", sdk.OneInt()), + myAddress,"myOrderID", + time.Time{}, ) require.NoError(t, err) k.setOrder(ctx, &o) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index d1612551..c009e40f 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -148,8 +148,8 @@ func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, ds return res, err } -// createMarketOrder creates a new market order allowing to set the message type -// to new (Add) or Replacement. +// createMarketOrder creates a market order that returns the created order and +// takes the original order creation timestamp. func (k *Keeper) createMarketOrder( ctx sdk.Context, srcDenom string, dst sdk.Coin, @@ -183,9 +183,10 @@ func (k *Keeper) createMarketOrder( return &order, res, err } -// calcOrderGas calculates the order rebate. The liquid fee applies to liquid -// unfilled orders. If filled partially, the difference between the full fee -// minus (-) liquid fee is applied proportionally. +// calcOrderGas computes the order gas by applying any liquidity rebate. The +// liquid fee i.e. 0 gas applies to liquid unfilled orders. For Orders filled +// partially the difference between the full fee minus (-) liquid fee is applied +// proportionally. func (k *Keeper) calcOrderGas( ctx sdk.Context, stdTrxFee sdk.Gas, dstFilled, dstAmount sdk.Int, ) sdk.Gas { @@ -241,14 +242,18 @@ func (k *Keeper) postNewOrderSingle( ctx sdk.Context, orderGasMeter sdk.GasMeter, order *types.Order, commitTrade func(), callerErr *error, ) { + // Catch NewSingleOrder() panics if orderErr := recover(); orderErr != nil { *callerErr = fmt.Errorf("%s", orderErr) + fmt.Println(orderErr) + fmt.Println(string(debug.Stack())) } defer func() { - if gasErr := recover(); gasErr != nil { - *callerErr = fmt.Errorf("%v", gasErr) - fmt.Println(gasErr) + // Catch Sdk panics i.e. store related + if sdkErr := recover(); sdkErr != nil { + *callerErr = fmt.Errorf("%v", sdkErr) + fmt.Println(sdkErr) fmt.Println(string(debug.Stack())) } }() @@ -263,11 +268,10 @@ func (k *Keeper) postNewOrderSingle( commitTrade() } -func (k *Keeper) NewOrderSingle( - ctx sdk.Context, aggressiveOrder types.Order, -) (res *sdk.Result, err error) { +func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (res *sdk.Result, err error) { ctx, commitTrade := ctx.CacheContext() + // the transactor's meter orderGasMeter := ctx.GasMeter() // impostor meter that would not panic ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) @@ -466,6 +470,7 @@ func (k *Keeper) NewOrderSingle( func (k *Keeper) initializeFromStore(ctx sdk.Context) { k.appstateInit.Do(func() { + // TODO should we move the market params to genesis or const them? k.InitParamsStore(ctx) // Load the restricted denominations from the authority module @@ -503,8 +508,7 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { } // postOrderSpendGas is a deferred function from Order processing -// NewSingleOrder, NewCancelReplace functions to charge the StdFee for canonical -// and exceptional cases. +// NewSingleOrder, NewCancelReplace functions to charge Gas. func (k *Keeper) postOrderSpendGas( ctx sdk.Context, order *types.Order, orderGasMeter sdk.GasMeter, callerErr *error, ) { @@ -554,16 +558,13 @@ func (k *Keeper) CancelReplaceLimitOrder( ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) defer func() { - // consume gas if did not enter NewSingleOrder() + // consume gas, if it did not make it to NewSingleOrder() if err != nil && orderGasMeter.GasConsumed() == 0 { k.postOrderSpendGas(ctx, &newOrder, orderGasMeter, &err) } }() - origOrder := k.GetOrderByOwnerAndClientOrderId( - ctx, newOrder.Owner, - origClientOrderId, - ) + origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, newOrder.Owner, origClientOrderId) if origOrder == nil { return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, origClientOrderId) @@ -590,6 +591,7 @@ func (k *Keeper) CancelReplaceLimitOrder( newOrder.TimeInForce = origOrder.TimeInForce newOrder.OrigOrderCreated = origOrder.Created + // pass in the meter we will charge Gas. resAdd, err := k.NewOrderSingle(ctx.WithGasMeter(orderGasMeter), newOrder) if err != nil { return nil, err @@ -601,14 +603,14 @@ func (k *Keeper) CancelReplaceLimitOrder( func (k *Keeper) CancelReplaceMarketOrder( ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder, -) (res *sdk.Result, err error) { +) (resAdd *sdk.Result, err error) { var newOrder *types.Order orderGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) defer func() { - // consume gas if did not enter NewSingleOrder() + // consume gas, if it did not make it to NewSingleOrder() if err != nil && orderGasMeter.GasConsumed() == 0 { k.postOrderSpendGas(ctx, newOrder, orderGasMeter, &err) } @@ -651,7 +653,8 @@ func (k *Keeper) CancelReplaceMarketOrder( dstRemaining := msg.Destination.Amount.Sub(destinationFilled) remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) - newOrder, res, err = k.createMarketOrder( + newOrder, resAdd, err = k.createMarketOrder( + // pass in the meter we will charge gas ctx.WithGasMeter(orderGasMeter), msg.Source, remDstCoin, @@ -665,7 +668,7 @@ func (k *Keeper) CancelReplaceMarketOrder( return nil, err } - evts := append(ctx.EventManager().ABCIEvents(), res.Events...) + evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) return &sdk.Result{Events: evts}, nil } diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 949f189c..7802ec85 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -786,26 +786,18 @@ func TestMultipleOrders(t *testing.T) { totalSupply := snapshotAccounts(ctx, bk) // Add two orders that draw on the same balance. - _, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), - ) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd")) require.NoError(t, err) - _, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), - ) + _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf")) require.NoError(t, err) // require.Len(t, k.instruments, 2) - res, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), - ) + res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur")) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), - ) + res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur")) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -822,9 +814,7 @@ func TestCancelZeroRemainingOrders(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc := createAccount(ctx, ak, bk, randomAddress(), "10000eur") - _, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc, "10000eur", "11000usd"), - ) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc, "10000eur", "11000usd")) require.NoError(t, err) err = bk.SendCoins(ctx, acc.GetAddress(), sdk.AccAddress([]byte("void")), coins("10000eur")) @@ -894,24 +884,16 @@ func TestAllInstruments(t *testing.T) { acc3 := createAccount(ctx, ak, bk, randomAddress(), "2200chf") // Add two orders that draw on the same balance. - _, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), - ) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd")) require.NoError(t, err) - _, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), - ) + _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf")) require.NoError(t, err) - res, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), - ) + res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur")) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), - ) + res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur")) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books @@ -1411,9 +1393,7 @@ func TestVestingAccount(t *testing.T) { vestingAcc := vestingtypes.NewDelayedVestingAccount(account.(*authtypes.BaseAccount), amount, math.MaxInt64) ak.SetAccount(ctx, vestingAcc) - _, err := keeper.NewOrderSingle( - ctx, order(ctx.BlockTime(), vestingAcc, "5000eur", "4700chf"), - ) + _, err := keeper.NewOrderSingle(ctx, order(ctx.BlockTime(), vestingAcc, "5000eur", "4700chf")) require.True(t, types.ErrAccountBalanceInsufficient.Is(err)) } @@ -1577,13 +1557,9 @@ func TestNonMatchingOrders(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "100000usd") acc2 := createAccount(ctx, ak, bk, randomAddress(), "240000eur") - _, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "20000usd", "20000eur"), - ) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "20000usd", "20000eur")) require.NoError(t, err) - _, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc2, "20000eur", "50000usd"), - ) + _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "20000eur", "50000usd")) require.NoError(t, err) acc1Orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) @@ -1912,21 +1888,9 @@ func coins(s string) sdk.Coins { } func order(createdTm time.Time, account authtypes.AccountI, src, dst string) types.Order { - return orderReplacement(createdTm, account, src, dst, time.Time{}) -} - -func orderReplacement( - createdTm time.Time, account authtypes.AccountI, src, dst string, - origOrderTm time.Time, -) types.Order { o, err := types.NewOrder( - createdTm, - types.TimeInForce_GoodTillCancel, - coin(src), - coin(dst), - account.GetAddress(), - cid(), - origOrderTm, + createdTm, types.TimeInForce_GoodTillCancel, coin(src), coin(dst), + account.GetAddress(), cid(), time.Time{}, ) if err != nil { panic(err) diff --git a/x/market/keeper/params.go b/x/market/keeper/params.go index a3a55238..74d4b056 100644 --- a/x/market/keeper/params.go +++ b/x/market/keeper/params.go @@ -5,7 +5,7 @@ import ( "github.com/e-money/em-ledger/x/market/types" ) -// InitParamsStore initializes param store +// InitParamsStore writes the params to the module store func (k Keeper) InitParamsStore(ctx sdk.Context) uint64 { defaultSet := types.DefaultTxParams() var trxFee uint64 @@ -41,8 +41,10 @@ func (k Keeper) GetLiquidTrxFee(ctx sdk.Context) uint64 { return liqTrxFee } -// GetLiquidityRebateMinutesSpan retrieves the default market order fee from the -// paramStore +// GetLiquidityRebateMinutesSpan retrieves the Minutes interval for eligible +// replacing transactions to receive a rebate. For a rebate to apply, the +// replacing transaction should occur these minutes after the signer's original +// trx. func (k Keeper) GetLiquidityRebateMinutesSpan(ctx sdk.Context) int64 { var liqTrxFee int64 k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &liqTrxFee) @@ -50,13 +52,13 @@ func (k Keeper) GetLiquidityRebateMinutesSpan(ctx sdk.Context) int64 { return liqTrxFee } -// GetParams returns the total set of Trx parameters. +// GetParams returns the total market parameters set. func (k Keeper) GetParams(ctx sdk.Context) types.TxParams { return types.NewTxParams(k.GetTrxFee(ctx), k.GetLiquidTrxFee(ctx), k.GetLiquidityRebateMinutesSpan(ctx)) } -// SetParams sets the total set of ibc-transfer parameters. +// SetParams sets the total market parameters set. func (k Keeper) SetParams(ctx sdk.Context, params types.TxParams) { k.paramStore.SetParamSet(ctx, ¶ms) } diff --git a/x/market/keeper/querier_test.go b/x/market/keeper/querier_test.go index 308cb33d..b68316ce 100644 --- a/x/market/keeper/querier_test.go +++ b/x/market/keeper/querier_test.go @@ -81,24 +81,16 @@ func TestQryGetAllInstrumentsWithNilBestPrices(t *testing.T) { acc3 := createAccount(ctx, ak, bk, randomAddress(), "2200chf") // generate passive order - _, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd"), - ) + _, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "11000usd")) require.NoError(t, err) - _, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf"), - ) + _, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc1, "10000eur", "1400chf")) require.NoError(t, err) - res, err := k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur"), - ) + res, err := k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc2, "7400usd", "5000eur")) require.True(t, err == nil, res.Log) - res, err = k.NewOrderSingle( - ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur"), - ) + res, err = k.NewOrderSingle(ctx, order(ctx.BlockTime(), acc3, "2200chf", "5000eur")) require.True(t, err == nil, res.Log) // All acc1's EUR are sold by now. No orders should be on books diff --git a/x/market/types/market.pb.go b/x/market/types/market.pb.go index 42174a4d..e1d93eed 100644 --- a/x/market/types/market.pb.go +++ b/x/market/types/market.pb.go @@ -123,8 +123,8 @@ type Order struct { Destination types.Coin `protobuf:"bytes,8,opt,name=destination,proto3" json:"destination" yaml:"destination"` DestinationFilled github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,9,opt,name=destination_filled,json=destinationFilled,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"destination_filled" yaml:"destination_filled"` Created time.Time `protobuf:"bytes,10,opt,name=created,proto3,stdtime" json:"created" yaml:"created"` - // applicable to CancelReplace orders: the creation timestamp of the order - // this order replaces. + // applicable to CancelReplace orders: the creation timestamp of the original + // order. OrigOrderCreated time.Time `protobuf:"bytes,11,opt,name=orig_order_created,json=origOrderCreated,proto3,stdtime" json:"orig_order_created" yaml:"orig_order_created"` } diff --git a/x/market/types/tx.pb.go b/x/market/types/tx.pb.go index 1c104475..1342285a 100644 --- a/x/market/types/tx.pb.go +++ b/x/market/types/tx.pb.go @@ -36,9 +36,9 @@ type TxParams struct { TrxFee uint64 `protobuf:"varint,1,opt,name=trx_fee,json=trxFee,proto3" json:"trx_fee,omitempty" yaml:"trx_fee"` // Valid liquidity adding orders are free or adjusted to a minimum nominal/fee LiquidTrxFee uint64 `protobuf:"varint,2,opt,name=liquid_trx_fee,json=liquidTrxFee,proto3" json:"liquid_trx_fee,omitempty" yaml:"liquid_trx_fee"` - // Minutes interval for eligible replacing liquidity transactions to qualify - // for the rebate. For the rebate to apply, the replacing transaction should - // occur x minutes after the signer's original trx. + // Minutes interval for eligible replacing transactions to receive a rebate. + // For a rebate to apply, the replacing transaction should occur these minutes + // after the signer's original trx. LiquidityRebateMinutesSpan int64 `protobuf:"varint,3,opt,name=liquidity_rebate_minutes_span,json=liquidityRebateMinutesSpan,proto3" json:"liquidity_rebate_minutes_span,omitempty" yaml:"liquidity_rebate_minutes_span"` } diff --git a/x/market/types/tx_params.go b/x/market/types/tx_params.go index d62b858b..fb2a2e22 100644 --- a/x/market/types/tx_params.go +++ b/x/market/types/tx_params.go @@ -30,7 +30,7 @@ func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&TxParams{}) } -// ParamSetPairs implements params.ParamSet +// ParamSetPairs implements params.ParamSet or map func (p *TxParams) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyTrxFee, &p.TrxFee, validateIsUInt), @@ -42,7 +42,7 @@ func (p *TxParams) ParamSetPairs() paramtypes.ParamSetPairs { } } -// NewTxParams creates a new parameter configuration for the bank module +// NewTxParams creates a new parameter configuration for the market module func NewTxParams(trxFee, liquidTrxFee uint64, liquidityRebateMinutes int64) TxParams { return TxParams{ TrxFee: trxFee, diff --git a/x/market/types/types.go b/x/market/types/types.go index a502d0ad..200ddd3c 100644 --- a/x/market/types/types.go +++ b/x/market/types/types.go @@ -87,7 +87,7 @@ func (o Order) Price() sdk.Dec { } func (o Order) String() string { - return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\nReplacementOrder:%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created, o.OrigOrderCreated) + return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\nOriginal Order Created:%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created, o.OrigOrderCreated) } func (ep ExecutionPlan) DestinationCapacity() sdk.Dec { From c6091f320bf996d4d8e89e80e84ca0b5803bd550 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 12:37:10 +0300 Subject: [PATCH 22/41] Remove previous gas const --- x/market/keeper/keeper.go | 7 ------- x/market/keeper/keeper_test.go | 36 +++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index c009e40f..bfa9f9ca 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -20,13 +20,6 @@ import ( "github.com/e-money/em-ledger/x/market/types" ) -const ( - // Gas prices must be predictable, and not depend on the number of passive orders matched. - gasPriceNewOrder = uint64(25000) - gasPriceCancelReplaceOrder = uint64(25000) - gasPriceCancelOrder = uint64(12500) -) - var _ marketKeeper = &Keeper{} type Keeper struct { diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 7802ec85..9b742911 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -91,7 +91,7 @@ func TestBasicTrade(t *testing.T) { require.Equal(t, *instruments[0].Timestamp, ctx.BlockTime()) // Ensure that gas usage is not higher due to the order being matched. - require.Equal(t, gasPriceNewOrder, gasmeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasmeter.GasConsumed()) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) bal2 := bk.GetAllBalances(ctx, acc2.GetAddress()) @@ -662,6 +662,23 @@ func TestLiquidNewLimit0Gas(t *testing.T) { require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) } +func TestLiquidNewLimitFullGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + src1, dst1 := "eur", "usd" + order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) +} + func TestLiquidNewMarket0Gas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) @@ -939,12 +956,15 @@ func Test3(t *testing.T) { o := order(ctx.BlockTime(), acc1, "100eur", "120usd") k.NewOrderSingle(ctx, o) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) for i := 0; i < 4; i++ { o = order(ctx.BlockTime(), acc2, "30usd", "25eur") k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) } - require.Equal(t, 4*gasPriceNewOrder, gasMeter.GasConsumed()) + require.Equal(t, 4*stdTrxFee, gasMeter.GasConsumed()) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) bal2 := bk.GetAllBalances(ctx, acc2.GetAddress()) @@ -1206,6 +1226,9 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) order2cid := cid() order2, _ := types.NewOrder( @@ -1214,7 +1237,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { ) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) - require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) { orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) @@ -1237,7 +1260,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { gasMeter = sdk.NewGasMeter(math.MaxUint64) _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) require.True(t, types.ErrOrderInstrumentChanged.Is(err)) - require.Equal(t, gasPriceCancelReplaceOrder, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") _, err = k.NewOrderSingle(ctx, o) @@ -1602,11 +1625,14 @@ func TestSyntheticInstruments2(t *testing.T) { require.NoError(t, err, res.Log) } + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + gasMeter := sdk.NewGasMeter(math.MaxUint64) monsterOrder := order(ctx.BlockTime(), acc3, "3700000eur", "4000000usd") res, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), monsterOrder) require.NoError(t, err, res.Log) - require.Equal(t, gasPriceNewOrder, gasMeter.GasConsumed()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) // require.Len(t, k.instruments, 0) From 62b38b7130abee756c170b3da33a87de7f26f8bb Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 13:42:41 +0300 Subject: [PATCH 23/41] Clarify expressions --- x/market/keeper/keeper.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index bfa9f9ca..fed330e6 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -204,16 +204,16 @@ func (k *Keeper) calcOrderGas( Sub(sdk.NewIntFromUint64(liquidTrxFee)) payPct := dstFilled.ToDec().Quo(dstAmount.ToDec()) - payGas := payPct.Mul(totalRebate.ToDec()) + payGas := payPct.Mul(totalRebate.ToDec()).RoundInt().Uint64() - return payGas.RoundInt().Uint64() + return payGas } // calcReplaceOrderGas computes gas for replacement orders. Because it needs // the original order's creation time, this func acts is a precondition for // calcOrderGas(). func (k *Keeper) calcReplaceOrderGas( - ctx sdk.Context, dstFilled, dstAmount sdk.Int, lastOrderTm time.Time, + ctx sdk.Context, dstFilled, dstAmount sdk.Int, origOrderTm time.Time, ) sdk.Gas { var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) @@ -221,8 +221,8 @@ func (k *Keeper) calcReplaceOrderGas( var qualificationMin int64 k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) - // check at least LiquidityRebateMinutesSpan elapsed from replaced order - if ctx.BlockTime().Sub(lastOrderTm).Minutes() >= float64(qualificationMin) { + elapsedMin := ctx.BlockTime().Sub(origOrderTm).Minutes() + if elapsedMin >= float64(qualificationMin) { return k.calcOrderGas(ctx, stdTrxFee, dstFilled, dstAmount) } From 712cb963389621cdb3388313106f22c0b6a7043d Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 18:04:21 +0300 Subject: [PATCH 24/41] Add Partial Gas Pricing Tests --- x/market/keeper/keeper_test.go | 376 +++++++++++++++++++++++++++++++-- 1 file changed, 361 insertions(+), 15 deletions(-) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 9b742911..61f1a70f 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -645,47 +645,87 @@ func TestInsufficientGas(t *testing.T) { require.True(t, strings.Contains(strings.ToLower(err.Error()), "gas")) } -func TestLiquidNewLimit0Gas(t *testing.T) { +func TestLimitOrderLiquidAndFullGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) - acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") - gasMeter := sdk.NewGasMeter(math.MaxUint64) + gasMeter := sdk.NewInfiniteGasMeter() + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - src1, dst1 := "eur", "usd" - order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) + order1 := order(ctx.BlockTime(), acc1, "1gbp", "1eur") _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + gasMeter = sdk.NewInfiniteGasMeter() + order2 := order(ctx.BlockTime(), acc2, "1eur", "1gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.NoError(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) } -func TestLiquidNewLimitFullGas(t *testing.T) { +func TestPartiallyLiquidLimitOrderGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) - acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") - gasMeter := sdk.NewGasMeter(math.MaxUint64) + gasMeter := sdk.NewInfiniteGasMeter() + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - src1, dst1 := "eur", "usd" - order1 := order(ctx.BlockTime(), acc1, "100"+src1, "120"+dst1) + order1 := order(ctx.BlockTime(), acc1, "1gbp", "1eur") _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + gasMeter = sdk.NewInfiniteGasMeter() + order2 := order(ctx.BlockTime(), acc2, "10eur", "10gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.NoError(t, err) + require.Equal( + t, sdk.Gas(float64(stdTrxFee-liquidTrxFee)*0.1), gasMeter.GasConsumed(), + "1/10 filled => 10% of total Gas", + ) + + gasMeter = sdk.NewInfiniteGasMeter() + order3 := order(ctx.BlockTime(), acc1, "36gbp", "36eur") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order3) + require.NoError(t, err) + require.Equal( + t, (stdTrxFee-liquidTrxFee)/4, gasMeter.GasConsumed(), + "9/36 filled => 25% of total Gas", + ) + + gasMeter = sdk.NewInfiniteGasMeter() + order4 := order(ctx.BlockTime(), acc2, "36eur", "36gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order4) + require.NoError(t, err) + expGas := sdk.Gas(float64((stdTrxFee-liquidTrxFee)*3)/4) + require.Equal( + t, expGas, gasMeter.GasConsumed(), + "27/36 filled => 3/4 of total Gas", + ) } -func TestLiquidNewMarket0Gas(t *testing.T) { +func TestLiquidNewMarketOrderGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") - acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") - gasMeter := sdk.NewGasMeter(math.MaxUint64) + gasMeter := sdk.NewInfiniteGasMeter() var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) @@ -693,12 +733,12 @@ func TestLiquidNewMarket0Gas(t *testing.T) { var liquidTrxFee uint64 k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - order1 := order(ctx.BlockTime(), acc1, "100gbp", "120eur") + order1 := order(ctx.BlockTime(), acc1, "100gbp", "100eur") _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) - order2 := order(ctx.BlockTime(), acc2, "120eur", "100gbp") + order2 := order(ctx.BlockTime(), acc2, "100eur", "100gbp") _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) require.NoError(t, err) require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) @@ -720,6 +760,312 @@ func TestLiquidNewMarket0Gas(t *testing.T) { require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed()) } +func TestPartiallyLiquidMarketOrderGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + order1 := order(ctx.BlockTime(), acc1, "1gbp", "1eur") + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + order2 := order(ctx.BlockTime(), acc2, "10eur", "10gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.NoError(t, err) + require.Equal( + t, sdk.Gas(float64(stdTrxFee-liquidTrxFee)*0.1), gasMeter.GasConsumed(), + "1/10 filled => 10% of total Gas", + ) + + bal1Bef := bk.GetBalance(ctx, acc1.GetAddress(), "gbp") + + gasMeter = sdk.NewInfiniteGasMeter() + slippage := sdk.NewDecWithPrec(75, 2) + cid := cid() + ctx = ctx.WithGasMeter(gasMeter) + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(36)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + cid, + ) + require.NoError(t, err) + bal1Aft := bk.GetBalance(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()), acc1.GetAddress(), "gbp") + rebate := stdTrxFee-liquidTrxFee + filledPct := bal1Bef.Sub(bal1Aft).Amount.ToDec().Quo(sdk.NewDec(36)) + expGas := sdk.Gas( + filledPct.Mul(sdk.NewInt(int64(rebate)).ToDec()).RoundInt64(), + ) + require.Equal( + t, expGas, gasMeter.GasConsumed(), + "9/36 filled => 1/4 of total Gas", + ) +} + +func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + acc1 := createAccount(ctx, ak, bk, randomAddress(), "100000eur") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "100000usd") + + order1cid := cid() + order1, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), + coin("100usd"), acc1.GetAddress(), order1cid, time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order1) + require.NoError(t, err) + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + + order2cid := cid() + order2, _ := types.NewOrder( + ctx.BlockTime(), + types.TimeInForce_GoodTillCancel, + coin("5000eur"), + coin("5000usd"), + acc1.GetAddress(), + order2cid, + time.Time{}, + ) + gasMeter := sdk.NewInfiniteGasMeter() + // Add + Interval Minutes + res, err := k.CancelReplaceLimitOrder( + ctx.WithGasMeter(gasMeter). + WithBlockTime(ctx.BlockTime(). + Add(time.Duration(qualificationMin)*time.Minute)), + order2, order1cid, + ) + require.True(t, err == nil, res.Log) + require.Equal( + t, liquidTrxFee, gasMeter.GasConsumed(), + "Liquid gas as unfilled replacing orders, past minute-interval", + ) + + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + require.Equal(t, order2cid, orders[0].ClientOrderID) + require.Equal(t, coin("5000eur").String(), orders[0].Source.String()) + require.Equal(t, coin("5000usd").String(), orders[0].Destination.String()) + // unfilled: remaining == source amount + require.Equal(t, sdk.NewInt(5000), orders[0].SourceRemaining) + } + + gasMeter = sdk.NewInfiniteGasMeter() + order3, err := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000chf"), + coin("5000usd"), acc1.GetAddress(), cid(), time.Time{}, + ) + require.NoError(t, err) + + // Wrong client order id for previous order submitted. + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order1cid) + require.True(t, types.ErrClientOrderIdNotFound.Is(err)) + require.Equal( + t, stdTrxFee, gasMeter.GasConsumed(), + "Erred replacing order is charged Std gas", + ) + + // Changing instrument of order + gasMeter = sdk.NewGasMeter(math.MaxUint64) + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) + require.True(t, types.ErrOrderInstrumentChanged.Is(err)) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed(), "erred trx") + + o := order(ctx.BlockTime(), acc2, "1000usd", "300eur") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) + bal2 := bk.GetAllBalances(ctx, acc2.GetAddress()) + + require.Equal(t, int64(300), bal2.AmountOf("eur").Int64()) + require.Equal(t, int64(300), bal1.AmountOf("usd").Int64()) + + filled := sdk.ZeroInt() + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + filled = orders[0].Source.Amount.Sub(orders[0].SourceRemaining) + } + + // CancelReplace and verify that previously filled amount is subtracted from the resulting order + order4cid := cid() + gasMeter = sdk.NewInfiniteGasMeter() + order4, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("3000eur"), + coin("3000usd"), acc1.GetAddress(), order4cid, time.Time{}, + ) + ctx = ctx.WithGasMeter(gasMeter) + res, err = k.CancelReplaceLimitOrder( + ctx.WithBlockTime(ctx.BlockTime().Add( + time.Duration(qualificationMin)*time.Minute)), + order4, order2cid, + ) + require.NoError(t, err, err) + require.Equal( + t, gasMeter.GasConsumed(), sdk.Gas(float64(stdTrxFee-liquidTrxFee)*0.1), + "300/3000 filled => 10% of total Gas", + ) + require.Greaterf( + t, gasMeter.GasConsumed(), liquidTrxFee, + "Gas consumed should filled should be greater than LiquidTrxFee", + ) + + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + require.Equal(t, order4cid, orders[0].ClientOrderID) + require.Equal(t, coin("3000eur").String(), orders[0].Source.String()) + require.Equal(t, coin("3000usd").String(), orders[0].Destination.String()) + require.Equal( + t, sdk.NewInt(3000).Sub(filled).String(), + orders[0].SourceRemaining.String(), + ) + } +} + +func TestKeeperReplaceMarketOrderFullLiquidGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + acc1 := createAccount(ctx, ak, bk, randomAddress(), "20000eur") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "45000usd") + + totalSupply := snapshotAccounts(ctx, bk) + + order1cid := cid() + order1, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), + coin("1200usd"), acc1.GetAddress(), order1cid, time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order1) + require.NoError(t, err) + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + + gasMeter := sdk.NewGasMeter(math.MaxUint64) + order2cid := cid() + order2, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), + coin("17000usd"), acc1.GetAddress(), order2cid, time.Time{}, + ) + res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) + require.True(t, err == nil, res.Log) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + require.Equal(t, order2cid, orders[0].ClientOrderID) + require.Equal(t, coin("5000eur"), orders[0].Source) + require.Equal(t, coin("17000usd"), orders[0].Destination) + require.Equal(t, sdk.NewInt(5000), orders[0].SourceRemaining) + } + + gasMeter = sdk.NewInfiniteGasMeter() + order3, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), + coin("1700usd"), acc1.GetAddress(), cid(), time.Time{}, + ) + // Wrong client order id for previous order submitted. + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order1cid) + require.True(t, types.ErrClientOrderIdNotFound.Is(err)) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + + // Changing instrument of order + gasMeter = sdk.NewGasMeter(math.MaxUint64) + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order2cid) + require.True(t, types.ErrOrderInstrumentChanged.Is(err)) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + + o := order(ctx.BlockTime(), acc2, "2600usd", "300eur") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) + bal2 := bk.GetAllBalances(ctx, acc2.GetAddress()) + + require.Equal(t, int64(300), bal2.AmountOf("eur").Int64()) + require.Equal(t, int64(1020), bal1.AmountOf("usd").Int64()) + + filled := sdk.ZeroInt() + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + filled = orders[0].Source.Amount.Sub(orders[0].SourceRemaining) + } + + // CancelReplace and verify that previously filled amount is subtracted from the resulting order + order4cid := cid() + order4, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), + coin("35050usd"), acc1.GetAddress(), order4cid, time.Time{}, + ) + gasMeter = sdk.NewInfiniteGasMeter() + // add qualification minutes + res, err = k.CancelReplaceLimitOrder( + ctx.WithGasMeter(gasMeter). + WithBlockTime(ctx.BlockTime(). + Add(time.Duration(qualificationMin)*time.Minute)), + order4, order2cid, + ) + t.Log(gasMeter.String()) + require.True(t, err == nil, res.Log) + expGas := sdk.NewDec(int64(stdTrxFee - liquidTrxFee)). + Mul(sdk.NewDec(1020)). + Quo(sdk.NewDec(35050)). + RoundInt(). + Uint64() + require.Equal(t, expGas, gasMeter.GasConsumed(), + "Partial Fee: Full fee * destinationFilled(1020)/totalDestination(35050)") + + { + orders := k.GetOrdersByOwner(ctx, acc1.GetAddress()) + require.Len(t, orders, 1) + require.Equal(t, order4cid, orders[0].ClientOrderID) + require.Equal(t, coin("10000eur"), orders[0].Source) + require.Equal(t, coin("35050usd"), orders[0].Destination) + require.Equal(t, sdk.NewInt(10000).Sub(filled), orders[0].SourceRemaining) + } + + // CancelReplace with an order that asks for a larger source than the replaced order has remaining + order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") + k.NewOrderSingle(ctx, order5) + require.True(t, err == nil, res.Log) + + order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") + _, err = k.CancelReplaceLimitOrder(ctx, order6, order4cid) + require.True(t, types.ErrNoSourceRemaining.Is(err)) + + require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) +} + func TestCancelNewLimitFullGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) From 6f8810a670f2f5c308f6c69d1ea26cf83b2389ed Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 18 May 2021 18:08:42 +0300 Subject: [PATCH 25/41] Dry --- x/market/keeper/keeper.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index fed330e6..5ae71250 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -229,6 +229,13 @@ func (k *Keeper) calcReplaceOrderGas( return stdTrxFee } +func handlePanic(r interface{}) error { + fmt.Println(r) + fmt.Println(string(debug.Stack())) + + return fmt.Errorf("%v", r) +} + // postNewOrderSingle is a deferred function for NewOrderSingle. It spends gas // on any order and adds non fill-or-kill orders to the order-book. func (k *Keeper) postNewOrderSingle( @@ -237,17 +244,14 @@ func (k *Keeper) postNewOrderSingle( ) { // Catch NewSingleOrder() panics if orderErr := recover(); orderErr != nil { - *callerErr = fmt.Errorf("%s", orderErr) - fmt.Println(orderErr) - fmt.Println(string(debug.Stack())) + // set NewSingleOrder() error value + *callerErr = handlePanic(orderErr) } defer func() { // Catch Sdk panics i.e. store related if sdkErr := recover(); sdkErr != nil { - *callerErr = fmt.Errorf("%v", sdkErr) - fmt.Println(sdkErr) - fmt.Println(string(debug.Stack())) + *callerErr = handlePanic(sdkErr) } }() From 671962b50185fb15353409285d9fa4093293d34e Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Wed, 19 May 2021 18:14:19 +0300 Subject: [PATCH 26/41] Add non-covered tests --- x/market/keeper/keeper_test.go | 174 ++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 1 deletion(-) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 61f1a70f..c357c25a 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -640,9 +640,14 @@ func TestInsufficientGas(t *testing.T) { // bummer missing 1 micro gasMeter := sdk.NewGasMeter(fullTrxFee - 1) + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + t.Log(gasMeter.String()) require.Error(t, err) require.True(t, strings.Contains(strings.ToLower(err.Error()), "gas")) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) } func TestLimitOrderLiquidAndFullGas(t *testing.T) { @@ -671,6 +676,67 @@ func TestLimitOrderLiquidAndFullGas(t *testing.T) { require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) } +func TestFilledLimitOrderGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + + gasMeter := sdk.NewInfiniteGasMeter() + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + order1 := order(ctx.BlockTime(), acc1, "1gbp", "1eur") + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + gasMeter = sdk.NewInfiniteGasMeter() + order2 := order(ctx.BlockTime(), acc2, "1eur", "1gbp") + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.NoError(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + + // Already filled + order2.DestinationFilled = order2.Destination.Amount + gasMeter = sdk.NewInfiniteGasMeter() + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.Error(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) +} + +func TestSingleOrderPanicFullGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") + + gasMeter := sdk.NewInfiniteGasMeter() + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + order1 := order(ctx.BlockTime(), acc1, "1gbp", "1eur") + _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order1) + require.NoError(t, err) + require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) + + gasMeter = sdk.NewInfiniteGasMeter() + order2 := order(ctx.BlockTime(), acc2, "1eur", "1gbp") + // Panic during banking interactions + k.bk = nil + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.Error(t, err) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) +} + func TestPartiallyLiquidLimitOrderGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) @@ -944,8 +1010,49 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { ) } } +func TestLimitOrderErrGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + acc1 := createAccount(ctx, ak, bk, randomAddress(), "100eur") + + order1cid := cid() + order1, _ := types.NewOrder( + ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), + coin("100usd"), acc1.GetAddress(), order1cid, time.Time{}, + ) + _, err := k.NewOrderSingle(ctx, order1) + require.NoError(t, err) + + order2cid := cid() + order2, _ := types.NewOrder( + ctx.BlockTime(), + types.TimeInForce_GoodTillCancel, + /** 1 above balance **/ + coin("101eur"), + coin("101usd"), + acc1.GetAddress(), + order2cid, + time.Time{}, + ) + + stdTrxFee := k.GetTrxFee(ctx) + qualificationMin := k.GetLiquidityRebateMinutesSpan(ctx) + + gasMeter := sdk.NewInfiniteGasMeter() + // Add + Interval Minutes.. but will err + _, err = k.CancelReplaceLimitOrder( + ctx.WithGasMeter(gasMeter). + WithBlockTime(ctx.BlockTime(). + Add(time.Duration(qualificationMin)*time.Minute)), + order2, order1cid, + ) + require.Error(t, err, "Insufficient balance") + require.Equal( + t, stdTrxFee, gasMeter.GasConsumed(), + "Err -> Full fee", + ) +} -func TestKeeperReplaceMarketOrderFullLiquidGas(t *testing.T) { +func TestKeeperReplaceLimitFullLiquidGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc1 := createAccount(ctx, ak, bk, randomAddress(), "20000eur") acc2 := createAccount(ctx, ak, bk, randomAddress(), "45000usd") @@ -1065,6 +1172,71 @@ func TestKeeperReplaceMarketOrderFullLiquidGas(t *testing.T) { require.True(t, totalSupply.Sub(snapshotAccounts(ctx, bk)).IsZero()) } +func TestReplaceMarketOrderErrGas(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + acc1 := createAccount(ctx, ak, bk, randomAddress(), "500gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + + trxPms := k.GetParams(ctx) + var stdTrxFee uint64 = trxPms.GetTrxFee() + //var liquidTrxFee uint64 = trxPms.GetLiquidTrxFee() + //var qualificationMin int64 = trxPms.GetLiquidityRebateMinutesSpan() + + var o types.Order + var err error + + // Establish market price by executing a 1:1 trade + o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + // Make a market order that allows slippage + clientID := cid() + slippage := sdk.NewDecWithPrec(100, 2) + _, err = k.NewMarketOrderWithSlippage( + ctx, + "gbp", + sdk.NewCoin("eur", sdk.NewInt(100)), + slippage, + acc1.GetAddress(), + types.TimeInForce_GoodTillCancel, + clientID, + ) + require.NoError(t, err) + foundOrder := k.GetOrderByOwnerAndClientOrderId( + ctx, acc1.GetAddress().String(), clientID, + ) + require.NotNil(t, foundOrder, "Market order should exist") + // 100% slippage to double source + require.True(t, foundOrder.Source.IsEqual(sdk.NewCoin("gbp", sdk.NewInt(200)))) + + // Gave 1 gbp and gained a eur + acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("1eur,499gbp").String(), acc1Bal.String()) + + newClientID := cid() + mcrm := &types.MsgCancelReplaceMarketOrder{ + Owner: acc1.GetAddress().String(), + OrigClientOrderId: clientID, + NewClientOrderId: newClientID, + TimeInForce: types.TimeInForce_GoodTillCancel, + Source: "gbp", + Destination: sdk.NewCoin("eur", sdk.NewInt(100)), + MaxSlippage: sdk.NewDecWithPrec(0, 2), + } + + gasMeter := sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + // panic NewSingleOrder + k.bk = nil + _, err = k.CancelReplaceMarketOrder(ctx, mcrm) + require.Error(t, err) + require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) +} func TestCancelNewLimitFullGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) From 0fe6d3f2bc7eb8e1ba4b3f840e6b271fada7282c Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 20 May 2021 14:16:15 +0300 Subject: [PATCH 27/41] Update swagger.json --- docs/client/em/market/v1/query.swagger.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/client/em/market/v1/query.swagger.json b/docs/client/em/market/v1/query.swagger.json index 4d1645f0..2932993c 100644 --- a/docs/client/em/market/v1/query.swagger.json +++ b/docs/client/em/market/v1/query.swagger.json @@ -147,6 +147,11 @@ "created": { "type": "string", "format": "date-time" + }, + "orig_order_created": { + "type": "string", + "format": "date-time", + "description": "applicable to CancelReplace orders: the creation timestamp of the original\norder." } } }, From 69db864f2beda18a1fa1c2052947c4fbc6ce0f3b Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 20 May 2021 14:31:15 +0300 Subject: [PATCH 28/41] Revert KillOrder flag --- x/market/keeper/keeper.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 5ae71250..0699a41e 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -240,7 +240,7 @@ func handlePanic(r interface{}) error { // on any order and adds non fill-or-kill orders to the order-book. func (k *Keeper) postNewOrderSingle( ctx sdk.Context, orderGasMeter sdk.GasMeter, order *types.Order, - commitTrade func(), callerErr *error, + commitTrade func(), killOrder *bool, callerErr *error, ) { // Catch NewSingleOrder() panics if orderErr := recover(); orderErr != nil { @@ -258,7 +258,7 @@ func (k *Keeper) postNewOrderSingle( k.postOrderSpendGas(ctx, order, orderGasMeter, callerErr) // Roll back any state changes made by the aggressive FillOrKill order. - if order.TimeInForce == types.TimeInForce_FillOrKill { + if *killOrder { return } @@ -266,6 +266,8 @@ func (k *Keeper) postNewOrderSingle( } func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (res *sdk.Result, err error) { + // Set this to true to roll back any state changes made by the aggressive order. Used for FillOrKill orders. + KillOrder := false ctx, commitTrade := ctx.CacheContext() // the transactor's meter @@ -273,7 +275,7 @@ func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (r // impostor meter that would not panic ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - defer k.postNewOrderSingle(ctx, orderGasMeter, &aggressiveOrder, commitTrade, &err) + defer k.postNewOrderSingle(ctx, orderGasMeter, &aggressiveOrder, commitTrade, &KillOrder, &err) if err := aggressiveOrder.IsValid(); err != nil { return nil, err @@ -449,6 +451,7 @@ func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (r addToBook = false types.EmitExpireEvent(ctx, aggressiveOrder) case types.TimeInForce_FillOrKill: + KillOrder = true ctx = ctx.WithEventManager(sdk.NewEventManager()) types.EmitExpireEvent(ctx, aggressiveOrder) } From f170f28a928d4eb1730e2becf8ac798d6722baef Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 20 May 2021 18:34:10 +0300 Subject: [PATCH 29/41] Fix FOK, IOC gas, add tests --- x/market/keeper/keeper.go | 19 +++++-- x/market/keeper/keeper_test.go | 91 ++++++++++++++++++++++++++++++---- 2 files changed, 94 insertions(+), 16 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 0699a41e..4636dbfc 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -259,6 +259,7 @@ func (k *Keeper) postNewOrderSingle( // Roll back any state changes made by the aggressive FillOrKill order. if *killOrder { + // order has not been filled return } @@ -510,17 +511,25 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { // postOrderSpendGas is a deferred function from Order processing // NewSingleOrder, NewCancelReplace functions to charge Gas. func (k *Keeper) postOrderSpendGas( - ctx sdk.Context, order *types.Order, orderGasMeter sdk.GasMeter, callerErr *error, + ctx sdk.Context, order *types.Order, orderGasMeter sdk.GasMeter, + callerErr *error, ) { - var stdTrxFee sdk.Gas - k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - + var stdTrxFee = k.GetTrxFee(ctx) // Order failed if *callerErr != nil || order == nil || order.IsValid() != nil { orderGasMeter.ConsumeGas( stdTrxFee, - fmt.Sprintf("cannot cover the erred order %d gas", stdTrxFee), + fmt.Sprintf("cannot cover the erred/cancelled order %d gas", stdTrxFee), + ) + return + } + + // Non-liquidity adding order + if order.TimeInForce != types.TimeInForce_GoodTillCancel { + orderGasMeter.ConsumeGas( + stdTrxFee, fmt.Sprintf("FOK, IOC orders cost the full gas"), ) + return } diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index c357c25a..a9c0782f 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -538,9 +538,12 @@ func TestFillOrKillMarketOrder1(t *testing.T) { string(res.Events[0].Attributes[len(res.Events[0].Attributes)-1].GetValue()), ) + stdTrxFee := k.GetTrxFee(ctx) + gasMeter := sdk.NewInfiniteGasMeter() + // Create a fill or kill order that cannot be satisfied by the current market result, err := k.NewMarketOrderWithSlippage( - ctx, + ctx.WithGasMeter(gasMeter), "gbp", sdk.NewCoin("eur", sdk.NewInt(200)), sdk.ZeroDec(), @@ -554,6 +557,8 @@ func TestFillOrKillMarketOrder1(t *testing.T) { require.Equal(t, types.EventTypeMarket, result.Events[0].Type) require.Equal(t, "action", string(result.Events[0].Attributes[0].GetKey())) require.Equal(t, "expire", string(result.Events[0].Attributes[0].GetValue())) + require.Equal(t, gasMeter.GasConsumed(), stdTrxFee, + "Partially filled FillOrKill costs like a cancelled order") // Last order must fail completely due to not being fillable acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -574,10 +579,15 @@ func TestFillOrKillLimitOrder1(t *testing.T) { _, err := k.NewOrderSingle(ctx, o) require.NoError(t, err) + stdTrxFee := k.GetTrxFee(ctx) + gasMeter := sdk.NewInfiniteGasMeter() + order2 := order(ctx.BlockTime(), acc1, "200gbp", "200eur") order2.TimeInForce = types.TimeInForce_FillOrKill - _, err = k.NewOrderSingle(ctx, order2) + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) require.NoError(t, err) + require.Equal(t, gasMeter.GasConsumed(), stdTrxFee, + "Partially filled FillOrKill costs like a cancelled order") // Order must fail completely due to not being fillable acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -593,32 +603,91 @@ func TestFillOrKillLimitOrder1(t *testing.T) { require.Equal(t, acc2Orders[0].Created, ctx.BlockTime()) } +func TestFillOrKillLimitOrder2Filled(t *testing.T) { + ctx, k, ak, bk := createTestComponents(t) + + acc1 := createAccount(ctx, ak, bk, randomAddress(), "500gbp") + acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") + + // Create a tiny market for eur + o := order(ctx.BlockTime(), acc2, "100eur", "100gbp") + _, err := k.NewOrderSingle(ctx, o) + require.NoError(t, err) + + stdTrxFee := k.GetTrxFee(ctx) + gasMeter := sdk.NewInfiniteGasMeter() + + // A successful FOK Order + order2 := order(ctx.BlockTime(), acc1, "100gbp", "100eur") + order2.TimeInForce = types.TimeInForce_FillOrKill + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + require.NoError(t, err) + require.Equal(t, gasMeter.GasConsumed(), stdTrxFee, + "Filled order") + + acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("400gbp,100eur"), acc1Bal) + + acc2Bal := bk.GetAllBalances(ctx, acc2.GetAddress()) + require.Equal(t, coins("400eur,100gbp"), acc2Bal) + + // Test that the order book looks as expected + require.Empty(t, k.GetOrdersByOwner(ctx, acc1.GetAddress())) + require.Empty(t, k.GetOrdersByOwner(ctx, acc2.GetAddress())) +} + func TestImmediateOrCancel(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc1 := createAccount(ctx, ak, bk, randomAddress(), "20gbp") acc2 := createAccount(ctx, ak, bk, randomAddress(), "20eur") - var o types.Order var err error - o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") - _, err = k.NewOrderSingle(ctx, o) + o1 := order(ctx.BlockTime(), acc2, "1eur", "1gbp") + _, err = k.NewOrderSingle(ctx, o1) require.NoError(t, err) - o = order(ctx.BlockTime(), acc1, "2gbp", "2eur") - o.TimeInForce = types.TimeInForce_ImmediateOrCancel - cid := o.ClientOrderID - _, err = k.NewOrderSingle(ctx, o) + stdTrxFee := k.GetTrxFee(ctx) + gasMeter := sdk.NewInfiniteGasMeter() + + // IOK partially Filled + o2 := order(ctx.BlockTime(), acc1, "2gbp", "2eur") + o2.TimeInForce = types.TimeInForce_ImmediateOrCancel + cid2 := o2.ClientOrderID + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o2) require.NoError(t, err) - require.Equal(t, o.Created, ctx.BlockTime()) + require.Equal(t, o2.Created, ctx.BlockTime()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) // Verify that order is not in book - order := k.GetOrderByOwnerAndClientOrderId(ctx, acc1.GetAddress().String(), cid) + order := k.GetOrderByOwnerAndClientOrderId(ctx, acc1.GetAddress().String(), cid2) require.Nil(t, order) bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) require.Equal(t, coins("19gbp,1eur"), bal1) + + // again o1 + _, err = k.NewOrderSingle(ctx, o1) + require.NoError(t, err) + + // IOK Filled + gasMeter = sdk.NewInfiniteGasMeter() + o2.Source = sdk.NewCoin("gbp", sdk.NewInt(1)) + o2.Destination = sdk.NewCoin("eur", sdk.NewInt(1)) + o2.TimeInForce = types.TimeInForce_ImmediateOrCancel + o2.ClientOrderID = cid() + _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o2) + require.NoError(t, err) + require.Equal(t, o2.Created, ctx.BlockTime()) + require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + + // Verify that order is not in book + order = k.GetOrderByOwnerAndClientOrderId(ctx, acc1.GetAddress().String(), o2.ClientOrderID) + require.Nil(t, order) + + bal2 := bk.GetAllBalances(ctx, acc1.GetAddress()) + require.Equal(t, coins("18gbp,2eur"), bal2) } func TestInsufficientGas(t *testing.T) { From f9f5efb50deb5a11c8b6b321572be475caac0d30 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 20 May 2021 18:37:51 +0300 Subject: [PATCH 30/41] Fix sort --- x/market/keeper/querier.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/market/keeper/querier.go b/x/market/keeper/querier.go index 82e381d0..3187f56d 100644 --- a/x/market/keeper/querier.go +++ b/x/market/keeper/querier.go @@ -68,7 +68,7 @@ func queryByAccount(ctx sdk.Context, k *Keeper, path []string, req abci.RequestQ sort.Slice( orders, func(i, j int) bool { - return orders[i].ID < orders[i].ID + return orders[i].ID < orders[j].ID }) resp := types.QueryByAccountResponse{Orders: orders} From baf359b4b81a553cad20f1120115ec867ce23118 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 20 May 2021 20:43:51 +0300 Subject: [PATCH 31/41] Add calcOrderGas tests --- x/market/keeper/keeper_test.go | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index a9c0782f..9086e195 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -47,6 +47,68 @@ func init() { emtypes.ConfigureSDK() } + +func TestKeeper_calcOrderGas(t *testing.T) { + ctx, k, _, _ := createTestComponents(t) + + var ( + stdTrxFee sdk.Gas = k.GetTrxFee(ctx) + liquidTrxFee sdk.Gas = k.GetLiquidTrxFee(ctx) + //liquidIntervalMin int64 = k.GetLiquidityRebateMinutesSpan(ctx) + ) + tests := []struct { + name string + ctx sdk.Context + stdTrxFee sdk.Gas + liquidTrxFee sdk.Gas + dstFilled sdk.Int + dstAmount sdk.Int + want sdk.Gas + }{ + { + name: "0% Filled Full Gas", + ctx: ctx, + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(0), + dstAmount: sdk.NewInt(0), + want: liquidTrxFee, + }, + { + name: "100% Filled Full Gas", + ctx: ctx, + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(1), + dstAmount: sdk.NewInt(1), + want: stdTrxFee, + }, + { + name: "10% Filled Full Gas", + ctx: ctx, + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(10), + dstAmount: sdk.NewInt(100), + want: stdTrxFee/10, + }, + { + name: "90% Filled Full Gas", + ctx: ctx, + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(90), + dstAmount: sdk.NewInt(100), + want: sdk.Gas(float64(stdTrxFee) * 0.9), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := k.calcOrderGas(tt.ctx, tt.stdTrxFee, tt.dstFilled, + tt.dstAmount); got != tt.want { + t.Errorf("calcOrderGas() = %v, want %v", got, tt.want) + } + }) + } +} + func TestBasicTrade(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) From 67f1548327e814f5771d85bc11f09fab7598c89c Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 21 May 2021 13:46:57 +0300 Subject: [PATCH 32/41] Remove panic handling --- x/market/keeper/keeper.go | 13 ------------- x/market/keeper/keeper_test.go | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 4636dbfc..9f4c5757 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -242,19 +242,6 @@ func (k *Keeper) postNewOrderSingle( ctx sdk.Context, orderGasMeter sdk.GasMeter, order *types.Order, commitTrade func(), killOrder *bool, callerErr *error, ) { - // Catch NewSingleOrder() panics - if orderErr := recover(); orderErr != nil { - // set NewSingleOrder() error value - *callerErr = handlePanic(orderErr) - } - - defer func() { - // Catch Sdk panics i.e. store related - if sdkErr := recover(); sdkErr != nil { - *callerErr = handlePanic(sdkErr) - } - }() - k.postOrderSpendGas(ctx, order, orderGasMeter, callerErr) // Roll back any state changes made by the aggressive FillOrKill order. diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 9086e195..eb0c56c6 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -774,10 +774,10 @@ func TestInsufficientGas(t *testing.T) { var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) - t.Log(gasMeter.String()) - require.Error(t, err) - require.True(t, strings.Contains(strings.ToLower(err.Error()), "gas")) + require.Panics(t, func() { + // Taking away liquidity not enough to cover the full Trx fee + k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + }) require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) } @@ -863,9 +863,11 @@ func TestSingleOrderPanicFullGas(t *testing.T) { order2 := order(ctx.BlockTime(), acc2, "1eur", "1gbp") // Panic during banking interactions k.bk = nil - _, err = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) - require.Error(t, err) - require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) + require.Panics(t, func() { + k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + }) + // Baseapp should charge the appropriate fee + require.Equal(t, sdk.Gas(0), gasMeter.GasConsumed()) } func TestPartiallyLiquidLimitOrderGas(t *testing.T) { @@ -1310,8 +1312,6 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { trxPms := k.GetParams(ctx) var stdTrxFee uint64 = trxPms.GetTrxFee() - //var liquidTrxFee uint64 = trxPms.GetLiquidTrxFee() - //var qualificationMin int64 = trxPms.GetLiquidityRebateMinutesSpan() var o types.Order var err error @@ -1362,10 +1362,11 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { gasMeter := sdk.NewInfiniteGasMeter() ctx = ctx.WithGasMeter(gasMeter) - // panic NewSingleOrder k.bk = nil - _, err = k.CancelReplaceMarketOrder(ctx, mcrm) - require.Error(t, err) + require.Panics(t, func() { + // panic CancelReplace + k.CancelReplaceMarketOrder(ctx, mcrm) + }) require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) } From d2a76c1f4b1c5d670c392ef1a3c762e2f845b45d Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Mon, 24 May 2021 17:53:05 +0300 Subject: [PATCH 33/41] Add Market Chain Decorator --- app.go | 2 ++ x/market/keeper/keeper.go | 35 +++++++++++++++--- x/market/keeper/keeper_test.go | 65 ++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 5 deletions(-) diff --git a/app.go b/app.go index d2ecfe71..a8830188 100644 --- a/app.go +++ b/app.go @@ -427,6 +427,8 @@ func NewApp( encodingConfig.TxConfig.SignModeHandler(), ), ) + sdk.ChainAnteDecorators(app.marketKeeper) + app.SetEndBlocker(app.EndBlocker) if loadLatest { diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 9f4c5757..49bfa77f 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -6,11 +6,11 @@ package keeper import ( "fmt" + "github.com/cosmos/cosmos-sdk/x/auth/ante" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" types2 "github.com/e-money/em-ledger/x/authority/types" "math" - "runtime/debug" "sync" "time" @@ -229,11 +229,36 @@ func (k *Keeper) calcReplaceOrderGas( return stdTrxFee } -func handlePanic(r interface{}) error { - fmt.Println(r) - fmt.Println(string(debug.Stack())) +// AnteHandle fulfills the AnteDecorator interface for the market module to +// charge the standard gas for panicked orders. +func (k *Keeper) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (anteCtx sdk.Context, anteErr error) { + // all transactions must implement GasTx + gasTx, ok := tx.(ante.GasTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx") + } + + defer func() { + // About recover(): + // https://github.com/cosmos/cosmos-sdk/blob/45265b1ea6251e50b28a96eea954edd4abbefd3a/x/auth/ante/setup.go#L45 + if r := recover(); r != nil { + fmt.Println("*** Market ante handle panic:") + stdTrxFee := k.GetTrxFee(ctx.WithGasMeter(sdk.NewInfiniteGasMeter())) + + anteCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasTx.GetGas())) + + // charge StdFee + anteCtx.GasMeter().ConsumeGas(stdTrxFee, "Panicked Market Order") + + log := fmt.Sprintf("market order panic: %v gasWanted: %d, gasUsed: %d", + r, gasTx.GetGas(), anteCtx.GasMeter().GasConsumed()) + + // send error downstream with required gas info + anteErr = sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, log) + } + }() - return fmt.Errorf("%v", r) + return next(ctx, tx, simulate) } // postNewOrderSingle is a deferred function for NewOrderSingle. It spends gas diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index eb0c56c6..27480802 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -17,6 +17,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/ante" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -870,6 +871,70 @@ func TestSingleOrderPanicFullGas(t *testing.T) { require.Equal(t, sdk.Gas(0), gasMeter.GasConsumed()) } +func TestAnteHandlerNoTrx(t *testing.T) { + ctx, k, _, _ := createTestComponents(t) + sud := ante.NewSetUpContextDecorator() + anteHandler := sdk.ChainAnteDecorators(sud, k) + + encodingConfig := MakeTestEncodingConfig() + + clientCtx := client.Context{}. + WithJSONMarshaler(encodingConfig.Marshaler). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithChainID("testing") + + flagSet := pflag.NewFlagSet("testing", pflag.PanicOnError) + txf := clienttx.NewFactoryCLI(clientCtx, flagSet). + WithMemo("PanicLimitOrder"). + WithFees("100000NGM") + + msg := &types.MsgAddLimitOrder{} + txb, err := clienttx.BuildUnsignedTx(txf, msg) + require.NoError(t, err) + + gasMeter := sdk.NewInfiniteGasMeter() + _, err = anteHandler(ctx.WithGasMeter(gasMeter), txb.GetTx(), false) + require.NoError(t, err) + require.Equal(t, gasMeter.GasConsumed(), sdk.Gas(0)) +} + +type PanicDecorator struct{} + +func (pd PanicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + panic("market order panic") +} + +func TestChargeStdFeeAnteHandlerPanic(t *testing.T) { + ctx, k, _, _ := createTestComponents(t) + sud := ante.NewSetUpContextDecorator() + + anteHandler := sdk.ChainAnteDecorators(sud, k, PanicDecorator{}) + + encodingConfig := MakeTestEncodingConfig() + + clientCtx := client.Context{}. + WithJSONMarshaler(encodingConfig.Marshaler). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithChainID("testing") + + flagSet := pflag.NewFlagSet("testing", pflag.PanicOnError) + txf := clienttx.NewFactoryCLI(clientCtx, flagSet) + + msg := &types.MsgAddLimitOrder{} + txb, err := clienttx.BuildUnsignedTx(txf, msg) + require.NoError(t, err) + + stdTrxFee := k.GetTrxFee(ctx.WithGasMeter(sdk.NewInfiniteGasMeter())) + gasMeter := sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + + ctx, err = anteHandler(ctx, txb.GetTx(), false) + require.Error(t, err) + require.Equal(t, ctx.GasMeter().GasConsumed(), stdTrxFee) +} + func TestPartiallyLiquidLimitOrderGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) From 685b5f6f9d5b9861a9d35e4fb27c12fa8652f39f Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Mon, 24 May 2021 22:58:30 +0300 Subject: [PATCH 34/41] WIP test chained AnteHandlers --- app_test.go | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/app_test.go b/app_test.go index fd5e8b48..b7a77c84 100644 --- a/app_test.go +++ b/app_test.go @@ -2,11 +2,23 @@ package emoney import ( "encoding/json" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client" + clienttx "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" "github.com/e-money/em-ledger/x/authority" + "github.com/e-money/em-ledger/x/market/types" "github.com/tendermint/tendermint/libs/rand" + tmrand "github.com/tendermint/tendermint/libs/rand" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "os" "testing" + "time" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/libs/log" @@ -15,6 +27,110 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) +func setupMarketApp(t *testing.T, options ...func(*baseapp.BaseApp)) (sdk.Context, *EMoneyApp, EncodingConfig) { + t.Helper() + + encCfg := MakeEncodingConfig() + + db := dbm.NewMemDB() + + app := NewApp( + log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, + map[int64]bool{}, t.TempDir(), 0, encCfg, EmptyAppOptions{}, options..., + ) + require.NotNil(t, app) + + ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{ChainID: "test-market-chain"}) + ctx = ctx.WithBlockTime(time.Now()) + + app.marketKeeper.InitParamsStore(ctx) + + return ctx, app, encCfg +} + +func randomAddress() sdk.AccAddress { + return tmrand.Bytes(sdk.AddrLen) +} + +func TestMarketApp(t *testing.T) { + ctx, app, enc := setupMarketApp(t, []func(*baseapp.BaseApp){}...) + require.NotNil(t, app) + + genesisState := ModuleBasics.DefaultGenesis(enc.Marshaler) + authorityState := authority.NewGenesisState(rand.Bytes(sdk.AddrLen), nil, sdk.NewDecCoins()) + genesisState[authority.ModuleName] = enc.Marshaler.MustMarshalJSON(&authorityState) + + stateBytes, err := json.MarshalIndent(genesisState, "", " ") + require.NoError(t, err) + + // Initialize the chain + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + AppStateBytes: stateBytes, + }, + ) + + keystore, err := keyring.New(t.Name(), keyring.BackendMemory, "", nil) + require.NoError(t, err) + + uid := "theKeyName" + + info, _, err := keystore.NewMnemonic( + uid, keyring.English, sdk.FullFundraiserPath, hd.Secp256k1, + ) + require.NoError(t, err) + t.Log(info.GetAddress().String()) + + app.accountKeeper.SetAccount( + ctx, app.accountKeeper.NewAccountWithAddress(ctx, info.GetAddress()), + ) + acci := app.accountKeeper.GetAccount(ctx, info.GetAddress()) + t.Log(acci.String()) + require.NotNil(t, acci) + require.Equal(t, acci.GetAddress().String(), info.GetAddress().String()) + + msg := &types.MsgAddLimitOrder{ + TimeInForce: types.TimeInForce_GoodTillCancel, + Owner: info.GetAddress().String(), + Source: sdk.NewCoin("echf", sdk.NewInt(50000)), + Destination: sdk.NewCoin("eeur", sdk.NewInt(60000)), + ClientOrderId: "testAddLimitOrder-chf-eur", + } + + txBuilder := enc.TxConfig.NewTxBuilder() + txBuilder.SetMsgs(msg) + txBuilder.SetFeeAmount(sdk.Coins{sdk.NewCoin("ungm", sdk.NewInt(25_000))}) + txBuilder.SetGasLimit(213456) + txBuilder.SetMemo("TestMarketApp") + + txFactory := clienttx.Factory{}. + WithChainID("test-market-app"). + WithTxConfig(enc.TxConfig). + WithSignMode(signing.SignMode_SIGN_MODE_DIRECT). + WithAccountNumber(1). + WithSequence(1). + WithKeybase(keystore) + + tx := txBuilder.GetTx() + signers := tx.GetSigners() + require.Equal(t, signers[0].String(), info.GetAddress().String()) + + err = authclient.SignTx(txFactory, client.Context{}, info.GetName(), + txBuilder, true, true) + require.NoError(t, err) + + _, err = enc.TxConfig.TxEncoder()(txBuilder.GetTx()) + require.NoError(t, err) + + gasInfo, res, err := app.Deliver(enc.TxConfig.TxEncoder(), tx) + require.NoError(t, err) + t.Log(gasInfo.String()) + t.Log(res.Log) + t.Log(res.String()) + require.Equal(t, gasInfo.GasUsed, sdk.Gas(0)) +} + func TestSimAppExportAndBlockedAddrs(t *testing.T) { encCfg := MakeEncodingConfig() db := dbm.NewMemDB() From 1a21a34fef7c547d121f29e95c3ee132549e559a Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 25 May 2021 17:01:41 +0300 Subject: [PATCH 35/41] Add trx liquid order test --- app.go | 34 +++++++++++++++-- app_test.go | 77 +++++++++++++++++++++++++-------------- x/market/keeper/keeper.go | 12 ++++-- 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/app.go b/app.go index a8830188..b1c61521 100644 --- a/app.go +++ b/app.go @@ -18,6 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/signing" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -422,12 +423,11 @@ func NewApp( app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) app.SetAnteHandler( - ante.NewAnteHandler( - app.accountKeeper, app.bankKeeper, ante.DefaultSigVerificationGasConsumer, - encodingConfig.TxConfig.SignModeHandler(), + getAnteHandler( + app.accountKeeper, app.bankKeeper, + encodingConfig.TxConfig.SignModeHandler(), app.marketKeeper, ), ) - sdk.ChainAnteDecorators(app.marketKeeper) app.SetEndBlocker(app.EndBlocker) @@ -643,6 +643,32 @@ func (app EMoneyApp) SetMinimumGasPrices(gasPricesStr string) (err error) { return } +func getAnteHandler( + ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, + signModeHandler signing.SignModeHandler, marketAnteHandler sdk.AnteDecorator, +) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + ante.NewRejectExtensionOptionsDecorator(), + ante.NewMempoolFeeDecorator(), + ante.NewValidateBasicDecorator(), + ante.TxTimeoutHeightDecorator{}, + ante.NewValidateMemoDecorator(ak), + ante.NewConsumeGasForTxSizeDecorator(ak), + ante.NewRejectFeeGranterDecorator(), + ante.NewSetPubKeyDecorator(ak), + ante.NewValidateSigCountDecorator(ak), + ante.NewDeductFeeDecorator(ak, bk), + ante.NewSigGasConsumeDecorator( + ak, ante.DefaultSigVerificationGasConsumer, + ), + ante.NewSigVerificationDecorator(ak, signModeHandler), + ante.NewIncrementSequenceDecorator(ak), + // last to execute + marketAnteHandler, + ) +} + func init() { sdk.PowerReduction = sdk.OneInt() } diff --git a/app_test.go b/app_test.go index b7a77c84..3f44a9d4 100644 --- a/app_test.go +++ b/app_test.go @@ -10,10 +10,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/e-money/em-ledger/x/authority" "github.com/e-money/em-ledger/x/market/types" "github.com/tendermint/tendermint/libs/rand" - tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "os" @@ -48,21 +48,51 @@ func setupMarketApp(t *testing.T, options ...func(*baseapp.BaseApp)) (sdk.Contex return ctx, app, encCfg } -func randomAddress() sdk.AccAddress { - return tmrand.Bytes(sdk.AddrLen) +func coins(s string) sdk.Coins { + coins, err := sdk.ParseCoinsNormalized(s) + if err != nil { + panic(err) + } + return coins } -func TestMarketApp(t *testing.T) { +func TestAppLiquidOrder0Gas(t *testing.T) { ctx, app, enc := setupMarketApp(t, []func(*baseapp.BaseApp){}...) require.NotNil(t, app) genesisState := ModuleBasics.DefaultGenesis(enc.Marshaler) - authorityState := authority.NewGenesisState(rand.Bytes(sdk.AddrLen), nil, sdk.NewDecCoins()) + authorityState := authority.NewGenesisState( + rand.Bytes(sdk.AddrLen), nil, + sdk.NewDecCoins(), + ) genesisState[authority.ModuleName] = enc.Marshaler.MustMarshalJSON(&authorityState) + keystore, err := keyring.New(t.Name(), keyring.BackendMemory, "", nil) + require.NoError(t, err) + + uid := "theKeyName" + + info, _, err := keystore.NewMnemonic( + uid, keyring.English, sdk.FullFundraiserPath, hd.Secp256k1, + ) + require.NoError(t, err) + t.Log(info.GetAddress().String()) + + supply := coins("100000chf,100000eur,1000000ngm") + + bankState := banktypes.NewGenesisState( + banktypes.DefaultParams(), + []banktypes.Balance{{info.GetAddress().String(), supply}}, + supply, + []banktypes.Metadata{}, + ) + genesisState[banktypes.ModuleName] = enc.Marshaler.MustMarshalJSON(bankState) + stateBytes, err := json.MarshalIndent(genesisState, "", " ") require.NoError(t, err) + app.bankKeeper.SetSupply(ctx, banktypes.NewSupply(supply)) + // Initialize the chain app.InitChain( abci.RequestInitChain{ @@ -71,45 +101,41 @@ func TestMarketApp(t *testing.T) { }, ) - keystore, err := keyring.New(t.Name(), keyring.BackendMemory, "", nil) - require.NoError(t, err) - - uid := "theKeyName" - - info, _, err := keystore.NewMnemonic( - uid, keyring.English, sdk.FullFundraiserPath, hd.Secp256k1, - ) - require.NoError(t, err) - t.Log(info.GetAddress().String()) + total := app.bankKeeper.GetSupply(ctx) + require.NotNil(t, total) app.accountKeeper.SetAccount( ctx, app.accountKeeper.NewAccountWithAddress(ctx, info.GetAddress()), ) acci := app.accountKeeper.GetAccount(ctx, info.GetAddress()) - t.Log(acci.String()) + t.Log(acci.GetAddress().String()) require.NotNil(t, acci) require.Equal(t, acci.GetAddress().String(), info.GetAddress().String()) + err = app.bankKeeper.SetBalances( + ctx, info.GetAddress(), coins("250000ngm,50000chf")) + require.NoError(t, err) + msg := &types.MsgAddLimitOrder{ TimeInForce: types.TimeInForce_GoodTillCancel, Owner: info.GetAddress().String(), - Source: sdk.NewCoin("echf", sdk.NewInt(50000)), - Destination: sdk.NewCoin("eeur", sdk.NewInt(60000)), + Source: sdk.NewCoin("chf", sdk.NewInt(50000)), + Destination: sdk.NewCoin("eur", sdk.NewInt(60000)), ClientOrderId: "testAddLimitOrder-chf-eur", } txBuilder := enc.TxConfig.NewTxBuilder() txBuilder.SetMsgs(msg) - txBuilder.SetFeeAmount(sdk.Coins{sdk.NewCoin("ungm", sdk.NewInt(25_000))}) + txBuilder.SetFeeAmount(coins("25000ngm")) txBuilder.SetGasLimit(213456) - txBuilder.SetMemo("TestMarketApp") + txBuilder.SetMemo("TestAppLiquidOrder0Gas") txFactory := clienttx.Factory{}. - WithChainID("test-market-app"). + WithChainID(""). WithTxConfig(enc.TxConfig). WithSignMode(signing.SignMode_SIGN_MODE_DIRECT). - WithAccountNumber(1). - WithSequence(1). + WithAccountNumber(acci.GetAccountNumber()). + WithSequence(acci.GetSequence()). WithKeybase(keystore) tx := txBuilder.GetTx() @@ -123,11 +149,8 @@ func TestMarketApp(t *testing.T) { _, err = enc.TxConfig.TxEncoder()(txBuilder.GetTx()) require.NoError(t, err) - gasInfo, res, err := app.Deliver(enc.TxConfig.TxEncoder(), tx) + gasInfo, _, err := app.Deliver(enc.TxConfig.TxEncoder(), tx) require.NoError(t, err) - t.Log(gasInfo.String()) - t.Log(res.Log) - t.Log(res.String()) require.Equal(t, gasInfo.GasUsed, sdk.Gas(0)) } diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 49bfa77f..a426a896 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -231,7 +231,9 @@ func (k *Keeper) calcReplaceOrderGas( // AnteHandle fulfills the AnteDecorator interface for the market module to // charge the standard gas for panicked orders. -func (k *Keeper) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (anteCtx sdk.Context, anteErr error) { +func (k Keeper) AnteHandle( + ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, +) (anteCtx sdk.Context, anteErr error) { // all transactions must implement GasTx gasTx, ok := tx.(ante.GasTx) if !ok { @@ -239,14 +241,15 @@ func (k *Keeper) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk. } defer func() { + // Set gas meter to 0 before running market messages + // Set limit to what the user requested + anteCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasTx.GetGas())) + // About recover(): // https://github.com/cosmos/cosmos-sdk/blob/45265b1ea6251e50b28a96eea954edd4abbefd3a/x/auth/ante/setup.go#L45 if r := recover(); r != nil { - fmt.Println("*** Market ante handle panic:") stdTrxFee := k.GetTrxFee(ctx.WithGasMeter(sdk.NewInfiniteGasMeter())) - anteCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasTx.GetGas())) - // charge StdFee anteCtx.GasMeter().ConsumeGas(stdTrxFee, "Panicked Market Order") @@ -254,6 +257,7 @@ func (k *Keeper) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk. r, gasTx.GetGas(), anteCtx.GasMeter().GasConsumed()) // send error downstream with required gas info + // an alternative pattern is to issue panic with the updated error anteErr = sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, log) } }() From 26fc8a45e224e33c50873c564cf702d7478290ac Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 25 May 2021 23:55:34 +0300 Subject: [PATCH 36/41] Add Market Msg Guard, App tests --- app_test.go | 122 ++++++++++++++++++++++++++++---------- x/market/keeper/keeper.go | 34 +++++------ 2 files changed, 107 insertions(+), 49 deletions(-) diff --git a/app_test.go b/app_test.go index 3f44a9d4..f2dc495a 100644 --- a/app_test.go +++ b/app_test.go @@ -10,6 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx/signing" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" + authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/e-money/em-ledger/x/authority" "github.com/e-money/em-ledger/x/market/types" @@ -56,7 +57,7 @@ func coins(s string) sdk.Coins { return coins } -func TestAppLiquidOrder0Gas(t *testing.T) { +func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { ctx, app, enc := setupMarketApp(t, []func(*baseapp.BaseApp){}...) require.NotNil(t, app) @@ -67,22 +68,19 @@ func TestAppLiquidOrder0Gas(t *testing.T) { ) genesisState[authority.ModuleName] = enc.Marshaler.MustMarshalJSON(&authorityState) - keystore, err := keyring.New(t.Name(), keyring.BackendMemory, "", nil) - require.NoError(t, err) + keystore1, acct1 := getNewAcctInfo(t) + keystore2, acct2 := getNewAcctInfo(t) - uid := "theKeyName" - - info, _, err := keystore.NewMnemonic( - uid, keyring.English, sdk.FullFundraiserPath, hd.Secp256k1, - ) - require.NoError(t, err) - t.Log(info.GetAddress().String()) - - supply := coins("100000chf,100000eur,1000000ngm") + bal1 := coins("100000chf,1000000ngm") + bal2 := coins("100000eur,1000000ngm") + supply := coins("100000chf,100000eur,2000000ngm") bankState := banktypes.NewGenesisState( banktypes.DefaultParams(), - []banktypes.Balance{{info.GetAddress().String(), supply}}, + []banktypes.Balance{ + {acct1.GetAddress().String(), bal1}, + {acct2.GetAddress().String(), bal2}, + }, supply, []banktypes.Metadata{}, ) @@ -105,53 +103,113 @@ func TestAppLiquidOrder0Gas(t *testing.T) { require.NotNil(t, total) app.accountKeeper.SetAccount( - ctx, app.accountKeeper.NewAccountWithAddress(ctx, info.GetAddress()), + ctx, app.accountKeeper.NewAccountWithAddress(ctx, acct1.GetAddress()), + ) + app.accountKeeper.SetAccount( + ctx, app.accountKeeper.NewAccountWithAddress(ctx, acct2.GetAddress()), ) - acci := app.accountKeeper.GetAccount(ctx, info.GetAddress()) - t.Log(acci.GetAddress().String()) - require.NotNil(t, acci) - require.Equal(t, acci.GetAddress().String(), info.GetAddress().String()) - err = app.bankKeeper.SetBalances( - ctx, info.GetAddress(), coins("250000ngm,50000chf")) + // + // Liquid 0 Gas Cost + // + msg := &types.MsgAddLimitOrder{ + TimeInForce: types.TimeInForce_GoodTillCancel, + Owner: acct1.GetAddress().String(), + Source: sdk.NewCoin("chf", sdk.NewInt(50000)), + Destination: sdk.NewCoin("eur", sdk.NewInt(50000)), + ClientOrderId: "testAddLimitOrder-chf-eur1", + } + + tx := getSignedTrx(ctx, t, app.accountKeeper, enc, msg, keystore1, acct1, 0, 0) + + gasInfo, _, err := app.Deliver(enc.TxConfig.TxEncoder(), tx) require.NoError(t, err) + require.Equal(t, gasInfo.GasUsed, sdk.Gas(0)) - msg := &types.MsgAddLimitOrder{ + // + // Destination denomination xxx does not exist and errs, full gas + // + msg2 := &types.MsgAddLimitOrder{ TimeInForce: types.TimeInForce_GoodTillCancel, - Owner: info.GetAddress().String(), + Owner: acct1.GetAddress().String(), Source: sdk.NewCoin("chf", sdk.NewInt(50000)), - Destination: sdk.NewCoin("eur", sdk.NewInt(60000)), - ClientOrderId: "testAddLimitOrder-chf-eur", + Destination: sdk.NewCoin("xxx", sdk.NewInt(50000)), + ClientOrderId: "testAddLimitOrder-chf-eur2", } + tx = getSignedTrx(ctx, t, app.accountKeeper, enc, msg2, keystore1, acct1, 0, 1) + + gasInfo, _, err = app.Deliver(enc.TxConfig.TxEncoder(), tx) + require.Error(t, err) + require.Equal(t, gasInfo.GasUsed, sdk.Gas(25000)) + + msg3 := &types.MsgAddLimitOrder{ + TimeInForce: types.TimeInForce_GoodTillCancel, + Owner: acct2.GetAddress().String(), + Source: sdk.NewCoin("eur", sdk.NewInt(50000)), + Destination: sdk.NewCoin("chf", sdk.NewInt(50000)), + ClientOrderId: "testAddLimitOrder-eur-chf", + } + + tx = getSignedTrx(ctx, t, app.accountKeeper, enc, msg3, keystore2, acct2, 0, 0) + + gasInfo, _, err = app.Deliver(enc.TxConfig.TxEncoder(), tx) + require.NoError(t, err) + require.Equal(t, gasInfo.GasUsed, sdk.Gas(25000)) +} + +func getSignedTrx( + ctx sdk.Context, + t *testing.T, ak types.AccountKeeper, enc EncodingConfig, + msg *types.MsgAddLimitOrder, + keystore keyring.Keyring, acct keyring.Info, + accountNumber, sequence uint64, +) authsign.Tx { + acci := ak.GetAccount(ctx, acct.GetAddress()) + require.Equal(t, acci.GetAddress().String(), acct.GetAddress().String()) + txBuilder := enc.TxConfig.NewTxBuilder() txBuilder.SetMsgs(msg) txBuilder.SetFeeAmount(coins("25000ngm")) txBuilder.SetGasLimit(213456) - txBuilder.SetMemo("TestAppLiquidOrder0Gas") + txBuilder.SetMemo("TestMarketOrder") txFactory := clienttx.Factory{}. WithChainID(""). WithTxConfig(enc.TxConfig). WithSignMode(signing.SignMode_SIGN_MODE_DIRECT). - WithAccountNumber(acci.GetAccountNumber()). - WithSequence(acci.GetSequence()). + WithAccountNumber(accountNumber). + WithSequence(sequence). WithKeybase(keystore) tx := txBuilder.GetTx() signers := tx.GetSigners() - require.Equal(t, signers[0].String(), info.GetAddress().String()) + require.Equal(t, signers[0].String(), acct.GetAddress().String()) - err = authclient.SignTx(txFactory, client.Context{}, info.GetName(), - txBuilder, true, true) + err := authclient.SignTx( + txFactory, client.Context{}, acct.GetName(), + txBuilder, true, true, + ) require.NoError(t, err) _, err = enc.TxConfig.TxEncoder()(txBuilder.GetTx()) require.NoError(t, err) - gasInfo, _, err := app.Deliver(enc.TxConfig.TxEncoder(), tx) + return tx +} + +func getNewAcctInfo(t *testing.T) (keyring.Keyring, keyring.Info) { + keystore, err := keyring.New(t.Name()+"1", keyring.BackendMemory, "", nil) require.NoError(t, err) - require.Equal(t, gasInfo.GasUsed, sdk.Gas(0)) + + uid := "theKeyName" + + info, _, err := keystore.NewMnemonic( + uid, keyring.English, sdk.FullFundraiserPath, hd.Secp256k1, + ) + require.NoError(t, err) + + return keystore, info } func TestSimAppExportAndBlockedAddrs(t *testing.T) { diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index a426a896..a484a68c 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -241,25 +241,25 @@ func (k Keeper) AnteHandle( } defer func() { + // tx -> messages have passed validation + msgs := tx.GetMsgs() + for _, msg := range msgs { + switch msg.Type() { + case types.MsgAddLimitOrder{}.Type(): + case types.MsgAddMarketOrder{}.Type(): + case types.MsgCancelOrder{}.Type(): + case types.MsgCancelReplaceLimitOrder{}.Type(): + case types.MsgCancelReplaceMarketOrder{}.Type(): + continue + default: + // not a market transaction + return + } + } + // Set gas meter to 0 before running market messages - // Set limit to what the user requested + // Set limit to the user value anteCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasTx.GetGas())) - - // About recover(): - // https://github.com/cosmos/cosmos-sdk/blob/45265b1ea6251e50b28a96eea954edd4abbefd3a/x/auth/ante/setup.go#L45 - if r := recover(); r != nil { - stdTrxFee := k.GetTrxFee(ctx.WithGasMeter(sdk.NewInfiniteGasMeter())) - - // charge StdFee - anteCtx.GasMeter().ConsumeGas(stdTrxFee, "Panicked Market Order") - - log := fmt.Sprintf("market order panic: %v gasWanted: %d, gasUsed: %d", - r, gasTx.GetGas(), anteCtx.GasMeter().GasConsumed()) - - // send error downstream with required gas info - // an alternative pattern is to issue panic with the updated error - anteErr = sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, log) - } }() return next(ctx, tx, simulate) From 552a3c76924eee50d7edd215e9d8dd9c71611687 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Thu, 27 May 2021 21:58:53 +0300 Subject: [PATCH 37/41] Remove OrigOrderCreated --- app_test.go | 2 +- docs/proto/em/proto-docs.md | 1 - proto/em/market/v1/market.proto | 8 -- x/market/keeper/keeper.go | 49 ++++---- x/market/keeper/keeper_test.go | 2 - x/market/keeper/msg_server.go | 17 ++- x/market/keeper/msg_server_test.go | 7 ++ x/market/types/market.pb.go | 179 ++++++++++------------------- x/market/types/types.go | 7 +- x/market/types/types_test.go | 1 - 10 files changed, 109 insertions(+), 164 deletions(-) diff --git a/app_test.go b/app_test.go index f2dc495a..161e2811 100644 --- a/app_test.go +++ b/app_test.go @@ -155,7 +155,7 @@ func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { gasInfo, _, err = app.Deliver(enc.TxConfig.TxEncoder(), tx) require.NoError(t, err) - require.Equal(t, gasInfo.GasUsed, sdk.Gas(25000)) + require.Equal(t, sdk.Gas(0), gasInfo.GasUsed) } func getSignedTrx( diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index d12e13e7..1089cf56 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -1123,7 +1123,6 @@ | `destination` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | | | | `destination_filled` | [string](#string) | | | | `created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | | -| `orig_order_created` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | applicable to CancelReplace orders: the creation timestamp of the original order. | diff --git a/proto/em/market/v1/market.proto b/proto/em/market/v1/market.proto index 324afd73..c0c2970d 100644 --- a/proto/em/market/v1/market.proto +++ b/proto/em/market/v1/market.proto @@ -77,14 +77,6 @@ message Order { (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; - - // applicable to CancelReplace orders: the creation timestamp of the original - // order. - google.protobuf.Timestamp orig_order_created = 11 [ - (gogoproto.moretags) = "yaml:\"orig_order_created\"", - (gogoproto.nullable) = false, - (gogoproto.stdtime) = true - ]; } message ExecutionPlan { diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index a484a68c..15e026f4 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -151,7 +151,13 @@ func (k *Keeper) createMarketOrder( timeInForce types.TimeInForce, clientOrderId string, origOrderCreated time.Time, -) (*types.Order, *sdk.Result, error) { +) (order *types.Order, res *sdk.Result, err error) { + gasMeter := ctx.GasMeter() + + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + + defer k.OrderSpendGas(ctx, order, origOrderCreated, gasMeter, &err) + // If the order allows for slippage, adjust the source amount accordingly. md := k.GetInstrument(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()), srcDenom, dst.Denom) if md == nil || md.LastPrice == nil { @@ -164,16 +170,18 @@ func (k *Keeper) createMarketOrder( source = source.Mul(sdk.NewDec(1).Add(maxSlippage)) slippageSource := sdk.NewCoin(srcDenom, source.RoundInt()) - order, err := types.NewOrder( + var orderTmp types.Order + orderTmp, err = types.NewOrder( ctx.BlockTime(), timeInForce, slippageSource, dst, owner, clientOrderId, origOrderCreated, ) if err != nil { return nil, nil, err } + order = &orderTmp - res, err := k.NewOrderSingle(ctx, order) - return &order, res, err + res, err = k.NewOrderSingle(ctx, *order) + return order, res, err } // calcOrderGas computes the order gas by applying any liquidity rebate. The @@ -271,8 +279,6 @@ func (k *Keeper) postNewOrderSingle( ctx sdk.Context, orderGasMeter sdk.GasMeter, order *types.Order, commitTrade func(), killOrder *bool, callerErr *error, ) { - k.postOrderSpendGas(ctx, order, orderGasMeter, callerErr) - // Roll back any state changes made by the aggressive FillOrKill order. if *killOrder { // order has not been filled @@ -524,11 +530,11 @@ func (k Keeper) assetExists(ctx sdk.Context, asset sdk.Coin) bool { return total.AmountOf(asset.Denom).GT(sdk.ZeroInt()) } -// postOrderSpendGas is a deferred function from Order processing +// OrderSpendGas is a deferred function from Order processing // NewSingleOrder, NewCancelReplace functions to charge Gas. -func (k *Keeper) postOrderSpendGas( - ctx sdk.Context, order *types.Order, orderGasMeter sdk.GasMeter, - callerErr *error, +func (k *Keeper) OrderSpendGas( + ctx sdk.Context, order *types.Order, origOrderCreated time.Time, + orderGasMeter sdk.GasMeter, callerErr *error, ) { var stdTrxFee = k.GetTrxFee(ctx) // Order failed @@ -559,7 +565,7 @@ func (k *Keeper) postOrderSpendGas( // Rebate candidate var orderGas sdk.Gas - if order.OrigOrderCreated.IsZero() { + if origOrderCreated.IsZero() { orderGas = k.calcOrderGas( ctx, stdTrxFee, order.DestinationFilled, order.Destination.Amount, @@ -567,7 +573,7 @@ func (k *Keeper) postOrderSpendGas( } else { orderGas = k.calcReplaceOrderGas( ctx, order.DestinationFilled, order.Destination.Amount, - order.OrigOrderCreated, + origOrderCreated, ) } @@ -582,15 +588,10 @@ func (k *Keeper) CancelReplaceLimitOrder( orderGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - defer func() { - // consume gas, if it did not make it to NewSingleOrder() - if err != nil && orderGasMeter.GasConsumed() == 0 { - k.postOrderSpendGas(ctx, &newOrder, orderGasMeter, &err) - } - }() - origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, newOrder.Owner, origClientOrderId) + defer k.OrderSpendGas(ctx, &newOrder, origOrder.Created, orderGasMeter, &err) + if origOrder == nil { return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, origClientOrderId) } @@ -614,7 +615,6 @@ func (k *Keeper) CancelReplaceLimitOrder( newOrder.DestinationFilled = origOrder.DestinationFilled newOrder.TimeInForce = origOrder.TimeInForce - newOrder.OrigOrderCreated = origOrder.Created // pass in the meter we will charge Gas. resAdd, err := k.NewOrderSingle(ctx.WithGasMeter(orderGasMeter), newOrder) @@ -634,15 +634,10 @@ func (k *Keeper) CancelReplaceMarketOrder( orderGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - defer func() { - // consume gas, if it did not make it to NewSingleOrder() - if err != nil && orderGasMeter.GasConsumed() == 0 { - k.postOrderSpendGas(ctx, newOrder, orderGasMeter, &err) - } - }() - origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) + defer k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) + if origOrder == nil { return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, msg.OrigClientOrderId) } diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 27480802..3b57c496 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -370,7 +370,6 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { Destination: mcrm.Destination, DestinationFilled: sdk.ZeroInt(), Created: ctx.BlockTime(), - OrigOrderCreated: foundOrder.Created, } require.NoError(t, err) @@ -459,7 +458,6 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { Destination: mcrm.Destination, DestinationFilled: sdk.ZeroInt(), Created: ctx.BlockTime(), - OrigOrderCreated: foundOrder.Created, } require.NoError(t, err) diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index f37627f5..3c9517ba 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -17,6 +17,7 @@ type marketKeeper interface { CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) + OrderSpendGas(ctx sdk.Context, order *types.Order, origOrderCreated time.Time, orderGasMeter sdk.GasMeter, callerErr *error) } type msgServer struct { k marketKeeper @@ -26,14 +27,26 @@ func NewMsgServerImpl(keeper marketKeeper) types.MsgServer { return &msgServer{k: keeper} } -func (m msgServer) AddLimitOrder(c context.Context, msg *types.MsgAddLimitOrder) (*types.MsgAddLimitOrderResponse, error) { +func (m msgServer) AddLimitOrder( + c context.Context, msg *types.MsgAddLimitOrder, +) (_ *types.MsgAddLimitOrderResponse, err error) { + var ( + order types.Order + gasMeter sdk.GasMeter + ) + ctx := sdk.UnwrapSDKContext(c) + gasMeter = ctx.GasMeter() + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + + defer m.k.OrderSpendGas(ctx, &order, time.Time{}, gasMeter, &err) + owner, err := sdk.AccAddressFromBech32(msg.Owner) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") } - order, err := types.NewOrder( + order, err = types.NewOrder( ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, msg.ClientOrderId, time.Time{}, ) diff --git a/x/market/keeper/msg_server_test.go b/x/market/keeper/msg_server_test.go index 6da5372e..a83a9f73 100644 --- a/x/market/keeper/msg_server_test.go +++ b/x/market/keeper/msg_server_test.go @@ -10,6 +10,7 @@ import ( abcitypes "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/rand" "testing" + "time" ) func TestAddLimitOrder(t *testing.T) { @@ -516,6 +517,12 @@ type marketKeeperMock struct { CancelReplaceMarketOrderFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) } +func (m marketKeeperMock) OrderSpendGas( + ctx sdk.Context, order *types.Order, origOrderCreated time.Time, + orderGasMeter sdk.GasMeter, callerErr *error, +) { +} + func (m marketKeeperMock) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { if m.NewMarketOrderWithSlippageFn == nil { panic("not expected to be called") diff --git a/x/market/types/market.pb.go b/x/market/types/market.pb.go index e1d93eed..4bcf72b3 100644 --- a/x/market/types/market.pb.go +++ b/x/market/types/market.pb.go @@ -123,9 +123,6 @@ type Order struct { Destination types.Coin `protobuf:"bytes,8,opt,name=destination,proto3" json:"destination" yaml:"destination"` DestinationFilled github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,9,opt,name=destination_filled,json=destinationFilled,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"destination_filled" yaml:"destination_filled"` Created time.Time `protobuf:"bytes,10,opt,name=created,proto3,stdtime" json:"created" yaml:"created"` - // applicable to CancelReplace orders: the creation timestamp of the original - // order. - OrigOrderCreated time.Time `protobuf:"bytes,11,opt,name=orig_order_created,json=origOrderCreated,proto3,stdtime" json:"orig_order_created" yaml:"orig_order_created"` } func (m *Order) Reset() { *m = Order{} } @@ -209,13 +206,6 @@ func (m *Order) GetCreated() time.Time { return time.Time{} } -func (m *Order) GetOrigOrderCreated() time.Time { - if m != nil { - return m.OrigOrderCreated - } - return time.Time{} -} - type ExecutionPlan struct { Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price"` FirstOrder *Order `protobuf:"bytes,2,opt,name=first_order,json=firstOrder,proto3" json:"first_order,omitempty"` @@ -340,65 +330,63 @@ func init() { func init() { proto.RegisterFile("em/market/v1/market.proto", fileDescriptor_888ec7fc0f7580e2) } var fileDescriptor_888ec7fc0f7580e2 = []byte{ - // 923 bytes of a gzipped FileDescriptorProto + // 896 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x3f, 0x6f, 0xdb, 0x46, - 0x14, 0x17, 0xfd, 0x37, 0x3e, 0x5a, 0xb6, 0x72, 0x75, 0x52, 0x89, 0x03, 0xa9, 0x12, 0x68, 0x10, - 0x24, 0x30, 0x09, 0xbb, 0x41, 0x86, 0xa0, 0x28, 0x10, 0x49, 0x54, 0x4a, 0x58, 0xb6, 0x0c, 0x46, - 0x41, 0x80, 0x2e, 0x04, 0x45, 0x9e, 0xd4, 0x83, 0xc9, 0x3b, 0x81, 0x3c, 0xb9, 0x71, 0x3f, 0x82, - 0xa7, 0x8c, 0x5d, 0x0c, 0x74, 0xe8, 0xd0, 0x8f, 0x92, 0x6e, 0xe9, 0x56, 0x74, 0x60, 0x0b, 0x79, - 0xea, 0xaa, 0x4f, 0x50, 0xf0, 0x8e, 0x94, 0xa9, 0x14, 0x6d, 0xe0, 0x4e, 0xbc, 0xf7, 0xe7, 0xf7, - 0xfe, 0xbf, 0x47, 0xd0, 0x40, 0x91, 0x19, 0x79, 0xf1, 0x19, 0x62, 0xe6, 0xf9, 0x41, 0xfe, 0x32, - 0x26, 0x31, 0x65, 0x14, 0x6e, 0xa3, 0xc8, 0xc8, 0x19, 0xe7, 0x07, 0xca, 0xde, 0x98, 0x8e, 0x29, - 0x17, 0x98, 0xd9, 0x4b, 0xe8, 0x28, 0xda, 0x98, 0xd2, 0x71, 0x88, 0x4c, 0x4e, 0x0d, 0xa7, 0x23, - 0x93, 0xe1, 0x08, 0x25, 0xcc, 0x8b, 0x26, 0xb9, 0x82, 0xea, 0xd3, 0x24, 0xa2, 0x89, 0x39, 0xf4, - 0x12, 0x64, 0x9e, 0x1f, 0x0c, 0x11, 0xf3, 0x0e, 0x4c, 0x9f, 0x62, 0x22, 0xe4, 0x7a, 0x17, 0x00, - 0x9b, 0x24, 0x2c, 0x9e, 0x46, 0x88, 0x30, 0x78, 0x1f, 0x6c, 0x24, 0x74, 0x1a, 0xfb, 0xa8, 0x2e, - 0x35, 0xa5, 0x87, 0x5b, 0x4e, 0x4e, 0xc1, 0x26, 0x90, 0x03, 0x94, 0x30, 0x4c, 0x3c, 0x86, 0x29, - 0xa9, 0xaf, 0x70, 0x61, 0x99, 0xa5, 0xa7, 0x9b, 0x60, 0xbd, 0x1f, 0x07, 0x28, 0x86, 0x4f, 0xc0, - 0x1d, 0x9a, 0x3d, 0x5c, 0x1c, 0x70, 0x2b, 0x6b, 0xad, 0xc6, 0x2c, 0xd5, 0x56, 0xec, 0xce, 0x3c, - 0xd5, 0x76, 0x2f, 0xbc, 0x28, 0x7c, 0xa6, 0x17, 0x72, 0xdd, 0xd9, 0xe4, 0x4f, 0x3b, 0x80, 0xaf, - 0x41, 0x35, 0x0b, 0xdd, 0xc5, 0xc4, 0x1d, 0xd1, 0x2c, 0x80, 0xcc, 0xc7, 0xce, 0x61, 0xc3, 0x28, - 0x17, 0xc1, 0x18, 0xe0, 0x08, 0xd9, 0xa4, 0x9b, 0x29, 0xb4, 0xea, 0xf3, 0x54, 0xdb, 0x13, 0xf6, - 0x96, 0x90, 0xba, 0x23, 0xb3, 0x1b, 0x35, 0xf8, 0x00, 0xac, 0xd3, 0xef, 0x08, 0x8a, 0xeb, 0xab, - 0x59, 0xd0, 0xad, 0xda, 0x3c, 0xd5, 0xb6, 0xf3, 0x28, 0x32, 0xb6, 0xee, 0x08, 0x31, 0x7c, 0x09, - 0x76, 0xfd, 0x10, 0x23, 0xc2, 0xdc, 0x45, 0xf4, 0x6b, 0x1c, 0xf1, 0x78, 0x96, 0x6a, 0xd5, 0x36, - 0x17, 0xf1, 0x04, 0x79, 0x22, 0xf7, 0x85, 0x89, 0x0f, 0x10, 0xba, 0x53, 0xf5, 0x4b, 0x8a, 0x01, - 0xfc, 0x7a, 0x51, 0xcf, 0xf5, 0xa6, 0xf4, 0x50, 0x3e, 0x6c, 0x18, 0xa2, 0x1d, 0x46, 0xd6, 0x0e, - 0x23, 0x6f, 0x87, 0xd1, 0xa6, 0x98, 0xb4, 0xee, 0xbd, 0x4b, 0xb5, 0xca, 0x3c, 0xd5, 0xaa, 0xc2, - 0xb2, 0x80, 0xe9, 0x8b, 0x0e, 0x30, 0x50, 0x13, 0x2f, 0x37, 0x46, 0x91, 0x87, 0x09, 0x26, 0xe3, - 0xfa, 0x06, 0x8f, 0xcf, 0xce, 0x80, 0xbf, 0xa7, 0xda, 0x83, 0x31, 0x66, 0xdf, 0x4e, 0x87, 0x86, - 0x4f, 0x23, 0x33, 0x6f, 0xba, 0xf8, 0xec, 0x27, 0xc1, 0x99, 0xc9, 0x2e, 0x26, 0x28, 0x31, 0x6c, - 0xc2, 0xe6, 0xa9, 0xf6, 0x69, 0xd9, 0xc5, 0x8d, 0x3d, 0xdd, 0xd9, 0x15, 0x2c, 0xa7, 0xe0, 0xc0, - 0x33, 0x50, 0xcd, 0xb5, 0x46, 0x38, 0x0c, 0x51, 0x50, 0xdf, 0xe4, 0x2e, 0xbb, 0xb7, 0x76, 0xb9, - 0xb7, 0xe4, 0x52, 0x18, 0xd3, 0x9d, 0x6d, 0x41, 0x77, 0x39, 0x09, 0x5f, 0x2f, 0x0f, 0xd9, 0x9d, - 0x8f, 0x55, 0x4c, 0xc9, 0x2b, 0x06, 0x85, 0xed, 0xf2, 0x34, 0x2e, 0xcd, 0x26, 0xfc, 0x1e, 0xc0, - 0x12, 0x59, 0xa4, 0xb2, 0xc5, 0x53, 0x39, 0xba, 0x75, 0x2a, 0x8d, 0x7f, 0xb8, 0x5b, 0xe4, 0x73, - 0xb7, 0xc4, 0xcc, 0x93, 0x3a, 0x05, 0x9b, 0x7e, 0x8c, 0x3c, 0x86, 0x82, 0x3a, 0xe0, 0x09, 0x29, - 0x86, 0x58, 0x59, 0xa3, 0x58, 0x59, 0x3e, 0xd4, 0x7c, 0x65, 0x17, 0x19, 0xed, 0xe4, 0xd3, 0x25, - 0x80, 0xfa, 0xdb, 0x3f, 0x34, 0xc9, 0x29, 0xcc, 0x40, 0x0a, 0x20, 0x8d, 0xf1, 0x38, 0x1f, 0xba, - 0xc2, 0xb8, 0xfc, 0x51, 0xe3, 0x9f, 0xe7, 0xc6, 0x1b, 0xc5, 0x0e, 0x7e, 0x68, 0x43, 0xf8, 0xa9, - 0x65, 0x02, 0x3e, 0xbf, 0x6d, 0xc1, 0x7e, 0xb6, 0xf6, 0xc3, 0x8f, 0x5a, 0x45, 0xff, 0x45, 0x02, - 0x55, 0xeb, 0x0d, 0xf2, 0xa7, 0x59, 0x72, 0xa7, 0xa1, 0x47, 0x60, 0x07, 0xac, 0x4f, 0x62, 0x5c, - 0xdc, 0x8a, 0x96, 0x71, 0x8b, 0x4a, 0x76, 0x90, 0xef, 0x08, 0x30, 0x7c, 0x02, 0xe4, 0x11, 0x8e, - 0x93, 0x7c, 0x89, 0xf8, 0xda, 0xcb, 0x87, 0x9f, 0x2c, 0xaf, 0x3d, 0x0f, 0xc7, 0x01, 0x5c, 0x4f, - 0x1c, 0x99, 0xa7, 0x60, 0x3b, 0x41, 0x3e, 0x25, 0x41, 0x0e, 0x5b, 0xfd, 0x77, 0x98, 0x2c, 0x14, - 0x39, 0x91, 0xe7, 0xf2, 0xab, 0x04, 0xc0, 0x31, 0x57, 0xeb, 0x78, 0xcc, 0xfb, 0xff, 0x57, 0x0f, - 0xda, 0x00, 0x84, 0x5e, 0xc2, 0x5c, 0x51, 0x07, 0x71, 0x61, 0x1e, 0xdd, 0xa2, 0x06, 0x5b, 0x19, - 0xfa, 0x94, 0xd7, 0xe1, 0x2b, 0xb0, 0xb5, 0xb8, 0xdd, 0xfc, 0xf2, 0xfc, 0x77, 0x37, 0xd7, 0x78, - 0xb3, 0x6e, 0x20, 0x8f, 0xfe, 0x92, 0x80, 0x5c, 0x3a, 0x8f, 0xd0, 0x00, 0x8d, 0x81, 0x7d, 0x6c, - 0xb9, 0xf6, 0x89, 0xdb, 0xed, 0x3b, 0x6d, 0xcb, 0x7d, 0x75, 0xf2, 0xf2, 0xd4, 0x6a, 0xdb, 0x5d, - 0xdb, 0xea, 0xd4, 0x2a, 0xca, 0xee, 0xe5, 0x55, 0x53, 0x7e, 0x45, 0x92, 0x09, 0xf2, 0xf1, 0x08, - 0xa3, 0x00, 0x3e, 0x05, 0xea, 0xb2, 0xfe, 0x8b, 0x7e, 0xbf, 0xe3, 0x0e, 0xec, 0x5e, 0xcf, 0x6d, - 0x3f, 0x3f, 0x69, 0x5b, 0xbd, 0x9a, 0xa4, 0xc0, 0xcb, 0xab, 0xe6, 0xce, 0x0b, 0x4a, 0x83, 0x01, - 0x0e, 0xc3, 0xb6, 0x47, 0x7c, 0x14, 0xc2, 0x2f, 0xc1, 0x67, 0xcb, 0x38, 0xfb, 0xf8, 0xd8, 0xea, - 0xd8, 0xcf, 0x07, 0x96, 0xdb, 0x77, 0x0a, 0xe8, 0x8a, 0x72, 0xef, 0xf2, 0xaa, 0x79, 0xd7, 0x8e, - 0x22, 0x14, 0x60, 0x8f, 0xa1, 0x7e, 0x9c, 0xa3, 0x0d, 0xa0, 0x2c, 0xa3, 0xbb, 0x99, 0xc3, 0xbe, - 0xe3, 0x1e, 0xd9, 0xbd, 0x5e, 0x6d, 0x55, 0xd9, 0xb9, 0xbc, 0x6a, 0x82, 0x6c, 0x95, 0xfa, 0xf1, - 0x11, 0x0e, 0x43, 0x65, 0xed, 0xe7, 0x9f, 0x54, 0xa9, 0x65, 0xbd, 0x9b, 0xa9, 0xd2, 0xfb, 0x99, - 0x2a, 0xfd, 0x39, 0x53, 0xa5, 0xb7, 0xd7, 0x6a, 0xe5, 0xfd, 0xb5, 0x5a, 0xf9, 0xed, 0x5a, 0xad, - 0x7c, 0xf3, 0xb8, 0x54, 0x78, 0xb4, 0x1f, 0x51, 0x82, 0x2e, 0x4c, 0x14, 0xed, 0x87, 0x28, 0x18, - 0xa3, 0xd8, 0x7c, 0x53, 0xfc, 0x6a, 0x79, 0x07, 0x86, 0x1b, 0xbc, 0xae, 0x5f, 0xfc, 0x1d, 0x00, - 0x00, 0xff, 0xff, 0x8f, 0xfc, 0x7b, 0x76, 0x84, 0x07, 0x00, 0x00, + 0x14, 0x17, 0x6d, 0xd9, 0x8e, 0x4f, 0x96, 0xad, 0x5c, 0x9d, 0x54, 0xe2, 0x40, 0xaa, 0x1c, 0x82, + 0x20, 0x81, 0x49, 0xd8, 0x0d, 0x32, 0x04, 0x45, 0x81, 0x48, 0xa2, 0x52, 0xc2, 0xb2, 0x65, 0x30, + 0x0a, 0x02, 0x74, 0x21, 0x28, 0xf2, 0xa4, 0x1e, 0x4c, 0xde, 0x09, 0xe4, 0xc9, 0x8d, 0xfb, 0x11, + 0x3c, 0x65, 0xec, 0x62, 0xa0, 0x43, 0x87, 0x7e, 0x94, 0x74, 0x73, 0xb7, 0xa2, 0x03, 0x5b, 0xc8, + 0x53, 0x87, 0x2e, 0xfa, 0x04, 0x05, 0xef, 0x28, 0x99, 0x6c, 0xd1, 0x16, 0xea, 0xa4, 0x7b, 0x7f, + 0x7e, 0xef, 0xbd, 0xdf, 0xfb, 0x43, 0x81, 0x06, 0x0a, 0x8d, 0xd0, 0x8d, 0xce, 0x11, 0x33, 0x2e, + 0x0e, 0xb3, 0x97, 0x3e, 0x89, 0x28, 0xa3, 0x70, 0x07, 0x85, 0x7a, 0xa6, 0xb8, 0x38, 0x94, 0xf7, + 0xc7, 0x74, 0x4c, 0xb9, 0xc1, 0x48, 0x5f, 0xc2, 0x47, 0x56, 0xc7, 0x94, 0x8e, 0x03, 0x64, 0x70, + 0x69, 0x38, 0x1d, 0x19, 0x0c, 0x87, 0x28, 0x66, 0x6e, 0x38, 0xc9, 0x1c, 0x14, 0x8f, 0xc6, 0x21, + 0x8d, 0x8d, 0xa1, 0x1b, 0x23, 0xe3, 0xe2, 0x70, 0x88, 0x98, 0x7b, 0x68, 0x78, 0x14, 0x13, 0x61, + 0xd7, 0xba, 0x00, 0x58, 0x24, 0x66, 0xd1, 0x34, 0x44, 0x84, 0xc1, 0x87, 0x60, 0x33, 0xa6, 0xd3, + 0xc8, 0x43, 0x75, 0xa9, 0x29, 0x3d, 0xde, 0xb6, 0x33, 0x09, 0x36, 0x41, 0xc5, 0x47, 0x31, 0xc3, + 0xc4, 0x65, 0x98, 0x92, 0xfa, 0x1a, 0x37, 0xe6, 0x55, 0xda, 0x1f, 0x9b, 0x60, 0xa3, 0x1f, 0xf9, + 0x28, 0x82, 0xcf, 0xc0, 0x3d, 0x9a, 0x3e, 0x1c, 0xec, 0xf3, 0x28, 0xe5, 0x56, 0x63, 0x96, 0xa8, + 0x6b, 0x56, 0x67, 0x9e, 0xa8, 0x7b, 0x97, 0x6e, 0x18, 0xbc, 0xd0, 0x16, 0x76, 0xcd, 0xde, 0xe2, + 0x4f, 0xcb, 0x87, 0x6f, 0x41, 0x35, 0x2d, 0xdd, 0xc1, 0xc4, 0x19, 0xd1, 0xb4, 0x80, 0x34, 0xc7, + 0xee, 0x51, 0x43, 0xcf, 0x37, 0x41, 0x1f, 0xe0, 0x10, 0x59, 0xa4, 0x9b, 0x3a, 0xb4, 0xea, 0xf3, + 0x44, 0xdd, 0x17, 0xf1, 0x0a, 0x48, 0xcd, 0xae, 0xb0, 0x3b, 0x37, 0xf8, 0x08, 0x6c, 0xd0, 0xaf, + 0x09, 0x8a, 0xea, 0xeb, 0x69, 0xd1, 0xad, 0xda, 0x3c, 0x51, 0x77, 0xb2, 0x2a, 0x52, 0xb5, 0x66, + 0x0b, 0x33, 0x7c, 0x0d, 0xf6, 0xbc, 0x00, 0x23, 0xc2, 0x9c, 0x65, 0xf5, 0x65, 0x8e, 0x78, 0x3a, + 0x4b, 0xd4, 0x6a, 0x9b, 0x9b, 0x38, 0x41, 0x4e, 0xe4, 0xa1, 0x08, 0xf1, 0x17, 0x84, 0x66, 0x57, + 0xbd, 0x9c, 0xa3, 0x0f, 0xbf, 0x58, 0xf6, 0x73, 0xa3, 0x29, 0x3d, 0xae, 0x1c, 0x35, 0x74, 0x31, + 0x0e, 0x3d, 0x1d, 0x87, 0x9e, 0x8d, 0x43, 0x6f, 0x53, 0x4c, 0x5a, 0x0f, 0x3e, 0x24, 0x6a, 0x69, + 0x9e, 0xa8, 0x55, 0x11, 0x59, 0xc0, 0xb4, 0xe5, 0x04, 0x18, 0xa8, 0x89, 0x97, 0x13, 0xa1, 0xd0, + 0xc5, 0x04, 0x93, 0x71, 0x7d, 0x93, 0xd7, 0x67, 0xa5, 0xc0, 0x5f, 0x12, 0xf5, 0xd1, 0x18, 0xb3, + 0xaf, 0xa6, 0x43, 0xdd, 0xa3, 0xa1, 0x91, 0x0d, 0x5d, 0xfc, 0x1c, 0xc4, 0xfe, 0xb9, 0xc1, 0x2e, + 0x27, 0x28, 0xd6, 0x2d, 0xc2, 0xe6, 0x89, 0xfa, 0x71, 0x3e, 0xc5, 0x5d, 0x3c, 0xcd, 0xde, 0x13, + 0x2a, 0x7b, 0xa1, 0x81, 0xe7, 0xa0, 0x9a, 0x79, 0x8d, 0x70, 0x10, 0x20, 0xbf, 0xbe, 0xc5, 0x53, + 0x76, 0x57, 0x4e, 0xb9, 0x5f, 0x48, 0x29, 0x82, 0x69, 0xf6, 0x8e, 0x90, 0xbb, 0x5c, 0x84, 0x6f, + 0x8b, 0x4b, 0x76, 0xef, 0xbf, 0x3a, 0x26, 0x67, 0x1d, 0x83, 0x22, 0x76, 0x7e, 0x1b, 0x0b, 0xbb, + 0x09, 0xbf, 0x01, 0x30, 0x27, 0x2e, 0xa8, 0x6c, 0x73, 0x2a, 0xc7, 0x2b, 0x53, 0x69, 0xfc, 0x2d, + 0xdd, 0x92, 0xcf, 0xfd, 0x9c, 0x32, 0x23, 0x75, 0x06, 0xb6, 0xbc, 0x08, 0xb9, 0x0c, 0xf9, 0x75, + 0xc0, 0x09, 0xc9, 0xba, 0x38, 0x59, 0x7d, 0x71, 0xb2, 0x7c, 0xa9, 0xf9, 0xc9, 0x2e, 0x19, 0xed, + 0x66, 0xdb, 0x25, 0x80, 0xda, 0xfb, 0x5f, 0x55, 0xc9, 0x5e, 0x84, 0x79, 0x51, 0xfe, 0xf6, 0x3b, + 0xb5, 0xa4, 0xfd, 0x28, 0x81, 0xaa, 0xf9, 0x0e, 0x79, 0xd3, 0x34, 0xd7, 0x59, 0xe0, 0x12, 0xd8, + 0x01, 0x1b, 0x93, 0x08, 0x2f, 0x4e, 0xb7, 0xa5, 0xaf, 0x40, 0xac, 0x83, 0x3c, 0x5b, 0x80, 0xe1, + 0x33, 0x50, 0x19, 0xe1, 0x28, 0xce, 0x76, 0x9a, 0x5f, 0x61, 0xe5, 0xe8, 0xa3, 0xe2, 0x15, 0xf2, + 0xed, 0xb6, 0x01, 0xf7, 0x13, 0x37, 0xff, 0x1c, 0xec, 0xc4, 0xc8, 0xa3, 0xc4, 0xcf, 0x60, 0xeb, + 0xff, 0x0c, 0xab, 0x08, 0x47, 0x2e, 0x64, 0x5c, 0x7e, 0x92, 0x00, 0x38, 0xe1, 0x6e, 0x1d, 0x97, + 0xb9, 0xff, 0xff, 0x23, 0x04, 0x2d, 0x00, 0x02, 0x37, 0x66, 0x8e, 0xe8, 0x83, 0x38, 0xf8, 0x27, + 0x2b, 0xf4, 0x60, 0x3b, 0x45, 0x9f, 0xf1, 0x3e, 0x7c, 0x0e, 0xb6, 0x97, 0x9f, 0x52, 0xfe, 0x21, + 0xf8, 0xf7, 0xc9, 0x95, 0xf9, 0x8c, 0xee, 0x20, 0x4f, 0x7e, 0x97, 0x40, 0x25, 0xf7, 0xb5, 0x82, + 0x3a, 0x68, 0x0c, 0xac, 0x13, 0xd3, 0xb1, 0x4e, 0x9d, 0x6e, 0xdf, 0x6e, 0x9b, 0xce, 0x9b, 0xd3, + 0xd7, 0x67, 0x66, 0xdb, 0xea, 0x5a, 0x66, 0xa7, 0x56, 0x92, 0xf7, 0xae, 0xae, 0x9b, 0x95, 0x37, + 0x24, 0x9e, 0x20, 0x0f, 0x8f, 0x30, 0xf2, 0xe1, 0x73, 0xa0, 0x14, 0xfd, 0x5f, 0xf5, 0xfb, 0x1d, + 0x67, 0x60, 0xf5, 0x7a, 0x4e, 0xfb, 0xe5, 0x69, 0xdb, 0xec, 0xd5, 0x24, 0x19, 0x5e, 0x5d, 0x37, + 0x77, 0x5f, 0x51, 0xea, 0x0f, 0x70, 0x10, 0xb4, 0x5d, 0xe2, 0xa1, 0x00, 0x7e, 0x06, 0x3e, 0x29, + 0xe2, 0xac, 0x93, 0x13, 0xb3, 0x63, 0xbd, 0x1c, 0x98, 0x4e, 0xdf, 0x5e, 0x40, 0xd7, 0xe4, 0x07, + 0x57, 0xd7, 0xcd, 0xfb, 0x56, 0x18, 0x22, 0x1f, 0xbb, 0x0c, 0xf5, 0xa3, 0x0c, 0xad, 0x03, 0xb9, + 0x88, 0xee, 0xa6, 0x09, 0xfb, 0xb6, 0x73, 0x6c, 0xf5, 0x7a, 0xb5, 0x75, 0x79, 0xf7, 0xea, 0xba, + 0x09, 0xd2, 0xcd, 0xee, 0x47, 0xc7, 0x38, 0x08, 0xe4, 0xf2, 0x0f, 0xdf, 0x2b, 0x52, 0xcb, 0xfc, + 0x30, 0x53, 0xa4, 0x9b, 0x99, 0x22, 0xfd, 0x36, 0x53, 0xa4, 0xf7, 0xb7, 0x4a, 0xe9, 0xe6, 0x56, + 0x29, 0xfd, 0x7c, 0xab, 0x94, 0xbe, 0x7c, 0x9a, 0x6b, 0x3c, 0x3a, 0x08, 0x29, 0x41, 0x97, 0x06, + 0x0a, 0x0f, 0x02, 0xe4, 0x8f, 0x51, 0x64, 0xbc, 0x5b, 0xfc, 0xf3, 0xf1, 0x09, 0x0c, 0x37, 0x79, + 0x5f, 0x3f, 0xfd, 0x33, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x22, 0xa6, 0x88, 0x13, 0x07, 0x00, 0x00, } func (m *Instrument) Marshal() (dAtA []byte, err error) { @@ -458,21 +446,13 @@ func (m *Order) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.OrigOrderCreated, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.OrigOrderCreated):]) + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) if err1 != nil { return 0, err1 } i -= n1 i = encodeVarintMarket(dAtA, i, uint64(n1)) i-- - dAtA[i] = 0x5a - n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Created, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Created):]) - if err2 != nil { - return 0, err2 - } - i -= n2 - i = encodeVarintMarket(dAtA, i, uint64(n2)) - i-- dAtA[i] = 0x52 { size := m.DestinationFilled.Size() @@ -629,12 +609,12 @@ func (m *MarketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l if m.Timestamp != nil { - n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Timestamp):]) - if err7 != nil { - return 0, err7 + n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Timestamp):]) + if err6 != nil { + return 0, err6 } - i -= n7 - i = encodeVarintMarket(dAtA, i, uint64(n7)) + i -= n6 + i = encodeVarintMarket(dAtA, i, uint64(n6)) i-- dAtA[i] = 0x22 } @@ -727,8 +707,6 @@ func (m *Order) Size() (n int) { n += 1 + l + sovMarket(uint64(l)) l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Created) n += 1 + l + sovMarket(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.OrigOrderCreated) - n += 1 + l + sovMarket(uint64(l)) return n } @@ -1228,39 +1206,6 @@ func (m *Order) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OrigOrderCreated", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowMarket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthMarket - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthMarket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.OrigOrderCreated, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMarket(dAtA[iNdEx:]) diff --git a/x/market/types/types.go b/x/market/types/types.go index 200ddd3c..7272f323 100644 --- a/x/market/types/types.go +++ b/x/market/types/types.go @@ -32,8 +32,7 @@ func (o Order) MarshalJSON() ([]byte, error) { "amount": "%v" }, "destination_filled": "%v", - "created": "%v", - "orig_order_created": "%v" + "created": "%v" } `, o.ID, @@ -49,7 +48,6 @@ func (o Order) MarshalJSON() ([]byte, error) { o.Destination.Amount, o.DestinationFilled, o.Created, - o.OrigOrderCreated, ) return []byte(s), nil @@ -87,7 +85,7 @@ func (o Order) Price() sdk.Dec { } func (o Order) String() string { - return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\nOriginal Order Created:%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created, o.OrigOrderCreated) + return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\nOriginal Order Created:%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created) } func (ep ExecutionPlan) DestinationCapacity() sdk.Dec { @@ -153,7 +151,6 @@ func NewOrder( Destination: dst, DestinationFilled: sdk.ZeroInt(), Created: createdTm, - OrigOrderCreated: origOrderCreated, } if err := o.IsValid(); err != nil { diff --git a/x/market/types/types_test.go b/x/market/types/types_test.go index 902b6779..cd51736a 100644 --- a/x/market/types/types_test.go +++ b/x/market/types/types_test.go @@ -54,7 +54,6 @@ func TestSerialization(t *testing.T) { require.Equal(t, order1.TimeInForce, order2.TimeInForce) require.True(t, order1.Created.Equal(order2.Created)) - require.Equal(t, order1.OrigOrderCreated, order2.OrigOrderCreated) } func TestInvalidOrder(t *testing.T) { From 4d6f267899128a9f9e9acda41e8d89e1d169cf11 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Fri, 28 May 2021 14:59:15 +0300 Subject: [PATCH 38/41] Remove ante handler, market order adj --- app.go | 34 ++---------------- x/market/keeper/keeper.go | 50 ++++++-------------------- x/market/keeper/keeper_test.go | 65 ---------------------------------- x/market/keeper/msg_server.go | 5 --- 4 files changed, 13 insertions(+), 141 deletions(-) diff --git a/app.go b/app.go index b1c61521..d2ecfe71 100644 --- a/app.go +++ b/app.go @@ -18,7 +18,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/signing" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -423,12 +422,11 @@ func NewApp( app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) app.SetAnteHandler( - getAnteHandler( - app.accountKeeper, app.bankKeeper, - encodingConfig.TxConfig.SignModeHandler(), app.marketKeeper, + ante.NewAnteHandler( + app.accountKeeper, app.bankKeeper, ante.DefaultSigVerificationGasConsumer, + encodingConfig.TxConfig.SignModeHandler(), ), ) - app.SetEndBlocker(app.EndBlocker) if loadLatest { @@ -643,32 +641,6 @@ func (app EMoneyApp) SetMinimumGasPrices(gasPricesStr string) (err error) { return } -func getAnteHandler( - ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, - signModeHandler signing.SignModeHandler, marketAnteHandler sdk.AnteDecorator, -) sdk.AnteHandler { - return sdk.ChainAnteDecorators( - ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first - ante.NewRejectExtensionOptionsDecorator(), - ante.NewMempoolFeeDecorator(), - ante.NewValidateBasicDecorator(), - ante.TxTimeoutHeightDecorator{}, - ante.NewValidateMemoDecorator(ak), - ante.NewConsumeGasForTxSizeDecorator(ak), - ante.NewRejectFeeGranterDecorator(), - ante.NewSetPubKeyDecorator(ak), - ante.NewValidateSigCountDecorator(ak), - ante.NewDeductFeeDecorator(ak, bk), - ante.NewSigGasConsumeDecorator( - ak, ante.DefaultSigVerificationGasConsumer, - ), - ante.NewSigVerificationDecorator(ak, signModeHandler), - ante.NewIncrementSequenceDecorator(ak), - // last to execute - marketAnteHandler, - ) -} - func init() { sdk.PowerReduction = sdk.OneInt() } diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 15e026f4..c09efd92 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -6,7 +6,6 @@ package keeper import ( "fmt" - "github.com/cosmos/cosmos-sdk/x/auth/ante" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" types2 "github.com/e-money/em-ledger/x/authority/types" @@ -237,48 +236,14 @@ func (k *Keeper) calcReplaceOrderGas( return stdTrxFee } -// AnteHandle fulfills the AnteDecorator interface for the market module to -// charge the standard gas for panicked orders. -func (k Keeper) AnteHandle( - ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler, -) (anteCtx sdk.Context, anteErr error) { - // all transactions must implement GasTx - gasTx, ok := tx.(ante.GasTx) - if !ok { - return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx") - } - - defer func() { - // tx -> messages have passed validation - msgs := tx.GetMsgs() - for _, msg := range msgs { - switch msg.Type() { - case types.MsgAddLimitOrder{}.Type(): - case types.MsgAddMarketOrder{}.Type(): - case types.MsgCancelOrder{}.Type(): - case types.MsgCancelReplaceLimitOrder{}.Type(): - case types.MsgCancelReplaceMarketOrder{}.Type(): - continue - default: - // not a market transaction - return - } - } - - // Set gas meter to 0 before running market messages - // Set limit to the user value - anteCtx = ctx.WithGasMeter(sdk.NewGasMeter(gasTx.GetGas())) - }() - - return next(ctx, tx, simulate) -} - // postNewOrderSingle is a deferred function for NewOrderSingle. It spends gas // on any order and adds non fill-or-kill orders to the order-book. func (k *Keeper) postNewOrderSingle( ctx sdk.Context, orderGasMeter sdk.GasMeter, order *types.Order, commitTrade func(), killOrder *bool, callerErr *error, ) { + k.OrderSpendGas(ctx, order, time.Time{}, orderGasMeter, callerErr) + // Roll back any state changes made by the aggressive FillOrKill order. if *killOrder { // order has not been filled @@ -636,14 +601,14 @@ func (k *Keeper) CancelReplaceMarketOrder( origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) - defer k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - if origOrder == nil { + k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, msg.OrigClientOrderId) } // Verify that instrument is the same. if origOrder.Source.Denom != msg.Source || origOrder.Destination.Denom != msg.Destination.Denom { + k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) return nil, sdkerrors.Wrap( types.ErrOrderInstrumentChanged, fmt.Sprintf( "source %s != %s Or dest %s != %s", origOrder.Source, msg.Source, @@ -654,6 +619,7 @@ func (k *Keeper) CancelReplaceMarketOrder( // Has the previous order already achieved the goal on the source side? if origOrder.DestinationFilled.GTE(msg.Destination.Amount) { + k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) return nil, sdkerrors.Wrap( types.ErrNoSourceRemaining, fmt.Sprintf( "has already been filled filled:%s >= %s", @@ -666,6 +632,7 @@ func (k *Keeper) CancelReplaceMarketOrder( ownerAddr, err := sdk.AccAddressFromBech32(msg.Owner) if err != nil { + k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") } @@ -675,7 +642,7 @@ func (k *Keeper) CancelReplaceMarketOrder( newOrder, resAdd, err = k.createMarketOrder( // pass in the meter we will charge gas - ctx.WithGasMeter(orderGasMeter), + ctx, msg.Source, remDstCoin, msg.MaxSlippage, @@ -685,9 +652,12 @@ func (k *Keeper) CancelReplaceMarketOrder( origOrder.Created, ) if err != nil { + k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) return nil, err } + defer k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) + evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) return &sdk.Result{Events: evts}, nil diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 3b57c496..38c9ca7a 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -17,7 +17,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/auth/ante" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -869,70 +868,6 @@ func TestSingleOrderPanicFullGas(t *testing.T) { require.Equal(t, sdk.Gas(0), gasMeter.GasConsumed()) } -func TestAnteHandlerNoTrx(t *testing.T) { - ctx, k, _, _ := createTestComponents(t) - sud := ante.NewSetUpContextDecorator() - anteHandler := sdk.ChainAnteDecorators(sud, k) - - encodingConfig := MakeTestEncodingConfig() - - clientCtx := client.Context{}. - WithJSONMarshaler(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithChainID("testing") - - flagSet := pflag.NewFlagSet("testing", pflag.PanicOnError) - txf := clienttx.NewFactoryCLI(clientCtx, flagSet). - WithMemo("PanicLimitOrder"). - WithFees("100000NGM") - - msg := &types.MsgAddLimitOrder{} - txb, err := clienttx.BuildUnsignedTx(txf, msg) - require.NoError(t, err) - - gasMeter := sdk.NewInfiniteGasMeter() - _, err = anteHandler(ctx.WithGasMeter(gasMeter), txb.GetTx(), false) - require.NoError(t, err) - require.Equal(t, gasMeter.GasConsumed(), sdk.Gas(0)) -} - -type PanicDecorator struct{} - -func (pd PanicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - panic("market order panic") -} - -func TestChargeStdFeeAnteHandlerPanic(t *testing.T) { - ctx, k, _, _ := createTestComponents(t) - sud := ante.NewSetUpContextDecorator() - - anteHandler := sdk.ChainAnteDecorators(sud, k, PanicDecorator{}) - - encodingConfig := MakeTestEncodingConfig() - - clientCtx := client.Context{}. - WithJSONMarshaler(encodingConfig.Marshaler). - WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). - WithChainID("testing") - - flagSet := pflag.NewFlagSet("testing", pflag.PanicOnError) - txf := clienttx.NewFactoryCLI(clientCtx, flagSet) - - msg := &types.MsgAddLimitOrder{} - txb, err := clienttx.BuildUnsignedTx(txf, msg) - require.NoError(t, err) - - stdTrxFee := k.GetTrxFee(ctx.WithGasMeter(sdk.NewInfiniteGasMeter())) - gasMeter := sdk.NewInfiniteGasMeter() - ctx = ctx.WithGasMeter(gasMeter) - - ctx, err = anteHandler(ctx, txb.GetTx(), false) - require.Error(t, err) - require.Equal(t, ctx.GasMeter().GasConsumed(), stdTrxFee) -} - func TestPartiallyLiquidLimitOrderGas(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index 3c9517ba..bbc7d4d3 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -32,14 +32,9 @@ func (m msgServer) AddLimitOrder( ) (_ *types.MsgAddLimitOrderResponse, err error) { var ( order types.Order - gasMeter sdk.GasMeter ) ctx := sdk.UnwrapSDKContext(c) - gasMeter = ctx.GasMeter() - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - - defer m.k.OrderSpendGas(ctx, &order, time.Time{}, gasMeter, &err) owner, err := sdk.AccAddressFromBech32(msg.Owner) if err != nil { From 0ccc291c76086ece8fb4552dee5ab3ab1790ccac Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Mon, 31 May 2021 23:03:21 +0300 Subject: [PATCH 39/41] Merge develop into PR 66 --- Makefile | 2 +- app.go | 9 +- app_test.go | 3 +- cmd/emd/cmd/testnet.go | 19 +- docs/proto/em/proto-docs.md | 34 -- docs/tokens.md | 15 +- hooks/bank/bankproxy_test.go | 228 +---------- hooks/bank/errors.go | 9 - hooks/bank/expected_keepers.go | 14 - hooks/bank/proxykeeper.go | 33 +- proto/em/authority/v1/authority.proto | 15 - proto/em/authority/v1/genesis.proto | 7 +- restricted_denom_test.go | 66 --- x/authority/genesis.go | 8 +- x/authority/keeper/keeper.go | 17 - x/authority/module.go | 5 +- x/authority/types/authority.go | 31 -- x/authority/types/authority.pb.go | 459 +-------------------- x/authority/types/authority_test.go | 54 --- x/authority/types/genesis.pb.go | 113 ++---- x/buyback/abci.go | 2 - x/buyback/abci_test.go | 29 +- {hooks => x}/distribution/abci.go | 18 +- {hooks => x}/distribution/module.go | 2 - x/market/alias.go | 5 +- x/market/keeper/grpc_query_test.go | 1 - x/market/keeper/keeper.go | 162 ++------ x/market/keeper/keeper_test.go | 553 ++++++++++++-------------- x/market/keeper/msg_server.go | 56 +-- x/market/keeper/msg_server_test.go | 163 ++++++-- x/market/types/expected_keepers.go | 5 - x/market/types/types.go | 3 +- x/market/types/types_test.go | 10 +- x/slashing/keeper/abci_test.go | 9 +- 34 files changed, 531 insertions(+), 1628 deletions(-) delete mode 100644 hooks/bank/errors.go delete mode 100644 hooks/bank/expected_keepers.go delete mode 100644 restricted_denom_test.go delete mode 100644 x/authority/types/authority.go delete mode 100644 x/authority/types/authority_test.go rename {hooks => x}/distribution/abci.go (78%) rename {hooks => x}/distribution/module.go (90%) diff --git a/Makefile b/Makefile index 38afcb14..0c664df4 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ test: go test -mod=readonly ./... bdd-test: - go test -mod=readonly -v -p 1 --tags="bdd" bdd_test.go restricted_denom_test.go multisigauthority_test.go authority_test.go market_test.go buyback_test.go capacity_test.go staking_test.go bep3swap_test.go + go test -mod=readonly -v -p 1 -timeout 1h --tags="bdd" bdd_test.go multisigauthority_test.go authority_test.go market_test.go buyback_test.go capacity_test.go staking_test.go bep3swap_test.go local-testnet: go test -mod=readonly -v --tags="bdd" bdd_test.go localnet_test.go diff --git a/app.go b/app.go index d2ecfe71..63cb0e5b 100644 --- a/app.go +++ b/app.go @@ -70,9 +70,9 @@ import ( "path/filepath" "time" - emdistr "github.com/e-money/em-ledger/hooks/distribution" "github.com/e-money/em-ledger/x/authority" "github.com/e-money/em-ledger/x/buyback" + emdistr "github.com/e-money/em-ledger/x/distribution" "github.com/e-money/em-ledger/x/inflation" "github.com/e-money/em-ledger/x/issuer" "github.com/e-money/em-ledger/x/liquidityprovider" @@ -99,8 +99,7 @@ import ( ) const ( - appName = "emoneyd" - stakingTokenDenom = "ungm" + appName = "emoneyd" ) var ( @@ -278,7 +277,7 @@ func NewApp( app.bankKeeper = embank.Wrap(bankkeeper.NewBaseKeeper( appCodec, keys[banktypes.StoreKey], app.accountKeeper, app.GetSubspace(banktypes.ModuleName), app.ModuleAccountAddrs(), - ), &app.authorityKeeper) + )) stakingKeeper := stakingkeeper.NewKeeper( appCodec, keys[stakingtypes.StoreKey], app.accountKeeper, app.bankKeeper, app.GetSubspace(stakingtypes.ModuleName), @@ -344,7 +343,7 @@ func NewApp( app.lpKeeper = liquidityprovider.NewKeeper(app.accountKeeper, app.bankKeeper) app.issuerKeeper = issuer.NewKeeper(app.appCodec, keys[issuer.StoreKey], app.lpKeeper, app.inflationKeeper) app.authorityKeeper = authority.NewKeeper(app.appCodec, keys[authority.StoreKey], app.issuerKeeper, app.bankKeeper, app) - app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], keys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper, app.authorityKeeper, app.GetSubspace(market.ModuleName)) + app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], keys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper, app.GetSubspace(market.ModuleName)) app.buybackKeeper = buyback.NewKeeper(app.appCodec, keys[buyback.StoreKey], app.marketKeeper, app.accountKeeper, app.stakingKeeper, app.bankKeeper) app.bep3Keeper = bep3.NewKeeper(app.appCodec, keys[bep3.StoreKey], app.bankKeeper, app.accountKeeper, app.paramsKeeper.Subspace(bep3.ModuleName), GetMaccs()) diff --git a/app_test.go b/app_test.go index 161e2811..35f50bf4 100644 --- a/app_test.go +++ b/app_test.go @@ -64,7 +64,6 @@ func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { genesisState := ModuleBasics.DefaultGenesis(enc.Marshaler) authorityState := authority.NewGenesisState( rand.Bytes(sdk.AddrLen), nil, - sdk.NewDecCoins(), ) genesisState[authority.ModuleName] = enc.Marshaler.MustMarshalJSON(&authorityState) @@ -226,7 +225,7 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { } genesisState := ModuleBasics.DefaultGenesis(encCfg.Marshaler) - authorityState := authority.NewGenesisState(rand.Bytes(sdk.AddrLen), nil, sdk.NewDecCoins()) + authorityState := authority.NewGenesisState(rand.Bytes(sdk.AddrLen), sdk.NewDecCoins()) genesisState[authority.ModuleName] = encCfg.Marshaler.MustMarshalJSON(&authorityState) stateBytes, err := json.MarshalIndent(genesisState, "", " ") diff --git a/cmd/emd/cmd/testnet.go b/cmd/emd/cmd/testnet.go index e8b696bf..e42bc1f6 100644 --- a/cmd/emd/cmd/testnet.go +++ b/cmd/emd/cmd/testnet.go @@ -40,7 +40,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - emauthtypes "github.com/e-money/em-ledger/x/authority/types" ) const stakingToken = "ungm" @@ -473,7 +472,7 @@ func createInflationGenesis() json.RawMessage { } func createAuthorityGenesis(akey sdk.AccAddress) json.RawMessage { - gen := authority.NewGenesisState(akey, []emauthtypes.RestrictedDenom{}, sdk.NewDecCoins()) + gen := authority.NewGenesisState(akey, sdk.NewDecCoins()) bz, err := json.Marshal(gen) if err != nil { @@ -524,16 +523,16 @@ func createTestBep3Genesis() json.RawMessage { SupplyLimit: bep3types.SupplyLimit{ Limit: limit, TimeLimited: false, - TimePeriod: int64(time.Hour*24), + TimePeriod: int64(time.Hour * 24), TimeBasedLimit: sdk.ZeroInt(), }, - Active: true, - DeputyAddress: depBech32Addr, - FixedFee: sdk.NewInt(bep3types.DeputyFee), - MinSwapAmount: sdk.OneInt(), - MaxSwapAmount: limit, - SwapTimestamp: time.Now().Unix(), - SwapTimeSpanMin: 24*3*60, // 3 days in minutes + Active: true, + DeputyAddress: depBech32Addr, + FixedFee: sdk.NewInt(bep3types.DeputyFee), + MinSwapAmount: sdk.OneInt(), + MaxSwapAmount: limit, + SwapTimestamp: time.Now().Unix(), + SwapTimeSpanMin: 24 * 3 * 60, // 3 days in minutes } } diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md index 1089cf56..0c4afc47 100644 --- a/docs/proto/em/proto-docs.md +++ b/docs/proto/em/proto-docs.md @@ -7,8 +7,6 @@ - [em/authority/v1/authority.proto](#em/authority/v1/authority.proto) - [Authority](#em.authority.v1.Authority) - [GasPrices](#em.authority.v1.GasPrices) - - [RestrictedDenom](#em.authority.v1.RestrictedDenom) - - [RestrictedDenoms](#em.authority.v1.RestrictedDenoms) - [em/authority/v1/genesis.proto](#em/authority/v1/genesis.proto) - [GenesisState](#em.authority.v1.GenesisState) @@ -178,37 +176,6 @@ - - - -### RestrictedDenom - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `denom` | [string](#string) | | todo (reviewer) : moved from /types/ todo (reviewer) : please note the lower case json/yaml attribute names now (convention) | -| `allowed` | [string](#string) | repeated | | - - - - - - - - -### RestrictedDenoms - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `denoms` | [RestrictedDenom](#em.authority.v1.RestrictedDenom) | repeated | | - - - - - @@ -235,7 +202,6 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | `key` | [string](#string) | | | -| `restricted_denoms` | [RestrictedDenom](#em.authority.v1.RestrictedDenom) | repeated | | | `min_gas_prices` | [cosmos.base.v1beta1.DecCoin](#cosmos.base.v1beta1.DecCoin) | repeated | | diff --git a/docs/tokens.md b/docs/tokens.md index 52cc332d..1a0065f4 100644 --- a/docs/tokens.md +++ b/docs/tokens.md @@ -18,22 +18,21 @@ The list of supported tokens and their respective exchange rates are available a ```json { "_comment": "See https://github.com/e-money/em-ledger/blob/master/docs/tokens.md", - "last_updated": "2020-01-01T00:00:00.000000Z", "tokens": [ { - "token": "eeur", + "token": "EEUR", "description": "Interest bearing EUR token", "exponent": 6, "underlying_currency": "EUR" }, { - "token": "echf", + "token": "ECHF", "description": "Interest bearing CHF token", "exponent": 6, "underlying_currency": "CHF" }, { - "token": "ejpy", + "token": "EJPY", "description": "Interest bearing JPY token", "exponent": 6, "underlying_currency": "JPY" @@ -64,10 +63,10 @@ The current exchange rate from a token to underlying currency can be fetched via ```json { - "eeur": { + "EEUR": { "EUR": 0.999950 }, - "echf": { + "ECHF": { "CHF": 0.999980 } } @@ -77,7 +76,7 @@ As the rates change slowly, it is typically not necessary to query more than onc ## Displaying Amounts -To display a `eeur` amount in terms of `EUR`, the following calculation must be made: +To display a `EEUR` amount in terms of `EUR`, the following calculation must be made: `EUR_amount = eeur_amount * exchange_rate / 10^eeur_exponent` -The `exponent` for EUR specifies the number of digits to display. For instance, `eeur 1234567890` at an exchange rate of 0.999950 should be displayed as `EUR 123,45` (after rounding down). +The `exponent` for EUR specifies the number of digits to display. For instance, `EEUR 1234567890` at an exchange rate of 0.999950 should be displayed as `EUR 123.45` (after rounding down). diff --git a/hooks/bank/bankproxy_test.go b/hooks/bank/bankproxy_test.go index 2d955075..4b5eb4f4 100644 --- a/hooks/bank/bankproxy_test.go +++ b/hooks/bank/bankproxy_test.go @@ -7,143 +7,16 @@ package bank import ( "bytes" "errors" - "fmt" - "github.com/cosmos/cosmos-sdk/codec" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - simappparams "github.com/cosmos/cosmos-sdk/simapp/params" - "github.com/cosmos/cosmos-sdk/std" - "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - "github.com/cosmos/cosmos-sdk/x/auth" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - "github.com/cosmos/cosmos-sdk/x/auth/tx" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" - emauthtypes "github.com/e-money/em-ledger/x/authority/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/rand" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - dbm "github.com/tendermint/tm-db" "testing" ) -func TestProxySendCoins(t *testing.T) { - ctx, ak, bk := createTestComponents(t) - - var ( - acc1 = createAccount(ctx, ak, bk, randomAddress(), "150000gbp, 150000usd, 150000sek") - acc2 = createAccount(ctx, ak, bk, randomAddress(), "150000gbp, 150000usd, 150000sek") - dest = randomAddress() - ) - - bk.rk = restrictedKeeper{ - RestrictedDenoms: emauthtypes.RestrictedDenoms{Denoms: []emauthtypes.RestrictedDenom{ - {"gbp", []string{}}, - {"usd", []string{acc1.GetAddress().String()}}, - }, - }} - - var testdata = []struct { - denom string - acc sdk.AccAddress - valid bool - }{ - {"gbp", acc2.GetAddress(), false}, - {"usd", acc2.GetAddress(), false}, - {"gbp", acc1.GetAddress(), false}, - {"usd", acc1.GetAddress(), true}, - {"sek", acc1.GetAddress(), true}, - {"sek", acc2.GetAddress(), true}, - } - - for i, d := range testdata { - t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) { - c := fmt.Sprintf("1000%s", d.denom) - err := bk.SendCoins(ctx, d.acc, dest, coins(c)) - if d.valid { - require.NoError(t, err) - } else { - require.True(t, ErrRestrictedDenomination.Is(err), "Actual error \"%s\" (%T)", err.Error(), err) - } - }) - } -} - -func TestInputOutputCoins(t *testing.T) { - ctx, ak, bk := createTestComponents(t) - - var ( - acc1 = createAccount(ctx, ak, bk, randomAddress(), "150000gbp, 150000usd, 150000sek") - acc2 = createAccount(ctx, ak, bk, randomAddress(), "150000gbp, 150000usd, 150000sek") - acc3 = createAccount(ctx, ak, bk, randomAddress(), "") - ) - - // For simplicity's sake, inputoutput will reject any transaction that includes restricted denominations. - - bk.rk = restrictedKeeper{ - RestrictedDenoms: emauthtypes.RestrictedDenoms{Denoms: []emauthtypes.RestrictedDenom{ - {"gbp", []string{}}, - {"usd", []string{acc1.GetAddress().String()}}, - }, - }} - - var testdata = []struct { - inputs []banktypes.Input - outputs []banktypes.Output - valid bool - }{ - {[]banktypes.Input{}, []banktypes.Output{}, true}, - { - inputs: []banktypes.Input{ - {acc1.GetAddress().String(), coins("1000sek")}, - }, - outputs: []banktypes.Output{ - {acc2.GetAddress().String(), coins("500sek")}, - {acc3.GetAddress().String(), coins("500sek")}, - }, - valid: true, - }, - { - inputs: []banktypes.Input{ - {acc1.GetAddress().String(), coins("500sek, 1000gbp")}, - }, - outputs: []banktypes.Output{ - {acc2.GetAddress().String(), coins("500sek, 500gbp")}, - {acc3.GetAddress().String(), coins("500gbp")}, - }, - valid: false, - }, - { - inputs: []banktypes.Input{ - {acc1.GetAddress().String(), coins("1000usd")}, - }, - outputs: []banktypes.Output{ - {acc2.GetAddress().String(), coins("1000usd")}, - }, - valid: false, - }, - } - - for i, d := range testdata { - t.Run(fmt.Sprintf("test case %d", i), func(t *testing.T) { - err := bk.InputOutputCoins(ctx, d.inputs, d.outputs) - if d.valid { - require.NoError(t, err) - } else { - require.True(t, ErrRestrictedDenomination.Is(err), "Actual error \"%s\" (%T)", err.Error(), err) - } - }) - } - - fmt.Println(bk.GetAllBalances(ctx, acc3.GetAddress())) -} - func TestDeduplicate(t *testing.T) { var ( addr1 = bytes.Repeat([]byte{0x1}, sdk.AddrLen) @@ -232,7 +105,7 @@ func TestSendCoinsBalanceUpdateNotification(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -312,7 +185,7 @@ func TestInputOutputCoinsBalanceUpdateNotification(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -385,7 +258,7 @@ func TestSendCoinsFromModuleToAccount(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -459,7 +332,7 @@ func TestSendCoinsFromAccountToModule(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -534,7 +407,7 @@ func TestDelegateCoinsFromAccountToModule(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -609,7 +482,7 @@ func TestUndelegateCoinsFromModuleToAccount(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -684,7 +557,7 @@ func TestDelegateCoins(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -760,7 +633,7 @@ func TestUndelegateCoins(t *testing.T) { return spec.nestedKeeperResult }, } - wrappedBankKeeper := Wrap(nestedBk, allDenomsAllowed) + wrappedBankKeeper := Wrap(nestedBk) // register listeners for i := 0; i < spec.listenerCount; i++ { @@ -786,10 +659,6 @@ func TestUndelegateCoins(t *testing.T) { } } -var allDenomsAllowed = RestrictedKeeperFunc(func(ctx sdk.Context) emauthtypes.RestrictedDenoms { - return emauthtypes.RestrictedDenoms{} // allow all -}) - type senderBankKeeperMock struct { bankkeeper.Keeper InputOutputCoinsFn func(ctx sdk.Context, inputs []banktypes.Input, outputs []banktypes.Output) error @@ -862,61 +731,6 @@ func randomAddress() sdk.AccAddress { return rand.Bytes(sdk.AddrLen) } -func createTestComponents(t *testing.T) (sdk.Context, authkeeper.AccountKeeper, *ProxyKeeper) { - t.Helper() - encConfig := MakeTestEncodingConfig() - var ( - bankKey = sdk.NewKVStoreKey(banktypes.ModuleName) - authCapKey = sdk.NewKVStoreKey("authCapKey") - keyParams = sdk.NewKVStoreKey("params") - tkeyParams = sdk.NewTransientStoreKey("transient_params") - - blacklistedAddrs = make(map[string]bool) - ) - - db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(authCapKey, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db) - - err := ms.LoadLatestVersion() - require.NoError(t, err) - - maccPerms := map[string][]string{} - - pk := paramskeeper.NewKeeper(encConfig.Marshaler, encConfig.Amino, keyParams, tkeyParams) - - ctx := sdk.NewContext(ms, tmproto.Header{ChainID: "test-chain"}, true, log.NewNopLogger()) - - accountKeeper := authkeeper.NewAccountKeeper( - encConfig.Marshaler, authCapKey, pk.Subspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, - ) - - bankKeeper := bankkeeper.NewBaseKeeper( - encConfig.Marshaler, bankKey, accountKeeper, pk.Subspace(banktypes.ModuleName), blacklistedAddrs, - ) - - wrappedBK := Wrap(bankKeeper, restrictedKeeper{}) - return ctx, accountKeeper, wrappedBK -} - -type restrictedKeeper struct { - RestrictedDenoms emauthtypes.RestrictedDenoms -} - -func (rk restrictedKeeper) GetRestrictedDenoms(sdk.Context) emauthtypes.RestrictedDenoms { - return rk.RestrictedDenoms -} - -func createAccount(ctx sdk.Context, ak authkeeper.AccountKeeper, bk bankkeeper.SendKeeper, address sdk.AccAddress, balance string) authtypes.AccountI { - acc := ak.NewAccountWithAddress(ctx, address) - if err := bk.SetBalances(ctx, address, coins(balance)); err != nil { - panic(err) - } - ak.SetAccount(ctx, acc) - return acc -} - func coins(s string) sdk.Coins { coins, err := sdk.ParseCoinsNormalized(s) if err != nil { @@ -924,27 +738,3 @@ func coins(s string) sdk.Coins { } return coins } - -func MakeTestEncodingConfig() simappparams.EncodingConfig { - cdc := codec.NewLegacyAmino() - interfaceRegistry := codectypes.NewInterfaceRegistry() - marshaler := codec.NewProtoCodec(interfaceRegistry) - - encodingConfig := simappparams.EncodingConfig{ - InterfaceRegistry: interfaceRegistry, - Marshaler: marshaler, - TxConfig: tx.NewTxConfig(marshaler, tx.DefaultSignModes), - Amino: cdc, - } - - std.RegisterLegacyAminoCodec(encodingConfig.Amino) - std.RegisterInterfaces(encodingConfig.InterfaceRegistry) - ModuleBasics := module.NewBasicManager( - bank.AppModuleBasic{}, - auth.AppModuleBasic{}, - ) - - ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) - ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) - return encodingConfig -} diff --git a/hooks/bank/errors.go b/hooks/bank/errors.go deleted file mode 100644 index 8cfd6daf..00000000 --- a/hooks/bank/errors.go +++ /dev/null @@ -1,9 +0,0 @@ -// This software is Copyright (c) 2019-2020 e-Money A/S. It is not offered under an open source license. -// -// Please contact partners@e-money.com for licensing related questions. - -package bank - -import sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - -var ErrRestrictedDenomination = sdkerrors.Register("embank", 1, "Denomination is restricted") diff --git a/hooks/bank/expected_keepers.go b/hooks/bank/expected_keepers.go deleted file mode 100644 index 6f8c0e6c..00000000 --- a/hooks/bank/expected_keepers.go +++ /dev/null @@ -1,14 +0,0 @@ -// This software is Copyright (c) 2019-2020 e-Money A/S. It is not offered under an open source license. -// -// Please contact partners@e-money.com for licensing related questions. - -package bank - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/e-money/em-ledger/x/authority/types" -) - -type RestrictedKeeper interface { - GetRestrictedDenoms(sdk.Context) types.RestrictedDenoms -} diff --git a/hooks/bank/proxykeeper.go b/hooks/bank/proxykeeper.go index 57af45ec..71cb7ca9 100644 --- a/hooks/bank/proxykeeper.go +++ b/hooks/bank/proxykeeper.go @@ -7,23 +7,20 @@ package bank import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/bank/exported" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/e-money/em-ledger/x/authority/types" ) var _ bankkeeper.Keeper = (*ProxyKeeper)(nil) type ProxyKeeper struct { bk bankkeeper.Keeper - rk RestrictedKeeper listeners []func(sdk.Context, []sdk.AccAddress) } -func Wrap(bk bankkeeper.Keeper, rk RestrictedKeeper) *ProxyKeeper { - return &ProxyKeeper{bk: bk, rk: rk} +func Wrap(bk bankkeeper.Keeper) *ProxyKeeper { + return &ProxyKeeper{bk: bk} } func (pk *ProxyKeeper) AddBalanceListener(l func(sdk.Context, []sdk.AccAddress)) { @@ -51,16 +48,6 @@ func deduplicate(accounts []sdk.AccAddress) []sdk.AccAddress { } func (pk ProxyKeeper) InputOutputCoins(ctx sdk.Context, inputs []banktypes.Input, outputs []banktypes.Output) error { - restrictedDenoms := pk.rk.GetRestrictedDenoms(ctx) - // Multisend does not support restricted denominations. - for _, input := range inputs { - for _, coin := range input.Coins { - if _, found := restrictedDenoms.Find(coin.Denom); found { - return sdkerrors.Wrap(ErrRestrictedDenomination, coin.Denom) - } - } - } - err := pk.bk.InputOutputCoins(ctx, inputs, outputs) if err != nil { return err @@ -82,15 +69,6 @@ func (pk ProxyKeeper) InputOutputCoins(ctx sdk.Context, inputs []banktypes.Input } func (pk ProxyKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { - restrictedDenoms := pk.rk.GetRestrictedDenoms(ctx) - for _, c := range amt { - if denom, found := restrictedDenoms.Find(c.Denom); found { - if !denom.IsAnyAllowed(fromAddr, toAddr) { - return sdkerrors.Wrap(ErrRestrictedDenomination, c.Denom) - } - } - } - err := pk.bk.SendCoins(ctx, fromAddr, toAddr, amt) if err != nil { return err @@ -300,10 +278,3 @@ func (pk *ProxyKeeper) DenomMetadata(ctx context.Context, request *banktypes.Que func (pk *ProxyKeeper) DenomsMetadata(ctx context.Context, request *banktypes.QueryDenomsMetadataRequest) (*banktypes.QueryDenomsMetadataResponse, error) { return pk.bk.DenomsMetadata(ctx, request) } - -// RestrictedKeeperFunc implements the RestrictedKeeper interface. -type RestrictedKeeperFunc func(sdk.Context) types.RestrictedDenoms - -func (r RestrictedKeeperFunc) GetRestrictedDenoms(ctx sdk.Context) types.RestrictedDenoms { - return r(ctx) -} diff --git a/proto/em/authority/v1/authority.proto b/proto/em/authority/v1/authority.proto index 8d2c5837..bc139ce2 100644 --- a/proto/em/authority/v1/authority.proto +++ b/proto/em/authority/v1/authority.proto @@ -6,21 +6,6 @@ import "cosmos/base/v1beta1/coin.proto"; option go_package = "github.com/e-money/em-ledger/x/authority/types"; -message RestrictedDenoms { - repeated RestrictedDenom denoms = 1 [ - (gogoproto.moretags) = "yaml:\"denoms\"", - (gogoproto.nullable) = false - ]; -} - -message RestrictedDenom { - // todo (reviewer) : moved from /types/ - // todo (reviewer) : please note the lower case json/yaml attribute names now - // (convention) - string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; - repeated string allowed = 2 [ (gogoproto.moretags) = "yaml:\"allowed\"" ]; -} - message Authority { string address = 1 [ (gogoproto.moretags) = "yaml:\"address\"" ]; } diff --git a/proto/em/authority/v1/genesis.proto b/proto/em/authority/v1/genesis.proto index 2ac03857..ae60b50b 100644 --- a/proto/em/authority/v1/genesis.proto +++ b/proto/em/authority/v1/genesis.proto @@ -13,12 +13,7 @@ message GenesisState { (gogoproto.moretags) = "yaml:\"key\"" ]; - repeated RestrictedDenom restricted_denoms = 2 [ - (gogoproto.moretags) = "yaml:\"restricted_denoms\"", - (gogoproto.nullable) = false - ]; - - repeated cosmos.base.v1beta1.DecCoin min_gas_prices = 3 [ + repeated cosmos.base.v1beta1.DecCoin min_gas_prices = 2 [ (gogoproto.moretags) = "yaml:\"min_gas_prices\"", (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins", (gogoproto.nullable) = false diff --git a/restricted_denom_test.go b/restricted_denom_test.go deleted file mode 100644 index 3fabc7bf..00000000 --- a/restricted_denom_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// +build bdd - -package emoney_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/tidwall/sjson" - "time" -) - -var _ = Describe("Restricted denominationsq", func() { - - var ( - Key1 = testnet.Keystore.Key1 - Key2 = testnet.Keystore.Key2 - Key3 = testnet.Keystore.Key3 - ) - - //tearDownAfterTests = false - - It("starts a new testnet", func() { - awaitReady, err := testnet.RestartWithModifications( - func(bz []byte) []byte { - type Obj map[string]interface{} - - o := Obj{ - "denom": "ungm", - "allowed": []string{ - Key1.GetAddress(), - }, - } - - bz, _ = sjson.SetBytes(bz, "app_state.authority.restricted_denoms", []Obj{o}) - - return bz - }) - Expect(err).ShouldNot(HaveOccurred()) - Expect(awaitReady()).To(BeTrue()) - }) - - It("tests transfer restrictions", func() { - time.Sleep(8 * time.Second) // Allow for a few blocks to avoid querying at height 1. - - emcli := testnet.NewEmcli() - { - // Key1 is whitelisted - txid, success, err := emcli.Send(Key1, Key2, "5000ungm") - Expect(err).ShouldNot(HaveOccurred()) - Expect(success).To(BeTrue(), txid) - } - - { - // No white-listed accounts involved. - txid, success, err := emcli.Send(Key3, Key2, "5000ungm") - Expect(err).Should(HaveOccurred()) - Expect(success).To(BeFalse(), txid) - } - { - // Key1 is whitelisted - txid, success, err := emcli.Send(Key3, Key1, "5000ungm") - Expect(err).ShouldNot(HaveOccurred()) - Expect(success).To(BeTrue(), txid) - } - }) -}) diff --git a/x/authority/genesis.go b/x/authority/genesis.go index a3d9f0a6..1239373e 100644 --- a/x/authority/genesis.go +++ b/x/authority/genesis.go @@ -10,11 +10,10 @@ import ( "github.com/e-money/em-ledger/x/authority/types" ) -func NewGenesisState(authorityKey sdk.AccAddress, restrictedDenoms []types.RestrictedDenom, gasPrices sdk.DecCoins) types.GenesisState { +func NewGenesisState(authorityKey sdk.AccAddress, gasPrices sdk.DecCoins) types.GenesisState { return types.GenesisState{ - AuthorityKey: authorityKey.String(), - RestrictedDenoms: restrictedDenoms, - MinGasPrices: gasPrices, + AuthorityKey: authorityKey.String(), + MinGasPrices: gasPrices, } } @@ -28,7 +27,6 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, state types.GenesisState) error return sdkerrors.Wrap(err, "authority key") } keeper.SetAuthority(ctx, authKey) - keeper.SetRestrictedDenoms(ctx, state.RestrictedDenoms) keeper.SetGasPrices(ctx, authKey, state.MinGasPrices) return nil } diff --git a/x/authority/keeper/keeper.go b/x/authority/keeper/keeper.go index 9968602d..7a5773a4 100644 --- a/x/authority/keeper/keeper.go +++ b/x/authority/keeper/keeper.go @@ -18,7 +18,6 @@ import ( const ( keyAuthorityAccAddress = "AuthorityAccountAddress" - keyRestrictedDenoms = "RestrictedDenoms" keyGasPrices = "GasPrices" ) @@ -135,22 +134,6 @@ func (k Keeper) MustBeAuthority(ctx sdk.Context, address sdk.AccAddress) { panic(sdkerrors.Wrap(types.ErrNotAuthority, address.String())) } -func (k Keeper) SetRestrictedDenoms(ctx sdk.Context, denoms []types.RestrictedDenom) { - store := ctx.KVStore(k.storeKey) - state := types.RestrictedDenoms{Denoms: denoms} - bz := k.cdc.MustMarshalBinaryLengthPrefixed(&state) - store.Set([]byte(keyRestrictedDenoms), bz) -} - -func (k Keeper) GetRestrictedDenoms(ctx sdk.Context) (res types.RestrictedDenoms) { - store := ctx.KVStore(k.storeKey) - - bz := store.Get([]byte(keyRestrictedDenoms)) - k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &res) - - return -} - // Gas prices are kept in-memory in the app structure. Make sure they are initialized on node restart. func (k Keeper) initGasPrices(ctx sdk.Context) { k.gasPricesInit.Do(func() { diff --git a/x/authority/module.go b/x/authority/module.go index 2fe6b149..0554d9d6 100644 --- a/x/authority/module.go +++ b/x/authority/module.go @@ -91,9 +91,8 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data j func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler) json.RawMessage { genesis := &types.GenesisState{ - AuthorityKey: am.keeper.GetAuthority(ctx).String(), - RestrictedDenoms: am.keeper.GetRestrictedDenoms(ctx).Denoms, - MinGasPrices: am.keeper.GetGasPrices(ctx), + AuthorityKey: am.keeper.GetAuthority(ctx).String(), + MinGasPrices: am.keeper.GetGasPrices(ctx), } return cdc.MustMarshalJSON(genesis) } diff --git a/x/authority/types/authority.go b/x/authority/types/authority.go deleted file mode 100644 index e3b63a31..00000000 --- a/x/authority/types/authority.go +++ /dev/null @@ -1,31 +0,0 @@ -// This software is Copyright (c) 2019-2020 e-Money A/S. It is not offered under an open source license. -// -// Please contact partners@e-money.com for licensing related questions. - -package types - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (rd RestrictedDenoms) Find(denom string) (RestrictedDenom, bool) { - for _, d := range rd.Denoms { - if d.Denom == denom { - return d, true - } - } - - return RestrictedDenom{}, false -} - -func (r RestrictedDenom) IsAnyAllowed(in ...sdk.AccAddress) bool { - for _, addr := range r.Allowed { - for _, inaddr := range in { - if addr == inaddr.String() { - return true - } - } - } - - return false -} diff --git a/x/authority/types/authority.pb.go b/x/authority/types/authority.pb.go index a7f9530c..33c0f1a6 100644 --- a/x/authority/types/authority.pb.go +++ b/x/authority/types/authority.pb.go @@ -25,105 +25,6 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -type RestrictedDenoms struct { - Denoms []RestrictedDenom `protobuf:"bytes,1,rep,name=denoms,proto3" json:"denoms" yaml:"denoms"` -} - -func (m *RestrictedDenoms) Reset() { *m = RestrictedDenoms{} } -func (m *RestrictedDenoms) String() string { return proto.CompactTextString(m) } -func (*RestrictedDenoms) ProtoMessage() {} -func (*RestrictedDenoms) Descriptor() ([]byte, []int) { - return fileDescriptor_3f91f8bbecb83881, []int{0} -} -func (m *RestrictedDenoms) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RestrictedDenoms) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RestrictedDenoms.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *RestrictedDenoms) XXX_Merge(src proto.Message) { - xxx_messageInfo_RestrictedDenoms.Merge(m, src) -} -func (m *RestrictedDenoms) XXX_Size() int { - return m.Size() -} -func (m *RestrictedDenoms) XXX_DiscardUnknown() { - xxx_messageInfo_RestrictedDenoms.DiscardUnknown(m) -} - -var xxx_messageInfo_RestrictedDenoms proto.InternalMessageInfo - -func (m *RestrictedDenoms) GetDenoms() []RestrictedDenom { - if m != nil { - return m.Denoms - } - return nil -} - -type RestrictedDenom struct { - // todo (reviewer) : moved from /types/ - // todo (reviewer) : please note the lower case json/yaml attribute names now - // (convention) - Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"` - Allowed []string `protobuf:"bytes,2,rep,name=allowed,proto3" json:"allowed,omitempty" yaml:"allowed"` -} - -func (m *RestrictedDenom) Reset() { *m = RestrictedDenom{} } -func (m *RestrictedDenom) String() string { return proto.CompactTextString(m) } -func (*RestrictedDenom) ProtoMessage() {} -func (*RestrictedDenom) Descriptor() ([]byte, []int) { - return fileDescriptor_3f91f8bbecb83881, []int{1} -} -func (m *RestrictedDenom) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *RestrictedDenom) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_RestrictedDenom.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *RestrictedDenom) XXX_Merge(src proto.Message) { - xxx_messageInfo_RestrictedDenom.Merge(m, src) -} -func (m *RestrictedDenom) XXX_Size() int { - return m.Size() -} -func (m *RestrictedDenom) XXX_DiscardUnknown() { - xxx_messageInfo_RestrictedDenom.DiscardUnknown(m) -} - -var xxx_messageInfo_RestrictedDenom proto.InternalMessageInfo - -func (m *RestrictedDenom) GetDenom() string { - if m != nil { - return m.Denom - } - return "" -} - -func (m *RestrictedDenom) GetAllowed() []string { - if m != nil { - return m.Allowed - } - return nil -} - type Authority struct { Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty" yaml:"address"` } @@ -132,7 +33,7 @@ func (m *Authority) Reset() { *m = Authority{} } func (m *Authority) String() string { return proto.CompactTextString(m) } func (*Authority) ProtoMessage() {} func (*Authority) Descriptor() ([]byte, []int) { - return fileDescriptor_3f91f8bbecb83881, []int{2} + return fileDescriptor_3f91f8bbecb83881, []int{0} } func (m *Authority) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -176,7 +77,7 @@ func (m *GasPrices) Reset() { *m = GasPrices{} } func (m *GasPrices) String() string { return proto.CompactTextString(m) } func (*GasPrices) ProtoMessage() {} func (*GasPrices) Descriptor() ([]byte, []int) { - return fileDescriptor_3f91f8bbecb83881, []int{3} + return fileDescriptor_3f91f8bbecb83881, []int{1} } func (m *GasPrices) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -213,8 +114,6 @@ func (m *GasPrices) GetMinimum() github_com_cosmos_cosmos_sdk_types.DecCoins { } func init() { - proto.RegisterType((*RestrictedDenoms)(nil), "em.authority.v1.RestrictedDenoms") - proto.RegisterType((*RestrictedDenom)(nil), "em.authority.v1.RestrictedDenom") proto.RegisterType((*Authority)(nil), "em.authority.v1.Authority") proto.RegisterType((*GasPrices)(nil), "em.authority.v1.GasPrices") } @@ -222,108 +121,26 @@ func init() { func init() { proto.RegisterFile("em/authority/v1/authority.proto", fileDescriptor_3f91f8bbecb83881) } var fileDescriptor_3f91f8bbecb83881 = []byte{ - // 387 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0xbf, 0xae, 0xd3, 0x30, - 0x14, 0xc6, 0x13, 0xae, 0xb8, 0x55, 0xcc, 0x9f, 0x56, 0x11, 0x48, 0x55, 0x85, 0x92, 0xc8, 0x03, - 0xaa, 0x04, 0xb5, 0x15, 0x98, 0x60, 0x23, 0x14, 0xc1, 0x06, 0xca, 0xc8, 0x96, 0x3f, 0x47, 0xa9, - 0x45, 0x1c, 0x57, 0xb1, 0x5b, 0xc8, 0xc0, 0x0b, 0x30, 0xf1, 0x1c, 0x3c, 0x49, 0xc7, 0x8e, 0x4c, - 0x01, 0xb5, 0x6f, 0xd0, 0x27, 0xb8, 0x6a, 0xec, 0xa8, 0x51, 0xa7, 0x9c, 0xe4, 0x3b, 0xbf, 0xef, - 0xc4, 0xdf, 0x31, 0xf2, 0x81, 0xd3, 0x64, 0xa3, 0x56, 0xa2, 0x66, 0xaa, 0xa1, 0xdb, 0xf0, 0xf2, - 0x42, 0xd6, 0xb5, 0x50, 0xc2, 0x1d, 0x03, 0x27, 0x97, 0x6f, 0xdb, 0x70, 0xf6, 0xa4, 0x10, 0x85, - 0xe8, 0x34, 0x7a, 0xae, 0x74, 0xdb, 0xcc, 0xcb, 0x84, 0xe4, 0x42, 0xd2, 0x34, 0x91, 0x40, 0xb7, - 0x61, 0x0a, 0x2a, 0x09, 0x69, 0x26, 0x58, 0xa5, 0x75, 0x9c, 0xa1, 0x49, 0x0c, 0x52, 0xd5, 0x2c, - 0x53, 0x90, 0x2f, 0xa1, 0x12, 0x5c, 0xba, 0x9f, 0xd1, 0x6d, 0xde, 0x55, 0x53, 0x3b, 0xb8, 0x99, - 0x3f, 0x78, 0x15, 0x90, 0xab, 0x59, 0xe4, 0x0a, 0x89, 0x9e, 0xee, 0x5a, 0xdf, 0x3a, 0xb5, 0xfe, - 0xa3, 0x26, 0xe1, 0xe5, 0x5b, 0xac, 0x69, 0x1c, 0x1b, 0x1b, 0x5c, 0xa0, 0xf1, 0x15, 0xe1, 0x3e, - 0x47, 0xf7, 0x3b, 0x71, 0x6a, 0x07, 0xf6, 0xdc, 0x89, 0x26, 0xa7, 0xd6, 0x7f, 0x38, 0x80, 0x71, - 0xac, 0x65, 0xf7, 0x25, 0x1a, 0x25, 0x65, 0x29, 0xbe, 0x43, 0x3e, 0xbd, 0x17, 0xdc, 0xcc, 0x9d, - 0xc8, 0x3d, 0xb5, 0xfe, 0x63, 0xdd, 0x69, 0x04, 0x1c, 0xf7, 0x2d, 0xf8, 0x0d, 0x72, 0xde, 0xf5, - 0xff, 0xd9, 0xa1, 0x79, 0x5e, 0x83, 0x94, 0x66, 0xc8, 0x10, 0xd5, 0xc2, 0x19, 0x35, 0xd5, 0x2f, - 0x1b, 0x39, 0x1f, 0x13, 0xf9, 0xa5, 0x66, 0x19, 0x48, 0xf7, 0x27, 0x1a, 0x71, 0x56, 0x31, 0xbe, - 0xe1, 0x26, 0x83, 0x67, 0x44, 0x07, 0x49, 0xce, 0x41, 0x12, 0x13, 0x24, 0x59, 0x42, 0xf6, 0x5e, - 0xb0, 0x2a, 0xfa, 0x60, 0xce, 0x6f, 0xdc, 0x0d, 0x8a, 0xff, 0xfc, 0xf3, 0x5f, 0x14, 0x4c, 0xad, - 0x36, 0x29, 0xc9, 0x04, 0xa7, 0x66, 0x15, 0xfa, 0xb1, 0x90, 0xf9, 0x37, 0xaa, 0x9a, 0x35, 0xc8, - 0xde, 0x45, 0xc6, 0xfd, 0xcc, 0xe8, 0xd3, 0xee, 0xe0, 0xd9, 0xfb, 0x83, 0x67, 0xff, 0x3f, 0x78, - 0xf6, 0xef, 0xa3, 0x67, 0xed, 0x8f, 0x9e, 0xf5, 0xf7, 0xe8, 0x59, 0x5f, 0xc9, 0xc0, 0x0f, 0x16, - 0x5c, 0x54, 0xd0, 0x50, 0xe0, 0x8b, 0x12, 0xf2, 0x02, 0x6a, 0xfa, 0x63, 0x70, 0x67, 0x3a, 0xef, - 0xf4, 0xb6, 0x5b, 0xf3, 0xeb, 0xbb, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x9f, 0x36, 0x34, 0x50, - 0x02, 0x00, 0x00, -} - -func (m *RestrictedDenoms) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RestrictedDenoms) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RestrictedDenoms) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Denoms) > 0 { - for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Denoms[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAuthority(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *RestrictedDenom) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *RestrictedDenom) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *RestrictedDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Allowed) > 0 { - for iNdEx := len(m.Allowed) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Allowed[iNdEx]) - copy(dAtA[i:], m.Allowed[iNdEx]) - i = encodeVarintAuthority(dAtA, i, uint64(len(m.Allowed[iNdEx]))) - i-- - dAtA[i] = 0x12 - } - } - if len(m.Denom) > 0 { - i -= len(m.Denom) - copy(dAtA[i:], m.Denom) - i = encodeVarintAuthority(dAtA, i, uint64(len(m.Denom))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil + // 297 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xbf, 0x4a, 0xc3, 0x40, + 0x1c, 0xc7, 0x73, 0x08, 0x96, 0x44, 0x50, 0x08, 0x0e, 0xa5, 0xc8, 0xa5, 0x64, 0x2a, 0x68, 0xee, + 0x88, 0x4e, 0xba, 0x19, 0x15, 0x1d, 0xa5, 0xa3, 0xdb, 0x25, 0xf9, 0x91, 0x1e, 0xf6, 0x72, 0x25, + 0x77, 0x09, 0x66, 0xf0, 0x05, 0x9c, 0x7c, 0x0e, 0x9f, 0xa4, 0x63, 0x47, 0xa7, 0x2a, 0xc9, 0x1b, + 0xf8, 0x04, 0xd2, 0xfc, 0x21, 0x9d, 0xee, 0xcf, 0xf7, 0x77, 0x9f, 0xcf, 0xf1, 0xb5, 0x1c, 0x10, + 0x94, 0xe5, 0x7a, 0x21, 0x33, 0xae, 0x4b, 0x5a, 0xf8, 0xc3, 0x81, 0xac, 0x32, 0xa9, 0xa5, 0x7d, + 0x02, 0x82, 0x0c, 0x77, 0x85, 0x3f, 0x39, 0x4d, 0x64, 0x22, 0x9b, 0x8c, 0xee, 0x76, 0xed, 0xd8, + 0x04, 0x47, 0x52, 0x09, 0xa9, 0x68, 0xc8, 0x14, 0xd0, 0xc2, 0x0f, 0x41, 0x33, 0x9f, 0x46, 0x92, + 0xa7, 0x6d, 0xee, 0x5e, 0x5b, 0xe6, 0x6d, 0x4f, 0xb1, 0x2f, 0xac, 0x11, 0x8b, 0xe3, 0x0c, 0x94, + 0x1a, 0xa3, 0x29, 0x9a, 0x99, 0x81, 0xfd, 0xb7, 0x75, 0x8e, 0x4b, 0x26, 0x96, 0x37, 0x6e, 0x17, + 0xb8, 0xf3, 0x7e, 0xc4, 0xfd, 0x40, 0x96, 0xf9, 0xc8, 0xd4, 0x73, 0xc6, 0x23, 0x50, 0xf6, 0xbb, + 0x35, 0x12, 0x3c, 0xe5, 0x22, 0x17, 0x63, 0x34, 0x3d, 0x98, 0x1d, 0x5d, 0x9e, 0x91, 0x56, 0x4d, + 0x76, 0x6a, 0xd2, 0xa9, 0xc9, 0x3d, 0x44, 0x77, 0x92, 0xa7, 0xc1, 0xc3, 0x7a, 0xeb, 0x18, 0x03, + 0xbd, 0x7b, 0xea, 0x7e, 0xfd, 0x38, 0xe7, 0x09, 0xd7, 0x8b, 0x3c, 0x24, 0x91, 0x14, 0xb4, 0xfb, + 0x7c, 0xbb, 0x78, 0x2a, 0x7e, 0xa5, 0xba, 0x5c, 0x81, 0xea, 0x29, 0x6a, 0xde, 0x3b, 0x83, 0xa7, + 0x75, 0x85, 0xd1, 0xa6, 0xc2, 0xe8, 0xb7, 0xc2, 0xe8, 0xb3, 0xc6, 0xc6, 0xa6, 0xc6, 0xc6, 0x77, + 0x8d, 0x8d, 0x17, 0xb2, 0xc7, 0x03, 0x4f, 0xc8, 0x14, 0x4a, 0x0a, 0xc2, 0x5b, 0x42, 0x9c, 0x40, + 0x46, 0xdf, 0xf6, 0x5a, 0x6e, 0xd8, 0xe1, 0x61, 0x53, 0xcc, 0xd5, 0x7f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x57, 0x7d, 0x71, 0xbc, 0x82, 0x01, 0x00, 0x00, } func (m *Authority) Marshal() (dAtA []byte, err error) { @@ -404,40 +221,6 @@ func encodeVarintAuthority(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *RestrictedDenoms) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Denoms) > 0 { - for _, e := range m.Denoms { - l = e.Size() - n += 1 + l + sovAuthority(uint64(l)) - } - } - return n -} - -func (m *RestrictedDenom) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Denom) - if l > 0 { - n += 1 + l + sovAuthority(uint64(l)) - } - if len(m.Allowed) > 0 { - for _, s := range m.Allowed { - l = len(s) - n += 1 + l + sovAuthority(uint64(l)) - } - } - return n -} - func (m *Authority) Size() (n int) { if m == nil { return 0 @@ -472,204 +255,6 @@ func sovAuthority(x uint64) (n int) { func sozAuthority(x uint64) (n int) { return sovAuthority(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *RestrictedDenoms) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthority - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RestrictedDenoms: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RestrictedDenoms: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthority - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthAuthority - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthAuthority - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denoms = append(m.Denoms, RestrictedDenom{}) - if err := m.Denoms[len(m.Denoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAuthority(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthority - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RestrictedDenom) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthority - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RestrictedDenom: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RestrictedDenom: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthority - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAuthority - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthority - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Allowed", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowAuthority - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthAuthority - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthAuthority - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Allowed = append(m.Allowed, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipAuthority(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthAuthority - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *Authority) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/authority/types/authority_test.go b/x/authority/types/authority_test.go deleted file mode 100644 index 39a14af3..00000000 --- a/x/authority/types/authority_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// This software is Copyright (c) 2019-2020 e-Money A/S. It is not offered under an open source license. -// -// Please contact partners@e-money.com for licensing related questions. - -package types - -import ( - "github.com/stretchr/testify/require" - "testing" -) - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func TestSimple(t *testing.T) { - var ( - addr1 = sdk.AccAddress([]byte("addr1")) - addr2 = sdk.AccAddress([]byte("addr2")) - ) - - state := []RestrictedDenom{ - {"ngm", []string{addr1.String()}}, - {"evilt", []string{}}, - {"othergovtoken", []string{addr2.String()}}, - } - - rs := RestrictedDenoms{Denoms: state} - - if ngm, found := rs.Find("ngm"); found { - require.True(t, ngm.IsAnyAllowed(addr1, addr2)) - require.True(t, ngm.IsAnyAllowed(addr1)) - require.False(t, ngm.IsAnyAllowed(addr2)) - require.False(t, ngm.IsAnyAllowed()) - } else { - require.Fail(t, "ngm token not found") - } - - if evilt, found := rs.Find("evilt"); found { - require.False(t, evilt.IsAnyAllowed(addr1, addr2)) - require.False(t, evilt.IsAnyAllowed()) - } else { - require.Fail(t, "evilt token not found") - } - - if othergovtoken, found := rs.Find("othergovtoken"); found { - require.True(t, othergovtoken.IsAnyAllowed(addr1, addr2)) - require.True(t, othergovtoken.IsAnyAllowed(addr2)) - require.False(t, othergovtoken.IsAnyAllowed(addr1)) - require.False(t, othergovtoken.IsAnyAllowed()) - } else { - require.Fail(t, "othergovtoken token not found") - } -} diff --git a/x/authority/types/genesis.pb.go b/x/authority/types/genesis.pb.go index 8d909cb8..7b20f4d7 100644 --- a/x/authority/types/genesis.pb.go +++ b/x/authority/types/genesis.pb.go @@ -26,9 +26,8 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { - AuthorityKey string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` - RestrictedDenoms []RestrictedDenom `protobuf:"bytes,2,rep,name=restricted_denoms,json=restrictedDenoms,proto3" json:"restricted_denoms" yaml:"restricted_denoms"` - MinGasPrices github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,3,rep,name=min_gas_prices,json=minGasPrices,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"min_gas_prices" yaml:"min_gas_prices"` + AuthorityKey string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` + MinGasPrices github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,2,rep,name=min_gas_prices,json=minGasPrices,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"min_gas_prices" yaml:"min_gas_prices"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -71,13 +70,6 @@ func (m *GenesisState) GetAuthorityKey() string { return "" } -func (m *GenesisState) GetRestrictedDenoms() []RestrictedDenom { - if m != nil { - return m.RestrictedDenoms - } - return nil -} - func (m *GenesisState) GetMinGasPrices() github_com_cosmos_cosmos_sdk_types.DecCoins { if m != nil { return m.MinGasPrices @@ -92,31 +84,28 @@ func init() { func init() { proto.RegisterFile("em/authority/v1/genesis.proto", fileDescriptor_51063264c25bc319) } var fileDescriptor_51063264c25bc319 = []byte{ - // 374 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0xbb, 0x6a, 0xe3, 0x40, - 0x14, 0x86, 0x25, 0x1b, 0x16, 0x56, 0x6b, 0xf6, 0x22, 0x76, 0x41, 0x98, 0xdd, 0x91, 0x50, 0x65, - 0x58, 0x3c, 0xb3, 0xda, 0x74, 0xe9, 0xa2, 0x18, 0x1c, 0x48, 0x8a, 0xa0, 0x74, 0x69, 0x8c, 0x2e, - 0x07, 0x79, 0xb0, 0x47, 0x63, 0x34, 0x63, 0x13, 0xbd, 0x85, 0x9f, 0x23, 0xcf, 0x91, 0xc2, 0xa5, - 0xcb, 0x54, 0x4a, 0x90, 0xdf, 0xc0, 0x4f, 0x10, 0x74, 0xb1, 0x63, 0x3b, 0x95, 0x04, 0xe7, 0x3f, - 0xdf, 0xc7, 0xfc, 0x47, 0xfb, 0x03, 0x8c, 0xf8, 0x73, 0x39, 0xe6, 0x29, 0x95, 0x19, 0x59, 0x38, - 0x24, 0x86, 0x04, 0x04, 0x15, 0x78, 0x96, 0x72, 0xc9, 0xf5, 0x6f, 0xc0, 0xf0, 0x7e, 0x8c, 0x17, - 0x4e, 0xf7, 0x67, 0xcc, 0x63, 0x5e, 0xcd, 0x48, 0xf9, 0x57, 0xc7, 0xba, 0x28, 0xe4, 0x82, 0x71, - 0x41, 0x02, 0x5f, 0x00, 0x59, 0x38, 0x01, 0x48, 0xdf, 0x21, 0x21, 0xa7, 0x49, 0x33, 0x37, 0x4f, - 0x2d, 0xef, 0xcc, 0x2a, 0x60, 0x3f, 0xb5, 0xb4, 0xce, 0xb0, 0x36, 0xdf, 0x49, 0x5f, 0x82, 0xfe, - 0x4f, 0x6b, 0x4f, 0x20, 0x33, 0x54, 0x4b, 0xed, 0x7d, 0x76, 0x51, 0x91, 0x9b, 0x9d, 0x8b, 0xdd, - 0xca, 0x35, 0x64, 0xdb, 0xdc, 0xd4, 0x32, 0x9f, 0x4d, 0xcf, 0xed, 0x09, 0x64, 0xb6, 0x57, 0x46, - 0x75, 0xae, 0xfd, 0x48, 0x41, 0xc8, 0x94, 0x86, 0x12, 0xa2, 0x51, 0x04, 0x09, 0x67, 0xc2, 0x68, - 0x59, 0xed, 0xde, 0x97, 0xff, 0x16, 0x3e, 0x79, 0x06, 0xf6, 0xf6, 0xc9, 0x41, 0x19, 0x74, 0xad, - 0x55, 0x6e, 0x2a, 0xdb, 0xdc, 0x34, 0x6a, 0xea, 0x07, 0x90, 0xed, 0x7d, 0x4f, 0x8f, 0x57, 0x84, - 0xbe, 0x54, 0xb5, 0xaf, 0x8c, 0x26, 0xa3, 0xd8, 0x17, 0xa3, 0x59, 0x4a, 0x43, 0x10, 0x46, 0xbb, - 0xd2, 0xfd, 0xc6, 0x75, 0x1d, 0xb8, 0xac, 0x03, 0x37, 0x75, 0xe0, 0x01, 0x84, 0x97, 0x9c, 0x26, - 0xee, 0x4d, 0xa3, 0xfa, 0x55, 0xab, 0x8e, 0x09, 0xf6, 0xe3, 0x8b, 0xf9, 0x37, 0xa6, 0x72, 0x3c, - 0x0f, 0x70, 0xc8, 0x19, 0x69, 0x7a, 0xad, 0x3f, 0x7d, 0x11, 0x4d, 0x88, 0xcc, 0x66, 0x20, 0x76, - 0x30, 0xe1, 0x75, 0x18, 0x4d, 0x86, 0xbe, 0xb8, 0xad, 0xb6, 0xdd, 0xab, 0x55, 0x81, 0xd4, 0x75, - 0x81, 0xd4, 0xd7, 0x02, 0xa9, 0xcb, 0x0d, 0x52, 0xd6, 0x1b, 0xa4, 0x3c, 0x6f, 0x90, 0x72, 0x8f, - 0x0f, 0xa0, 0xd0, 0x67, 0x3c, 0x81, 0x8c, 0x00, 0xeb, 0x4f, 0x21, 0x8a, 0x21, 0x25, 0x0f, 0x07, - 0xd7, 0xa9, 0x04, 0xc1, 0xa7, 0xea, 0x2e, 0x67, 0x6f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb5, 0xbb, - 0xd9, 0x92, 0x20, 0x02, 0x00, 0x00, + // 327 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0xf3, 0x40, + 0x14, 0x85, 0x33, 0x7f, 0xe1, 0x07, 0x63, 0x51, 0x28, 0x0a, 0xa5, 0xe8, 0xa4, 0x64, 0x55, 0x90, + 0xce, 0x18, 0xdd, 0xb9, 0xb3, 0x0a, 0x15, 0x74, 0x21, 0x75, 0xe7, 0xa6, 0x4c, 0xd2, 0x4b, 0x3a, + 0xb4, 0x33, 0x53, 0x32, 0xd3, 0xe2, 0xbc, 0x45, 0x9f, 0xc3, 0x27, 0xe9, 0xb2, 0xe0, 0xc6, 0x55, + 0x94, 0xf4, 0x0d, 0xfa, 0x04, 0xd2, 0x24, 0xd5, 0xea, 0x6a, 0x06, 0xce, 0xb9, 0xdf, 0x39, 0xf7, + 0xba, 0xa7, 0x20, 0x28, 0x9b, 0x9a, 0xa1, 0x4a, 0xb8, 0xb1, 0x74, 0x16, 0xd0, 0x18, 0x24, 0x68, + 0xae, 0xc9, 0x24, 0x51, 0x46, 0xd5, 0x0e, 0x41, 0x90, 0x6f, 0x99, 0xcc, 0x82, 0xc6, 0x51, 0xac, + 0x62, 0x95, 0x6b, 0x74, 0xf3, 0x2b, 0x6c, 0x0d, 0x1c, 0x29, 0x2d, 0x94, 0xa6, 0x21, 0xd3, 0x40, + 0x67, 0x41, 0x08, 0x86, 0x05, 0x34, 0x52, 0x5c, 0x96, 0xba, 0xf7, 0x37, 0xe5, 0x87, 0x99, 0x1b, + 0xfc, 0x37, 0xe4, 0x56, 0xbb, 0x45, 0xf2, 0x93, 0x61, 0x06, 0x6a, 0xe7, 0x6e, 0x65, 0x04, 0xb6, + 0x8e, 0x9a, 0xa8, 0xb5, 0xd7, 0xc1, 0x59, 0xea, 0x55, 0xaf, 0xb7, 0x23, 0xf7, 0x60, 0xd7, 0xa9, + 0xe7, 0x5a, 0x26, 0xc6, 0x57, 0xfe, 0x08, 0xac, 0xdf, 0xdb, 0x58, 0x6b, 0x73, 0xe4, 0x1e, 0x08, + 0x2e, 0xfb, 0x31, 0xd3, 0xfd, 0x49, 0xc2, 0x23, 0xd0, 0xf5, 0x7f, 0xcd, 0x4a, 0x6b, 0xff, 0xe2, + 0x84, 0x14, 0xed, 0xc8, 0xa6, 0x1d, 0x29, 0xdb, 0x91, 0x5b, 0x88, 0x6e, 0x14, 0x97, 0x9d, 0x87, + 0x45, 0xea, 0x39, 0xeb, 0xd4, 0x3b, 0x2e, 0x78, 0xbf, 0x09, 0xfe, 0xeb, 0x87, 0x77, 0x16, 0x73, + 0x33, 0x9c, 0x86, 0x24, 0x52, 0x82, 0x96, 0x6b, 0x16, 0x4f, 0x5b, 0x0f, 0x46, 0xd4, 0xd8, 0x09, + 0xe8, 0x2d, 0x4c, 0xf7, 0xaa, 0x82, 0xcb, 0x2e, 0xd3, 0x8f, 0xf9, 0x74, 0xe7, 0x6e, 0x91, 0x61, + 0xb4, 0xcc, 0x30, 0xfa, 0xcc, 0x30, 0x9a, 0xaf, 0xb0, 0xb3, 0x5c, 0x61, 0xe7, 0x7d, 0x85, 0x9d, + 0x67, 0xb2, 0x03, 0x85, 0xb6, 0x50, 0x12, 0x2c, 0x05, 0xd1, 0x1e, 0xc3, 0x20, 0x86, 0x84, 0xbe, + 0xec, 0x1c, 0x2b, 0x0f, 0x08, 0xff, 0xe7, 0x67, 0xba, 0xfc, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xe1, + 0x96, 0xe9, 0x1d, 0xaf, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -150,20 +139,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - } - } - if len(m.RestrictedDenoms) > 0 { - for iNdEx := len(m.RestrictedDenoms) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.RestrictedDenoms[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- dAtA[i] = 0x12 } } @@ -198,12 +173,6 @@ func (m *GenesisState) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - if len(m.RestrictedDenoms) > 0 { - for _, e := range m.RestrictedDenoms { - l = e.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - } if len(m.MinGasPrices) > 0 { for _, e := range m.MinGasPrices { l = e.Size() @@ -281,40 +250,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { m.AuthorityKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RestrictedDenoms", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RestrictedDenoms = append(m.RestrictedDenoms, RestrictedDenom{}) - if err := m.RestrictedDenoms[len(m.RestrictedDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field MinGasPrices", wireType) } diff --git a/x/buyback/abci.go b/x/buyback/abci.go index 15494d6d..61dccbea 100644 --- a/x/buyback/abci.go +++ b/x/buyback/abci.go @@ -5,7 +5,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/e-money/em-ledger/x/buyback/internal/types" markettypes "github.com/e-money/em-ledger/x/market/types" - "time" ) func BeginBlocker(ctx sdk.Context, k Keeper, bk types.BankKeeper) { @@ -47,7 +46,6 @@ func BeginBlocker(ctx sdk.Context, k Keeper, bk types.BankKeeper) { sdk.NewCoin(stakingDenom, destinationAmount), account, generateClientOrderId(ctx, balance), - time.Time{}, ) if err != nil { diff --git a/x/buyback/abci_test.go b/x/buyback/abci_test.go index f1647ca6..ed286b98 100644 --- a/x/buyback/abci_test.go +++ b/x/buyback/abci_test.go @@ -15,7 +15,6 @@ import ( paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" embank "github.com/e-money/em-ledger/hooks/bank" - types2 "github.com/e-money/em-ledger/x/authority/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "strings" "testing" @@ -216,7 +215,6 @@ func order(account authtypes.AccountI, src, dst string) types.Order { s, d, account.GetAddress(), tmrand.Str(10), - time.Time{}, ) if err != nil { panic(err) @@ -274,16 +272,11 @@ func createTestComponents(t *testing.T) (sdk.Context, keeper.Keeper, *market.Kee pk = paramskeeper.NewKeeper(encConfig.Marshaler, encConfig.Amino, keyParams, tkeyParams) ak = authkeeper.NewAccountKeeper( encConfig.Marshaler, authCapKey, pk.Subspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, - ) - allowAllDenoms = embank.RestrictedKeeperFunc(func(context sdk.Context) types2.RestrictedDenoms { - return types2.RestrictedDenoms{} - }) - bk = embank.Wrap(bankkeeper.NewBaseKeeper( - encConfig.Marshaler, bankKey, ak, pk.Subspace(banktypes.ModuleName), blockedAddr, - ), allowAllDenoms) - + ) + bk = embank.Wrap(bankkeeper.NewBaseKeeper(encConfig.Marshaler, bankKey, ak, pk.Subspace(banktypes.ModuleName), blockedAddr)) + marketKeeper = market.NewKeeper( - encConfig.Marshaler, keyMarket, keyIndices, ak, bk, mockAuthority{}, + encConfig.Marshaler, keyMarket, keyIndices, ak, bk, pk.Subspace(market.ModuleName), ) ) @@ -340,20 +333,10 @@ func randomAddress() sdk.AccAddress { return tmrand.Bytes(sdk.AddrLen) } -var ( - _ types.RestrictedKeeper = (*mockAuthority)(nil) - _ keeper.StakingKeeper = (*mockStakingKeeper)(nil) -) +var _ keeper.StakingKeeper = (*mockStakingKeeper)(nil) -type ( - mockAuthority struct{} - mockStakingKeeper struct{} -) +type mockStakingKeeper struct{} func (mockStakingKeeper) BondDenom(sdk.Context) string { return stakingDenom } - -func (mockAuthority) GetRestrictedDenoms(sdk.Context) types2.RestrictedDenoms { - return types2.RestrictedDenoms{} -} diff --git a/hooks/distribution/abci.go b/x/distribution/abci.go similarity index 78% rename from hooks/distribution/abci.go rename to x/distribution/abci.go index 39fa8bc4..05e06a08 100644 --- a/hooks/distribution/abci.go +++ b/x/distribution/abci.go @@ -20,7 +20,6 @@ var ( previousProposerKey = []byte("emdistr/previousproposer") ) -// todo (reviewer) : using the same name as sdk module to prevent adding both. const ModuleName = distrtypes.ModuleName type AccountKeeper interface { @@ -39,13 +38,12 @@ type DistributionKeeper interface { // set the proposer for determining distribution during endblock // and distribute rewards for the previous block -// todo (reviewer): the logic in the this function was not modified. Please ensure that it still is what you need. func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k DistributionKeeper, ak AccountKeeper, bk bankkeeper.ViewKeeper, db db.DB) { defer telemetry.ModuleMeasureSince(ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) batch := apptypes.GetCurrentBatch(ctx) if batch == nil { - panic("batch object not found") // todo (reviewer): panic in begin blocker is not handled downstream and will crash the node. + panic("batch object not found") } // determine the total power signing the block @@ -57,15 +55,14 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k DistributionKee } } - previousProposer, err := db.Get(previousProposerKey) - // todo (reviewer) : a panic in the begin blocker will crash the node. It is not "recovered" anywhere downstream - if err != nil { - panic(err) - } - // TODO this is Tendermint-dependent // ref https://github.com/cosmos/cosmos-sdk/issues/3095 if ctx.BlockHeight() > 1 { + previousProposer, err := db.Get(previousProposerKey) + if err != nil { + panic(err) + } + feeCollector := ak.GetModuleAddress(auth.FeeCollectorName) coins := bk.GetAllBalances(ctx, feeCollector) @@ -75,6 +72,5 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k DistributionKee } } - previousProposer = req.Header.ProposerAddress - batch.Set(previousProposerKey, previousProposer) + batch.Set(previousProposerKey, req.Header.ProposerAddress) } diff --git a/hooks/distribution/module.go b/x/distribution/module.go similarity index 90% rename from hooks/distribution/module.go rename to x/distribution/module.go index 47f24ca9..fa9766c4 100644 --- a/hooks/distribution/module.go +++ b/x/distribution/module.go @@ -50,5 +50,3 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONMarshaler) json.RawMessage { state.Params.CommunityTax = sdk.ZeroDec() return cdc.MustMarshalJSON(state) } - -// todo (reviewer) : IMHO this modules would fit better into x/ than hooks as it contains an alternative/modified impl than adding callbacks diff --git a/x/market/alias.go b/x/market/alias.go index 603279e7..08ed565b 100644 --- a/x/market/alias.go +++ b/x/market/alias.go @@ -63,7 +63,6 @@ type ( MsgCancelOrder = types.MsgCancelOrder MsgCancelReplaceLimitOrder = types.MsgCancelReplaceLimitOrder - AccountKeeper = types.AccountKeeper - BankKeeper = types.BankKeeper - RestrictedKeeper = types.RestrictedKeeper + AccountKeeper = types.AccountKeeper + BankKeeper = types.BankKeeper ) diff --git a/x/market/keeper/grpc_query_test.go b/x/market/keeper/grpc_query_test.go index 79994bdf..30d6eed1 100644 --- a/x/market/keeper/grpc_query_test.go +++ b/x/market/keeper/grpc_query_test.go @@ -26,7 +26,6 @@ func TestQueryByAccount(t *testing.T) { sdk.NewCoin("alx", sdk.OneInt()), sdk.NewCoin("blx", sdk.OneInt()), myAddress,"myOrderID", - time.Time{}, ) require.NoError(t, err) k.setOrder(ctx, &o) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index c09efd92..fbdd1265 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -8,7 +8,6 @@ import ( "fmt" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - types2 "github.com/e-money/em-ledger/x/authority/types" "math" "sync" "time" @@ -26,16 +25,13 @@ type Keeper struct { keyIndices sdk.StoreKey cdc codec.BinaryMarshaler // instruments types.Instruments - ak types.AccountKeeper - bk types.BankKeeper - authorityk types.RestrictedKeeper + ak types.AccountKeeper + bk types.BankKeeper paramStore paramtypes.Subspace // accountOrders types.Orders appstateInit *sync.Once - - restrictedDenoms types2.RestrictedDenoms } func NewKeeper( @@ -44,7 +40,6 @@ func NewKeeper( keyIndices sdk.StoreKey, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, - authorityKeeper types.RestrictedKeeper, paramStore paramtypes.Subspace, ) *Keeper { // set params map @@ -61,8 +56,6 @@ func NewKeeper( paramStore: paramStore, appstateInit: new(sync.Once), - - authorityk: authorityKeeper, } bankKeeper.AddBalanceListener(k.accountChanged) @@ -125,42 +118,25 @@ func (k *Keeper) createExecutionPlan(ctx sdk.Context, SourceDenom, DestinationDe return bestPlan } -func (k *Keeper) NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { - _, res, err := k.createMarketOrder( - ctx, - srcDenom, - dst, - maxSlippage, - owner, - timeInForce, - clientOrderId, - time.Time{}, - ) - - return res, err -} - -// createMarketOrder creates a market order that returns the created order and -// takes the original order creation timestamp. -func (k *Keeper) createMarketOrder( - ctx sdk.Context, - srcDenom string, dst sdk.Coin, - maxSlippage sdk.Dec, - owner sdk.AccAddress, - timeInForce types.TimeInForce, - clientOrderId string, - origOrderCreated time.Time, -) (order *types.Order, res *sdk.Result, err error) { - gasMeter := ctx.GasMeter() - - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - - defer k.OrderSpendGas(ctx, order, origOrderCreated, gasMeter, &err) +// GetSrcFromSlippage expresses the maximum source amount to spend to buy the +// requested dst amount. Taking the corresponding source amount +// (dst amount/last market price) and adding the slippage percentage is the +// resulting value. The maxSlippage decimal expresses a percentage (1 is 100%). +func (k *Keeper) GetSrcFromSlippage( + ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, +) (sdk.Coin, error) { + // ValidateBasic() for the 2 Market messages has validated the src/dst coins + if maxSlippage.LT(sdk.ZeroDec()) { + return sdk.Coin{}, sdkerrors.Wrapf( + types.ErrInvalidSlippage, + "cannot specify negative slippage %s", maxSlippage.String(), + ) + } // If the order allows for slippage, adjust the source amount accordingly. md := k.GetInstrument(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()), srcDenom, dst.Denom) if md == nil || md.LastPrice == nil { - return nil, nil, sdkerrors.Wrapf( + return sdk.Coin{}, sdkerrors.Wrapf( types.ErrNoMarketDataAvailable, "%v/%v", srcDenom, dst.Denom, ) } @@ -169,18 +145,7 @@ func (k *Keeper) createMarketOrder( source = source.Mul(sdk.NewDec(1).Add(maxSlippage)) slippageSource := sdk.NewCoin(srcDenom, source.RoundInt()) - var orderTmp types.Order - orderTmp, err = types.NewOrder( - ctx.BlockTime(), timeInForce, slippageSource, dst, owner, clientOrderId, - origOrderCreated, - ) - if err != nil { - return nil, nil, err - } - order = &orderTmp - - res, err = k.NewOrderSingle(ctx, *order) - return order, res, err + return slippageSource, nil } // calcOrderGas computes the order gas by applying any liquidity rebate. The @@ -424,15 +389,7 @@ func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (r if aggressiveOrder.IsFilled() { types.EmitExpireEvent(ctx, aggressiveOrder) } else { - // Check whether this denomination is restricted and thus cannot create passive orders addToBook := true - if denom, found := k.restrictedDenoms.Find(aggressiveOrder.Source.Denom); found { - addToBook = denom.IsAnyAllowed(owner) - } - - if denom, found := k.restrictedDenoms.Find(aggressiveOrder.Destination.Denom); addToBook && found { - addToBook = denom.IsAnyAllowed(owner) - } switch aggressiveOrder.TimeInForce { case types.TimeInForce_ImmediateOrCancel: @@ -440,6 +397,7 @@ func (k *Keeper) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (r types.EmitExpireEvent(ctx, aggressiveOrder) case types.TimeInForce_FillOrKill: KillOrder = true + addToBook = false ctx = ctx.WithEventManager(sdk.NewEventManager()) types.EmitExpireEvent(ctx, aggressiveOrder) } @@ -461,9 +419,6 @@ func (k *Keeper) initializeFromStore(ctx sdk.Context) { // TODO should we move the market params to genesis or const them? k.InitParamsStore(ctx) - // Load the restricted denominations from the authority module - k.restrictedDenoms = k.authorityk.GetRestrictedDenoms(ctx) - // TODO Reinstate this when the mem store arrives in v0.40 of the Cosmos SDK. //// Load the last known market state from app state. //store := ctx.KVStore(k.key) @@ -563,7 +518,12 @@ func (k *Keeper) CancelReplaceLimitOrder( // Verify that instrument is the same. if origOrder.Source.Denom != newOrder.Source.Denom || origOrder.Destination.Denom != newOrder.Destination.Denom { - return nil, sdkerrors.Wrap(types.ErrOrderInstrumentChanged, "") + return nil, sdkerrors.Wrap( + types.ErrOrderInstrumentChanged, fmt.Sprintf( + "source %s != %s Or dest %s != %s", origOrder.Source, newOrder.Source, + origOrder.Destination.Denom, newOrder.Destination.Denom, + ), + ) } // Has the previous order already achieved the goal on the source side? @@ -591,78 +551,6 @@ func (k *Keeper) CancelReplaceLimitOrder( return &sdk.Result{Events: evts}, nil } -func (k *Keeper) CancelReplaceMarketOrder( - ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder, -) (resAdd *sdk.Result, err error) { - var newOrder *types.Order - - orderGasMeter := ctx.GasMeter() - ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - - origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, msg.Owner, msg.OrigClientOrderId) - - if origOrder == nil { - k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, msg.OrigClientOrderId) - } - - // Verify that instrument is the same. - if origOrder.Source.Denom != msg.Source || origOrder.Destination.Denom != msg.Destination.Denom { - k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - return nil, sdkerrors.Wrap( - types.ErrOrderInstrumentChanged, fmt.Sprintf( - "source %s != %s Or dest %s != %s", origOrder.Source, msg.Source, - origOrder.Destination.Denom, msg.Destination.Denom, - ), - ) - } - - // Has the previous order already achieved the goal on the source side? - if origOrder.DestinationFilled.GTE(msg.Destination.Amount) { - k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - return nil, sdkerrors.Wrap( - types.ErrNoSourceRemaining, fmt.Sprintf( - "has already been filled filled:%s >= %s", - origOrder.Destination.Amount.String(), msg.Destination.Amount.String()), - ) - } - - k.deleteOrder(ctx, origOrder) - types.EmitExpireEvent(ctx, *origOrder) - - ownerAddr, err := sdk.AccAddressFromBech32(msg.Owner) - if err != nil { - k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") - } - - destinationFilled := origOrder.DestinationFilled - dstRemaining := msg.Destination.Amount.Sub(destinationFilled) - remDstCoin := sdk.NewCoin(msg.Destination.Denom, dstRemaining) - - newOrder, resAdd, err = k.createMarketOrder( - // pass in the meter we will charge gas - ctx, - msg.Source, - remDstCoin, - msg.MaxSlippage, - ownerAddr, - msg.TimeInForce, - msg.NewClientOrderId, - origOrder.Created, - ) - if err != nil { - k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - return nil, err - } - - defer k.OrderSpendGas(ctx, newOrder, origOrder.Created, orderGasMeter, &err) - - evts := append(ctx.EventManager().ABCIEvents(), resAdd.Events...) - - return &sdk.Result{Events: evts}, nil -} - func (k *Keeper) GetOrderByOwnerAndClientOrderId(ctx sdk.Context, owner, clientOrderId string) *types.Order { store := ctx.KVStore(k.key) diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 38c9ca7a..41c5be3a 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -29,7 +29,6 @@ import ( paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" embank "github.com/e-money/em-ledger/hooks/bank" emtypes "github.com/e-money/em-ledger/types" - emauthtypes "github.com/e-money/em-ledger/x/authority/types" "github.com/e-money/em-ledger/x/market/types" "github.com/spf13/pflag" "github.com/stretchr/testify/require" @@ -263,16 +262,15 @@ func TestMarketOrderSlippage1(t *testing.T) { // Make a market order that allows slippage slippage := sdk.NewDecWithPrec(50, 2) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(200)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - cid(), + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(200)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) // Check that the balance matches the first two orders being executed while the third did not fall within the slippage bal1 := bk.GetAllBalances(ctx, acc1.GetAddress()) @@ -283,15 +281,12 @@ func TestMarketOrderSlippage1(t *testing.T) { // Ensure that the order can not exceed account balance slippage = sdk.NewDecWithPrec(500, 2) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(200)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - cid(), + slippageSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) + require.NoError(t, err) + limitOrder = order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) require.True(t, types.ErrAccountBalanceInsufficient.Is(err)) } @@ -314,18 +309,18 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { require.NoError(t, err) // Make a market order that allows slippage - clientID := cid() slippage := sdk.NewDecWithPrec(100, 2) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(100)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - clientID, + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(100)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) + + clientID := limitOrder.ClientOrderID foundOrder := k.GetOrderByOwnerAndClientOrderId( ctx, acc1.GetAddress().String(), clientID, ) @@ -338,22 +333,27 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { require.Equal(t, coins("1eur,499gbp").String(), acc1Bal.String()) newClientID := cid() - mcrm := &types.MsgCancelReplaceMarketOrder{ - Owner: acc1.GetAddress().String(), - OrigClientOrderId: clientID, - NewClientOrderId: newClientID, - TimeInForce: types.TimeInForce_GoodTillCancel, - Source: "gbp", - Destination: sdk.NewCoin("eur", sdk.NewInt(100)), - MaxSlippage: sdk.NewDecWithPrec(0, 2), - } + slippageSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, sdk.NewDecWithPrec(0, 2), + ) + require.NoError(t, err) + order, err := types.NewOrder( + ctx.BlockTime(), + types.TimeInForce_GoodTillCancel, + slippageSource, + dest, + acc1.GetAddress(), + newClientID, + ) + require.NoError(t, err) var stdTrxFee uint64 k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) gasMeter := sdk.NewInfiniteGasMeter() ctx = ctx.WithGasMeter(gasMeter) - _, err = k.CancelReplaceMarketOrder(ctx, mcrm) + + _, err = k.CancelReplaceLimitOrder(ctx, order, clientID) require.NoError(t, err) require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) @@ -363,10 +363,10 @@ func TestCancelReplaceMarketOrderZeroSlippage(t *testing.T) { Owner: acc1.GetAddress().String(), ClientOrderID: newClientID, // Zero slippage same amount - Source: sdk.NewCoin(mcrm.Source, sdk.NewInt(100)), + Source: sdk.NewCoin("gbp", sdk.NewInt(100)), SourceRemaining: sdk.NewInt(100), SourceFilled: sdk.ZeroInt(), - Destination: mcrm.Destination, + Destination: dest, DestinationFilled: sdk.ZeroInt(), Created: ctx.BlockTime(), } @@ -396,30 +396,49 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { var o types.Order var err error + var liquidTrxFee uint64 + k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + + gasMeter := sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + // Establish market price by executing a 2:1 trade o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) + require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed(), "Liquid Trx are discounted") + + var stdTrxFee uint64 + k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) + + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) + require.Equal( + t, stdTrxFee, ctx.GasMeter().GasConsumed(), + "Filled order costs std fee", + ) + acc1b := bk.GetAllBalances(ctx, acc1.GetAddress()) require.Equal(t, coins("20eur,90gbp").String(), acc1b.String()) - // Make a market order that allows slippage - clientID := cid() + // Make a market newOrder that allows slippage slippage := sdk.NewDecWithPrec(0, 2) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(10)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - clientID, + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(10)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) + + clientID := limitOrder.ClientOrderID + acc1b = bk.GetAllBalances(ctx, acc1.GetAddress()) // Gave 1 gbp and gained a eur @@ -429,7 +448,7 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { foundOrder := k.GetOrderByOwnerAndClientOrderId( ctx, acc1.GetAddress().String(), clientID, ) - require.NotNil(t, foundOrder, "Market order should exist") + require.NotNil(t, foundOrder, "Market newOrder should exist") // 0% slippage same as ratio (1eur/2gbp) * 10 => 5gbp require.True(t, foundOrder.Source.IsEqual(sdk.NewCoin("gbp", sdk.NewInt(5)))) @@ -443,8 +462,40 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { Destination: sdk.NewCoin("eur", sdk.NewInt(10)), MaxSlippage: sdk.NewDecWithPrec(100, 2), } - _, err = k.CancelReplaceMarketOrder(ctx, mcrm) + + dest = sdk.NewCoin("eur", sdk.NewInt(10)) + + slippageSource, err = k.GetSrcFromSlippage( + ctx, "gbp", dest, sdk.NewDecWithPrec(100, 2), + ) + require.NoError(t, err) + + newOrder, err := types.NewOrder( + ctx.BlockTime(), + types.TimeInForce_GoodTillCancel, + slippageSource, + dest, + acc1.GetAddress(), + newClientID, + ) require.NoError(t, err) + + var qualificationMin int64 + k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) + + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + + _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter).WithBlockTime( + ctx.BlockTime(). + Add(time.Duration(qualificationMin)*time.Minute), + ), newOrder, clientID) + require.NoError(t, err) + require.Equal( + t, liquidTrxFee, ctx.GasMeter().GasConsumed(), + "Unfilled/liquid are discounted", + ) + expOrder := &types.Order{ ID: 3, TimeInForce: types.TimeInForce_GoodTillCancel, @@ -463,7 +514,7 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { origOrder := k.GetOrderByOwnerAndClientOrderId( ctx, acc1.GetAddress().String(), clientID, ) - require.Nil(t, origOrder, "Original market order should not exist") + require.Nil(t, origOrder, "Original market newOrder should not exist") foundOrder = k.GetOrderByOwnerAndClientOrderId( ctx, acc1.GetAddress().String(), newClientID, @@ -475,92 +526,93 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { require.Equal(t, coins("20eur,90gbp").String(), acc1Bal.String()) } -func TestCancelReplaceMarketOrder0GasFee(t *testing.T) { +func TestGetSrcFromSlippage(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) - acc1 := createAccount(ctx, ak, bk, randomAddress(), "100gbp") - acc2 := createAccount(ctx, ak, bk, randomAddress(), "100eur") + var ( + acc1 = createAccount(ctx, ak, bk, randomAddress(), "500gbp") + acc2 = createAccount(ctx, ak, bk, randomAddress(), "500eur") - var o types.Order - var err error + o types.Order + err error + srcDenom string + slippedSource, dest sdk.Coin + ) - var liquidTrxFee uint64 - k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) + srcDenom = "jpy" + dest = sdk.NewCoin("eur", sdk.NewInt(100)) + slippedSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, sdk.ZeroDec(), + ) + require.Error(t, err, "No trades yet with jpy") - gasMeter := sdk.NewInfiniteGasMeter() - ctx = ctx.WithGasMeter(gasMeter) + srcDenom = "gbp" + dest = sdk.NewCoin("dek", sdk.NewInt(100)) + slippedSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, sdk.ZeroDec(), + ) + require.Error(t, err, "No trades yet with dek") - // Establish market price by executing a 2:1 trade - o = order(ctx.BlockTime(), acc2, "20eur", "10gbp") + slippage := sdk.NewDec(-2) + + srcDenom = "gbp" + dest = sdk.NewCoin("eur", sdk.NewInt(100)) + slippedSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, + ) + require.Error(t, err) + require.True(t, types.ErrInvalidSlippage.Is(err)) + + // Establish market price by executing a 1:1 trade + o = order(ctx.BlockTime(), acc2, "1eur", "1gbp") _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) - require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed(), "Liquid Trx are discounted") - var stdTrxFee uint64 - k.paramStore.Get(ctx, types.KeyTrxFee, &stdTrxFee) - - gasMeter = sdk.NewInfiniteGasMeter() - ctx = ctx.WithGasMeter(gasMeter) + o = order(ctx.BlockTime(), acc1, "1gbp", "1eur") + _, err = k.NewOrderSingle(ctx, o) + require.NoError(t, err) - o = order(ctx.BlockTime(), acc1, "10gbp", "20eur") + // Add liquidity + o = order(ctx.BlockTime(), acc2, "100eur", "100gbp") _, err = k.NewOrderSingle(ctx, o) require.NoError(t, err) + + srcDenom = "gbp" + dest = sdk.NewCoin("eur", sdk.NewInt(100)) + slippedSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, sdk.ZeroDec(), + ) + require.NoError(t, err) require.Equal( - t, stdTrxFee, ctx.GasMeter().GasConsumed(), "Filled order costs std fee", + t, slippedSource.String(), sdk.NewCoin(srcDenom, dest.Amount).String(), + "0% slippage -> source amount or last market price", ) - acc1b := bk.GetAllBalances(ctx, acc1.GetAddress()) - require.Equal(t, coins("20eur,90gbp").String(), acc1b.String()) - - // Make a market order that allows slippage - clientID := cid() - slippage := sdk.NewDecWithPrec(0, 2) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(10)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - clientID, + // 100% + slippage = sdk.NewDec(1) + srcDenom = "gbp" + dest = sdk.NewCoin("eur", sdk.NewInt(1)) + slippedSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) - acc1b = bk.GetAllBalances(ctx, acc1.GetAddress()) - - foundOrder := k.GetOrderByOwnerAndClientOrderId( - ctx, acc1.GetAddress().String(), clientID, + require.Equal( + t, sdk.NewCoin(srcDenom, sdk.NewInt(2)).String(), + slippedSource.String(), + "100% slippage -> 1+100% source amount", ) - require.NotNil(t, foundOrder, "Market order should exist") - // 0% slippage same as ratio (1eur/2gbp) * 10 => 5gbp - require.True(t, foundOrder.Source.IsEqual(sdk.NewCoin("gbp", sdk.NewInt(5)))) - - newClientID := cid() - mcrm := &types.MsgCancelReplaceMarketOrder{ - Owner: acc1.GetAddress().String(), - OrigClientOrderId: clientID, - NewClientOrderId: newClientID, - TimeInForce: types.TimeInForce_GoodTillCancel, - Source: "gbp", - Destination: sdk.NewCoin("eur", sdk.NewInt(10)), - MaxSlippage: sdk.NewDecWithPrec(100, 2), - } - var qualificationMin int64 - k.paramStore.Get(ctx, types.KeyLiquidityRebateMinutesSpan, &qualificationMin) - - gasMeter = sdk.NewInfiniteGasMeter() - ctx = ctx.WithGasMeter(gasMeter) - - _, err = k.CancelReplaceMarketOrder( - ctx.WithGasMeter(gasMeter).WithBlockTime( - ctx.BlockTime(). - Add(time.Duration(qualificationMin)*time.Minute), - ), mcrm, + // 20% + slippage = sdk.OneDec().Quo(sdk.NewDec(5)) + srcDenom = "gbp" + dest = sdk.NewCoin("eur", sdk.NewInt(10)) + slippedSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) require.Equal( - t, liquidTrxFee, ctx.GasMeter().GasConsumed(), - "Unfilled/liquid are discounted", + t, sdk.NewCoin(srcDenom, sdk.NewInt(12)).String(), slippedSource.String(), + "20% slippage -> 10+20%=>12 amount", ) } @@ -602,16 +654,15 @@ func TestFillOrKillMarketOrder1(t *testing.T) { gasMeter := sdk.NewInfiniteGasMeter() // Create a fill or kill order that cannot be satisfied by the current market - result, err := k.NewMarketOrderWithSlippage( - ctx.WithGasMeter(gasMeter), - "gbp", - sdk.NewCoin("eur", sdk.NewInt(200)), - sdk.ZeroDec(), - acc1.GetAddress(), - types.TimeInForce_FillOrKill, - cid(), + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(200)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, sdk.ZeroDec(), ) - + require.NoError(t, err) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + limitOrder.TimeInForce = types.TimeInForce_FillOrKill + result, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), limitOrder) require.NoError(t, err) require.Len(t, result.Events, 1) require.Equal(t, types.EventTypeMarket, result.Events[0].Type) @@ -940,20 +991,19 @@ func TestLiquidNewMarketOrderGas(t *testing.T) { require.NoError(t, err) require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) - gasMeter = sdk.NewInfiniteGasMeter() slippage := sdk.NewDecWithPrec(50, 2) - cid := cid() - ctx = ctx.WithGasMeter(gasMeter) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(200)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - cid, + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(200)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + + gasMeter = sdk.NewInfiniteGasMeter() + ctx = ctx.WithGasMeter(gasMeter) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) require.Equal(t, liquidTrxFee, ctx.GasMeter().GasConsumed()) } @@ -988,18 +1038,18 @@ func TestPartiallyLiquidMarketOrderGas(t *testing.T) { gasMeter = sdk.NewInfiniteGasMeter() slippage := sdk.NewDecWithPrec(75, 2) - cid := cid() - ctx = ctx.WithGasMeter(gasMeter) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(36)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - cid, + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(36)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + + ctx = ctx.WithGasMeter(gasMeter) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) + bal1Aft := bk.GetBalance(ctx.WithGasMeter(sdk.NewInfiniteGasMeter()), acc1.GetAddress(), "gbp") rebate := stdTrxFee-liquidTrxFee filledPct := bal1Bef.Sub(bal1Aft).Amount.ToDec().Quo(sdk.NewDec(36)) @@ -1020,7 +1070,7 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), - coin("100usd"), acc1.GetAddress(), order1cid, time.Time{}, + coin("100usd"), acc1.GetAddress(), order1cid, ) _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) @@ -1042,7 +1092,6 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { coin("5000usd"), acc1.GetAddress(), order2cid, - time.Time{}, ) gasMeter := sdk.NewInfiniteGasMeter() // Add + Interval Minutes @@ -1071,7 +1120,7 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { gasMeter = sdk.NewInfiniteGasMeter() order3, err := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000chf"), - coin("5000usd"), acc1.GetAddress(), cid(), time.Time{}, + coin("5000usd"), acc1.GetAddress(), cid(), ) require.NoError(t, err) @@ -1111,7 +1160,7 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { gasMeter = sdk.NewInfiniteGasMeter() order4, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("3000eur"), - coin("3000usd"), acc1.GetAddress(), order4cid, time.Time{}, + coin("3000usd"), acc1.GetAddress(), order4cid, ) ctx = ctx.WithGasMeter(gasMeter) res, err = k.CancelReplaceLimitOrder( @@ -1148,7 +1197,7 @@ func TestLimitOrderErrGas(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), - coin("100usd"), acc1.GetAddress(), order1cid, time.Time{}, + coin("100usd"), acc1.GetAddress(), order1cid, ) _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) @@ -1162,7 +1211,6 @@ func TestLimitOrderErrGas(t *testing.T) { coin("101usd"), acc1.GetAddress(), order2cid, - time.Time{}, ) stdTrxFee := k.GetTrxFee(ctx) @@ -1193,7 +1241,7 @@ func TestKeeperReplaceLimitFullLiquidGas(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), - coin("1200usd"), acc1.GetAddress(), order1cid, time.Time{}, + coin("1200usd"), acc1.GetAddress(), order1cid, ) _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) @@ -1211,7 +1259,7 @@ func TestKeeperReplaceLimitFullLiquidGas(t *testing.T) { order2cid := cid() order2, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), - coin("17000usd"), acc1.GetAddress(), order2cid, time.Time{}, + coin("17000usd"), acc1.GetAddress(), order2cid, ) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) @@ -1229,7 +1277,7 @@ func TestKeeperReplaceLimitFullLiquidGas(t *testing.T) { gasMeter = sdk.NewInfiniteGasMeter() order3, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), - coin("1700usd"), acc1.GetAddress(), cid(), time.Time{}, + coin("1700usd"), acc1.GetAddress(), cid(), ) // Wrong client order id for previous order submitted. _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order1cid) @@ -1263,7 +1311,7 @@ func TestKeeperReplaceLimitFullLiquidGas(t *testing.T) { order4cid := cid() order4, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), - coin("35050usd"), acc1.GetAddress(), order4cid, time.Time{}, + coin("35050usd"), acc1.GetAddress(), order4cid, ) gasMeter = sdk.NewInfiniteGasMeter() // add qualification minutes @@ -1326,16 +1374,15 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { // Make a market order that allows slippage clientID := cid() slippage := sdk.NewDecWithPrec(100, 2) - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(100)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - clientID, + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(100)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) foundOrder := k.GetOrderByOwnerAndClientOrderId( ctx, acc1.GetAddress().String(), clientID, ) @@ -1347,23 +1394,20 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) require.Equal(t, coins("1eur,499gbp").String(), acc1Bal.String()) - newClientID := cid() - mcrm := &types.MsgCancelReplaceMarketOrder{ - Owner: acc1.GetAddress().String(), - OrigClientOrderId: clientID, - NewClientOrderId: newClientID, - TimeInForce: types.TimeInForce_GoodTillCancel, - Source: "gbp", - Destination: sdk.NewCoin("eur", sdk.NewInt(100)), - MaxSlippage: sdk.NewDecWithPrec(0, 2), - } - + slippage = sdk.NewDecWithPrec(0, 2) + srcDenom = "gbp" + dest = sdk.NewCoin("eur", sdk.NewInt(100)) + slippageSource, err = k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, + ) + require.NoError(t, err) + limitOrder = order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) gasMeter := sdk.NewInfiniteGasMeter() ctx = ctx.WithGasMeter(gasMeter) k.bk = nil require.Panics(t, func() { // panic CancelReplace - k.CancelReplaceMarketOrder(ctx, mcrm) + k.NewOrderSingle(ctx, limitOrder) }) require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) } @@ -1424,16 +1468,15 @@ func TestCancelNewMarketFullGas(t *testing.T) { gasMeter = sdk.NewGasMeter(math.MaxUint64) slippage := sdk.NewDecWithPrec(50, 2) cid := cid() - _, err = k.NewMarketOrderWithSlippage( - ctx, - "gbp", - sdk.NewCoin("eur", sdk.NewInt(200)), - slippage, - acc1.GetAddress(), - types.TimeInForce_GoodTillCancel, - cid, + srcDenom := "gbp" + dest := sdk.NewCoin("eur", sdk.NewInt(200)) + slippageSource, err := k.GetSrcFromSlippage( + ctx, srcDenom, dest, slippage, ) require.NoError(t, err) + limitOrder := order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) + _, err = k.NewOrderSingle(ctx, limitOrder) + require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed(), "Non-filled-Liquid") _, err = k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), cid) @@ -1632,14 +1675,14 @@ func TestDeleteOrder(t *testing.T) { order1, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), - coin("120usd"), acc1.GetAddress(), cid, time.Time{}, + coin("120usd"), acc1.GetAddress(), cid, ) _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) order2, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("100eur"), - coin("77chf"), acc1.GetAddress(), cid, time.Time{}, + coin("77chf"), acc1.GetAddress(), cid, ) _, err = k.NewOrderSingle(ctx, order2) require.Error(t, err) // Verify that client order ids cannot be duplicated. @@ -1660,7 +1703,7 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { for i := 0; i < 5; i++ { order, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5eur"), - coin("12usd"), acc1.GetAddress(), cid(), time.Time{}, + coin("12usd"), acc1.GetAddress(), cid(), ) _, err := k.NewOrderSingle(ctx, order) require.NoError(t, err) @@ -1669,7 +1712,7 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { for i := 0; i < 5; i++ { order, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("7usd"), - coin("3chf"), acc2.GetAddress(), cid(), time.Time{}, + coin("3chf"), acc2.GetAddress(), cid(), ) res, err := k.NewOrderSingle(ctx, order) require.True(t, err == nil, res.Log) @@ -1681,7 +1724,7 @@ func TestGetOrdersByOwnerAndCancel(t *testing.T) { { order, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("12usd"), - coin("5eur"), acc2.GetAddress(), cid(), time.Time{}, + coin("5eur"), acc2.GetAddress(), cid(), ) res, err := k.NewOrderSingle(ctx, order) require.True(t, err == nil, res.Log) @@ -1741,7 +1784,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), - coin("1200usd"), acc1.GetAddress(), order1cid, time.Time{}, + coin("1200usd"), acc1.GetAddress(), order1cid, ) _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) @@ -1751,10 +1794,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { gasMeter := sdk.NewGasMeter(math.MaxUint64) order2cid := cid() - order2, _ := types.NewOrder( - ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), - coin("17000usd"), acc1.GetAddress(), order2cid, time.Time{}, - ) + order2, _ := types.NewOrder(ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), coin("17000usd"), acc1.GetAddress(), order2cid) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) @@ -1770,7 +1810,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { order3, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), - coin("1700usd"), acc1.GetAddress(), cid(), time.Time{}, + coin("1700usd"), acc1.GetAddress(), cid(), ) // Wrong client order id for previous order submitted. _, err = k.CancelReplaceLimitOrder(ctx, order3, order1cid) @@ -1811,7 +1851,7 @@ func TestKeeperCancelReplaceLimitOrder(t *testing.T) { ctx = ctx.WithGasMeter(gasMeter) order4, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), - coin("35050usd"), acc1.GetAddress(), order4cid, time.Time{}, + coin("35050usd"), acc1.GetAddress(), order4cid, ) res, err = k.CancelReplaceLimitOrder( ctx.WithBlockTime(ctx.BlockTime().Add( @@ -1869,7 +1909,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { order1cid := cid() order1, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500eur"), - coin("1200usd"), acc1.GetAddress(), order1cid, time.Time{}, + coin("1200usd"), acc1.GetAddress(), order1cid, ) _, err := k.NewOrderSingle(ctx, order1) require.NoError(t, err) @@ -1881,7 +1921,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { order2cid := cid() order2, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("5000eur"), - coin("17000usd"), acc1.GetAddress(), order2cid, time.Time{}, + coin("17000usd"), acc1.GetAddress(), order2cid, ) res, err := k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order2, order1cid) require.True(t, err == nil, res.Log) @@ -1898,7 +1938,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { order3, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("500chf"), - coin("1700usd"), acc1.GetAddress(), cid(), time.Time{}, + coin("1700usd"), acc1.GetAddress(), cid(), ) // Wrong client order id for previous order submitted. _, err = k.CancelReplaceLimitOrder(ctx, order3, order1cid) @@ -1931,7 +1971,7 @@ func TestKeeperCancelReplaceMarketOrder(t *testing.T) { order4cid := cid() order4, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), - coin("35050usd"), acc1.GetAddress(), order4cid, time.Time{}, + coin("35050usd"), acc1.GetAddress(), order4cid, ) res, err = k.CancelReplaceLimitOrder(ctx, order4, order2cid) require.True(t, err == nil, res.Log) @@ -1964,7 +2004,7 @@ func TestOrdersChangeWithAccountBalance(t *testing.T) { order, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("10000eur"), - coin("1000usd"), acc.GetAddress(), cid(), time.Time{}, + coin("1000usd"), acc.GetAddress(), cid(), ) _, err := k.NewOrderSingle(ctx, order) require.NoError(t, err) @@ -1974,7 +2014,7 @@ func TestOrdersChangeWithAccountBalance(t *testing.T) { acc2 := createAccount(ctx, ak, bk, randomAddress(), "900000usd") order2, _ := types.NewOrder( ctx.BlockTime(), types.TimeInForce_GoodTillCancel, coin("400usd"), - coin("4000eur"), acc2.GetAddress(), cid(), time.Time{}, + coin("4000eur"), acc2.GetAddress(), cid(), ) _, err = k.NewOrderSingle(ctx, order2) require.NoError(t, err) @@ -2087,95 +2127,6 @@ func TestInvalidInstrument(t *testing.T) { _, err := k.NewOrderSingle(ctx, o) require.True(t, types.ErrInvalidInstrument.Is(err)) } - -func TestRestrictedDenominations1(t *testing.T) { - ctx, k, ak, bk := createTestComponents(t) - - acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp, 10000eur") - acc2 := createAccount(ctx, ak, bk, randomAddress(), "6500usd,1200gbp") - - // Restrict trading of gbp - k.authorityk = dummyAuthority{ - RestrictedDenoms: emauthtypes.RestrictedDenoms{Denoms: []emauthtypes.RestrictedDenom{ - {"gbp", []string{acc1.GetAddress().String()}}, - }}, - } - - k.initializeFromStore(ctx) - - { // Verify that acc2 can't create a passive gbp order - o := order(ctx.BlockTime(), acc2, "500gbp", "542eur") - _, err := k.NewOrderSingle(ctx, o) - require.NoError(t, err) - // require.Empty(t, k.instruments) - - o = order(ctx.BlockTime(), acc2, "542usd", "500gbp") - _, err = k.NewOrderSingle(ctx, o) - require.NoError(t, err) - // require.Empty(t, k.instruments) - } - - { // Verify that acc1 can create a passive gbp order - o := order(ctx.BlockTime(), acc1, "542eur", "500gbp") - _, err := k.NewOrderSingle(ctx, o) - require.NoError(t, err) - // require.Len(t, k.instruments, 1) - - o = order(ctx.BlockTime(), acc1, "200gbp", "333usd") - _, err = k.NewOrderSingle(ctx, o) - require.NoError(t, err) - // require.Len(t, k.instruments, 2) - } - - { // Verify that acc2 managed to sell its gbp to a passive order - o := order(ctx.BlockTime(), acc2, "500gbp", "542eur") - _, err := k.NewOrderSingle(ctx, o) - require.NoError(t, err) - - balance := bk.GetAllBalances(ctx, acc2.GetAddress()) - require.Equal(t, "542", balance.AmountOf("eur").String()) - - o = order(ctx.BlockTime(), acc2, "333usd", "200gbp") - _, err = k.NewOrderSingle(ctx, o) - require.NoError(t, err) - balance = bk.GetAllBalances(ctx, acc2.GetAddress()) - require.Equal(t, "900", balance.AmountOf("gbp").String()) - } -} - -func TestRestrictedDenominations2(t *testing.T) { - // Two instruments are restricted. - ctx, k, ak, bk := createTestComponents(t) - - acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000gbp, 10000usd") - - // Restrict trading of gbp and usd - k.authorityk = dummyAuthority{ - RestrictedDenoms: emauthtypes.RestrictedDenoms{Denoms: []emauthtypes.RestrictedDenom{ - {"gbp", []string{}}, - {"usd", []string{acc1.GetAddress().String()}}, - }}, - } - - k.initializeFromStore(ctx) - - var liquidTrxFee sdk.Gas - k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - - gasMeter := sdk.NewGasMeter(math.MaxUint64) - // Ensure that no orders can be created, even though acc1 is allowed to create usd orders - o := order(ctx.BlockTime(), acc1, "542usd", "500gbp") - _, err := k.NewOrderSingle(ctx.WithGasMeter(gasMeter), o) - require.NoError(t, err) - // require.Empty(t, k.instruments) - require.Equal(t, liquidTrxFee, gasMeter.GasConsumed()) - - o = order(ctx.BlockTime(), acc1, "500gbp", "542usd") - _, err = k.NewOrderSingle(ctx, o) - require.NoError(t, err) - // require.Empty(t, k.instruments) -} - func TestSyntheticInstruments1(t *testing.T) { ctx, k, ak, bk := createTestComponents(t) acc1 := createAccount(ctx, ak, bk, randomAddress(), "5000eur") @@ -2492,15 +2443,11 @@ func createTestComponentsWithEncoding(t *testing.T, encConfig simappparams.Encod encConfig.Marshaler, keyBank, ak, pk.Subspace(banktypes.ModuleName), blockedAddr, ) - wrappedBank = embank.Wrap(bk, embank.RestrictedKeeperFunc(func(ctx sdk.Context) emauthtypes.RestrictedDenoms { - return emauthtypes.RestrictedDenoms{} // allow all - })) + wrappedBank = embank.Wrap(bk) - marketKeeper = NewKeeper( - encConfig.Marshaler, keyMarket, keyIndices, ak, wrappedBank, - dummyAuthority{}, - pk.Subspace(types.ModuleName), - ) + marketKeeper = NewKeeper(encConfig.Marshaler, keyMarket, keyIndices, ak, + wrappedBank, + pk.Subspace(types.ModuleName)) ) marketKeeper.InitParamsStore(ctx) @@ -2537,14 +2484,6 @@ func MakeTestEncodingConfig() simappparams.EncodingConfig { return encodingConfig } -type dummyAuthority struct { - RestrictedDenoms emauthtypes.RestrictedDenoms -} - -func (da dummyAuthority) GetRestrictedDenoms(sdk.Context) emauthtypes.RestrictedDenoms { - return da.RestrictedDenoms -} - func coin(s string) sdk.Coin { coin, err := sdk.ParseCoinNormalized(s) if err != nil { @@ -2564,7 +2503,7 @@ func coins(s string) sdk.Coins { func order(createdTm time.Time, account authtypes.AccountI, src, dst string) types.Order { o, err := types.NewOrder( createdTm, types.TimeInForce_GoodTillCancel, coin(src), coin(dst), - account.GetAddress(), cid(), time.Time{}, + account.GetAddress(), cid(), ) if err != nil { panic(err) diff --git a/x/market/keeper/msg_server.go b/x/market/keeper/msg_server.go index bbc7d4d3..4e1849db 100644 --- a/x/market/keeper/msg_server.go +++ b/x/market/keeper/msg_server.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/e-money/em-ledger/x/market/types" @@ -12,11 +11,10 @@ import ( var _ types.MsgServer = msgServer{} type marketKeeper interface { - NewMarketOrderWithSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) NewOrderSingle(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) CancelOrder(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrder(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) - CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) + GetSrcFromSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) OrderSpendGas(ctx sdk.Context, order *types.Order, origOrderCreated time.Time, orderGasMeter sdk.GasMeter, callerErr *error) } type msgServer struct { @@ -43,7 +41,7 @@ func (m msgServer) AddLimitOrder( order, err = types.NewOrder( ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, - msg.ClientOrderId, time.Time{}, + msg.ClientOrderId, ) if err != nil { @@ -64,19 +62,23 @@ func (m msgServer) AddLimitOrder( func (m msgServer) AddMarketOrder(c context.Context, msg *types.MsgAddMarketOrder) (*types.MsgAddMarketOrderResponse, error) { ctx := sdk.UnwrapSDKContext(c) - owner, err := sdk.AccAddressFromBech32(msg.Owner) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") - } - result, err := m.k.NewMarketOrderWithSlippage(ctx, msg.Source, msg.Destination, msg.MaxSlippage, owner, msg.TimeInForce, msg.ClientOrderId) + slippageSource, err := m.k.GetSrcFromSlippage( + ctx, msg.Source, msg.Destination, msg.MaxSlippage, + ) if err != nil { return nil, err } - for _, e := range result.Events { - ctx.EventManager().EmitEvent(sdk.Event(e)) + + limitMsg := &types.MsgAddLimitOrder{ + Owner: msg.Owner, + ClientOrderId: msg.ClientOrderId, + TimeInForce: msg.TimeInForce, + Source: slippageSource, + Destination: msg.Destination, } - return &types.MsgAddMarketOrderResponse{}, nil + _, err = m.AddLimitOrder(c, limitMsg) + return &types.MsgAddMarketOrderResponse{}, err } func (m msgServer) CancelOrder(c context.Context, msg *types.MsgCancelOrder) (*types.MsgCancelOrderResponse, error) { @@ -103,10 +105,7 @@ func (m msgServer) CancelReplaceLimitOrder(c context.Context, msg *types.MsgCanc if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "owner") } - order, err := types.NewOrder( - ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, - msg.NewClientOrderId, time.Time{}, - ) + order, err := types.NewOrder(ctx.BlockTime(), msg.TimeInForce, msg.Source, msg.Destination, owner, msg.NewClientOrderId) if err != nil { return nil, err } @@ -124,25 +123,26 @@ func (m msgServer) CancelReplaceLimitOrder(c context.Context, msg *types.MsgCanc func (m msgServer) CancelReplaceMarketOrder(c context.Context, msg *types.MsgCancelReplaceMarketOrder) (*types.MsgCancelReplaceMarketOrderResponse, error) { ctx := sdk.UnwrapSDKContext(c) - _, err := sdk.AccAddressFromBech32(msg.Owner) - if err != nil { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, fmt.Sprintf("invalid owner value:%s", msg.Owner)) - } if msg.Destination.Amount.LTE(sdk.ZeroInt()) { return nil, sdkerrors.Wrapf(types.ErrInvalidPrice, "Destination %s price is Zero or less: %s", msg.Destination.Denom, msg.Destination.Amount) } - if msg.TimeInForce <= types.TimeInForce_Unspecified || msg.TimeInForce > types.TimeInForce_FillOrKill { - return nil, sdkerrors.Wrapf(types.ErrUnknownTimeInForce, "Invalid Time In Force: %d", msg.TimeInForce) - } - - result, err := m.k.CancelReplaceMarketOrder(ctx, msg) + slippageSource, err := m.k.GetSrcFromSlippage( + ctx, msg.Source, msg.Destination, msg.MaxSlippage, + ) if err != nil { return nil, err } - for _, e := range result.Events { - ctx.EventManager().EmitEvent(sdk.Event(e)) + + limitMsg := &types.MsgCancelReplaceLimitOrder{ + Owner: msg.Owner, + OrigClientOrderId: msg.OrigClientOrderId, + NewClientOrderId: msg.NewClientOrderId, + TimeInForce: msg.TimeInForce, + Source: slippageSource, + Destination: msg.Destination, } - return &types.MsgCancelReplaceMarketOrderResponse{}, nil + _, err = m.CancelReplaceLimitOrder(c, limitMsg) + return &types.MsgCancelReplaceMarketOrderResponse{}, err } diff --git a/x/market/keeper/msg_server_test.go b/x/market/keeper/msg_server_test.go index a83a9f73..1ea505f7 100644 --- a/x/market/keeper/msg_server_test.go +++ b/x/market/keeper/msg_server_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/e-money/em-ledger/x/market/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -114,34 +115,40 @@ func TestAddLimitOrder(t *testing.T) { func TestAddMarketOrder(t *testing.T) { var ( ownerAddr = randomAccAddress() - gotDenom string + gotSrc sdk.Coin gotDst sdk.Coin gotMaxSlippage sdk.Dec - gotOwner sdk.AccAddress - gotTimeInForce types.TimeInForce - gotClientOrderId string + gotOrder types.Order ) keeper := marketKeeperMock{} svr := NewMsgServerImpl(&keeper) specs := map[string]struct { - req *types.MsgAddMarketOrder - mockFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) - expErr bool - expEvents sdk.Events + req *types.MsgAddMarketOrder + mockAddLimitOrderFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) + mockGetSrcFromSlippageFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) + expErr bool + expSrc sdk.Coin + expEvents sdk.Events + expOrder types.Order }{ "all good": { req: &types.MsgAddMarketOrder{ Owner: ownerAddr.String(), ClientOrderId: "myClientIOrderID", TimeInForce: types.TimeInForce_FillOrKill, - Source: "eur", + Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, - mockFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { - gotDenom, gotDst, gotMaxSlippage, gotOwner, gotTimeInForce, gotClientOrderId = srcDenom, dst, maxSlippage, owner, timeInForce, clientOrderId + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + gotDst, gotMaxSlippage = dst, maxSlippage + return gotSrc, nil + }, + mockAddLimitOrderFn: func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { + gotOrder = aggressiveOrder return &sdk.Result{ Events: []abcitypes.Event{{ Type: "testing", @@ -153,14 +160,44 @@ func TestAddMarketOrder(t *testing.T) { Type: "testing", Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}, }}, + expSrc: sdk.NewCoin("eeur", sdk.OneInt()), + expOrder: types.Order{ + TimeInForce: types.TimeInForce_FillOrKill, + Owner: ownerAddr.String(), + ClientOrderID: "myClientIOrderID", + Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, + SourceRemaining: sdk.OneInt(), + SourceFilled: sdk.ZeroInt(), + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + DestinationFilled: sdk.ZeroInt(), + }, }, "owner missing": { req: &types.MsgAddMarketOrder{ ClientOrderId: "myClientIOrderID", TimeInForce: types.TimeInForce_FillOrKill, + Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + gotDst, gotMaxSlippage = dst, maxSlippage + return gotSrc, nil + }, + expErr: true, + }, + "slippage func fails": { + req: &types.MsgAddMarketOrder{ + ClientOrderId: "myClientIOrderID", + TimeInForce: types.TimeInForce_FillOrKill, + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + MaxSlippage: sdk.NewDec(10), + }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + return sdk.Coin{}, sdkerrors.Wrap(types.ErrInvalidInstrument, "xxx") + }, expErr: true, }, "owner invalid": { @@ -168,9 +205,15 @@ func TestAddMarketOrder(t *testing.T) { Owner: "invalid", ClientOrderId: "myClientIOrderID", TimeInForce: types.TimeInForce_FillOrKill, + Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + gotDst, gotMaxSlippage = dst, maxSlippage + return gotSrc, nil + }, expErr: true, }, "processing failure": { @@ -178,10 +221,15 @@ func TestAddMarketOrder(t *testing.T) { Owner: ownerAddr.String(), ClientOrderId: "myClientIOrderID", TimeInForce: types.TimeInForce_FillOrKill, + Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, - mockFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec, owner sdk.AccAddress, timeInForce types.TimeInForce, clientOrderId string) (*sdk.Result, error) { + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + return gotSrc, nil + }, + mockAddLimitOrderFn: func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) { return nil, errors.New("testing") }, expErr: true, @@ -189,7 +237,8 @@ func TestAddMarketOrder(t *testing.T) { } for name, spec := range specs { t.Run(name, func(t *testing.T) { - keeper.NewMarketOrderWithSlippageFn = spec.mockFn + keeper.GetSrcFromSlippageFn = spec.mockGetSrcFromSlippageFn + keeper.NewOrderSingleFn = spec.mockAddLimitOrderFn eventManager := sdk.NewEventManager() ctx := sdk.Context{}.WithContext(context.Background()).WithEventManager(eventManager) _, gotErr := svr.AddMarketOrder(sdk.WrapSDKContext(ctx), spec.req) @@ -198,13 +247,11 @@ func TestAddMarketOrder(t *testing.T) { return } require.NoError(t, gotErr) + require.Equal(t, spec.expOrder.String(), gotOrder.String()) assert.Equal(t, spec.expEvents, eventManager.Events()) - assert.Equal(t, spec.req.Source, gotDenom) + assert.Equal(t, spec.expSrc, gotSrc) assert.Equal(t, spec.req.Destination, gotDst) assert.Equal(t, spec.req.MaxSlippage, gotMaxSlippage) - assert.Equal(t, ownerAddr, gotOwner) - assert.Equal(t, spec.req.TimeInForce, gotTimeInForce) - assert.Equal(t, spec.req.ClientOrderId, gotClientOrderId) }) } } @@ -399,7 +446,8 @@ func TestCancelReplaceLimitOrder(t *testing.T) { func TestCancelReplaceMarketOrder(t *testing.T) { var ( ownerAddr = randomAccAddress() - gotMsg *types.MsgCancelReplaceMarketOrder + gotOrder types.Order + gotSrc sdk.Coin gotOrigClientOrderId string ) @@ -407,11 +455,13 @@ func TestCancelReplaceMarketOrder(t *testing.T) { svr := NewMsgServerImpl(&keeper) specs := map[string]struct { - req *types.MsgCancelReplaceMarketOrder - mockFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) - expErr bool - expEvents sdk.Events - expMsg *types.MsgCancelReplaceMarketOrder + req *types.MsgCancelReplaceMarketOrder + mockGetSrcFromSlippageFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) + mockCancelReplaceLimitOrderFn func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) + expErr bool + expEvents sdk.Events + expSrc sdk.Coin + expOrder types.Order }{ "all good": { req: &types.MsgCancelReplaceMarketOrder{ @@ -423,8 +473,12 @@ func TestCancelReplaceMarketOrder(t *testing.T) { Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, - mockFn: func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { - gotMsg, gotOrigClientOrderId = msg, msg.OrigClientOrderId + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + return gotSrc, nil + }, + mockCancelReplaceLimitOrderFn: func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) { + gotOrder, gotOrigClientOrderId = newOrder, origClientOrderId return &sdk.Result{ Events: []abcitypes.Event{{ Type: "testing", @@ -436,14 +490,16 @@ func TestCancelReplaceMarketOrder(t *testing.T) { Type: "testing", Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}}, }}, - expMsg: &types.MsgCancelReplaceMarketOrder{ - Owner: ownerAddr.String(), - OrigClientOrderId: "origClientID", - NewClientOrderId: "myNewClientID", + expSrc: sdk.NewCoin("eeur", sdk.OneInt()), + expOrder: types.Order{ TimeInForce: types.TimeInForce_ImmediateOrCancel, - Source: "eeur", + Owner: ownerAddr.String(), + ClientOrderID: "myNewClientID", + Source: sdk.Coin{Denom: "eeur", Amount: sdk.OneInt()}, + SourceRemaining: sdk.OneInt(), + SourceFilled: sdk.ZeroInt(), Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, - MaxSlippage: sdk.NewDec(10), + DestinationFilled: sdk.ZeroInt(), }, }, "Time In Force invalid": { @@ -456,6 +512,10 @@ func TestCancelReplaceMarketOrder(t *testing.T) { Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, MaxSlippage: sdk.NewDec(10), }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + return gotSrc, nil + }, expErr: true, }, "owner missing": { @@ -465,6 +525,10 @@ func TestCancelReplaceMarketOrder(t *testing.T) { Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + return gotSrc, nil + }, expErr: true, }, "owner invalid": { @@ -475,6 +539,25 @@ func TestCancelReplaceMarketOrder(t *testing.T) { Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + gotSrc = sdk.NewCoin(srcDenom, sdk.OneInt()) + return gotSrc, nil + }, + expErr: true, + }, + "slippage func fails": { + req: &types.MsgCancelReplaceMarketOrder{ + Owner: ownerAddr.String(), + OrigClientOrderId: "origClientID", + NewClientOrderId: "myNewClientID", + TimeInForce: types.TimeInForce_ImmediateOrCancel, + Source: "eeur", + Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, + MaxSlippage: sdk.NewDec(10), + }, + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + return sdk.Coin{}, sdkerrors.Wrap(types.ErrInvalidInstrument, "xxx") + }, expErr: true, }, "processing failure": { @@ -485,15 +568,16 @@ func TestCancelReplaceMarketOrder(t *testing.T) { Source: "eeur", Destination: sdk.Coin{Denom: "alx", Amount: sdk.OneInt()}, }, - mockFn: func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { - return nil, errors.New("testing") + mockGetSrcFromSlippageFn: func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + return sdk.Coin{}, errors.New("testing") }, expErr: true, }, } for name, spec := range specs { t.Run(name, func(t *testing.T) { - keeper.CancelReplaceMarketOrderFn = spec.mockFn + keeper.GetSrcFromSlippageFn = spec.mockGetSrcFromSlippageFn + keeper.CancelReplaceLimitOrderFn = spec.mockCancelReplaceLimitOrderFn eventManager := sdk.NewEventManager() ctx := sdk.Context{}.WithContext(context.Background()).WithEventManager(eventManager) _, gotErr := svr.CancelReplaceMarketOrder(sdk.WrapSDKContext(ctx), spec.req) @@ -503,7 +587,8 @@ func TestCancelReplaceMarketOrder(t *testing.T) { } require.NoError(t, gotErr) assert.Equal(t, spec.expEvents, eventManager.Events()) - assert.Equal(t, spec.expMsg, gotMsg) + assert.Equal(t, spec.expSrc.String(), gotSrc.String()) + assert.Equal(t, spec.expOrder, gotOrder) assert.Equal(t, spec.req.OrigClientOrderId, gotOrigClientOrderId) }) } @@ -514,7 +599,7 @@ type marketKeeperMock struct { NewOrderSingleFn func(ctx sdk.Context, aggressiveOrder types.Order) (*sdk.Result, error) CancelOrderFn func(ctx sdk.Context, owner sdk.AccAddress, clientOrderId string) (*sdk.Result, error) CancelReplaceLimitOrderFn func(ctx sdk.Context, newOrder types.Order, origClientOrderId string) (*sdk.Result, error) - CancelReplaceMarketOrderFn func(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) + GetSrcFromSlippageFn func(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) } func (m marketKeeperMock) OrderSpendGas( @@ -551,11 +636,11 @@ func (m marketKeeperMock) CancelReplaceLimitOrder(ctx sdk.Context, newOrder type return m.CancelReplaceLimitOrderFn(ctx, newOrder, origClientOrderId) } -func (m marketKeeperMock) CancelReplaceMarketOrder(ctx sdk.Context, msg *types.MsgCancelReplaceMarketOrder) (*sdk.Result, error) { - if m.CancelReplaceMarketOrderFn == nil { +func (m marketKeeperMock) GetSrcFromSlippage(ctx sdk.Context, srcDenom string, dst sdk.Coin, maxSlippage sdk.Dec) (sdk.Coin, error) { + if m.GetSrcFromSlippageFn == nil { panic("not expected to be called") } - return m.CancelReplaceMarketOrderFn(ctx, msg) + return m.GetSrcFromSlippageFn(ctx, srcDenom, dst, maxSlippage) } func randomAccAddress() sdk.AccAddress { diff --git a/x/market/types/expected_keepers.go b/x/market/types/expected_keepers.go index 04474a4c..fbc11a38 100644 --- a/x/market/types/expected_keepers.go +++ b/x/market/types/expected_keepers.go @@ -9,7 +9,6 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/bank/exported" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - emauthtypes "github.com/e-money/em-ledger/x/authority/types" ) type ( @@ -24,8 +23,4 @@ type ( GetSupply(ctx sdk.Context) exported.SupplyI AddBalanceListener(l func(sdk.Context, []sdk.AccAddress)) } - - RestrictedKeeper interface { - GetRestrictedDenoms(sdk.Context) emauthtypes.RestrictedDenoms - } ) diff --git a/x/market/types/types.go b/x/market/types/types.go index 7272f323..d6407720 100644 --- a/x/market/types/types.go +++ b/x/market/types/types.go @@ -132,8 +132,7 @@ func NewOrder( timeInForce TimeInForce, src, dst sdk.Coin, seller sdk.AccAddress, - clientOrderId string, - origOrderCreated time.Time) (Order, error) { + clientOrderId string) (Order, error) { if src.Amount.LTE(sdk.ZeroInt()) || dst.Amount.LTE(sdk.ZeroInt()) { return Order{}, sdkerrors.Wrapf(ErrInvalidPrice, "Order price is invalid: %s -> %s", src.Amount, dst.Amount) diff --git a/x/market/types/types_test.go b/x/market/types/types_test.go index cd51736a..d3a22033 100644 --- a/x/market/types/types_test.go +++ b/x/market/types/types_test.go @@ -17,7 +17,7 @@ func TestSerialization(t *testing.T) { tm := time.Now() order1, _ := NewOrder( tm, TimeInForce_GoodTillCancel, coin("100eur"), coin("120usd"), - []byte("acc1"), "A", time.Time{}, + []byte("acc1"), "A", ) order1.ID = 3123 order1.SourceRemaining = sdk.NewInt(50) @@ -60,21 +60,21 @@ func TestInvalidOrder(t *testing.T) { // 0 amount source _, err := NewOrder( time.Now(), TimeInForce_GoodTillCancel, coin("0eur"), coin("120usd"), - []byte("acc"), "A", time.Time{}, + []byte("acc"), "A", ) require.Error(t, err) // 0 amount destination _, err = NewOrder( time.Now(), TimeInForce_GoodTillCancel, coin("120eur"), coin("0usd"), - []byte("acc"), "A", time.Time{}, + []byte("acc"), "A", ) require.Error(t, err) // Same denomination _, err = NewOrder( time.Now(), TimeInForce_GoodTillCancel, coin("1000eur"), coin("850eur"), - []byte("acc"), "A", time.Time{}, + []byte("acc"), "A", ) require.Error(t, err) @@ -86,7 +86,7 @@ func TestInvalidOrder(t *testing.T) { // Negative source _, err = NewOrder( time.Now(), TimeInForce_GoodTillCancel, c, coin("120usd"), - []byte("acc"), "B", time.Time{}, + []byte("acc"), "B", ) require.Error(t, err) } diff --git a/x/slashing/keeper/abci_test.go b/x/slashing/keeper/abci_test.go index e213829d..bc91ea7a 100644 --- a/x/slashing/keeper/abci_test.go +++ b/x/slashing/keeper/abci_test.go @@ -29,7 +29,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" embank "github.com/e-money/em-ledger/hooks/bank" apptypes "github.com/e-money/em-ledger/types" - emauthtypes "github.com/e-money/em-ledger/x/authority/types" "github.com/e-money/em-ledger/x/slashing/types" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -245,12 +244,8 @@ func createTestComponents(t *testing.T) (sdk.Context, Keeper, banktypes.AccountK ak = authkeeper.NewAccountKeeper( encConfig.Marshaler, authCapKey, pk.Subspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, ) - allowAllDenoms = embank.RestrictedKeeperFunc(func(context sdk.Context) emauthtypes.RestrictedDenoms { - return emauthtypes.RestrictedDenoms{} - }) - bk = embank.Wrap(bankkeeper.NewBaseKeeper( - encConfig.Marshaler, bankKey, ak, pk.Subspace(banktypes.ModuleName), blockedAddr, - ), allowAllDenoms) + + bk = embank.Wrap(bankkeeper.NewBaseKeeper(encConfig.Marshaler, bankKey, ak, pk.Subspace(banktypes.ModuleName), blockedAddr)) sk = stakingkeeper.NewKeeper(encConfig.Marshaler, stakingKey, ak, bk, pk.Subspace(stakingtypes.ModuleName)) ) From c8baf6a1b680c13dd24efe711ccc4b3042e69e79 Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Tue, 1 Jun 2021 22:25:34 +0300 Subject: [PATCH 40/41] Adjust tests without ante handler --- app_test.go | 15 ++++++++++---- x/market/keeper/keeper.go | 18 +++++++++++++---- x/market/keeper/keeper_test.go | 36 ++++++++++++++++++---------------- x/market/types/types.go | 2 +- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/app_test.go b/app_test.go index 35f50bf4..fa42f118 100644 --- a/app_test.go +++ b/app_test.go @@ -58,6 +58,9 @@ func coins(s string) sdk.Coins { } func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { + // Gas cost expended before entering the market module. + const gasStartingCost = 55914 + ctx, app, enc := setupMarketApp(t, []func(*baseapp.BaseApp){}...) require.NotNil(t, app) @@ -123,10 +126,11 @@ func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { gasInfo, _, err := app.Deliver(enc.TxConfig.TxEncoder(), tx) require.NoError(t, err) - require.Equal(t, gasInfo.GasUsed, sdk.Gas(0)) + t.Log(gasInfo.GasUsed) + require.Equal(t, gasInfo.GasUsed, sdk.Gas(gasStartingCost)) // - // Destination denomination xxx does not exist and errs, full gas + // Destination denomination xxx does not exist and errs // msg2 := &types.MsgAddLimitOrder{ TimeInForce: types.TimeInForce_GoodTillCancel, @@ -140,7 +144,8 @@ func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { gasInfo, _, err = app.Deliver(enc.TxConfig.TxEncoder(), tx) require.Error(t, err) - require.Equal(t, gasInfo.GasUsed, sdk.Gas(25000)) + t.Log(gasInfo.GasUsed) + require.Less(t, sdk.Gas(gasStartingCost), gasInfo.GasUsed) msg3 := &types.MsgAddLimitOrder{ TimeInForce: types.TimeInForce_GoodTillCancel, @@ -150,11 +155,13 @@ func TestAppLimitOrder_0_Full_Err_Gas(t *testing.T) { ClientOrderId: "testAddLimitOrder-eur-chf", } + ctx = ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) tx = getSignedTrx(ctx, t, app.accountKeeper, enc, msg3, keystore2, acct2, 0, 0) gasInfo, _, err = app.Deliver(enc.TxConfig.TxEncoder(), tx) require.NoError(t, err) - require.Equal(t, sdk.Gas(0), gasInfo.GasUsed) + t.Log(gasInfo.GasUsed) + require.Less(t, sdk.Gas(gasStartingCost), gasInfo.GasUsed) } func getSignedTrx( diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index fbdd1265..63d37686 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -469,7 +469,7 @@ func (k *Keeper) OrderSpendGas( // Non-liquidity adding order if order.TimeInForce != types.TimeInForce_GoodTillCancel { orderGasMeter.ConsumeGas( - stdTrxFee, fmt.Sprintf("FOK, IOC orders cost the full gas"), + stdTrxFee, "FOK, IOC orders cost the full gas", ) return @@ -485,20 +485,23 @@ func (k *Keeper) OrderSpendGas( // Rebate candidate var orderGas sdk.Gas + var gasMsg string if origOrderCreated.IsZero() { orderGas = k.calcOrderGas( ctx, stdTrxFee, order.DestinationFilled, order.Destination.Amount, ) + gasMsg = fmt.Sprintf("aggressive order gas:%d", orderGas) } else { orderGas = k.calcReplaceOrderGas( ctx, order.DestinationFilled, order.Destination.Amount, origOrderCreated, ) + gasMsg = fmt.Sprintf("replacing order gas:%d", orderGas) } orderGasMeter.ConsumeGas( - orderGas, fmt.Sprintf("cannot cover order %d gas", orderGas), + orderGas, gasMsg, ) } @@ -508,9 +511,16 @@ func (k *Keeper) CancelReplaceLimitOrder( orderGasMeter := ctx.GasMeter() ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + // failed decoding of the original order results in panic origOrder := k.GetOrderByOwnerAndClientOrderId(ctx, newOrder.Owner, origClientOrderId) - defer k.OrderSpendGas(ctx, &newOrder, origOrder.Created, orderGasMeter, &err) + // origOrder could be nil + origOrderCreated := time.Time{} + if origOrder != nil { + origOrderCreated = origOrder.Created + } + + defer k.OrderSpendGas(ctx, &newOrder, origOrderCreated, orderGasMeter, &err) if origOrder == nil { return nil, sdkerrors.Wrap(types.ErrClientOrderIdNotFound, origClientOrderId) @@ -542,7 +552,7 @@ func (k *Keeper) CancelReplaceLimitOrder( newOrder.TimeInForce = origOrder.TimeInForce // pass in the meter we will charge Gas. - resAdd, err := k.NewOrderSingle(ctx.WithGasMeter(orderGasMeter), newOrder) + resAdd, err := k.NewOrderSingle(ctx, newOrder) if err != nil { return nil, err } diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index 41c5be3a..e9d7db0d 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -439,8 +439,6 @@ func TestCancelReplaceMarketOrder100Slippage(t *testing.T) { clientID := limitOrder.ClientOrderID - acc1b = bk.GetAllBalances(ctx, acc1.GetAddress()) - // Gave 1 gbp and gained a eur acc1Bal := bk.GetAllBalances(ctx, acc1.GetAddress()) require.Equal(t, coins("20eur,90gbp").String(), acc1Bal.String()) @@ -541,14 +539,14 @@ func TestGetSrcFromSlippage(t *testing.T) { srcDenom = "jpy" dest = sdk.NewCoin("eur", sdk.NewInt(100)) - slippedSource, err = k.GetSrcFromSlippage( + _, err = k.GetSrcFromSlippage( ctx, srcDenom, dest, sdk.ZeroDec(), ) require.Error(t, err, "No trades yet with jpy") srcDenom = "gbp" dest = sdk.NewCoin("dek", sdk.NewInt(100)) - slippedSource, err = k.GetSrcFromSlippage( + _, err = k.GetSrcFromSlippage( ctx, srcDenom, dest, sdk.ZeroDec(), ) require.Error(t, err, "No trades yet with dek") @@ -557,7 +555,7 @@ func TestGetSrcFromSlippage(t *testing.T) { srcDenom = "gbp" dest = sdk.NewCoin("eur", sdk.NewInt(100)) - slippedSource, err = k.GetSrcFromSlippage( + _, err = k.GetSrcFromSlippage( ctx, srcDenom, dest, slippage, ) require.Error(t, err) @@ -825,7 +823,7 @@ func TestInsufficientGas(t *testing.T) { require.Panics(t, func() { // Taking away liquidity not enough to cover the full Trx fee - k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) + _, _ = k.NewOrderSingle(ctx.WithGasMeter(gasMeter), order2) }) require.Equal(t, stdTrxFee, gasMeter.GasConsumed()) } @@ -1123,6 +1121,10 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { coin("5000usd"), acc1.GetAddress(), cid(), ) require.NoError(t, err) + require.Equal( + t, liquidTrxFee, gasMeter.GasConsumed(), + "Liquid trx changed instrument eur->chf", + ) // Wrong client order id for previous order submitted. _, err = k.CancelReplaceLimitOrder(ctx.WithGasMeter(gasMeter), order3, order1cid) @@ -1163,7 +1165,7 @@ func TestKeeperLimitOrderLiquidFullGas(t *testing.T) { coin("3000usd"), acc1.GetAddress(), order4cid, ) ctx = ctx.WithGasMeter(gasMeter) - res, err = k.CancelReplaceLimitOrder( + _, err = k.CancelReplaceLimitOrder( ctx.WithBlockTime(ctx.BlockTime().Add( time.Duration(qualificationMin)*time.Minute)), order4, order2cid, @@ -1342,7 +1344,7 @@ func TestKeeperReplaceLimitFullLiquidGas(t *testing.T) { // CancelReplace with an order that asks for a larger source than the replaced order has remaining order5 := order(ctx.BlockTime(), acc2, "42000usd", "8000eur") - k.NewOrderSingle(ctx, order5) + _, err = k.NewOrderSingle(ctx, order5) require.True(t, err == nil, res.Log) order6 := order(ctx.BlockTime(), acc1, "8000eur", "30000usd") @@ -1356,8 +1358,7 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { acc1 := createAccount(ctx, ak, bk, randomAddress(), "500gbp") acc2 := createAccount(ctx, ak, bk, randomAddress(), "500eur") - trxPms := k.GetParams(ctx) - var stdTrxFee uint64 = trxPms.GetTrxFee() + var liquidTrxFee uint64 = k.GetLiquidTrxFee(ctx) var o types.Order var err error @@ -1372,7 +1373,6 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { require.NoError(t, err) // Make a market order that allows slippage - clientID := cid() slippage := sdk.NewDecWithPrec(100, 2) srcDenom := "gbp" dest := sdk.NewCoin("eur", sdk.NewInt(100)) @@ -1384,7 +1384,7 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { _, err = k.NewOrderSingle(ctx, limitOrder) require.NoError(t, err) foundOrder := k.GetOrderByOwnerAndClientOrderId( - ctx, acc1.GetAddress().String(), clientID, + ctx, acc1.GetAddress().String(), limitOrder.ClientOrderID, ) require.NotNil(t, foundOrder, "Market order should exist") // 100% slippage to double source @@ -1404,12 +1404,15 @@ func TestReplaceMarketOrderErrGas(t *testing.T) { limitOrder = order(ctx.BlockTime(), acc1, slippageSource.String(), dest.String()) gasMeter := sdk.NewInfiniteGasMeter() ctx = ctx.WithGasMeter(gasMeter) + // panic execution of single order k.bk = nil require.Panics(t, func() { - // panic CancelReplace - k.NewOrderSingle(ctx, limitOrder) + _, _ = k.NewOrderSingle(ctx, limitOrder) }) - require.Equal(t, stdTrxFee, ctx.GasMeter().GasConsumed()) + require.Equal( + t, liquidTrxFee, + ctx.GasMeter().GasConsumed(), "Panic gas consumption is unpredictable", + ) } func TestCancelNewLimitFullGas(t *testing.T) { @@ -1467,7 +1470,6 @@ func TestCancelNewMarketFullGas(t *testing.T) { gasMeter = sdk.NewGasMeter(math.MaxUint64) slippage := sdk.NewDecWithPrec(50, 2) - cid := cid() srcDenom := "gbp" dest := sdk.NewCoin("eur", sdk.NewInt(200)) slippageSource, err := k.GetSrcFromSlippage( @@ -1479,7 +1481,7 @@ func TestCancelNewMarketFullGas(t *testing.T) { require.NoError(t, err) require.Equal(t, liquidTrxFee, gasMeter.GasConsumed(), "Non-filled-Liquid") - _, err = k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), cid) + _, err = k.CancelOrder(ctx.WithGasMeter(gasMeter), acc1.GetAddress(), limitOrder.ClientOrderID) require.NoError(t, err) require.Equal(t, stdTrxFee, gasMeter.GasConsumed(), "Cancel pays std fee") } diff --git a/x/market/types/types.go b/x/market/types/types.go index d6407720..d853a3b7 100644 --- a/x/market/types/types.go +++ b/x/market/types/types.go @@ -85,7 +85,7 @@ func (o Order) Price() sdk.Dec { } func (o Order) String() string { - return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\nOriginal Order Created:%v", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created) + return fmt.Sprintf("%d : %v -> %v @ %v\n(%v%v remaining) (%v%v filled) (%v%v filled)\n%v\nCreated:%v\n", o.ID, o.Source, o.Destination, o.Price(), o.SourceRemaining, o.Source.Denom, o.SourceFilled, o.Source.Denom, o.DestinationFilled, o.Destination.Denom, o.Owner, o.Created) } func (ep ExecutionPlan) DestinationCapacity() sdk.Dec { From 45d2fbf3c02e477183c4147dd4ca70180cc29fbe Mon Sep 17 00:00:00 2001 From: Mario Karagiorgas Date: Wed, 2 Jun 2021 12:08:45 +0300 Subject: [PATCH 41/41] #51 Add unit test --- x/market/keeper/keeper.go | 2 - x/market/keeper/keeper_test.go | 88 +++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/x/market/keeper/keeper.go b/x/market/keeper/keeper.go index 63d37686..0fb77fad 100644 --- a/x/market/keeper/keeper.go +++ b/x/market/keeper/keeper.go @@ -158,8 +158,6 @@ func (k *Keeper) calcOrderGas( var liquidTrxFee sdk.Gas k.paramStore.Get(ctx, types.KeyLiquidTrxFee, &liquidTrxFee) - // TODO is destination sufficient to evaluate the total filling impact - // for limit/market orders? if dstFilled.IsZero() { // 0% fill -> 100% totalRebate return liquidTrxFee diff --git a/x/market/keeper/keeper_test.go b/x/market/keeper/keeper_test.go index e9d7db0d..3edac0ef 100644 --- a/x/market/keeper/keeper_test.go +++ b/x/market/keeper/keeper_test.go @@ -53,7 +53,6 @@ func TestKeeper_calcOrderGas(t *testing.T) { var ( stdTrxFee sdk.Gas = k.GetTrxFee(ctx) liquidTrxFee sdk.Gas = k.GetLiquidTrxFee(ctx) - //liquidIntervalMin int64 = k.GetLiquidityRebateMinutesSpan(ctx) ) tests := []struct { name string @@ -108,6 +107,93 @@ func TestKeeper_calcOrderGas(t *testing.T) { } } +func TestKeeper_calcReplaceOrderGas(t *testing.T) { + ctx, k, _, _ := createTestComponents(t) + + ctx = ctx.WithBlockTime(time.Now()) + + var ( + stdTrxFee sdk.Gas = k.GetTrxFee(ctx) + liquidTrxFee sdk.Gas = k.GetLiquidTrxFee(ctx) + // set ctx to rebate allowance + 1 + liquidIntervalMin = time.Duration(k.GetLiquidityRebateMinutesSpan(ctx)+1) * + time.Minute + ) + + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) + + tests := []struct { + name string + ctx sdk.Context + stdTrxFee sdk.Gas + liquidTrxFee sdk.Gas + dstFilled sdk.Int + dstAmount sdk.Int + origOrderCreated time.Time + want sdk.Gas + }{ + { + name: "0% Filled Full Gas", + ctx: ctx.WithBlockTime(ctx.BlockTime().Add(liquidIntervalMin)), + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(0), + dstAmount: sdk.NewInt(0), + origOrderCreated: time.Now(), + want: liquidTrxFee, + }, + { + name: "0% Filled but not meeting qualified minutes, Full Gas", + ctx: ctx, + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(0), + dstAmount: sdk.NewInt(0), + origOrderCreated: time.Now(), + want: stdTrxFee, + }, + { + name: "100% Filled Full Gas", + ctx: ctx.WithBlockTime(ctx.BlockTime().Add(liquidIntervalMin)), + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(1), + dstAmount: sdk.NewInt(1), + origOrderCreated: time.Now(), + want: stdTrxFee, + }, + { + name: "10% Filled Full Gas", + ctx: ctx.WithBlockTime(ctx.BlockTime().Add(liquidIntervalMin)), + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(10), + dstAmount: sdk.NewInt(100), + origOrderCreated: time.Now(), + want: stdTrxFee / 10, + }, + { + name: "90% Filled Full Gas", + ctx: ctx.WithBlockTime(ctx.BlockTime().Add(liquidIntervalMin)), + stdTrxFee: stdTrxFee, + dstFilled: sdk.NewInt(90), + dstAmount: sdk.NewInt(100), + origOrderCreated: time.Now(), + want: sdk.Gas(float64(stdTrxFee) * 0.9), + }, + } + + for _, tt := range tests { + t.Run( + tt.name, func(t *testing.T) { + if got := k.calcReplaceOrderGas( + tt.ctx, tt.dstFilled, tt.dstAmount, tt.origOrderCreated, + ); got != tt.want { + t.Errorf( + "calcReplaceOrderGas() = %v, want %v", got, tt.want, + ) + } + }, + ) + } +} + func TestBasicTrade(t *testing.T) { ctx, k, ak, bk := createTestComponents(t)