@@ -5,16 +5,23 @@ use adex_primitives::{
5
5
supermarket:: units_for_slot,
6
6
supermarket:: units_for_slot:: response:: { AdUnit , Campaign } ,
7
7
targeting:: { self , input, Value } ,
8
- BigNum , ChannelId , SpecValidators ,
8
+ BigNum , ChannelId , SpecValidators , IPFS ,
9
9
} ;
10
10
use async_std:: { sync:: RwLock , task:: block_on} ;
11
11
use chrono:: { DateTime , Utc } ;
12
12
use lazy_static:: lazy_static;
13
+ use num_integer:: Integer ;
13
14
use rand:: Rng ;
14
15
use reqwest:: StatusCode ;
15
16
use serde:: { Deserialize , Serialize } ;
16
17
use slog:: { error, Logger } ;
17
- use std:: { cmp:: Ordering , collections:: VecDeque , convert:: TryFrom , sync:: Arc } ;
18
+ use std:: {
19
+ cmp:: Ordering ,
20
+ collections:: VecDeque ,
21
+ convert:: TryFrom ,
22
+ ops:: { Add , Mul } ,
23
+ sync:: Arc ,
24
+ } ;
18
25
use thiserror:: Error ;
19
26
use units_for_slot:: response:: UnitsWithPrice ;
20
27
use url:: Url ;
@@ -44,7 +51,7 @@ pub struct Options {
44
51
// Defaulted via defaultOpts
45
52
#[ serde( rename = "marketURL" ) ]
46
53
pub market_url : String ,
47
- pub market_slot : String ,
54
+ pub market_slot : IPFS ,
48
55
pub publisher_addr : String ,
49
56
// All passed tokens must be of the same price and decimals, so that the amounts can be accurately compared
50
57
pub whitelisted_tokens : Vec < String > ,
@@ -66,9 +73,9 @@ impl Options {
66
73
#[ derive( Debug , Clone ) ]
67
74
pub struct HistoryEntry {
68
75
time : DateTime < Utc > ,
69
- unit_id : String ,
76
+ unit_id : IPFS ,
70
77
campaign_id : ChannelId ,
71
- slot_id : String ,
78
+ slot_id : IPFS ,
72
79
}
73
80
74
81
#[ derive( Serialize ) ]
@@ -77,8 +84,8 @@ struct Event {
77
84
#[ serde( rename = "type" ) ]
78
85
event_type : String ,
79
86
publisher : String ,
80
- ad_unit : String ,
81
- ad_slot : String ,
87
+ ad_unit : IPFS ,
88
+ ad_slot : IPFS ,
82
89
#[ serde( rename = "ref" ) ]
83
90
referrer : String ,
84
91
}
@@ -149,16 +156,15 @@ fn is_video(ad_unit: &AdUnit) -> bool {
149
156
ad_unit. media_mime . split ( '/' ) . next ( ) == Some ( "video" )
150
157
}
151
158
152
- // @TODO: IMPL
153
- // function randomizedSortPos(unit: Unit, seed: BN): BN {
154
- // // using base32 is technically wrong (IDs are in base 58), but it works well enough for this purpose
155
- // // kind of a LCG PRNG but without the state; using GCC's constraints as seen on stack overflow
156
- // // takes around ~700ms for 100k iterations, yields very decent distribution (e.g. 724ms 50070, 728ms 49936)
157
- // return new BN(unit.id, 32).mul(seed).add(new BN(12345)).mod(new BN(0x80000000))
158
- // }
159
- fn randomized_sort_pos ( _ad_unit : & AdUnit , _seed : BigNum ) -> BigNum {
160
- // todo!("Implement the randomized_sort_pos() function!")
161
- BigNum :: from ( 10 )
159
+ /// Does not copy the JS impl, instead it generates the BigNum from the IPFS CID bytes instead
160
+ fn randomized_sort_pos ( ad_unit : & AdUnit , seed : BigNum ) -> BigNum {
161
+ let bytes = ad_unit. id . 0 . to_bytes ( ) ;
162
+
163
+ let unit_id = BigNum :: from_bytes_be ( & bytes) ;
164
+
165
+ let x: BigNum = unit_id. mul ( seed) . add ( BigNum :: from ( 12345 ) ) ;
166
+
167
+ x. mod_floor ( & BigNum :: from ( 0x80000000 ) )
162
168
}
163
169
164
170
fn get_unit_html (
@@ -605,10 +611,11 @@ pub struct StickyAdUnit {
605
611
#[ cfg( test) ]
606
612
mod test {
607
613
use super :: * ;
614
+ use adex_primitives:: util:: tests:: prep_db:: DUMMY_IPFS ;
608
615
609
616
fn get_ad_unit ( media_mime : & str ) -> AdUnit {
610
617
AdUnit {
611
- id : "" . to_string ( ) ,
618
+ id : DUMMY_IPFS [ 0 ] . clone ( ) ,
612
619
media_url : "" . to_string ( ) ,
613
620
media_mime : media_mime. to_string ( ) ,
614
621
target_url : "" . to_string ( ) ,
@@ -633,4 +640,24 @@ mod test {
633
640
// Non-IPFS case
634
641
assert_eq ! ( "http://123" . to_string( ) , normalize_url( "http://123" ) ) ;
635
642
}
643
+
644
+ mod randomized_sort_pos {
645
+
646
+ use super :: * ;
647
+
648
+ #[ test]
649
+ fn test_randomized_position ( ) {
650
+ let ad_unit = AdUnit {
651
+ id : DUMMY_IPFS [ 0 ] . clone ( ) ,
652
+ media_url : "ipfs://QmWWQSuPMS6aXCbZKpEjPHPUZN2NjB3YrhJTHsV4X3vb2t" . to_string ( ) ,
653
+ media_mime : "image/jpeg" . to_string ( ) ,
654
+ target_url : "https://google.com" . to_string ( ) ,
655
+ } ;
656
+
657
+ let result = randomized_sort_pos ( & ad_unit, 5 . into ( ) ) ;
658
+
659
+ // The seed is responsible for generating different results since the AdUnit IPFS can be the same
660
+ assert_eq ! ( BigNum :: from( 177_349_401 ) , result) ;
661
+ }
662
+ }
636
663
}
0 commit comments