1
1
use alloc:: vec:: Vec ;
2
+ use byteorder:: { BigEndian , ByteOrder } ;
2
3
use stylus_sdk:: {
3
4
prelude:: * ,
4
5
storage:: {
@@ -8,6 +9,15 @@ use stylus_sdk::{
8
9
use stylus_sdk:: alloy_primitives:: { U16 , FixedBytes , U64 , I32 , I64 , B256 , U256 , keccak256} ;
9
10
use pythnet_sdk:: messages:: PriceFeedMessage ;
10
11
12
+ fn serialize_data_source_to_bytes ( chain_id : u16 , emitter_address : & [ u8 ; 32 ] ) -> [ u8 ; 34 ] {
13
+ let mut bytes = [ 0u8 ; 34 ] ;
14
+
15
+ BigEndian :: write_u16 ( & mut bytes[ 0 ..2 ] , chain_id) ;
16
+ bytes[ 2 ..] . copy_from_slice ( emitter_address) ;
17
+
18
+ bytes
19
+ }
20
+
11
21
#[ derive( Debug ) ]
12
22
#[ storage]
13
23
pub struct DataSourceStorage {
@@ -23,29 +33,21 @@ pub struct DataSource {
23
33
24
34
impl StorageKey for DataSourceStorage {
25
35
fn to_slot ( & self , root : B256 ) -> U256 {
26
- let mut bytes = [ 0u8 ; 34 ] ;
27
-
28
36
let chain_id: u16 = self . chain_id . get ( ) . to :: < u16 > ( ) ;
29
- // now you can use `chain_id` as a regular u16
30
- let chain_id_bytes = chain_id. to_be_bytes ( ) ;
31
-
32
- bytes[ 0 ..2 ] . copy_from_slice ( & chain_id_bytes) ;
33
- bytes[ 2 ..] . copy_from_slice ( self . emitter_address . get ( ) . as_slice ( ) ) ;
37
+ let emitter_address = self . emitter_address . get ( ) ;
38
+
39
+ let bytes = serialize_data_source_to_bytes ( chain_id, emitter_address. as_slice ( ) . try_into ( ) . unwrap ( ) ) ;
34
40
35
41
keccak256 ( bytes) . to_slot ( root)
36
42
}
37
43
}
38
44
39
45
impl StorageKey for DataSource {
40
46
fn to_slot ( & self , root : B256 ) -> U256 {
41
- let mut bytes = [ 0u8 ; 34 ] ;
42
-
43
47
let chain_id: u16 = self . chain_id . to :: < u16 > ( ) ;
44
- // now you can use `chain_id` as a regular u16
45
- let chain_id_bytes = chain_id. to_be_bytes ( ) ;
46
-
47
- bytes[ 0 ..2 ] . copy_from_slice ( & chain_id_bytes) ;
48
- bytes[ 2 ..] . copy_from_slice ( self . emitter_address . as_slice ( ) ) ;
48
+ let emitter_address: [ u8 ; 32 ] = self . emitter_address . as_slice ( ) . try_into ( ) . unwrap ( ) ;
49
+
50
+ let bytes = serialize_data_source_to_bytes ( chain_id, & emitter_address) ;
49
51
50
52
keccak256 ( bytes) . to_slot ( root)
51
53
}
@@ -101,4 +103,29 @@ impl From<&PriceFeedMessage> for PriceInfo {
101
103
}
102
104
103
105
// PriceInfo struct storing price information
104
- pub type PriceInfoReturn = ( U64 , I32 , I64 , U64 , I64 , U64 ) ;
106
+ pub type PriceInfoReturn = ( U64 , I32 , I64 , U64 , I64 , U64 ) ;
107
+
108
+ #[ cfg( test) ]
109
+ mod tests {
110
+ use super :: * ;
111
+ use stylus_sdk:: alloy_primitives:: { U16 , FixedBytes , B256 , U256 } ;
112
+
113
+ #[ test]
114
+ fn test_data_source_serialization_compatibility ( ) {
115
+ let chain_id = 1u16 ;
116
+ let emitter_address = [ 1u8 ; 32 ] ;
117
+
118
+ let data_source = DataSource {
119
+ chain_id : U16 :: from ( chain_id) ,
120
+ emitter_address : FixedBytes :: from ( emitter_address) ,
121
+ } ;
122
+
123
+ let mut expected_bytes = [ 0u8 ; 34 ] ;
124
+ expected_bytes[ 0 ..2 ] . copy_from_slice ( & chain_id. to_be_bytes ( ) ) ;
125
+ expected_bytes[ 2 ..] . copy_from_slice ( & emitter_address) ;
126
+
127
+ let actual_bytes = serialize_data_source_to_bytes ( chain_id, & emitter_address) ;
128
+
129
+ assert_eq ! ( actual_bytes, expected_bytes, "Serialization should produce identical bytes" ) ;
130
+ }
131
+ }
0 commit comments