-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CT-520] Validatebasic for new MsgBatchCancel #1101
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package types | ||
|
||
import ( | ||
errorsmod "cosmossdk.io/errors" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
types "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types" | ||
) | ||
|
||
var _ sdk.Msg = &MsgBatchCancel{} | ||
|
||
// NewMsgBatchCancel constructs a MsgBatchCancel. | ||
func NewMsgBatchCancel(subaccountId types.SubaccountId, cancelBatch []OrderBatch, goodTilBlock uint32) *MsgBatchCancel { | ||
return &MsgBatchCancel{ | ||
SubaccountId: subaccountId, | ||
ShortTermCancels: cancelBatch, | ||
GoodTilBlock: goodTilBlock, | ||
} | ||
} | ||
|
||
// ValidateBasic performs stateless validation for the `MsgBatchCancel` msg. | ||
func (msg *MsgBatchCancel) ValidateBasic() (err error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so ValidateBasic is actually optional as of v0.50 - I think it's still supported for backwards compatibility but can you maybe spend 10-15 minutes to see how it works w/ the new version and what was the motivation? kind of curious about this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just wondering if transactions that are obviously wrong (e.g. failing ValidateBasic) can now enter mempool and be included in a block There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like they have moved all validation to the msg server. Example PRS Based on this comment |
||
subaccountId := msg.GetSubaccountId() | ||
if err := subaccountId.Validate(); err != nil { | ||
return err | ||
} | ||
|
||
cancelBatches := msg.GetShortTermCancels() | ||
if len(cancelBatches) == 0 { | ||
return errorsmod.Wrapf( | ||
ErrInvalidBatchCancel, | ||
"Batch cancel cannot have zero orders specified.", | ||
) | ||
} | ||
totalNumberCancels := 0 | ||
for _, cancelBatch := range cancelBatches { | ||
numClientIds := len(cancelBatch.GetClientIds()) | ||
if numClientIds == 0 { | ||
return errorsmod.Wrapf( | ||
ErrInvalidBatchCancel, | ||
"Order Batch cannot have zero client ids.", | ||
) | ||
} | ||
totalNumberCancels += numClientIds | ||
seenClientIds := map[uint32]struct{}{} | ||
for _, clientId := range cancelBatch.GetClientIds() { | ||
if _, seen := seenClientIds[clientId]; seen { | ||
return errorsmod.Wrapf( | ||
ErrInvalidBatchCancel, | ||
"Batch cancel cannot have duplicate cancels. Duplicate clob pair id: %+v, client id: %+v", | ||
cancelBatch.GetClobPairId(), | ||
clientId, | ||
) | ||
} | ||
seenClientIds[clientId] = struct{}{} | ||
} | ||
} | ||
if uint32(totalNumberCancels) > MaxMsgBatchCancelBatchSize { | ||
return errorsmod.Wrapf( | ||
ErrInvalidBatchCancel, | ||
"Batch cancel cannot have over %+v orders. Order count: %+v", | ||
MaxMsgBatchCancelBatchSize, | ||
totalNumberCancels, | ||
) | ||
} | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package types_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/dydxprotocol/v4-chain/protocol/testutil/constants" | ||
"github.com/dydxprotocol/v4-chain/protocol/x/clob/types" | ||
satypes "github.com/dydxprotocol/v4-chain/protocol/x/subaccounts/types" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestMsgBatchCancel_ValidateBasic(t *testing.T) { | ||
oneOverMax := []uint32{} | ||
for i := uint32(0); i < types.MaxMsgBatchCancelBatchSize+1; i++ { | ||
oneOverMax = append(oneOverMax, i) | ||
} | ||
|
||
tests := map[string]struct { | ||
msg types.MsgBatchCancel | ||
err error | ||
}{ | ||
"invalid subaccount": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.InvalidSubaccountIdNumber, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: []uint32{ | ||
0, 1, 2, 3, | ||
}, | ||
}, | ||
}, | ||
10, | ||
), | ||
err: satypes.ErrInvalidSubaccountIdNumber, | ||
}, | ||
"over 100 cancels in for one clob pair id": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: oneOverMax, | ||
}, | ||
}, | ||
10, | ||
), | ||
err: types.ErrInvalidBatchCancel, | ||
}, | ||
"over 100 cancels split over two clob pair id": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: oneOverMax[:types.MaxMsgBatchCancelBatchSize/2+2], | ||
}, | ||
{ | ||
ClobPairId: 1, | ||
ClientIds: oneOverMax[:types.MaxMsgBatchCancelBatchSize/2+2], | ||
}, | ||
}, | ||
10, | ||
), | ||
err: types.ErrInvalidBatchCancel, | ||
}, | ||
"success: two clob pair id, 100 cancels": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: oneOverMax[:types.MaxMsgBatchCancelBatchSize/2], | ||
}, | ||
{ | ||
ClobPairId: 1, | ||
ClientIds: oneOverMax[:types.MaxMsgBatchCancelBatchSize/2], | ||
}, | ||
}, | ||
10, | ||
), | ||
err: nil, | ||
}, | ||
"success: one clob pair id, 100 cancels": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: oneOverMax[:types.MaxMsgBatchCancelBatchSize], | ||
}, | ||
}, | ||
10, | ||
), | ||
err: nil, | ||
}, | ||
"duplicate clob pair ids": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: []uint32{ | ||
0, 1, 2, 3, 1, | ||
}, | ||
}, | ||
}, | ||
10, | ||
), | ||
err: types.ErrInvalidBatchCancel, | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add cases where |
||
"zero batches in cancel batch": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{}, | ||
10, | ||
), | ||
err: types.ErrInvalidBatchCancel, | ||
}, | ||
"zero client ids in cancel batch": { | ||
msg: *types.NewMsgBatchCancel( | ||
constants.Alice_Num0, | ||
[]types.OrderBatch{ | ||
{ | ||
ClobPairId: 0, | ||
ClientIds: []uint32{}, | ||
}, | ||
}, | ||
10, | ||
), | ||
err: types.ErrInvalidBatchCancel, | ||
}, | ||
} | ||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
err := tc.msg.ValidateBasic() | ||
if tc.err != nil { | ||
require.ErrorIs(t, err, tc.err) | ||
return | ||
} | ||
require.NoError(t, err) | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for my understanding - did we decide to set to to 100 or 1000?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://dydx-team.slack.com/archives/C06JZMTFACV/p1708985170576359?thread_ts=1708970027.055389&cid=C06JZMTFACV
We can change this as needed later.