mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-18 21:26:20 +00:00
Prepare and process proposal excecution
This commit is contained in:
+158
-68
@@ -20,12 +20,13 @@ type StateMachine struct {
|
||||
db dbm.DB
|
||||
|
||||
// in-memory state
|
||||
accounts map[uint64]*Account
|
||||
accounts map[uint64]*Account
|
||||
|
||||
// ephemeral state (not used for the app hash) but for
|
||||
// convienience
|
||||
pairs map[string]struct{} // lookup pairs
|
||||
commodity map[string]struct{} // lookup commodities
|
||||
pairs map[string]struct{} // lookup pairs
|
||||
commodities map[string]struct{} // lookup commodities
|
||||
publicKeys map[string]struct{} // lookup existence of an account
|
||||
|
||||
// app-side mempool (also emphemeral)
|
||||
markets map[string]*Market // i.e. ATOM/USDC
|
||||
@@ -51,15 +52,14 @@ func (sm *StateMachine) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx
|
||||
// validations for each msg below
|
||||
switch m := msg.Sum.(type) {
|
||||
case *Msg_MsgRegisterPair:
|
||||
// mustnt already have the same pair (also the reverse pairing)
|
||||
// inbound can also be outbound for pair
|
||||
if err := m.MsgRegisterPair.ValidateBasic(); err != nil {
|
||||
return types.ResponseCheckTx{Code: 3}
|
||||
}
|
||||
|
||||
case *Msg_MsgCreateAccount:
|
||||
|
||||
if m.MsgCreateAccount.ValidateBasic(); err != nil {
|
||||
if err := m.MsgCreateAccount.ValidateBasic(); err != nil {
|
||||
return types.ResponseCheckTx{Code: 3}
|
||||
}
|
||||
//check there is no other account with the same public key
|
||||
|
||||
case *Msg_MsgBid:
|
||||
|
||||
@@ -77,8 +77,6 @@ func (sm *StateMachine) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx
|
||||
return types.ResponseCheckTx{Code: 4}
|
||||
}
|
||||
|
||||
// check that the account has enough funds to support the bid (quantity * max_price)
|
||||
|
||||
case *Msg_MsgAsk:
|
||||
|
||||
if err := m.MsgAsk.ValidateBasic(); err != nil {
|
||||
@@ -142,12 +140,9 @@ func (sm *StateMachine) BeginBlock(req types.RequestBeginBlock) types.ResponseBe
|
||||
func (sm *StateMachine) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
|
||||
tradeSet := new(TradeSet)
|
||||
if err := proto.Unmarshal(req.Tx, tradeSet); err != nil {
|
||||
panic(fmt.Sprintf("unmarshalling tx: %w", err))
|
||||
panic(fmt.Sprintf("unmarshalling tx: %v", err))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return types.ResponseDeliverTx{Code: 0}
|
||||
}
|
||||
|
||||
@@ -172,82 +167,177 @@ func (sm *StateMachine) ApplySnapshotChunk(req types.RequestApplySnapshotChunk)
|
||||
}
|
||||
|
||||
func (sm *StateMachine) PrepareProposal(req types.RequestPrepareProposal) types.ResponsePrepareProposal {
|
||||
|
||||
// declare transaction with the size of 0
|
||||
txs := make([][]byte, 0)
|
||||
|
||||
// fetch and match all the bids and asks for each market
|
||||
for _, market := range sm.markets {
|
||||
TradeSet := market.Match();
|
||||
tradeSet := market.Match()
|
||||
// tradesets into bytes and bytes into a transaction
|
||||
if TradeSet == nil {
|
||||
if tradeSet == nil {
|
||||
continue
|
||||
}
|
||||
bz, err := proto.Marshal(TradeSet)
|
||||
|
||||
tradeSet = sm.validateTradeSetAgainstState(tradeSet)
|
||||
if tradeSet == nil || len(tradeSet.MatchedOrders) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// wrap this as a message typ
|
||||
msgTradeSet := &MsgTradeSet{TradeSet: tradeSet}
|
||||
bz, err := proto.Marshal(msgTradeSet)
|
||||
if err != nil {
|
||||
return err
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// check to see that we don't over populate the block
|
||||
if len(txs)+len(bz) > int(req.MaxTxBytes) {
|
||||
return types.ResponsePrepareProposal{Txs: txs}
|
||||
}
|
||||
txs = append(txs, bz)
|
||||
}
|
||||
|
||||
for _, tx := range req.Txs {
|
||||
var msg = new(Msg)
|
||||
err := proto.Unmarshal(tx, msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
switch m := msg.Sum.(type) {
|
||||
case *Msg_MsgRegisterPair:
|
||||
// run the validation checks to see if duplicates within the pairs
|
||||
pair := m.MsgRegisterPair.Pair
|
||||
if _, ok := sm.pairs[pair.String()]; ok {
|
||||
// this pair already exists so we skip over the message
|
||||
// garbage collection should pick it up
|
||||
continue
|
||||
}
|
||||
|
||||
reversePair := &Pair{BuyersDenomination: pair.SellersDenomination, SellersDenomination: pair.BuyersDenomination}
|
||||
if _, ok := sm.pairs[reversePair.String()]; ok {
|
||||
// the reverse pair already exists so we skip over it
|
||||
continue
|
||||
}
|
||||
|
||||
// check to see that we don't over populate the block
|
||||
if len(txs)+len(tx) > int(req.MaxTxBytes) {
|
||||
return types.ResponsePrepareProposal{Txs: txs}
|
||||
}
|
||||
txs = append(txs, tx)
|
||||
|
||||
case *Msg_MsgCreateAccount:
|
||||
// check for duplicate accounts in sm
|
||||
if _, ok := sm.publicKeys[string(m.MsgCreateAccount.PublicKey)]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// check to see that we don't over populate the block
|
||||
if len(txs)+len(tx) > int(req.MaxTxBytes) {
|
||||
return types.ResponsePrepareProposal{Txs: txs}
|
||||
}
|
||||
txs = append(txs, tx)
|
||||
case *Msg_MsgAsk, *Msg_MsgBid:
|
||||
// Already have these in the market and are paring together so not necessary to include here
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown msg type in prepare proposal %T", m))
|
||||
}
|
||||
}
|
||||
|
||||
// pull in for every single pair
|
||||
|
||||
// does the buyer and seller have sufficient funds
|
||||
for _, matchedOrder := range tradeSet.MatchedOrders {
|
||||
bidOwner := sm.accounts[matchedOrder.OrderBid.OwnerId]
|
||||
askOwner := sm.accounts[matchedOrder.OrderAsk.OwnerId]
|
||||
|
||||
askCommodities := askOwner.Commodities[tradeSet.Pairs.SellersDenomination]
|
||||
buyCommodities := askOwner.Commodities[tradeSet.Pairs.BuyersDenomination]
|
||||
|
||||
// if bidowner commodities quantity - askowner commodities quantity != 0 then continue
|
||||
if bidOwner.Commodities[askCommodities.String()]
|
||||
}
|
||||
|
||||
// // validate the trade:
|
||||
//
|
||||
|
||||
// // add it to the set of txs
|
||||
|
||||
// }
|
||||
|
||||
//
|
||||
// }
|
||||
|
||||
// loop through the transactions provided by tendermint and look out for register pair and create account.
|
||||
// those should still be added.
|
||||
|
||||
return types.ResponsePrepareProposal{Txs: req.Txs}
|
||||
}
|
||||
|
||||
// Validate matched order
|
||||
// Process Proposal either rejects or accepts transactions
|
||||
func (sm *StateMachine) ProcessProposal(req types.RequestProcessProposal) types.ResponseProcessProposal {
|
||||
var msg = new(Msg)
|
||||
for _, tx := range req.Txs {
|
||||
var msg = new(Msg)
|
||||
err := proto.Unmarshal(tx, msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err := proto.Unmarshal(req.Txs[], msg)
|
||||
if err != nil {
|
||||
return types.ResponseCheckTx{Code: 1} // decoding error
|
||||
switch m := msg.Sum.(type) {
|
||||
case *Msg_MsgRegisterPair:
|
||||
if err := m.MsgRegisterPair.ValidateBasic(); err != nil {
|
||||
return rejectProposal()
|
||||
}
|
||||
|
||||
pair := m.MsgRegisterPair.Pair
|
||||
if _, ok := sm.pairs[pair.String()]; ok {
|
||||
return rejectProposal()
|
||||
}
|
||||
|
||||
reversePair := &Pair{BuyersDenomination: pair.SellersDenomination, SellersDenomination: pair.BuyersDenomination}
|
||||
if _, ok := sm.pairs[reversePair.String()]; ok {
|
||||
return rejectProposal()
|
||||
}
|
||||
|
||||
case *Msg_MsgAsk, *Msg_MsgBid:
|
||||
return rejectProposal()
|
||||
case *Msg_MsgCreateAccount:
|
||||
if err := m.MsgCreateAccount.ValidateBasic(); err != nil {
|
||||
return rejectProposal()
|
||||
}
|
||||
|
||||
// check for duplicate accounts in sm
|
||||
if _, ok := sm.publicKeys[string(m.MsgCreateAccount.PublicKey)]; ok {
|
||||
return rejectProposal()
|
||||
}
|
||||
|
||||
case *Msg_MsgTradeSet:
|
||||
if err := m.MsgTradeSet.TradeSet.ValidateBasic(); err != nil {
|
||||
return rejectProposal()
|
||||
}
|
||||
|
||||
// for each matched order
|
||||
// check the accounts exist, that the signatures are valid and that they have the available funds to make the swap
|
||||
|
||||
default:
|
||||
return rejectProposal()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// check if there is more than one account
|
||||
if ok := len(sm.accounts) >= 1; !ok {
|
||||
return types.ResponseProcessProposal{Code: 4}
|
||||
}
|
||||
return acceptProposal()
|
||||
}
|
||||
|
||||
func (sm *StateMachine) validateTradeSetAgainstState(tradeSet *TradeSet) *TradeSet {
|
||||
output := &TradeSet{Pair: tradeSet.Pair}
|
||||
|
||||
for _, matchedOrder := range tradeSet.MatchedOrders {
|
||||
bidOwner := sm.accounts[matchedOrder.OrderBid.OwnerId]
|
||||
askOwner := sm.accounts[matchedOrder.OrderAsk.OwnerId]
|
||||
|
||||
askCommodities := askOwner.FindCommidity(tradeSet.Pair.SellersDenomination)
|
||||
if askCommodities == nil {
|
||||
continue
|
||||
}
|
||||
buyCommodities := bidOwner.FindCommidity(tradeSet.Pair.BuyersDenomination)
|
||||
if buyCommodities == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Seller has enough of the commodity
|
||||
if askCommodities.Quantity-matchedOrder.OrderAsk.Quantity < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Buyer has enough of the buying commodity
|
||||
if buyCommodities.Quantity-(matchedOrder.OrderAsk.AskPrice*matchedOrder.OrderAsk.Quantity) < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// check if there is more than one commodity
|
||||
if ok := len(sm.commodities) >= 1; !ok {
|
||||
return types.ResponseProcessProposal{Code: 4}
|
||||
// yayy! this matched order is still valid and can be executed
|
||||
output.MatchedOrders = append(output.MatchedOrders, matchedOrder)
|
||||
}
|
||||
|
||||
// check if there is more than one pair
|
||||
if ok := len(sm.pairs) >= 1; !ok {
|
||||
return types.ResponseProcessProposal{Code: 4}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// check if there is a market
|
||||
if ok := len(sm.markets) >= 1; !ok {
|
||||
return types.ResponseProcessProposal{Code: 4}
|
||||
}
|
||||
func rejectProposal() types.ResponseProcessProposal {
|
||||
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_REJECT}
|
||||
}
|
||||
|
||||
return types.ResponseProcessProposal{
|
||||
Status: types.ResponseProcessProposal_ACCEPT}
|
||||
func acceptProposal() types.ResponseProcessProposal {
|
||||
return types.ResponseProcessProposal{Status: types.ResponseProcessProposal_ACCEPT}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package orderbook_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/abci/example/orderbook"
|
||||
)
|
||||
|
||||
func TestPrepareProposal(t *testing.T) {
|
||||
// check to see if the market collected all of the pairs
|
||||
market := orderbook.NewMarket(testPair)
|
||||
require.EqualValues(t, )
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ func TestSimpleOrderMatching(t *testing.T) {
|
||||
ask: testAsk(40, 10),
|
||||
match: true,
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
for idx, tc := range testcases {
|
||||
@@ -90,10 +89,10 @@ func TestSimpleOrderMatching(t *testing.T) {
|
||||
|
||||
func TestMultiOrderMatching(t *testing.T) {
|
||||
testcases := []struct {
|
||||
bids []*orderbook.OrderBid
|
||||
asks []*orderbook.OrderAsk
|
||||
expected []*orderbook.MatchedOrder
|
||||
expectedLowestAsk float64
|
||||
bids []*orderbook.OrderBid
|
||||
asks []*orderbook.OrderAsk
|
||||
expected []*orderbook.MatchedOrder
|
||||
expectedLowestAsk float64
|
||||
expectedHighestBid float64
|
||||
}{
|
||||
{
|
||||
@@ -115,8 +114,8 @@ func TestMultiOrderMatching(t *testing.T) {
|
||||
OrderAsk: testAsk(30, 15),
|
||||
OrderBid: testBid(50, 20),
|
||||
},
|
||||
},
|
||||
expectedLowestAsk: 0,
|
||||
},
|
||||
expectedLowestAsk: 0,
|
||||
expectedHighestBid: 40,
|
||||
},
|
||||
{
|
||||
@@ -134,8 +133,8 @@ func TestMultiOrderMatching(t *testing.T) {
|
||||
OrderAsk: testAsk(60, 15),
|
||||
OrderBid: testBid(60, 20),
|
||||
},
|
||||
},
|
||||
expectedLowestAsk: 50,
|
||||
},
|
||||
expectedLowestAsk: 50,
|
||||
expectedHighestBid: 80,
|
||||
},
|
||||
{
|
||||
@@ -143,9 +142,9 @@ func TestMultiOrderMatching(t *testing.T) {
|
||||
testBid(60, 20),
|
||||
testBid(80, 5),
|
||||
},
|
||||
asks: []*orderbook.OrderAsk{},
|
||||
expected: []*orderbook.MatchedOrder{},
|
||||
expectedLowestAsk: 0,
|
||||
asks: []*orderbook.OrderAsk{},
|
||||
expected: []*orderbook.MatchedOrder{},
|
||||
expectedLowestAsk: 0,
|
||||
expectedHighestBid: 80,
|
||||
},
|
||||
{
|
||||
@@ -154,8 +153,8 @@ func TestMultiOrderMatching(t *testing.T) {
|
||||
testAsk(70, 10),
|
||||
testAsk(50, 20),
|
||||
},
|
||||
expected: []*orderbook.MatchedOrder{},
|
||||
expectedLowestAsk: 50,
|
||||
expected: []*orderbook.MatchedOrder{},
|
||||
expectedLowestAsk: 50,
|
||||
expectedHighestBid: 0,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ type MsgCreateAccount struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PublicKey [][]byte `protobuf:"bytes,1,rep,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
Commodities []*Commodity `protobuf:"bytes,2,rep,name=commodities,proto3" json:"commodities,omitempty"`
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func (*MsgCreateAccount) Descriptor() ([]byte, []int) {
|
||||
return file_msgs_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *MsgCreateAccount) GetPublicKey() [][]byte {
|
||||
func (x *MsgCreateAccount) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
@@ -232,25 +232,74 @@ func (x *MsgRegisterPair) GetPair() *Pair {
|
||||
return nil
|
||||
}
|
||||
|
||||
type MsgTradeSet struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
TradeSet *TradeSet `protobuf:"bytes,1,opt,name=trade_set,json=tradeSet,proto3" json:"trade_set,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MsgTradeSet) Reset() {
|
||||
*x = MsgTradeSet{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_msgs_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MsgTradeSet) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MsgTradeSet) ProtoMessage() {}
|
||||
|
||||
func (x *MsgTradeSet) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_msgs_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MsgTradeSet.ProtoReflect.Descriptor instead.
|
||||
func (*MsgTradeSet) Descriptor() ([]byte, []int) {
|
||||
return file_msgs_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *MsgTradeSet) GetTradeSet() *TradeSet {
|
||||
if x != nil {
|
||||
return x.TradeSet
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Msg struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
//a Msg has to be one of the below
|
||||
// a Msg has to be one of the below
|
||||
//
|
||||
// Types that are assignable to Sum:
|
||||
//
|
||||
// *Msg_MsgBid
|
||||
// *Msg_MsgAsk
|
||||
// *Msg_MsgRegisterPair
|
||||
// *Msg_MsgCreateAccount
|
||||
// *Msg_MsgTradeSet
|
||||
Sum isMsg_Sum `protobuf_oneof:"sum"`
|
||||
}
|
||||
|
||||
func (x *Msg) Reset() {
|
||||
*x = Msg{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_msgs_proto_msgTypes[4]
|
||||
mi := &file_msgs_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -263,7 +312,7 @@ func (x *Msg) String() string {
|
||||
func (*Msg) ProtoMessage() {}
|
||||
|
||||
func (x *Msg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_msgs_proto_msgTypes[4]
|
||||
mi := &file_msgs_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -276,7 +325,7 @@ func (x *Msg) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Msg.ProtoReflect.Descriptor instead.
|
||||
func (*Msg) Descriptor() ([]byte, []int) {
|
||||
return file_msgs_proto_rawDescGZIP(), []int{4}
|
||||
return file_msgs_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (m *Msg) GetSum() isMsg_Sum {
|
||||
@@ -314,6 +363,13 @@ func (x *Msg) GetMsgCreateAccount() *MsgCreateAccount {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Msg) GetMsgTradeSet() *MsgTradeSet {
|
||||
if x, ok := x.GetSum().(*Msg_MsgTradeSet); ok {
|
||||
return x.MsgTradeSet
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isMsg_Sum interface {
|
||||
isMsg_Sum()
|
||||
}
|
||||
@@ -334,6 +390,10 @@ type Msg_MsgCreateAccount struct {
|
||||
MsgCreateAccount *MsgCreateAccount `protobuf:"bytes,4,opt,name=msg_create_account,json=msgCreateAccount,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Msg_MsgTradeSet struct {
|
||||
MsgTradeSet *MsgTradeSet `protobuf:"bytes,5,opt,name=msg_trade_set,json=msgTradeSet,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Msg_MsgBid) isMsg_Sum() {}
|
||||
|
||||
func (*Msg_MsgAsk) isMsg_Sum() {}
|
||||
@@ -342,6 +402,8 @@ func (*Msg_MsgRegisterPair) isMsg_Sum() {}
|
||||
|
||||
func (*Msg_MsgCreateAccount) isMsg_Sum() {}
|
||||
|
||||
func (*Msg_MsgTradeSet) isMsg_Sum() {}
|
||||
|
||||
var File_msgs_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_msgs_proto_rawDesc = []byte{
|
||||
@@ -361,7 +423,7 @@ var file_msgs_proto_rawDesc = []byte{
|
||||
0x6f, 0x6b, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x41, 0x73, 0x6b, 0x52, 0x08, 0x61, 0x73, 0x6b,
|
||||
0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x69, 0x0a, 0x10, 0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x70,
|
||||
0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x6f, 0x64, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,
|
||||
0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x64,
|
||||
@@ -369,27 +431,35 @@ var file_msgs_proto_rawDesc = []byte{
|
||||
0x22, 0x36, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50,
|
||||
0x61, 0x69, 0x72, 0x12, 0x23, 0x0a, 0x04, 0x70, 0x61, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x50, 0x61,
|
||||
0x69, 0x72, 0x52, 0x04, 0x70, 0x61, 0x69, 0x72, 0x22, 0xff, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67,
|
||||
0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x5f, 0x62, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x11, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x73,
|
||||
0x67, 0x42, 0x69, 0x64, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x73, 0x67, 0x42, 0x69, 0x64, 0x12, 0x2c,
|
||||
0x0a, 0x07, 0x6d, 0x73, 0x67, 0x5f, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x11, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x73, 0x67, 0x41,
|
||||
0x73, 0x6b, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x73, 0x67, 0x41, 0x73, 0x6b, 0x12, 0x48, 0x0a, 0x11,
|
||||
0x6d, 0x73, 0x67, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x69,
|
||||
0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62,
|
||||
0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50,
|
||||
0x61, 0x69, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
|
||||
0x65, 0x72, 0x50, 0x61, 0x69, 0x72, 0x12, 0x4b, 0x0a, 0x12, 0x6d, 0x73, 0x67, 0x5f, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d,
|
||||
0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x48,
|
||||
0x00, 0x52, 0x10, 0x6d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x42, 0x05, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d,
|
||||
0x69, 0x6e, 0x74, 0x2f, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x61,
|
||||
0x62, 0x63, 0x69, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x6f, 0x72, 0x64, 0x65,
|
||||
0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x69, 0x72, 0x52, 0x04, 0x70, 0x61, 0x69, 0x72, 0x22, 0x3f, 0x0a, 0x0b, 0x4d, 0x73, 0x67, 0x54,
|
||||
0x72, 0x61, 0x64, 0x65, 0x53, 0x65, 0x74, 0x12, 0x30, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x64, 0x65,
|
||||
0x5f, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x72, 0x64,
|
||||
0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x54, 0x72, 0x61, 0x64, 0x65, 0x53, 0x65, 0x74, 0x52,
|
||||
0x08, 0x74, 0x72, 0x61, 0x64, 0x65, 0x53, 0x65, 0x74, 0x22, 0xbd, 0x02, 0x0a, 0x03, 0x4d, 0x73,
|
||||
0x67, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x5f, 0x62, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d,
|
||||
0x73, 0x67, 0x42, 0x69, 0x64, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x73, 0x67, 0x42, 0x69, 0x64, 0x12,
|
||||
0x2c, 0x0a, 0x07, 0x6d, 0x73, 0x67, 0x5f, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x11, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x73, 0x67,
|
||||
0x41, 0x73, 0x6b, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x73, 0x67, 0x41, 0x73, 0x6b, 0x12, 0x48, 0x0a,
|
||||
0x11, 0x6d, 0x73, 0x67, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61,
|
||||
0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
||||
0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
||||
0x50, 0x61, 0x69, 0x72, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73,
|
||||
0x74, 0x65, 0x72, 0x50, 0x61, 0x69, 0x72, 0x12, 0x4b, 0x0a, 0x12, 0x6d, 0x73, 0x67, 0x5f, 0x63,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e,
|
||||
0x4d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x48, 0x00, 0x52, 0x10, 0x6d, 0x73, 0x67, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0d, 0x6d, 0x73, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x64,
|
||||
0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x72,
|
||||
0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x4d, 0x73, 0x67, 0x54, 0x72, 0x61, 0x64, 0x65,
|
||||
0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6d, 0x73, 0x67, 0x54, 0x72, 0x61, 0x64, 0x65, 0x53,
|
||||
0x65, 0x74, 0x42, 0x05, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69,
|
||||
0x6e, 0x74, 0x2f, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x74, 0x2f, 0x61, 0x62,
|
||||
0x63, 0x69, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2f, 0x6f, 0x72, 0x64, 0x65, 0x72,
|
||||
0x62, 0x6f, 0x6f, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -404,34 +474,38 @@ func file_msgs_proto_rawDescGZIP() []byte {
|
||||
return file_msgs_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_msgs_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_msgs_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_msgs_proto_goTypes = []interface{}{
|
||||
(*MsgBid)(nil), // 0: orderbook.MsgBid
|
||||
(*MsgAsk)(nil), // 1: orderbook.MsgAsk
|
||||
(*MsgCreateAccount)(nil), // 2: orderbook.MsgCreateAccount
|
||||
(*MsgRegisterPair)(nil), // 3: orderbook.MsgRegisterPair
|
||||
(*Msg)(nil), // 4: orderbook.Msg
|
||||
(*Pair)(nil), // 5: orderbook.Pair
|
||||
(*OrderBid)(nil), // 6: orderbook.OrderBid
|
||||
(*OrderAsk)(nil), // 7: orderbook.OrderAsk
|
||||
(*Commodity)(nil), // 8: orderbook.Commodity
|
||||
(*MsgTradeSet)(nil), // 4: orderbook.MsgTradeSet
|
||||
(*Msg)(nil), // 5: orderbook.Msg
|
||||
(*Pair)(nil), // 6: orderbook.Pair
|
||||
(*OrderBid)(nil), // 7: orderbook.OrderBid
|
||||
(*OrderAsk)(nil), // 8: orderbook.OrderAsk
|
||||
(*Commodity)(nil), // 9: orderbook.Commodity
|
||||
(*TradeSet)(nil), // 10: orderbook.TradeSet
|
||||
}
|
||||
var file_msgs_proto_depIdxs = []int32{
|
||||
5, // 0: orderbook.MsgBid.pair:type_name -> orderbook.Pair
|
||||
6, // 1: orderbook.MsgBid.bid_order:type_name -> orderbook.OrderBid
|
||||
5, // 2: orderbook.MsgAsk.pair:type_name -> orderbook.Pair
|
||||
7, // 3: orderbook.MsgAsk.ask_order:type_name -> orderbook.OrderAsk
|
||||
8, // 4: orderbook.MsgCreateAccount.commodities:type_name -> orderbook.Commodity
|
||||
5, // 5: orderbook.MsgRegisterPair.pair:type_name -> orderbook.Pair
|
||||
0, // 6: orderbook.Msg.msg_bid:type_name -> orderbook.MsgBid
|
||||
1, // 7: orderbook.Msg.msg_ask:type_name -> orderbook.MsgAsk
|
||||
3, // 8: orderbook.Msg.msg_register_pair:type_name -> orderbook.MsgRegisterPair
|
||||
2, // 9: orderbook.Msg.msg_create_account:type_name -> orderbook.MsgCreateAccount
|
||||
10, // [10:10] is the sub-list for method output_type
|
||||
10, // [10:10] is the sub-list for method input_type
|
||||
10, // [10:10] is the sub-list for extension type_name
|
||||
10, // [10:10] is the sub-list for extension extendee
|
||||
0, // [0:10] is the sub-list for field type_name
|
||||
6, // 0: orderbook.MsgBid.pair:type_name -> orderbook.Pair
|
||||
7, // 1: orderbook.MsgBid.bid_order:type_name -> orderbook.OrderBid
|
||||
6, // 2: orderbook.MsgAsk.pair:type_name -> orderbook.Pair
|
||||
8, // 3: orderbook.MsgAsk.ask_order:type_name -> orderbook.OrderAsk
|
||||
9, // 4: orderbook.MsgCreateAccount.commodities:type_name -> orderbook.Commodity
|
||||
6, // 5: orderbook.MsgRegisterPair.pair:type_name -> orderbook.Pair
|
||||
10, // 6: orderbook.MsgTradeSet.trade_set:type_name -> orderbook.TradeSet
|
||||
0, // 7: orderbook.Msg.msg_bid:type_name -> orderbook.MsgBid
|
||||
1, // 8: orderbook.Msg.msg_ask:type_name -> orderbook.MsgAsk
|
||||
3, // 9: orderbook.Msg.msg_register_pair:type_name -> orderbook.MsgRegisterPair
|
||||
2, // 10: orderbook.Msg.msg_create_account:type_name -> orderbook.MsgCreateAccount
|
||||
4, // 11: orderbook.Msg.msg_trade_set:type_name -> orderbook.MsgTradeSet
|
||||
12, // [12:12] is the sub-list for method output_type
|
||||
12, // [12:12] is the sub-list for method input_type
|
||||
12, // [12:12] is the sub-list for extension type_name
|
||||
12, // [12:12] is the sub-list for extension extendee
|
||||
0, // [0:12] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_msgs_proto_init() }
|
||||
@@ -490,6 +564,18 @@ func file_msgs_proto_init() {
|
||||
}
|
||||
}
|
||||
file_msgs_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MsgTradeSet); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_msgs_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Msg); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -502,11 +588,12 @@ func file_msgs_proto_init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
file_msgs_proto_msgTypes[4].OneofWrappers = []interface{}{
|
||||
file_msgs_proto_msgTypes[5].OneofWrappers = []interface{}{
|
||||
(*Msg_MsgBid)(nil),
|
||||
(*Msg_MsgAsk)(nil),
|
||||
(*Msg_MsgRegisterPair)(nil),
|
||||
(*Msg_MsgCreateAccount)(nil),
|
||||
(*Msg_MsgTradeSet)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -514,7 +601,7 @@ func file_msgs_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_msgs_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ message MsgAsk {
|
||||
}
|
||||
|
||||
message MsgCreateAccount {
|
||||
repeated bytes public_key = 1;
|
||||
bytes public_key = 1;
|
||||
repeated Commodity commodities = 2;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@ message MsgRegisterPair {
|
||||
Pair pair = 1;
|
||||
}
|
||||
|
||||
message MsgTradeSet {
|
||||
TradeSet trade_set = 1;
|
||||
}
|
||||
|
||||
message Msg {
|
||||
//a Msg has to be one of the below
|
||||
oneof sum {
|
||||
@@ -31,5 +35,6 @@ message Msg {
|
||||
MsgAsk msg_ask = 2;
|
||||
MsgRegisterPair msg_register_pair = 3;
|
||||
MsgCreateAccount msg_create_account = 4;
|
||||
MsgTradeSet msg_trade_set = 5;
|
||||
}
|
||||
}
|
||||
@@ -98,10 +98,22 @@ func (o *OrderBid) ValidateBasic() error {
|
||||
if o.MaxPrice <= 0 {
|
||||
return errors.New("min price must be greater than 0")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MatchedOrder) ValidateBasic() error {
|
||||
if len(m.OrderAsk.Signature) != ed25519.SignatureSize {
|
||||
return errors.New("invalid signature size")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TradeSet) ValidateBasic() error {
|
||||
return t.Pair.ValidateBasic()
|
||||
return t.MatchedOrders.ValidateBasic()
|
||||
|
||||
}
|
||||
|
||||
func (o *OrderAsk) ValidateBasic() error {
|
||||
if o.Quantity == 0 {
|
||||
return errors.New("quantity outbound must be non zero")
|
||||
|
||||
@@ -279,8 +279,8 @@ type Account struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Index uint64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
|
||||
PublicKey [][]byte `protobuf:"bytes,2,rep,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
Index uint64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
|
||||
PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
|
||||
// the set of commodities that the account has
|
||||
Commodities []*Commodity `protobuf:"bytes,3,rep,name=commodities,proto3" json:"commodities,omitempty"`
|
||||
}
|
||||
@@ -324,7 +324,7 @@ func (x *Account) GetIndex() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Account) GetPublicKey() [][]byte {
|
||||
func (x *Account) GetPublicKey() []byte {
|
||||
if x != nil {
|
||||
return x.PublicKey
|
||||
}
|
||||
@@ -485,7 +485,7 @@ var file_wire_proto_rawDesc = []byte{
|
||||
0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x76, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62,
|
||||
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x64,
|
||||
0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x72,
|
||||
0x64, 0x65, 0x72, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, 0x69, 0x74,
|
||||
|
||||
@@ -32,7 +32,7 @@ message Commodity {
|
||||
|
||||
message Account {
|
||||
uint64 index = 1;
|
||||
repeated bytes public_key = 2;
|
||||
bytes public_key = 2;
|
||||
// the set of commodities that the account has
|
||||
repeated Commodity commodities = 3;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user