Skip to content

Commit 28598b9

Browse files
feat: convert DataSource structs to use serde serialization
- Replace manual byte manipulation in to_slot functions with serde-based approach - Add shared serialize_data_source_to_bytes function to avoid code duplication - Maintain exact same 34-byte layout (u16 big-endian + 32 bytes) - Add test to verify compatibility with original implementation - Use byteorder crate for consistent big-endian serialization Co-Authored-By: [email protected] <[email protected]>
1 parent 1ecd765 commit 28598b9

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

target_chains/stylus/contracts/pyth-receiver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ alloy-sol-types = "=0.8.20"
1414
stylus-sdk = "0.9.0"
1515
byteorder = { version = "1.4.3" }
1616
hex = { version = "0.4", default-features = false }
17+
serde = { version = "1.0", features = ["derive"] }
1718
pythnet-sdk = { path = "../../../../pythnet/pythnet_sdk" }
1819
pyth-types = { path = "../pyth-types" }
1920
wormhole-vaas = "0.1.1"

target_chains/stylus/contracts/pyth-receiver/src/structs.rs

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use alloc::vec::Vec;
2+
use byteorder::{BigEndian, ByteOrder};
23
use stylus_sdk::{
34
prelude::*,
45
storage::{
@@ -8,6 +9,15 @@ use stylus_sdk::{
89
use stylus_sdk::alloy_primitives::{U16, FixedBytes,U64, I32, I64, B256, U256, keccak256};
910
use pythnet_sdk::messages::PriceFeedMessage;
1011

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+
1121
#[derive(Debug)]
1222
#[storage]
1323
pub struct DataSourceStorage {
@@ -23,29 +33,21 @@ pub struct DataSource {
2333

2434
impl StorageKey for DataSourceStorage {
2535
fn to_slot(&self, root: B256) -> U256 {
26-
let mut bytes = [0u8; 34];
27-
2836
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());
3440

3541
keccak256(bytes).to_slot(root)
3642
}
3743
}
3844

3945
impl StorageKey for DataSource {
4046
fn to_slot(&self, root: B256) -> U256 {
41-
let mut bytes = [0u8; 34];
42-
4347
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);
4951

5052
keccak256(bytes).to_slot(root)
5153
}
@@ -101,4 +103,29 @@ impl From<&PriceFeedMessage> for PriceInfo {
101103
}
102104

103105
// 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

Comments
 (0)