github.com/gagliardetto/solana-go@v1.11.0/programs/serum/types_test.go (about) 1 // Copyright 2021 github.com/gagliardetto 2 // This file has been modified by github.com/gagliardetto 3 // 4 // Copyright 2020 dfuse Platform Inc. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package serum 19 20 import ( 21 "encoding/base64" 22 "encoding/binary" 23 "encoding/hex" 24 "fmt" 25 "io/ioutil" 26 "testing" 27 28 bin "github.com/gagliardetto/binary" 29 "github.com/gagliardetto/solana-go" 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 ) 33 34 func TestAccountFlag_Decoder(t *testing.T) { 35 hexStr := "0300000000000000" 36 data, err := hex.DecodeString(hexStr) 37 require.NoError(t, err) 38 39 var f *AccountFlag 40 err = bin.NewBinDecoder(data).Decode(&f) 41 require.NoError(t, err) 42 43 assert.Equal(t, f.Is(AccountFlagInitialized), true, "initialized") 44 assert.Equal(t, f.Is(AccountFlagMarket), true, "market") 45 assert.Equal(t, f.Is(AccountFlagOpenOrders), false, "openOrders") 46 assert.Equal(t, f.Is(AccountFlagRequestQueue), false, "requestQueue") 47 assert.Equal(t, f.Is(AccountFlagEventQueue), false, "eventQueue") 48 assert.Equal(t, f.Is(AccountFlagBids), false, "bids") 49 assert.Equal(t, f.Is(AccountFlagAsks), false, "asks") 50 assert.Equal(t, f.Is(AccountFlagDisabled), false, "disabled") 51 52 hexStr = "0900000000000000" 53 data, err = hex.DecodeString(hexStr) 54 require.NoError(t, err) 55 56 var f2 *AccountFlag 57 err = bin.NewBinDecoder(data).Decode(&f2) 58 require.NoError(t, err) 59 60 assert.Equal(t, f2.Is(AccountFlagInitialized), true, "initialized") 61 assert.Equal(t, f2.Is(AccountFlagMarket), false, "market") 62 assert.Equal(t, f2.Is(AccountFlagOpenOrders), false, "openOrders") 63 assert.Equal(t, f2.Is(AccountFlagRequestQueue), true, "requestQueue") 64 assert.Equal(t, f2.Is(AccountFlagEventQueue), false, "eventQueue") 65 assert.Equal(t, f2.Is(AccountFlagBids), false, "bids") 66 assert.Equal(t, f2.Is(AccountFlagAsks), false, "asks") 67 assert.Equal(t, f2.Is(AccountFlagDisabled), false, "disabled") 68 } 69 70 func TestDecoder_Market(t *testing.T) { 71 b64 := `c2VydW0DAAAAAAAAAF4kKlwSa8cc6xshYrDN0SrwrDDLBBUwemtddQHhfjgKAQAAAAAAAACL34duLBe2W5K3QFyI1rhNSESYe+cR/nc2UqvgE9x1VMb6evO+2606PWXzaqvJdDGxu+TC0vbg5HymAgNFL11habDAgiZH59TQw5/Y/52i1DhnPZFYOUB4C3G0hhSSXiRAZw8oAwAAAAAAAAAAAAAANvvq/rQwheCOf85MPshRgZEhXzDFAUh3IjalXs/zJ3I5cTmQBAAAABoqGA0AAAAAZAAAAAAAAACuBhNqk2KYdlbj/V5jbAGnnybh+XBss48/P00r053wbACx0Z1WrY+X9jL+huHdyUdpKzL/JScDimaQlNfzjpWANi1Nu6kEazO0bu0NkhnKFyQt2psF0SRCimAVpNimaOjou1Esrd0dKTtLbedHvt62Vi1bRJYveY74GEP6vkH/qBAnAAAAAAAACgAAAAAAAAAAAAAAAAAAAMsrAAAAAAAAcGFkZGluZw==` 72 73 data, err := base64.StdEncoding.DecodeString(b64) 74 require.NoError(t, err) 75 fmt.Println(hex.EncodeToString(data)) 76 77 var m *MarketV2 78 err = bin.NewBinDecoder(data).Decode(&m) 79 require.NoError(t, err) 80 81 assert.Equal(t, true, m.AccountFlags.Is(AccountFlagInitialized)) 82 assert.Equal(t, true, m.AccountFlags.Is(AccountFlagMarket)) 83 assert.Equal(t, false, m.AccountFlags.Is(AccountFlagEventQueue)) 84 assert.Equal(t, solana.MustPublicKeyFromBase58("13iGJcA4w5hcJZDjJbJQor1zUiDLE4jv2rMW9HkD5Eo1"), m.EventQueue) 85 } 86 87 func TestDecoder_Orderbook(t *testing.T) { 88 t.Skip("long running test") 89 cnt, err := ioutil.ReadFile("./testdata/orderbook.hex") 90 require.NoError(t, err) 91 92 data, err := hex.DecodeString(string(cnt)) 93 require.NoError(t, err) 94 95 decoder := bin.NewBinDecoder(data) 96 var ob *Orderbook 97 err = decoder.Decode(&ob) 98 require.NoError(t, err) 99 100 assert.Equal(t, uint32(101), ob.BumpIndex) 101 assert.Equal(t, uint32(68), ob.FreeListLen) 102 assert.Equal(t, uint32(37), ob.FreeListHead) 103 assert.Equal(t, uint32(17), ob.LeafCount) 104 assert.Equal(t, 101, len(ob.Nodes)) 105 assert.Equal(t, &Slab{ 106 BaseVariant: bin.BaseVariant{ 107 TypeID: bin.TypeIDFromUint32(1, binary.LittleEndian), 108 Impl: &SlabInnerNode{ 109 PrefixLen: 57, 110 Key: bin.Uint128{ 111 Lo: 1858, 112 Hi: 18446744073702344907, 113 }, 114 Children: [2]uint32{55, 56}, 115 Padding: [40]byte{ 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 }, 121 }, 122 }, 123 }, ob.Nodes[0]) 124 assert.Equal(t, &Slab{ 125 BaseVariant: bin.BaseVariant{ 126 TypeID: bin.TypeIDFromUint32(3, binary.LittleEndian), 127 Impl: &SlabFreeNode{ 128 Next: 2, 129 Padding: [64]byte{ 130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 0x00, 0x00, 0x00, 0x00, 137 }, 138 }, 139 }, 140 }, ob.Nodes[1]) 141 assert.Equal(t, &Slab{ 142 BaseVariant: bin.BaseVariant{ 143 TypeID: bin.TypeIDFromUint32(2, binary.LittleEndian), 144 Impl: &SlabLeafNode{ 145 OwnerSlot: 1, 146 FeeTier: 5, 147 Padding: [2]byte{0x00, 0x00}, 148 Key: bin.Uint128{ 149 Lo: 1820, 150 Hi: 18446744073702358592, 151 }, 152 Owner: solana.MustPublicKeyFromBase58("77jtrBDbUvwsdNKeq1ERUBcg8kk2hNTzf5E4iRihNgTh"), 153 Quantity: 38918, 154 ClientOrderId: 14114313590397044635, 155 }, 156 }, 157 }, ob.Nodes[5]) 158 159 } 160 161 func TestDecoder_Slabs(t *testing.T) { 162 tests := []struct { 163 name string 164 slabData string 165 expectSlab *Slab 166 }{ 167 { 168 name: "inner_node", 169 slabData: "0100000035000000010babffffffffff4105000000000000400000003f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 170 expectSlab: &Slab{ 171 BaseVariant: bin.BaseVariant{ 172 TypeID: bin.TypeIDFromUint32(1, binary.LittleEndian), 173 Impl: &SlabInnerNode{ 174 PrefixLen: 53, 175 Key: bin.Uint128{ 176 Lo: 18446744073703983873, 177 Hi: 1345, 178 }, 179 Children: [2]uint32{ 180 64, 181 63, 182 }, 183 }, 184 }, 185 }, 186 }, 187 188 { 189 name: "leaf_node", 190 slabData: "0200000014060000b2cea5ffffffffff23070000000000005ae01b52d00a090c6dc6fce8e37a225815cff2223a99c6dfdad5aae56d3db670e62c000000000000140b0fadcf8fcebf", 191 expectSlab: &Slab{ 192 BaseVariant: bin.BaseVariant{ 193 TypeID: bin.TypeIDFromUint32(2, binary.LittleEndian), 194 Impl: &SlabLeafNode{ 195 OwnerSlot: 20, 196 FeeTier: 6, 197 Padding: [2]byte{0x00, 0x00}, 198 Key: bin.Uint128{ 199 Lo: 18446744073703640754, 200 Hi: 1827, 201 }, 202 Owner: solana.MustPublicKeyFromBase58("77jtrBDbUvwsdNKeq1ERUBcg8kk2hNTzf5E4iRihNgTh"), 203 Quantity: 11494, 204 ClientOrderId: 13821142428571077396, 205 }, 206 }, 207 }, 208 }, 209 { 210 name: "free_node", 211 slabData: "030000003400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 212 expectSlab: &Slab{ 213 BaseVariant: bin.BaseVariant{ 214 TypeID: bin.TypeIDFromUint32(3, binary.LittleEndian), 215 Impl: &SlabFreeNode{ 216 Next: 52, 217 }, 218 }, 219 }, 220 }, 221 } 222 223 for _, test := range tests { 224 t.Run(test.name, func(t *testing.T) { 225 cnt, err := hex.DecodeString(test.slabData) 226 require.NoError(t, err) 227 228 decoder := bin.NewBinDecoder(cnt) 229 var slab *Slab 230 err = decoder.Decode(&slab) 231 require.NoError(t, err) 232 233 assert.Equal(t, test.expectSlab, slab) 234 }) 235 236 } 237 } 238 239 func TestOrderID(t *testing.T) { 240 orderID, err := NewOrderID("000000000000b868ffffffffff8ee7a0") 241 require.NoError(t, err) 242 assert.Equal(t, uint64(0xffffffffff8ee7a0), orderID.Lo) 243 assert.Equal(t, uint64(0xb868), orderID.Hi) 244 245 assert.Equal(t, uint64(47208), orderID.Price()) 246 assert.Equal(t, uint64(7411807), orderID.SeqNum(SideBid)) 247 248 assert.Equal(t, "000000000000b868ffffffffff8ee7a0", orderID.HexString(false)) 249 assert.Equal(t, "0x000000000000b868ffffffffff8ee7a0", orderID.HexString(true)) 250 251 orderID, err = NewOrderID("00000000000193c100000000000fbcc2") 252 require.NoError(t, err) 253 assert.Equal(t, uint64(0xfbcc2), orderID.Lo) 254 assert.Equal(t, uint64(0x193c1), orderID.Hi) 255 256 assert.Equal(t, uint64(103361), orderID.Price()) 257 assert.Equal(t, uint64(1031362), orderID.SeqNum(SideAsk)) 258 259 assert.Equal(t, "00000000000193c100000000000fbcc2", orderID.HexString(false)) 260 assert.Equal(t, "0x00000000000193c100000000000fbcc2", orderID.HexString(true)) 261 262 } 263 264 func Test_OpenOrder_GetOrder(t *testing.T) { 265 openOrderData := "testdata/serum-open-orders-new.hex" 266 267 openOrders := &OpenOrders{} 268 require.NoError(t, openOrders.Decode(readHexFile(t, openOrderData))) 269 o := openOrders.GetOrder(20) 270 assert.Equal(t, &Order{ 271 ID: OrderID{ 272 Hi: 0x0000000000000840, 273 Lo: 0xffffffffffacdefd, 274 }, 275 Side: SideBid, 276 }, o) 277 assert.Equal(t, o.SeqNum(), uint64(5447938)) 278 assert.Equal(t, o.Price(), uint64(2112)) 279 } 280 281 func TestIsBitZero(t *testing.T) { 282 tests := []struct { 283 name string 284 value bin.Uint128 285 index uint32 286 expect bool 287 expectError bool 288 }{ 289 { 290 name: "Index 0, bit is 1", 291 value: bin.Uint128{ 292 Hi: 0x0000000000000000, 293 Lo: 0x0000000000000001, 294 }, 295 index: 0, 296 expect: false, 297 }, 298 { 299 name: "Index 0, bit is 0", 300 value: bin.Uint128{ 301 Hi: 0x0000000000000000, 302 Lo: 0x0000000000000000, 303 }, 304 index: 0, 305 expect: true, 306 }, 307 { 308 name: "Index less then 64, bit is 1", 309 value: bin.Uint128{ 310 Hi: 0x0000000000000000, 311 Lo: 0x0000000000100000, 312 }, 313 index: 20, 314 expect: false, 315 }, 316 { 317 name: "Index less then 64, bit is 1", 318 value: bin.Uint128{ 319 Hi: 0xffffffffffffffff, 320 Lo: 0xffffffffffefffff, 321 }, 322 index: 20, 323 expect: true, 324 }, 325 { 326 name: "Index 64, bit is 1", 327 value: bin.Uint128{ 328 Hi: 0x0000000000000001, 329 Lo: 0x0000000000000000, 330 }, 331 index: 64, 332 expect: false, 333 }, 334 { 335 name: "Index 64, bit is 0", 336 value: bin.Uint128{ 337 Hi: 0x0000000000000000, 338 Lo: 0x0000000000000000, 339 }, 340 index: 64, 341 expect: true, 342 }, 343 { 344 name: "Index greater 64, bit is 1", 345 value: bin.Uint128{ 346 Hi: 0x0000002000000000, 347 Lo: 0x0000000000000000, 348 }, 349 index: 101, 350 expect: false, 351 }, 352 { 353 name: "Index greater 64, bit is 0", 354 value: bin.Uint128{ 355 Hi: 0xffffffdfffffffff, 356 Lo: 0xffffffffffffffff, 357 }, 358 index: 101, 359 expect: true, 360 }, 361 { 362 name: "Index 128", 363 value: bin.Uint128{}, 364 index: 128, 365 expectError: true, 366 }, 367 } 368 for _, test := range tests { 369 t.Run(test.name, func(t *testing.T) { 370 f, err := IsBitZero(test.value, test.index) 371 if test.expectError { 372 require.Error(t, err) 373 } else { 374 assert.NoError(t, err) 375 assert.Equal(t, f, test.expect) 376 } 377 }) 378 } 379 }