diff --git a/docs/proto-docs.md b/docs/proto-docs.md index 0b03ea9e06..abd741cd0e 100644 --- a/docs/proto-docs.md +++ b/docs/proto-docs.md @@ -1891,6 +1891,7 @@ GenesisState is the data that should be loaded into the exchange module during g | `markets` | [Market](#provenance.exchange.v1.Market) | repeated | markets are all of the markets to create at genesis. | | `orders` | [Order](#provenance.exchange.v1.Order) | repeated | orders are all the orders to create at genesis. | | `last_market_id` | [uint32](#uint32) | | last_market_id is the value of the last auto-selected market id. | +| `last_order_id` | [uint64](#uint64) | | last_order_id is the value of the last order id created. | diff --git a/proto/provenance/exchange/v1/genesis.proto b/proto/provenance/exchange/v1/genesis.proto index aca884d657..3ccf87d24d 100644 --- a/proto/provenance/exchange/v1/genesis.proto +++ b/proto/provenance/exchange/v1/genesis.proto @@ -27,4 +27,7 @@ message GenesisState { // last_market_id is the value of the last auto-selected market id. uint32 last_market_id = 4; + + // last_order_id is the value of the last order id created. + uint64 last_order_id = 5; } \ No newline at end of file diff --git a/x/exchange/genesis.go b/x/exchange/genesis.go index af65dbaef9..97d7c9bdc2 100644 --- a/x/exchange/genesis.go +++ b/x/exchange/genesis.go @@ -38,6 +38,7 @@ func (g GenesisState) Validate() error { } } + maxOrderID := uint64(0) orderIDs := make(map[uint64]int) for i, order := range g.Orders { if order.OrderId != 0 { @@ -58,6 +59,15 @@ func (g GenesisState) Validate() error { if !knownMarket { errs = append(errs, fmt.Errorf("invalid order[%d]: unknown market id %d", i, order.GetMarketID())) } + + if order.OrderId > maxOrderID { + maxOrderID = order.OrderId + } + } + + if g.LastOrderId < maxOrderID { + errs = append(errs, fmt.Errorf("last order id %d is less than the largest id in the provided orders %d", + g.LastOrderId, maxOrderID)) } // No validation to do on LastMarketId. diff --git a/x/exchange/genesis.pb.go b/x/exchange/genesis.pb.go index 8417f9d9e6..dc3556a30f 100644 --- a/x/exchange/genesis.pb.go +++ b/x/exchange/genesis.pb.go @@ -33,6 +33,8 @@ type GenesisState struct { Orders []Order `protobuf:"bytes,3,rep,name=orders,proto3" json:"orders"` // last_market_id is the value of the last auto-selected market id. LastMarketId uint32 `protobuf:"varint,4,opt,name=last_market_id,json=lastMarketId,proto3" json:"last_market_id,omitempty"` + // last_order_id is the value of the last order id created. + LastOrderId uint64 `protobuf:"varint,5,opt,name=last_order_id,json=lastOrderId,proto3" json:"last_order_id,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -77,26 +79,28 @@ func init() { } var fileDescriptor_087ceebafabf03c9 = []byte{ - // 301 bytes of a gzipped FileDescriptorProto + // 324 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x29, 0x28, 0xca, 0x2f, 0x4b, 0xcd, 0x4b, 0xcc, 0x4b, 0x4e, 0xd5, 0x4f, 0xad, 0x48, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0xd5, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x43, 0xa8, 0xd2, 0x83, 0xa9, 0xd2, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0x94, 0x71, 0x98, 0x99, 0x9b, 0x58, 0x94, 0x9d, 0x5a, 0x42, 0x40, 0x51, 0x7e, 0x51, 0x4a, 0x6a, 0x51, 0x31, 0x01, 0x45, 0x05, 0x89, 0x45, 0x89, - 0xb9, 0x50, 0x45, 0x4a, 0x9f, 0x19, 0xb9, 0x78, 0xdc, 0x21, 0xce, 0x0d, 0x2e, 0x49, 0x2c, 0x49, + 0xb9, 0x50, 0x45, 0x4a, 0xd3, 0x99, 0xb8, 0x78, 0xdc, 0x21, 0xce, 0x0d, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0x32, 0xe3, 0x62, 0x83, 0x28, 0x90, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x92, 0xd3, 0xc3, 0xee, 0x7c, 0xbd, 0x00, 0xb0, 0xaa, 0x20, 0xa8, 0x6a, 0x21, 0x3b, 0x2e, 0x76, 0x88, 0x13, 0x8b, 0x25, 0x98, 0x14, 0x98, 0xf1, 0x69, 0xf4, 0x05, 0x2b, 0x73, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xa6, 0x49, 0xc8, 0x9a, 0x8b, 0x0d, 0xe2, 0x7a, 0x09, 0x66, 0xb0, 0x76, 0x59, 0x5c, 0xda, 0xfd, 0x41, 0xaa, 0xa0, 0xba, 0xa1, 0x5a, 0x84, 0x54, 0xb8, 0xf8, 0x72, 0x12, 0x8b, 0x4b, 0xe2, 0x21, 0x86, 0xc5, 0x67, 0xa6, 0x48, 0xb0, 0x28, 0x30, 0x6a, 0xf0, 0x06, 0xf1, 0x80, 0x44, 0x21, - 0xf6, 0x79, 0xa6, 0x58, 0x71, 0x74, 0x2c, 0x90, 0x67, 0x78, 0xb1, 0x40, 0x9e, 0xc1, 0x29, 0xf5, - 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, - 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xb8, 0x24, 0x33, 0xf3, 0x71, 0x58, 0x1c, - 0xc0, 0x18, 0xa5, 0x97, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x8f, 0x50, - 0xa4, 0x9b, 0x99, 0x8f, 0xc4, 0xd3, 0xaf, 0x80, 0x07, 0x76, 0x12, 0x1b, 0x38, 0x8c, 0x8d, 0x01, - 0x01, 0x00, 0x00, 0xff, 0xff, 0x74, 0x34, 0x75, 0x11, 0x28, 0x02, 0x00, 0x00, + 0xf6, 0x79, 0xa6, 0x08, 0x29, 0x71, 0xf1, 0x82, 0x55, 0x81, 0x35, 0x81, 0x14, 0xb1, 0x2a, 0x30, + 0x6a, 0xb0, 0x04, 0x71, 0x83, 0x04, 0xc1, 0xa6, 0x7a, 0xa6, 0x58, 0x71, 0x74, 0x2c, 0x90, 0x67, + 0x78, 0xb1, 0x40, 0x9e, 0xc1, 0x29, 0xf5, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, + 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, + 0xb8, 0x24, 0x33, 0xf3, 0x71, 0x38, 0x2e, 0x80, 0x31, 0x4a, 0x2f, 0x3d, 0xb3, 0x24, 0xa3, 0x34, + 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xa1, 0x48, 0x37, 0x33, 0x1f, 0x89, 0xa7, 0x5f, 0x01, 0x8f, + 0x90, 0x24, 0x36, 0x70, 0x3c, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x92, 0x09, 0xe8, 0xf5, + 0x4c, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -119,6 +123,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.LastOrderId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.LastOrderId)) + i-- + dAtA[i] = 0x28 + } if m.LastMarketId != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.LastMarketId)) i-- @@ -203,6 +212,9 @@ func (m *GenesisState) Size() (n int) { if m.LastMarketId != 0 { n += 1 + sovGenesis(uint64(m.LastMarketId)) } + if m.LastOrderId != 0 { + n += 1 + sovGenesis(uint64(m.LastOrderId)) + } return n } @@ -364,6 +376,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastOrderId", wireType) + } + m.LastOrderId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastOrderId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/exchange/genesis_test.go b/x/exchange/genesis_test.go index 86769835ce..6db54503e0 100644 --- a/x/exchange/genesis_test.go +++ b/x/exchange/genesis_test.go @@ -105,6 +105,7 @@ func TestGenesisState_Validate(t *testing.T) { bidOrder(8, 3, "5wong", "50nibbler"), bidOrder(9, 3, "5wong", "50nibbler"), }, + LastOrderId: 9, }, expErr: nil, }, @@ -177,6 +178,7 @@ func TestGenesisState_Validate(t *testing.T) { bidOrder(2, 2, "28fry", "2bender"), askOrder(3, 3, "28fry", "2bender"), }, + LastOrderId: 3, }, expErr: []string{ `invalid order[0]: unknown market id 1`, @@ -193,6 +195,7 @@ func TestGenesisState_Validate(t *testing.T) { bidOrder(1, 5, "28fry", "2bender"), askOrder(1, 6, "28fry", "2bender"), }, + LastOrderId: 1, }, expErr: []string{ `invalid order[1]: duplicate order id 1 seen at [0]`, @@ -213,11 +216,13 @@ func TestGenesisState_Validate(t *testing.T) { bidOrder(2, 4, "28fry", "2bender"), askOrder(3, 3, "28fry", "2bender"), }, + LastOrderId: 1, }, expErr: []string{ "invalid params: default split 10001 cannot be greater than 10000", `invalid market[1]: invalid create-bid flat fee option "-1zapp": negative coin amount: -1`, `invalid order[1]: unknown market id 4`, + "last order id 1 is less than the largest id in the provided orders 3", }, }, { @@ -225,6 +230,14 @@ func TestGenesisState_Validate(t *testing.T) { genState: GenesisState{LastMarketId: 1}, expErr: nil, }, + { + name: "last market id less than largest market id", + genState: GenesisState{ + Markets: []Market{{MarketId: 3}, {MarketId: 1}}, + LastMarketId: 1, + }, + expErr: nil, + }, { name: "last market id 256", genState: GenesisState{LastMarketId: 256}, @@ -245,6 +258,48 @@ func TestGenesisState_Validate(t *testing.T) { genState: GenesisState{LastMarketId: 4_294_967_295}, expErr: nil, }, + { + name: "last order id less than largest order id", + genState: GenesisState{ + Markets: []Market{{MarketId: 1}}, + Orders: []Order{ + askOrder(1, 1, "28fry", "2bender"), + bidOrder(88, 1, "28fry", "2bender"), + bidOrder(2, 1, "28fry", "2bender"), + askOrder(3, 1, "28fry", "2bender"), + }, + LastOrderId: 87, + }, + expErr: []string{"last order id 87 is less than the largest id in the provided orders 88"}, + }, + { + name: "last order id equals largest order id", + genState: GenesisState{ + Markets: []Market{{MarketId: 1}}, + Orders: []Order{ + askOrder(1, 1, "28fry", "2bender"), + bidOrder(88, 1, "28fry", "2bender"), + bidOrder(2, 1, "28fry", "2bender"), + askOrder(3, 1, "28fry", "2bender"), + }, + LastOrderId: 88, + }, + expErr: nil, + }, + { + name: "last order id more than largest order id", + genState: GenesisState{ + Markets: []Market{{MarketId: 1}}, + Orders: []Order{ + askOrder(1, 1, "28fry", "2bender"), + bidOrder(88, 1, "28fry", "2bender"), + bidOrder(2, 1, "28fry", "2bender"), + askOrder(3, 1, "28fry", "2bender"), + }, + LastOrderId: 89, + }, + expErr: nil, + }, } for _, tc := range tests { diff --git a/x/exchange/keeper/genesis.go b/x/exchange/keeper/genesis.go index cd3c5dfcda..afcff92f8a 100644 --- a/x/exchange/keeper/genesis.go +++ b/x/exchange/keeper/genesis.go @@ -38,6 +38,8 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState *exchange.GenesisState) { amounts[addr] = amounts[addr].Add(order.GetHoldAmount()...) } + setLastOrderID(store, genState.LastOrderId) + // Make sure all the needed funds have holds on them. These should have been placed during initialization of the hold module. for _, addr := range addrs { for _, reqAmt := range amounts[addr] { @@ -54,9 +56,11 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState *exchange.GenesisState) { // ExportGenesis creates a genesis state from the current state store. func (k Keeper) ExportGenesis(ctx sdk.Context) *exchange.GenesisState { + store := k.getStore(ctx) genState := &exchange.GenesisState{ Params: k.GetParams(ctx), - LastMarketId: getLastAutoMarketID(k.getStore(ctx)), + LastMarketId: getLastAutoMarketID(store), + LastOrderId: getLastOrderID(store), } k.IterateMarkets(ctx, func(market *exchange.Market) bool {