@@ -21,18 +21,20 @@ use {
2121
2222#[ derive( Clone , Debug , Copy ) ]
2323pub struct DataEvent {
24- price : i64 ,
25- conf : u64 ,
26- slot_gap : u64 ,
24+ price : i64 ,
25+ conf : u64 ,
26+ slot_gap : u64 ,
27+ max_latency : u8 ,
2728}
2829
2930impl Arbitrary for DataEvent {
3031 fn arbitrary ( g : & mut quickcheck:: Gen ) -> Self {
3132 DataEvent {
32- slot_gap : u64:: from ( u8:: arbitrary ( g) ) + 1 , /* Slot gap is always > 1, because there
33- * has been a succesful aggregation */
34- price : i64:: arbitrary ( g) ,
35- conf : u64:: arbitrary ( g) ,
33+ slot_gap : u64:: from ( u8:: arbitrary ( g) ) + 1 , /* Slot gap is always > 1, because there
34+ * has been a succesful aggregation */
35+ price : i64:: arbitrary ( g) ,
36+ conf : u64:: arbitrary ( g) ,
37+ max_latency : u8:: arbitrary ( g) ,
3638 }
3739 }
3840}
@@ -44,6 +46,7 @@ impl Arbitrary for DataEvent {
4446/// - slot_gap is a random number between 1 and u8::MAX + 1 (256)
4547/// - price is a random i64
4648/// - conf is a random u64
49+ /// - max_latency is a random u8
4750#[ quickcheck]
4851fn test_twap ( input : Vec < DataEvent > ) -> bool {
4952 let mut price_cumulative = PriceCumulative {
@@ -56,7 +59,12 @@ fn test_twap(input: Vec<DataEvent>) -> bool {
5659 let mut data = Vec :: < DataEvent > :: new ( ) ;
5760
5861 for data_event in input {
59- price_cumulative. update ( data_event. price , data_event. conf , data_event. slot_gap ) ;
62+ price_cumulative. update (
63+ data_event. price ,
64+ data_event. conf ,
65+ data_event. slot_gap ,
66+ data_event. max_latency ,
67+ ) ;
6068 data. push ( data_event) ;
6169 price_cumulative. check_price ( data. as_slice ( ) ) ;
6270 price_cumulative. check_conf ( data. as_slice ( ) ) ;
@@ -67,7 +75,6 @@ fn test_twap(input: Vec<DataEvent>) -> bool {
6775 true
6876}
6977
70-
7178impl PriceCumulative {
7279 pub fn check_price ( & self , data : & [ DataEvent ] ) {
7380 assert_eq ! (
@@ -87,12 +94,18 @@ impl PriceCumulative {
8794 }
8895 pub fn check_num_down_slots ( & self , data : & [ DataEvent ] ) {
8996 assert_eq ! (
90- data. iter( )
91- . fold( 0 , |acc, x| if x. slot_gap > PC_MAX_SEND_LATENCY . into( ) {
92- acc + ( x. slot_gap - PC_MAX_SEND_LATENCY as u64 )
97+ data. iter( ) . fold( 0 , |acc, x| {
98+ let latency_threshold = if x. max_latency == 0 {
99+ PC_MAX_SEND_LATENCY . into( )
100+ } else {
101+ x. max_latency. into( )
102+ } ;
103+ if x. slot_gap > latency_threshold {
104+ acc + ( x. slot_gap - latency_threshold)
93105 } else {
94106 acc
95- } ) ,
107+ }
108+ } ) ,
96109 self . num_down_slots
97110 ) ;
98111 }
@@ -112,35 +125,65 @@ fn test_twap_unit() {
112125
113126 let data = vec ! [
114127 DataEvent {
115- price: 1 ,
116- conf: 2 ,
117- slot_gap: 4 ,
128+ price: 1 ,
129+ conf: 2 ,
130+ slot_gap: 4 ,
131+ max_latency: 0 ,
132+ } ,
133+ DataEvent {
134+ price: i64 :: MAX ,
135+ conf: u64 :: MAX ,
136+ slot_gap: 1 ,
137+ max_latency: 0 ,
118138 } ,
119139 DataEvent {
120- price: i64 :: MAX ,
121- conf: u64 :: MAX ,
122- slot_gap: 1 ,
140+ price: -10 ,
141+ conf: 4 ,
142+ slot_gap: 30 ,
143+ max_latency: 0 ,
123144 } ,
124145 DataEvent {
125- price: -10 ,
126- conf: 4 ,
127- slot_gap: 30 ,
146+ price: 1 ,
147+ conf: 2 ,
148+ slot_gap: 4 ,
149+ max_latency: 5 ,
150+ } ,
151+ DataEvent {
152+ price: 6 ,
153+ conf: 7 ,
154+ slot_gap: 8 ,
155+ max_latency: 5 ,
128156 } ,
129157 ] ;
130158
131- price_cumulative. update ( data[ 0 ] . price , data[ 0 ] . conf , data[ 0 ] . slot_gap ) ;
159+ price_cumulative. update (
160+ data[ 0 ] . price ,
161+ data[ 0 ] . conf ,
162+ data[ 0 ] . slot_gap ,
163+ data[ 0 ] . max_latency ,
164+ ) ;
132165 assert_eq ! ( price_cumulative. price, 5 ) ;
133166 assert_eq ! ( price_cumulative. conf, 10 ) ;
134167 assert_eq ! ( price_cumulative. num_down_slots, 3 ) ;
135168 assert_eq ! ( price_cumulative. unused, 0 ) ;
136169
137- price_cumulative. update ( data[ 1 ] . price , data[ 1 ] . conf , data[ 1 ] . slot_gap ) ;
170+ price_cumulative. update (
171+ data[ 1 ] . price ,
172+ data[ 1 ] . conf ,
173+ data[ 1 ] . slot_gap ,
174+ data[ 1 ] . max_latency ,
175+ ) ;
138176 assert_eq ! ( price_cumulative. price, 9_223_372_036_854_775_812i128 ) ;
139177 assert_eq ! ( price_cumulative. conf, 18_446_744_073_709_551_625u128 ) ;
140178 assert_eq ! ( price_cumulative. num_down_slots, 3 ) ;
141179 assert_eq ! ( price_cumulative. unused, 0 ) ;
142180
143- price_cumulative. update ( data[ 2 ] . price , data[ 2 ] . conf , data[ 2 ] . slot_gap ) ;
181+ price_cumulative. update (
182+ data[ 2 ] . price ,
183+ data[ 2 ] . conf ,
184+ data[ 2 ] . slot_gap ,
185+ data[ 2 ] . max_latency ,
186+ ) ;
144187 assert_eq ! ( price_cumulative. price, 9_223_372_036_854_775_512i128 ) ;
145188 assert_eq ! ( price_cumulative. conf, 18_446_744_073_709_551_745u128 ) ;
146189 assert_eq ! ( price_cumulative. num_down_slots, 8 ) ;
@@ -152,7 +195,7 @@ fn test_twap_unit() {
152195 num_down_slots : 0 ,
153196 unused : 0 ,
154197 } ;
155- price_cumulative_overflow. update ( i64:: MIN , u64:: MAX , u64:: MAX ) ;
198+ price_cumulative_overflow. update ( i64:: MIN , u64:: MAX , u64:: MAX , u8 :: MAX ) ;
156199 assert_eq ! (
157200 price_cumulative_overflow. price,
158201 i128 :: MIN - i128 :: from( i64 :: MIN )
@@ -163,9 +206,38 @@ fn test_twap_unit() {
163206 ) ;
164207 assert_eq ! (
165208 price_cumulative_overflow. num_down_slots,
166- u64 :: MAX - PC_MAX_SEND_LATENCY as u64
209+ u64 :: MAX - u64 :: from ( u8 :: MAX )
167210 ) ;
168211 assert_eq ! ( price_cumulative_overflow. unused, 0 ) ;
212+
213+ let mut price_cumulative_nonzero_max_latency = PriceCumulative {
214+ price : 1 ,
215+ conf : 2 ,
216+ num_down_slots : 3 ,
217+ unused : 0 ,
218+ } ;
219+
220+ price_cumulative_nonzero_max_latency. update (
221+ data[ 3 ] . price ,
222+ data[ 3 ] . conf ,
223+ data[ 3 ] . slot_gap ,
224+ data[ 3 ] . max_latency ,
225+ ) ;
226+ assert_eq ! ( price_cumulative_nonzero_max_latency. price, 5 ) ;
227+ assert_eq ! ( price_cumulative_nonzero_max_latency. conf, 10 ) ;
228+ assert_eq ! ( price_cumulative_nonzero_max_latency. num_down_slots, 3 ) ;
229+ assert_eq ! ( price_cumulative_nonzero_max_latency. unused, 0 ) ;
230+
231+ price_cumulative_nonzero_max_latency. update (
232+ data[ 4 ] . price ,
233+ data[ 4 ] . conf ,
234+ data[ 4 ] . slot_gap ,
235+ data[ 4 ] . max_latency ,
236+ ) ;
237+ assert_eq ! ( price_cumulative_nonzero_max_latency. price, 53 ) ;
238+ assert_eq ! ( price_cumulative_nonzero_max_latency. conf, 66 ) ;
239+ assert_eq ! ( price_cumulative_nonzero_max_latency. num_down_slots, 6 ) ;
240+ assert_eq ! ( price_cumulative_nonzero_max_latency. unused, 0 ) ;
169241}
170242
171243#[ test]
@@ -224,7 +296,6 @@ fn test_twap_with_price_account() {
224296 Err ( OracleError :: NeedsSuccesfulAggregation )
225297 ) ;
226298
227-
228299 assert_eq ! ( price_data. price_cumulative. price, 1 - 2 * 10 ) ;
229300 assert_eq ! ( price_data. price_cumulative. conf, 2 + 2 * 5 ) ;
230301 assert_eq ! ( price_data. price_cumulative. num_down_slots, 3 ) ;
0 commit comments