solana-go/serum/types.go

186 lines
5.4 KiB
Go
Raw Normal View History

2020-11-05 14:54:08 -08:00
package serum
2020-11-06 08:47:26 -08:00
import (
"fmt"
"io"
"github.com/dfuse-io/solana-go"
"github.com/lunixbochs/struc"
)
2020-11-05 14:54:08 -08:00
type MarketV2 struct {
/*
blob(5),
accountFlagsLayout('accountFlags'),
publicKeyLayout('ownAddress'),
u64('vaultSignerNonce'),
publicKeyLayout('baseMint'),
publicKeyLayout('quoteMint'),
publicKeyLayout('baseVault'),
u64('baseDepositsTotal'),
u64('baseFeesAccrued'),
publicKeyLayout('quoteVault'),
u64('quoteDepositsTotal'),
u64('quoteFeesAccrued'),
u64('quoteDustThreshold'),
publicKeyLayout('requestQueue'),
publicKeyLayout('eventQueue'),
publicKeyLayout('bids'),
publicKeyLayout('asks'),
u64('baseLotSize'),
u64('quoteLotSize'),
u64('feeRateBps'),
u64('referrerRebatesAccrued'),
blob(7),
*/
2020-11-06 10:18:04 -08:00
SerumPadding [5]byte `json:"-" struc:"[5]pad"`
2020-11-06 08:47:26 -08:00
AccountFlags solana.U64 `struc:"uint64,little"`
OwnAddress solana.PublicKey `struc:"[32]byte"`
VaultSignerNonce solana.U64 `struc:"uint64,little"`
BaseMint solana.PublicKey `struc:"[32]byte"`
QuoteMint solana.PublicKey `struc:"[32]byte"`
BaseVault solana.PublicKey `struc:"[32]byte"`
BaseDepositsTotal solana.U64 `struc:"uint64,little"`
BaseFeesAccrued solana.U64 `struc:"uint64,little"`
QuoteVault solana.PublicKey `struc:"[32]byte"`
QuoteDepositsTotal solana.U64 `struc:"uint64,little"`
QuoteFeesAccrued solana.U64 `struc:"uint64,little"`
QuoteDustThreshold solana.U64 `struc:"uint64,little"`
RequestQueue solana.PublicKey `struc:"[32]byte"`
EventQueue solana.PublicKey `struc:"[32]byte"`
Bids solana.PublicKey `struc:"[32]byte"`
Asks solana.PublicKey `struc:"[32]byte"`
BaseLotSize solana.U64 `struc:"uint64,little"`
QuoteLotSize solana.U64 `struc:"uint64,little"`
FeeRateBPS solana.U64 `struc:"uint64,little"`
ReferrerRebatesAccrued solana.U64 `struc:"uint64,little"`
2020-11-06 10:18:04 -08:00
EndPadding [7]byte `json:"-" struc:"[7]pad"`
2020-11-06 08:47:26 -08:00
}
2020-11-05 14:54:08 -08:00
2020-11-06 08:47:26 -08:00
type Orderbook struct {
// ORDERBOOK_LAYOUT
2020-11-06 10:18:04 -08:00
SerumPadding [5]byte `json:"-" struc:"[5]pad"`
2020-11-06 08:47:26 -08:00
AccountFlags solana.U64 `struc:"uint64,little"`
// SLAB_LAYOUT
// SLAB_HEADER_LAYOUT
BumpIndex uint32 `struc:"uint32,sizeof=Nodes"`
2020-11-06 10:18:04 -08:00
ZeroPaddingA [4]byte `json:"-" struc:"[4]pad"`
2020-11-06 08:47:26 -08:00
FreeListLen uint32 `struc:"uint32,little"`
2020-11-06 10:18:04 -08:00
ZeroPaddingB [4]byte `json:"-" struc:"[4]pad"`
2020-11-06 08:47:26 -08:00
FreeListHead uint32 `struc:"uint32,little"`
Root uint32 `struc:"uint32,little"`
LeafCount uint32 `struc:"uint32,little"`
2020-11-06 10:18:04 -08:00
ZeroPaddingC [4]byte `json:"-" struc:"[4]pad"`
2020-11-06 08:47:26 -08:00
// SLAB_NODE_LAYOUT
Nodes []SlabNode `struc:""`
2020-11-06 08:47:26 -08:00
}
2020-11-05 14:54:08 -08:00
2020-11-06 10:18:04 -08:00
func (o *Orderbook) Items(descending bool, f func(node SlackLeafNode) error) error {
if o.LeafCount == 0 {
return nil
}
itr := 0
stack := []uint32{o.Root}
for itr < len(stack) {
index := stack[itr]
slab := o.Nodes[index]
switch s := slab.Impl.(type) {
case SlabInnerNode:
if descending {
stack = append(stack, s.Children[0], s.Children[1])
} else {
stack = append(stack, s.Children[1], s.Children[0])
}
case SlackLeafNode:
f(s)
}
itr++
}
return nil
}
2020-11-06 08:47:26 -08:00
var slabInstructionDef = solana.NewVariantDefinition([]solana.VariantType{
{"uninitialized", (*SlabUninitialized)(nil)},
{"innerNode", (*SlabInnerNode)(nil)},
{"leafNode", (*SlabLeafNode)(nil)},
2020-11-06 08:47:26 -08:00
{"freeNode", (*SlabFreeNode)(nil)},
{"lastFreeNode", (*SlabLastFreeNode)(nil)},
})
2020-11-05 14:54:08 -08:00
2020-11-06 08:47:26 -08:00
type SlabNode struct {
Type solana.Varuint16
Variant interface{}
2020-11-06 08:47:26 -08:00
}
2020-11-05 14:54:08 -08:00
func (s *SlabNode) Unpack(r io.Reader, length int, opt *struc.Options) (err error) {
fmt.Println("Unpacking SlabNode")
if err = struc.Unpack(r, &s.Type); err != nil {
return
}
var el interface{}
switch s.Type {
case 0:
el = &SlabUninitialized{}
case 1:
el = &SlabInnerNode{}
case 2:
el = &SlabLeafNode{}
case 3:
el = &SlabFreeNode{}
case 4:
el = &SlabLastFreeNode{}
default:
return fmt.Errorf("unsupported SlabNode variant %d", s.Type)
}
return struc.Unpack(r, el)
2020-11-06 08:47:26 -08:00
}
2020-11-05 14:54:08 -08:00
func (s SlabNode) Pack(p []byte, opt *struc.Options) (written int, err error) {
return 0, nil
}
func (s SlabNode) Size(opt *struc.Options) int { return 0 }
func (s SlabNode) String() string { return fmt.Sprintf("variant %d, %T", s.Type, s.Variant) }
2020-11-06 08:47:26 -08:00
type SlabUninitialized struct {
}
2020-11-05 14:54:08 -08:00
2020-11-06 08:47:26 -08:00
type SlabInnerNode struct {
PrefixLen uint32 `struc:"uint32,little"`
2020-11-06 10:18:04 -08:00
// this corresponds to the uint128 key
KeyPrice solana.U64 `struc:"uint64",little"`
KeySeq solana.U64 `struc:"uint64",little"`
Children []uint32 `struc:"[2]uint32,little"`
2020-11-05 14:54:08 -08:00
}
type SlabLeafNode struct {
2020-11-06 10:18:04 -08:00
//u8('ownerSlot'), // Index into OPEN_ORDERS_LAYOUT.orders
//u8('feeTier'),
//blob(2),
//u128('key'), // (price, seqNum)
//publicKeyLayout('owner'), // Open orders account
//u64('quantity'), // In units of lot size
//u64('clientOrderId'),
OwnerSlot uint8 `struc:"uint8,little"`
FeeTier uint8 `struc:"uint8,little"`
Padding [2]byte `json:"-" struc:"[2]pad"`
KeyPrice solana.U64 `struc:"uint64",little"`
KeySeq solana.U64 `struc:"uint64",little"`
Owner solana.PublicKey `struc:"[32]byte"`
Quantity solana.U64 `struc:"uint64",little"`
ClientOrderId solana.U64 `struc:"uint64",little"`
2020-11-06 08:47:26 -08:00
}
2020-11-05 14:54:08 -08:00
2020-11-06 08:47:26 -08:00
type SlabFreeNode struct {
Next uint32 `struc:"uint32,little"`
2020-11-05 14:54:08 -08:00
}
2020-11-06 08:47:26 -08:00
type SlabLastFreeNode struct {
2020-11-05 14:54:08 -08:00
}