@@ -19,355 +19,3 @@ Test(oracle, pc_size ) {
1919 3 * sizeof ( pc_pub_key_t ) + sizeof ( pc_price_info_t ) +
2020 PC_COMP_SIZE * sizeof ( pc_price_comp_t ) );
2121}
22-
23- Test ( oracle , upd_price ) {
24- cmd_upd_price_t idata = {
25- .ver_ = PC_VERSION ,
26- .cmd_ = e_cmd_upd_price ,
27- .status_ = PC_STATUS_TRADING ,
28- .price_ = 42L ,
29- .conf_ = 2L ,
30- .pub_slot_ = 1
31- };
32- SolPubkey p_id = {.x = { 0xff , }};
33- SolPubkey pkey = {.x = { 1 , }};
34- SolPubkey skey = {.x = { 3 , }};
35- sysvar_clock_t cvar = {
36- .slot_ = 1
37- };
38- uint64_t pqty = 100 , sqty = 200 ;
39- pc_price_t sptr [1 ];
40- sol_memset ( sptr , 0 , sizeof ( pc_price_t ) );
41- sptr -> magic_ = PC_MAGIC ;
42- sptr -> ver_ = PC_VERSION ;
43- sptr -> ptype_ = PC_PTYPE_PRICE ;
44- sptr -> type_ = PC_ACCTYPE_PRICE ;
45- sptr -> num_ = 1 ;
46- pc_pub_key_assign ( & sptr -> comp_ [0 ].pub_ , (pc_pub_key_t * )& pkey );
47- SolAccountInfo acc [] = {{
48- .key = & pkey ,
49- .lamports = & pqty ,
50- .data_len = 0 ,
51- .data = NULL ,
52- .owner = NULL ,
53- .rent_epoch = 0 ,
54- .is_signer = true,
55- .is_writable = true,
56- .executable = false
57- },{
58- .key = & skey ,
59- .lamports = & PRICE_ACCOUNT_LAMPORTS ,
60- .data_len = sizeof ( pc_price_t ),
61- .data = (uint8_t * )sptr ,
62- .owner = & p_id ,
63- .rent_epoch = 0 ,
64- .is_signer = false,
65- .is_writable = true,
66- .executable = false
67- },{
68- .key = (SolPubkey * )sysvar_clock ,
69- .lamports = & sqty ,
70- .data_len = sizeof ( sysvar_clock_t ),
71- .data = (uint8_t * )& cvar ,
72- .owner = & p_id ,
73- .rent_epoch = 0 ,
74- .is_signer = false,
75- .is_writable = false,
76- .executable = false
77- }};
78- SolParameters prm = {
79- .ka = acc ,
80- .ka_num = 3 ,
81- .data = (const uint8_t * )& idata ,
82- .data_len = sizeof ( idata ),
83- .program_id = & p_id
84- };
85- cr_assert ( SUCCESS == dispatch ( & prm , acc ) );
86- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 42L );
87- cr_assert ( sptr -> comp_ [0 ].latest_ .conf_ == 2L );
88- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 1 );
89- cr_assert ( sptr -> agg_ .pub_slot_ == 1 );
90- cr_assert ( sptr -> valid_slot_ == 0 );
91-
92- // add some prices for current slot - get rejected
93- idata .price_ = 43 ;
94- cr_assert ( ERROR_INVALID_ARGUMENT == dispatch ( & prm , acc ) );
95- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 42L );
96- cr_assert ( sptr -> comp_ [0 ].agg_ .price_ == 0 );
97-
98- // add next price in new slot triggering snapshot and aggregate calc
99- idata .price_ = 81 ;
100- idata .pub_slot_ = 2 ;
101- cvar .slot_ = 3 ;
102- cr_assert ( SUCCESSFULLY_UPDATED_AGGREGATE == dispatch ( & prm , acc ) );
103- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 81L );
104- cr_assert ( sptr -> comp_ [0 ].agg_ .price_ == 42L );
105- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 2 );
106- cr_assert ( sptr -> agg_ .pub_slot_ == 3 );
107- cr_assert ( sptr -> valid_slot_ == 1 );
108-
109- // next price doesnt change but slot does
110- cvar .slot_ = 4 ;
111- idata .pub_slot_ = 3 ;
112- cr_assert ( SUCCESSFULLY_UPDATED_AGGREGATE == dispatch ( & prm , acc ) );
113- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 81L );
114- cr_assert ( sptr -> comp_ [0 ].agg_ .price_ == 81L );
115- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 3 );
116- cr_assert ( sptr -> agg_ .pub_slot_ == 4 );
117- cr_assert ( sptr -> valid_slot_ == 3 );
118-
119- // next price doesnt change and neither does aggregate but slot does
120- idata .pub_slot_ = 4 ;
121- cvar .slot_ = 5 ;
122- cr_assert ( SUCCESSFULLY_UPDATED_AGGREGATE == dispatch ( & prm , acc ) );
123- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 81L );
124- cr_assert ( sptr -> comp_ [0 ].agg_ .price_ == 81L );
125- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 4 );
126- cr_assert ( sptr -> agg_ .pub_slot_ == 5 );
127- cr_assert ( sptr -> valid_slot_ == 4 );
128-
129- // try to publish back-in-time
130- idata .pub_slot_ = 1 ;
131- cr_assert ( ERROR_INVALID_ARGUMENT == dispatch ( & prm , acc ) );
132-
133-
134- // Publishing a wide CI results in a status of unknown.
135-
136- // check that someone doesn't accidentally break the test.
137- cr_assert (sptr -> comp_ [0 ].latest_ .status_ == PC_STATUS_TRADING );
138- idata .pub_slot_ = 5 ;
139- cvar .slot_ = 6 ;
140- idata .price_ = 50 ;
141- idata .conf_ = 6 ;
142- cr_assert ( SUCCESSFULLY_UPDATED_AGGREGATE == dispatch ( & prm , acc ) );
143- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 50L );
144- cr_assert ( sptr -> comp_ [0 ].latest_ .conf_ == 6L );
145- cr_assert ( sptr -> comp_ [0 ].latest_ .status_ == PC_STATUS_UNKNOWN );
146- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 5 );
147- cr_assert ( sptr -> agg_ .pub_slot_ == 6 );
148- // Aggregate is still trading because it uses price from previous slot
149- cr_assert ( sptr -> agg_ .status_ == PC_STATUS_TRADING );
150-
151- // Crank one more time and aggregate should be unknown
152- idata .pub_slot_ = 6 ;
153- cvar .slot_ = 7 ;
154- cr_assert ( SUCCESS == dispatch ( & prm , acc ) );
155- cr_assert ( sptr -> agg_ .status_ == PC_STATUS_UNKNOWN );
156- }
157-
158- Test ( oracle , upd_price_no_fail_on_error ) {
159- cmd_upd_price_t idata = {
160- .ver_ = PC_VERSION ,
161- .cmd_ = e_cmd_upd_price_no_fail_on_error ,
162- .status_ = PC_STATUS_TRADING ,
163- .price_ = 42L ,
164- .conf_ = 9L ,
165- .pub_slot_ = 1
166- };
167- SolPubkey p_id = {.x = { 0xff , }};
168- SolPubkey pkey = {.x = { 1 , }};
169- SolPubkey skey = {.x = { 3 , }};
170- sysvar_clock_t cvar = {
171- .slot_ = 1
172- };
173- uint64_t pqty = 100 , sqty = 200 ;
174- pc_price_t sptr [1 ];
175- sol_memset ( sptr , 0 , sizeof ( pc_price_t ) );
176- sptr -> magic_ = PC_MAGIC ;
177- sptr -> ver_ = PC_VERSION ;
178- sptr -> ptype_ = PC_PTYPE_PRICE ;
179- sptr -> type_ = PC_ACCTYPE_PRICE ;
180- sptr -> num_ = 1 ;
181-
182- SolAccountInfo acc [] = {{
183- .key = & pkey ,
184- .lamports = & pqty ,
185- .data_len = 0 ,
186- .data = NULL ,
187- .owner = NULL ,
188- .rent_epoch = 0 ,
189- .is_signer = true,
190- .is_writable = true,
191- .executable = false
192- },{
193- .key = & skey ,
194- .lamports = & PRICE_ACCOUNT_LAMPORTS ,
195- .data_len = sizeof ( pc_price_t ),
196- .data = (uint8_t * )sptr ,
197- .owner = & p_id ,
198- .rent_epoch = 0 ,
199- .is_signer = false,
200- .is_writable = true,
201- .executable = false
202- },{
203- .key = (SolPubkey * )sysvar_clock ,
204- .lamports = & sqty ,
205- .data_len = sizeof ( sysvar_clock_t ),
206- .data = (uint8_t * )& cvar ,
207- .owner = & p_id ,
208- .rent_epoch = 0 ,
209- .is_signer = false,
210- .is_writable = false,
211- .executable = false
212- }};
213- SolParameters prm = {
214- .ka = acc ,
215- .ka_num = 3 ,
216- .data = (const uint8_t * )& idata ,
217- .data_len = sizeof ( idata ),
218- .program_id = & p_id
219- };
220-
221- // We haven't permissioned the publish account for the price account
222- // yet, so any update should fail silently and have no effect. The
223- // transaction should "succeed".
224- cr_assert ( SUCCESS == dispatch ( & prm , acc ) );
225- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 0L );
226- cr_assert ( sptr -> comp_ [0 ].latest_ .conf_ == 0L );
227- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 0 );
228- cr_assert ( sptr -> agg_ .pub_slot_ == 0 );
229- cr_assert ( sptr -> valid_slot_ == 0 );
230-
231- // Now permission the publish account for the price account.
232- pc_pub_key_assign ( & sptr -> comp_ [0 ].pub_ , (pc_pub_key_t * )& pkey );
233-
234- // The update should now succeed, and have an effect.
235- cr_assert ( SUCCESS == dispatch ( & prm , acc ) );
236- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 42L );
237- cr_assert ( sptr -> comp_ [0 ].latest_ .conf_ == 9L );
238- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 1 );
239- cr_assert ( sptr -> agg_ .pub_slot_ == 1 );
240- cr_assert ( sptr -> valid_slot_ == 0 );
241-
242- // Invalid updates, such as publishing an update for the current slot,
243- // should still fail silently and have no effect.
244- idata .price_ = 55L ;
245- idata .conf_ = 22L ;
246- idata .pub_slot_ = 1 ;
247- cr_assert ( SUCCESS == dispatch ( & prm , acc ) );
248- cr_assert ( sptr -> comp_ [0 ].latest_ .price_ == 42L );
249- cr_assert ( sptr -> comp_ [0 ].latest_ .conf_ == 9L );
250- cr_assert ( sptr -> comp_ [0 ].latest_ .pub_slot_ == 1 );
251- cr_assert ( sptr -> agg_ .pub_slot_ == 1 );
252- cr_assert ( sptr -> valid_slot_ == 0 );
253- }
254-
255- Test ( oracle , upd_aggregate ) {
256- pc_price_t px [1 ];
257- sol_memset ( px , 0 , sizeof ( pc_price_t ) );
258- pc_price_info_t p1 = { .price_ = 100 , .conf_ = 10 ,
259- .status_ = PC_STATUS_TRADING , .corp_act_status_ = 0 , .pub_slot_ = 1000 };
260- pc_price_info_t p2 = { .price_ = 200 , .conf_ = 20 ,
261- .status_ = PC_STATUS_TRADING , .corp_act_status_ = 0 , .pub_slot_ = 1000 };
262- pc_price_info_t p3 = { .price_ = 300 , .conf_ = 30 ,
263- .status_ = PC_STATUS_TRADING , .corp_act_status_ = 0 , .pub_slot_ = 1000 };
264- pc_price_info_t p4 = { .price_ = 400 , .conf_ = 40 ,
265- .status_ = PC_STATUS_TRADING , .corp_act_status_ = 0 , .pub_slot_ = 1000 };
266-
267- // single publisher
268- px -> num_ = 1 ;
269- px -> last_slot_ = 1000 ;
270- px -> agg_ .pub_slot_ = 1000 ;
271- px -> comp_ [0 ].latest_ = p1 ;
272- upd_aggregate ( px , 1001 , 1 );
273- cr_assert ( px -> agg_ .price_ == 100 );
274- cr_assert ( px -> agg_ .conf_ == 10 );
275- cr_assert ( px -> twap_ .val_ == 100 );
276- cr_assert ( px -> twac_ .val_ == 10 );
277- cr_assert ( px -> num_qt_ == 1 );
278- cr_assert ( px -> timestamp_ == 1 );
279- cr_assert ( px -> prev_slot_ == 0 );
280- cr_assert ( px -> prev_price_ == 0 );
281- cr_assert ( px -> prev_conf_ == 0 );
282- cr_assert ( px -> prev_timestamp_ == 0 );
283-
284- // two publishers
285- px -> num_ = 0 ;
286- px -> last_slot_ = 1000 ;
287- px -> agg_ .pub_slot_ = 1000 ;
288- px -> comp_ [px -> num_ ++ ].latest_ = p2 ;
289- px -> comp_ [px -> num_ ++ ].latest_ = p1 ;
290- upd_aggregate ( px , 1001 , 2 );
291- cr_assert ( px -> agg_ .price_ == 145 );
292- cr_assert ( px -> agg_ .conf_ == 55 );
293- cr_assert ( px -> twap_ .val_ == 106 );
294- cr_assert ( px -> twac_ .val_ == 16 );
295- cr_assert ( px -> num_qt_ == 2 );
296- cr_assert ( px -> timestamp_ == 2 );
297- cr_assert ( px -> prev_slot_ == 1000 );
298- cr_assert ( px -> prev_price_ == 100 );
299- cr_assert ( px -> prev_conf_ == 10 );
300- cr_assert ( px -> prev_timestamp_ == 1 );
301-
302- // three publishers
303- px -> num_ = 0 ;
304- px -> last_slot_ = 1000 ;
305- px -> agg_ .pub_slot_ = 1000 ;
306- px -> comp_ [px -> num_ ++ ].latest_ = p2 ;
307- px -> comp_ [px -> num_ ++ ].latest_ = p1 ;
308- px -> comp_ [px -> num_ ++ ].latest_ = p3 ;
309- upd_aggregate ( px , 1001 , 3 );
310- cr_assert ( px -> agg_ .price_ == 200 );
311- cr_assert ( px -> agg_ .conf_ == 90 );
312- cr_assert ( px -> twap_ .val_ == 114 );
313- cr_assert ( px -> twac_ .val_ == 23 );
314- cr_assert ( px -> num_qt_ == 3 );
315- cr_assert ( px -> timestamp_ == 3 );
316- cr_assert ( px -> prev_slot_ == 1000 );
317- cr_assert ( px -> prev_price_ == 145 );
318- cr_assert ( px -> prev_conf_ == 55 );
319- cr_assert ( px -> prev_timestamp_ == 2 );
320-
321- // four publishers
322- px -> num_ = 0 ;
323- px -> last_slot_ = 1000 ;
324- px -> agg_ .pub_slot_ = 1000 ;
325- px -> comp_ [px -> num_ ++ ].latest_ = p3 ;
326- px -> comp_ [px -> num_ ++ ].latest_ = p1 ;
327- px -> comp_ [px -> num_ ++ ].latest_ = p4 ;
328- px -> comp_ [px -> num_ ++ ].latest_ = p2 ;
329- upd_aggregate ( px , 1001 , 4 );
330- cr_assert ( px -> agg_ .price_ == 245 );
331- cr_assert ( px -> agg_ .conf_ == 85 );
332- cr_assert ( px -> twap_ .val_ == 125 );
333- cr_assert ( px -> twac_ .val_ == 28 );
334- cr_assert ( px -> last_slot_ == 1001 );
335- cr_assert ( px -> num_qt_ == 4 );
336- cr_assert ( px -> timestamp_ == 4 );
337- cr_assert ( px -> prev_slot_ == 1000 );
338- cr_assert ( px -> prev_price_ == 200 );
339- cr_assert ( px -> prev_conf_ == 90 );
340- cr_assert ( px -> prev_timestamp_ == 3 );
341-
342- upd_aggregate ( px , 1025 , 5 );
343- cr_assert ( px -> agg_ .status_ == PC_STATUS_TRADING );
344- cr_assert ( px -> last_slot_ == 1025 );
345- cr_assert ( px -> num_qt_ == 4 );
346- cr_assert ( px -> timestamp_ == 5 );
347- cr_assert ( px -> prev_slot_ == 1001 );
348- cr_assert ( px -> prev_price_ == 245 );
349- cr_assert ( px -> prev_conf_ == 85 );
350- cr_assert ( px -> prev_timestamp_ == 4 );
351-
352- // check what happens when nothing publishes for a while
353- upd_aggregate ( px , 1026 , 10 );
354- cr_assert ( px -> agg_ .status_ == PC_STATUS_UNKNOWN );
355- cr_assert ( px -> last_slot_ == 1025 );
356- cr_assert ( px -> num_qt_ == 0 );
357- cr_assert ( px -> timestamp_ == 10 );
358- cr_assert ( px -> prev_slot_ == 1025 );
359- cr_assert ( px -> prev_timestamp_ == 5 );
360-
361- // Check that the prev_* fields don't update if the aggregate status is UNKNOWN
362- uint64_t prev_slot_ = px -> prev_slot_ ;
363- int64_t prev_price_ = px -> prev_price_ ;
364- uint64_t prev_conf_ = px -> prev_conf_ ;
365- int64_t prev_timestamp_ = px -> prev_timestamp_ ;
366- upd_aggregate ( px , 1028 , 12 );
367- cr_assert ( px -> agg_ .status_ == PC_STATUS_UNKNOWN );
368- cr_assert ( px -> timestamp_ == 12 );
369- cr_assert ( px -> prev_slot_ == prev_slot_ );
370- cr_assert ( px -> prev_price_ == prev_price_ );
371- cr_assert ( px -> prev_conf_ == prev_conf_ );
372- cr_assert ( px -> prev_timestamp_ == prev_timestamp_ );
373- }
0 commit comments