structs.rs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. use alloc::vec::Vec;
  2. use stylus_sdk::alloy_primitives::{keccak256, FixedBytes, B256, I32, I64, U16, U256, U64};
  3. use stylus_sdk::{
  4. prelude::*,
  5. storage::{StorageFixedBytes, StorageI32, StorageI64, StorageKey, StorageU16, StorageU64},
  6. };
  7. fn serialize_data_source_to_bytes(chain_id: u16, emitter_address: &[u8; 32]) -> [u8; 34] {
  8. let mut result = [0u8; 34];
  9. result[0..2].copy_from_slice(&chain_id.to_be_bytes());
  10. result[2..].copy_from_slice(emitter_address);
  11. result
  12. }
  13. #[derive(Debug)]
  14. #[storage]
  15. pub struct DataSourceStorage {
  16. pub chain_id: StorageU16,
  17. pub emitter_address: StorageFixedBytes<32>,
  18. }
  19. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
  20. pub struct DataSource {
  21. pub chain_id: U16,
  22. pub emitter_address: FixedBytes<32>,
  23. }
  24. impl StorageKey for DataSource {
  25. fn to_slot(&self, root: B256) -> U256 {
  26. let chain_id: u16 = self.chain_id.to::<u16>();
  27. let emitter_address: [u8; 32] = self.emitter_address.as_slice().try_into().unwrap();
  28. let bytes = serialize_data_source_to_bytes(chain_id, &emitter_address);
  29. keccak256(bytes).to_slot(root)
  30. }
  31. }
  32. #[storage]
  33. pub struct PriceInfoStorage {
  34. pub publish_time: StorageU64,
  35. pub expo: StorageI32,
  36. pub price: StorageI64,
  37. pub conf: StorageU64,
  38. pub ema_price: StorageI64,
  39. pub ema_conf: StorageU64,
  40. }
  41. // Addressing nit -- running into some versioning issues that preclude me
  42. // from returning the PriceInfo struct directly. Need to figure that out.
  43. // pub struct PriceInfo {
  44. // pub publish_time: U64,
  45. // pub expo: I32,
  46. // pub price: I64,
  47. // pub conf: U64,
  48. // pub ema_price: I64,
  49. // pub ema_conf: U64,
  50. // }
  51. pub type PriceInfoReturn = (U64, I32, I64, U64, I64, U64);
  52. #[cfg(test)]
  53. mod tests {
  54. use super::*;
  55. use stylus_sdk::alloy_primitives::{FixedBytes, U16};
  56. #[test]
  57. fn test_data_source_serialization_compatibility() {
  58. let chain_id = 1u16;
  59. let emitter_address = [1u8; 32];
  60. let _data_source = DataSource {
  61. chain_id: U16::from(chain_id),
  62. emitter_address: FixedBytes::from(emitter_address),
  63. };
  64. let mut expected_bytes = [0u8; 34];
  65. expected_bytes[0..2].copy_from_slice(&chain_id.to_be_bytes());
  66. expected_bytes[2..].copy_from_slice(&emitter_address);
  67. let actual_bytes = serialize_data_source_to_bytes(chain_id, &emitter_address);
  68. assert_eq!(
  69. actual_bytes, expected_bytes,
  70. "Serialization should produce identical bytes"
  71. );
  72. }
  73. }