Skip to content
This repository was archived by the owner on May 31, 2023. It is now read-only.

Commit 3106ff8

Browse files
author
Richard Patel
authored
Add support for instructions (#6)
1 parent cb32dc9 commit 3106ff8

23 files changed

+1283
-151
lines changed

types.go renamed to accounts.go

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package pyth
1616

1717
import (
18-
"bytes"
1918
"errors"
2019

2120
bin "github.com/gagliardetto/binary"
@@ -60,25 +59,12 @@ func PeekAccount(data []byte) uint32 {
6059
return header.AccountType
6160
}
6261

63-
// readLPString returns a length-prefixed string as seen in ProductAccount.Attrs.
64-
func readLPString(rd *bytes.Reader) (string, error) {
65-
strLen, err := rd.ReadByte()
66-
if err != nil {
67-
return "", err
68-
}
69-
val := make([]byte, strLen)
70-
if _, err := rd.Read(val); err != nil {
71-
return "", err
72-
}
73-
return string(val), nil
74-
}
75-
7662
// ProductAccount contains metadata for a single product,
7763
// such as its symbol and its base/quote currencies.
7864
type ProductAccount struct {
7965
AccountHeader
8066
FirstPrice solana.PublicKey // first price account in list
81-
Attrs [464]byte // key-value string pairs of additional data
67+
AttrsData [464]byte // key-value string pairs of additional data
8268
}
8369

8470
// UnmarshalBinary decodes the product account from the on-chain format.
@@ -96,30 +82,18 @@ func (p *ProductAccount) UnmarshalBinary(buf []byte) error {
9682
return nil
9783
}
9884

99-
// GetAttrs returns the parsed set of key-value pairs.
100-
func (p *ProductAccount) GetAttrs() (map[string]string, error) {
101-
kvps := make(map[string]string)
102-
103-
attrs := p.Attrs[:]
85+
// GetAttrsMap returns the parsed set of key-value pairs.
86+
func (p *ProductAccount) GetAttrsMap() (AttrsMap, error) {
87+
// Length of attrs is determined by size value in header.
88+
data := p.AttrsData[:]
10489
maxSize := int(p.Size) - 48
105-
if maxSize > 0 && len(attrs) > maxSize {
106-
attrs = attrs[:maxSize]
90+
if maxSize > 0 && len(data) > maxSize {
91+
data = data[:maxSize]
10792
}
108-
109-
rd := bytes.NewReader(attrs)
110-
for rd.Len() > 0 {
111-
key, err := readLPString(rd)
112-
if err != nil {
113-
return kvps, err
114-
}
115-
val, err := readLPString(rd)
116-
if err != nil {
117-
return kvps, err
118-
}
119-
kvps[key] = val
120-
}
121-
122-
return kvps, nil
93+
// Unmarshal attrs.
94+
var attrs AttrsMap
95+
err := attrs.UnmarshalBinary(data)
96+
return attrs, err
12397
}
12498

12599
// Ema is an exponentially-weighted moving average.
@@ -140,6 +114,14 @@ type PriceInfo struct {
140114
PubSlot uint64 // valid publishing slot
141115
}
142116

117+
// Price status.
118+
const (
119+
PriceStatusUnknown = uint32(iota)
120+
PriceStatusTrading
121+
PriceStatusHalted
122+
PriceStatusAuction
123+
)
124+
143125
// PriceComp contains the price and confidence contributed by a specific publisher.
144126
type PriceComp struct {
145127
Publisher solana.PublicKey // key of contributing publisher

types_test.go renamed to accounts_test.go

Lines changed: 105 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ import (
2424
)
2525

2626
var (
27-
//go:embed tests/EWxGfxoPQSNA2744AYdAKmsQZ8F9o9M7oKkvL3VM1dko.bin
27+
//go:embed tests/product_account/EWxGfxoPQSNA2744AYdAKmsQZ8F9o9M7oKkvL3VM1dko.bin
2828
caseProductAccount []byte
29-
//go:embed tests/E36MyBbavhYKHVLWR79GiReNNnBDiHj6nWA7htbkNZbh.bin
29+
//go:embed tests/price_account/E36MyBbavhYKHVLWR79GiReNNnBDiHj6nWA7htbkNZbh.bin
3030
casePriceAccount []byte
31-
//go:embed tests/BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2.bin
31+
//go:embed tests/mapping_account/BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2.bin
3232
caseMappingAccount []byte
3333
)
3434

@@ -41,7 +41,7 @@ func TestProductAccount(t *testing.T) {
4141
Size: 161,
4242
},
4343
FirstPrice: solana.MustPublicKeyFromBase58("E36MyBbavhYKHVLWR79GiReNNnBDiHj6nWA7htbkNZbh"),
44-
Attrs: [464]byte{
44+
AttrsData: [464]byte{
4545
0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x0a,
4646
0x46, 0x58, 0x2e, 0x45, 0x55, 0x52, 0x2f, 0x55,
4747
0x53, 0x44, 0x0a, 0x61, 0x73, 0x73, 0x65, 0x74,
@@ -65,10 +65,9 @@ func TestProductAccount(t *testing.T) {
6565

6666
var actual ProductAccount
6767
require.NoError(t, actual.UnmarshalBinary(caseProductAccount))
68-
6968
assert.Equal(t, &expected, &actual)
7069

71-
t.Run("GetAttrs", func(t *testing.T) {
70+
t.Run("GetAttrsMap", func(t *testing.T) {
7271
expected := map[string]string{
7372
"asset_type": "FX",
7473
"base": "EUR",
@@ -78,123 +77,124 @@ func TestProductAccount(t *testing.T) {
7877
"symbol": "FX.EUR/USD",
7978
"tenor": "Spot",
8079
}
81-
actual, err := actual.GetAttrs()
80+
actualList, err := actual.GetAttrsMap()
8281
assert.NoError(t, err)
82+
actual := actualList.KVs()
8383
assert.Equal(t, expected, actual)
8484
})
8585
}
8686

87-
func TestPriceAccount(t *testing.T) {
88-
expected := PriceAccount{
89-
AccountHeader: AccountHeader{
90-
Magic: Magic,
91-
Version: V2,
92-
AccountType: AccountTypePrice,
93-
Size: 1200,
87+
var priceAccount_E36MyBbavhYKHVLWR79GiReNNnBDiHj6nWA7htbkNZbh = PriceAccount{
88+
AccountHeader: AccountHeader{
89+
Magic: Magic,
90+
Version: V2,
91+
AccountType: AccountTypePrice,
92+
Size: 1200,
93+
},
94+
PriceType: 1,
95+
Exponent: -5,
96+
Num: 10,
97+
NumQt: 0,
98+
LastSlot: 117136050,
99+
ValidSlot: 117491486,
100+
Twap: Ema{
101+
Val: 112674,
102+
Numer: 5644642336,
103+
Denom: 5009691136,
104+
},
105+
Twac: Ema{
106+
Val: 4,
107+
Numer: 2033641276,
108+
Denom: 5009691136,
109+
},
110+
Drv1: 1,
111+
Drv2: 0,
112+
Product: solana.MustPublicKeyFromBase58("EWxGfxoPQSNA2744AYdAKmsQZ8F9o9M7oKkvL3VM1dko"),
113+
Next: solana.PublicKey{},
114+
PrevSlot: 117491485,
115+
PrevPrice: 112717,
116+
PrevConf: 6,
117+
Drv3: -2413575930482041166,
118+
Agg: PriceInfo{
119+
Price: 112717,
120+
Conf: 6,
121+
Status: 0,
122+
CorpAct: 0,
123+
PubSlot: 117491487,
124+
},
125+
Components: [32]PriceComp{
126+
{
127+
Publisher: solana.MustPublicKeyFromBase58("5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7"),
128+
Agg: PriceInfo{
129+
PubSlot: 117491484,
130+
},
131+
Latest: PriceInfo{
132+
PubSlot: 117491485,
133+
},
94134
},
95-
PriceType: 1,
96-
Exponent: -5,
97-
Num: 10,
98-
NumQt: 0,
99-
LastSlot: 117136050,
100-
ValidSlot: 117491486,
101-
Twap: Ema{
102-
Val: 112674,
103-
Numer: 5644642336,
104-
Denom: 5009691136,
135+
{
136+
Publisher: solana.MustPublicKeyFromBase58("4iVm6RJVU4R6kvc3KUDnE6cw4Ffb6769FzbXMu26sJrs"),
105137
},
106-
Twac: Ema{
107-
Val: 4,
108-
Numer: 2033641276,
109-
Denom: 5009691136,
138+
{
139+
Publisher: solana.MustPublicKeyFromBase58("3djmXHmD9kuAydgFnSnWAjq4Kos5GnEx2KdFR2kvGiUw"),
110140
},
111-
Drv1: 1,
112-
Drv2: 0,
113-
Product: solana.MustPublicKeyFromBase58("EWxGfxoPQSNA2744AYdAKmsQZ8F9o9M7oKkvL3VM1dko"),
114-
Next: solana.PublicKey{},
115-
PrevSlot: 117491485,
116-
PrevPrice: 112717,
117-
PrevConf: 6,
118-
Drv3: -2413575930482041166,
119-
Agg: PriceInfo{
120-
Price: 112717,
121-
Conf: 6,
122-
Status: 0,
123-
CorpAct: 0,
124-
PubSlot: 117491487,
141+
{
142+
Publisher: solana.MustPublicKeyFromBase58("86DsXwBCqFoCUiuB1t9oV2inHKQ5h2vFaNZ4GETvTHuz"),
125143
},
126-
Components: [32]PriceComp{
127-
{
128-
Publisher: solana.MustPublicKeyFromBase58("5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7"),
129-
Agg: PriceInfo{
130-
PubSlot: 117491484,
131-
},
132-
Latest: PriceInfo{
133-
PubSlot: 117491485,
134-
},
135-
},
136-
{
137-
Publisher: solana.MustPublicKeyFromBase58("4iVm6RJVU4R6kvc3KUDnE6cw4Ffb6769FzbXMu26sJrs"),
138-
},
139-
{
140-
Publisher: solana.MustPublicKeyFromBase58("3djmXHmD9kuAydgFnSnWAjq4Kos5GnEx2KdFR2kvGiUw"),
141-
},
142-
{
143-
Publisher: solana.MustPublicKeyFromBase58("86DsXwBCqFoCUiuB1t9oV2inHKQ5h2vFaNZ4GETvTHuz"),
144-
},
145-
{
146-
Publisher: solana.MustPublicKeyFromBase58("rkTtobRtTCDLXbADsbVxHcfBr7Z8Z1JDSBM3kyk3LJe"),
147-
},
148-
{
149-
Publisher: solana.MustPublicKeyFromBase58("2pfE7YYVhM9WaneVVF2kcwArMoconfjtq83oZfSurkkY"),
150-
},
151-
{
152-
Publisher: solana.MustPublicKeyFromBase58("2vTC3XNpi7ED5T643KxVH5HqM7cSRKuUGnmMtKACY4Ju"),
144+
{
145+
Publisher: solana.MustPublicKeyFromBase58("rkTtobRtTCDLXbADsbVxHcfBr7Z8Z1JDSBM3kyk3LJe"),
146+
},
147+
{
148+
Publisher: solana.MustPublicKeyFromBase58("2pfE7YYVhM9WaneVVF2kcwArMoconfjtq83oZfSurkkY"),
149+
},
150+
{
151+
Publisher: solana.MustPublicKeyFromBase58("2vTC3XNpi7ED5T643KxVH5HqM7cSRKuUGnmMtKACY4Ju"),
152+
},
153+
{
154+
Publisher: solana.MustPublicKeyFromBase58("45FYxKkPM1NhavyAHFTyXG2JCSsy5jD1UwwCz5UtHX5y"),
155+
},
156+
{
157+
Publisher: solana.MustPublicKeyFromBase58("EevTjv14eGHqsxKvgpastHsuLr9FNPfzkP23wG61pT2U"),
158+
Agg: PriceInfo{
159+
Price: 113062,
160+
Conf: 1,
161+
Status: 1,
162+
CorpAct: 0,
163+
PubSlot: 116660829,
153164
},
154-
{
155-
Publisher: solana.MustPublicKeyFromBase58("45FYxKkPM1NhavyAHFTyXG2JCSsy5jD1UwwCz5UtHX5y"),
165+
Latest: PriceInfo{
166+
Price: 113062,
167+
Conf: 1,
168+
Status: 1,
169+
CorpAct: 0,
170+
PubSlot: 116660829,
156171
},
157-
{
158-
Publisher: solana.MustPublicKeyFromBase58("EevTjv14eGHqsxKvgpastHsuLr9FNPfzkP23wG61pT2U"),
159-
Agg: PriceInfo{
160-
Price: 113062,
161-
Conf: 1,
162-
Status: 1,
163-
CorpAct: 0,
164-
PubSlot: 116660829,
165-
},
166-
Latest: PriceInfo{
167-
Price: 113062,
168-
Conf: 1,
169-
Status: 1,
170-
CorpAct: 0,
171-
PubSlot: 116660829,
172-
},
172+
},
173+
{
174+
Publisher: solana.MustPublicKeyFromBase58("AKPWGLY5KpxbTx7DaVp4Pve8JweMjKbb1A19MyL2nrYT"),
175+
Agg: PriceInfo{
176+
Price: 111976,
177+
Conf: 16,
178+
Status: 1,
179+
CorpAct: 0,
180+
PubSlot: 116917242,
173181
},
174-
{
175-
Publisher: solana.MustPublicKeyFromBase58("AKPWGLY5KpxbTx7DaVp4Pve8JweMjKbb1A19MyL2nrYT"),
176-
Agg: PriceInfo{
177-
Price: 111976,
178-
Conf: 16,
179-
Status: 1,
180-
CorpAct: 0,
181-
PubSlot: 116917242,
182-
},
183-
Latest: PriceInfo{
184-
Price: 111976,
185-
Conf: 16,
186-
Status: 1,
187-
CorpAct: 0,
188-
PubSlot: 116917242,
189-
},
182+
Latest: PriceInfo{
183+
Price: 111976,
184+
Conf: 16,
185+
Status: 1,
186+
CorpAct: 0,
187+
PubSlot: 116917242,
190188
},
191189
},
192-
}
190+
},
191+
}
193192

193+
func TestPriceAccount(t *testing.T) {
194194
var actual PriceAccount
195195
require.NoError(t, actual.UnmarshalBinary(casePriceAccount))
196196

197-
assert.Equal(t, &expected, &actual)
197+
assert.Equal(t, &priceAccount_E36MyBbavhYKHVLWR79GiReNNnBDiHj6nWA7htbkNZbh, &actual)
198198
}
199199

200200
func TestMappingAccount(t *testing.T) {

0 commit comments

Comments
 (0)