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  }