瀏覽代碼

cleaned initialize and sorted out stylus storage type issue for now. also added wormhole integration temporarily

Ayush Suresh 4 月之前
父節點
當前提交
1ceadcf97d

+ 74 - 17
target_chains/stylus/Cargo.lock

@@ -95,7 +95,7 @@ checksum = "69e32ef5c74bbeb1733c37f4ac7f866f8c8af208b7b4265e21af609dcac5bd5e"
 dependencies = [
  "alloy-eips",
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "alloy-serde",
  "alloy-trie",
  "auto_impl",
@@ -113,7 +113,7 @@ dependencies = [
  "alloy-consensus",
  "alloy-eips",
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "alloy-serde",
  "serde",
 ]
@@ -125,7 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "675264c957689f0fd75f5993a73123c2cc3b5c235a38f5b9037fe6c826bfb2c0"
 dependencies = [
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "crc",
  "thiserror 2.0.12",
 ]
@@ -137,7 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41"
 dependencies = [
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "serde",
 ]
 
@@ -148,7 +148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b15b13d38b366d01e818fe8e710d4d702ef7499eacd44926a06171dd9585d0c"
 dependencies = [
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "serde",
  "thiserror 2.0.12",
 ]
@@ -163,7 +163,7 @@ dependencies = [
  "alloy-eip2930",
  "alloy-eip7702",
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "alloy-serde",
  "auto_impl",
  "c-kzg",
@@ -237,6 +237,23 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "alloy-primitives"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f09d3cd21353cf2f41f401e35093390f2a238ce0a72af0f6fc6be5157f525c7"
+dependencies = [
+ "alloy-rlp 0.2.0",
+ "bytes",
+ "const-hex",
+ "derive_more 0.99.20",
+ "itoa",
+ "proptest",
+ "ruint2",
+ "serde",
+ "tiny-keccak",
+]
+
 [[package]]
 name = "alloy-primitives"
 version = "0.7.6"
@@ -259,7 +276,7 @@ version = "0.8.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bc1360603efdfba91151e623f13a4f4d3dc4af4adc1cbd90bf37c81e84db4c77"
 dependencies = [
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "bytes",
  "cfg-if 1.0.0",
  "const-hex",
@@ -317,6 +334,16 @@ dependencies = [
  "wasmtimer",
 ]
 
+[[package]]
+name = "alloy-rlp"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6aa8b63682a5fa571b7c0281839e267b6a1f7569ba07b9b57b093050b7c2efda"
+dependencies = [
+ "arrayvec",
+ "bytes",
+]
+
 [[package]]
 name = "alloy-rlp"
 version = "0.3.12"
@@ -384,7 +411,7 @@ dependencies = [
  "alloy-eips",
  "alloy-network-primitives",
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "alloy-serde",
  "alloy-sol-types 0.8.20",
  "itertools 0.14.0",
@@ -589,7 +616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d95a94854e420f07e962f7807485856cde359ab99ab6413883e15235ad996e8b"
 dependencies = [
  "alloy-primitives 0.8.20",
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "arrayvec",
  "derive_more 1.0.0",
  "nybbles",
@@ -3853,6 +3880,13 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "pyth-types"
+version = "0.1.0"
+dependencies = [
+ "stylus-sdk 0.6.0",
+]
+
 [[package]]
 name = "pythnet-sdk"
 version = "2.3.1"
@@ -3871,13 +3905,6 @@ dependencies = [
  "thiserror 1.0.69",
 ]
 
-[[package]]
-name = "pyth-types"
-version = "0.1.0"
-dependencies = [
- "stylus-sdk 0.6.0",
-]
-
 [[package]]
 name = "quick-error"
 version = "1.2.3"
@@ -4205,7 +4232,7 @@ version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "11256b5fe8c68f56ac6f39ef0720e592f33d2367a4782740d9c9142e889c7fb4"
 dependencies = [
- "alloy-rlp",
+ "alloy-rlp 0.3.12",
  "ark-ff 0.3.0",
  "ark-ff 0.4.2",
  "bytes",
@@ -4232,6 +4259,24 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18"
 
+[[package]]
+name = "ruint2"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b066b8e4fcea7fae86b6932d2449670b6b5545b7e8407841b2d3a916ff2a9f86"
+dependencies = [
+ "derive_more 0.99.20",
+ "ruint2-macro",
+ "rustc_version 0.4.1",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "ruint2-macro"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89dc553bc0cf4512a8b96caa2e21ed5f6e4b66bf28a1bd08fd9eb07c0b39b28c"
+
 [[package]]
 name = "rustc-demangle"
 version = "0.1.25"
@@ -4857,10 +4902,12 @@ dependencies = [
  "ethers",
  "eyre",
  "hex",
+ "pyth-types",
  "pythnet-sdk",
  "stylus-sdk 0.9.0",
  "tokio",
  "wormhole-contract",
+ "wormhole-vaas",
 ]
 
 [[package]]
@@ -5992,6 +6039,16 @@ dependencies = [
  "stylus-sdk 0.6.0",
 ]
 
+[[package]]
+name = "wormhole-vaas"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cd4775f602f96f911d079c81a12fc964fab8632d56229bbb953335bae043d73"
+dependencies = [
+ "alloy-primitives 0.2.0",
+ "hex-literal",
+]
+
 [[package]]
 name = "writeable"
 version = "0.6.1"

+ 3 - 0
target_chains/stylus/contracts/pyth-receiver/Cargo.toml

@@ -14,8 +14,11 @@ alloy-sol-types = "=0.8.20"
 stylus-sdk = "0.9.0"
 hex = { version = "0.4", default-features = false }
 pythnet-sdk = { path = "../../../../pythnet/pythnet_sdk" }
+pyth-types = { path = "../pyth-types" }
+wormhole-vaas = "0.1.1"
 wormhole-contract = { path = "../../contracts/wormhole" }
 
+
 [dev-dependencies]
 alloy-primitives = { version = "=0.8.20", features = ["sha3-keccak"] }
 tokio = { version = "1.12.0", features = ["full"] }

+ 20 - 10
target_chains/stylus/contracts/pyth-receiver/src/lib.rs

@@ -9,18 +9,19 @@ mod structs;
 mod error;
 
 use alloc::vec::Vec;
-use stylus_sdk::{alloy_primitives::{U16, U32, U256, U64, I32, I64, FixedBytes, Bytes, Address},
+use stylus_sdk::{alloy_primitives::{U16, U32, U256, U64, I32, I64, FixedBytes, Address},
                 prelude::*, 
-                storage::{StorageAddress, StorageVec, StorageMap, StorageUint, StorageBool, StorageU256, StorageU16, StorageFixedBytes},
+                storage::{StorageGuardMut, StorageAddress, StorageVec, StorageMap, StorageUint, StorageBool, StorageU256, StorageU16, StorageFixedBytes},
                 call::Call};
 
-use structs::{PriceInfoReturn, PriceInfoStorage, DataSourceStorage};
+use structs::{PriceInfoReturn, PriceInfoStorage, DataSourceStorage, DataSource};
 use error::{PythReceiverError};
 use pythnet_sdk::{wire::{v1::{
             AccumulatorUpdateData, Proof,
         },
     },
 };
+use wormhole_vaas::{Readable, Vaa, VaaBody, VaaHeader};
 
 sol_interface! {
     interface IWormholeContract {
@@ -36,7 +37,7 @@ sol_interface! {
 pub struct PythReceiver {
     pub wormhole: StorageAddress,
     pub valid_data_sources: StorageVec<DataSourceStorage>,
-    pub is_valid_data_source: StorageMap<FixedBytes<32>, StorageBool>,
+    pub is_valid_data_source: StorageMap<DataSource, StorageBool>,
     pub single_update_fee_in_wei: StorageU256,
     pub valid_time_period_seconds: StorageU256,
     pub governance_data_source_chain_id: StorageU16,
@@ -71,9 +72,15 @@ impl PythReceiver {
             let mut data_source = self.valid_data_sources.grow();
             data_source.chain_id.set(U16::from(*chain_id));
             data_source.emitter_address.set(emitter_address);
+
+            let data_source_key = DataSource {
+                chain_id: U16::from(*chain_id),
+                emitter_address: emitter_address,
+            };
             
+
             self.is_valid_data_source
-                .setter(emitter_address)
+                .setter(data_source_key)
                 .set(true);
         }
     }
@@ -121,15 +128,18 @@ impl PythReceiver {
             Proof::WormholeMerkle { vaa, updates } => {
                 let wormhole: IWormholeContract = IWormholeContract::new(self.wormhole.get());
                 let config = Call::new_in(self);
-                let _parsed_vaa = wormhole.parse_and_verify_vm(config, Bytes::from(Vec::from(vaa))).map_err(|_| PythReceiverError::PriceUnavailable).unwrap();
-
-                if !self.is_valid_data_source.entry(_parsed_vaa.data_source()).read() {
-                    panic!("Update data source is not a valid data source.");
-                }
+                let parsed_vaa = wormhole.parse_and_verify_vm(config, Vec::from(vaa)).map_err(|_| PythReceiverError::PriceUnavailable).unwrap();
+                let vaa = Vaa::read(&mut parsed_vaa.as_slice()).unwrap();
 
                 for update in updates {
                     // fill in update processing logic.
                     // update is a merkle price update
+
+                    // pub struct MerklePriceUpdate {
+                    //     pub message: PrefixedVec<u16, u8>,
+                    //     pub proof: MerklePath<Keccak160>,
+                    // }
+
                     let message = update.message;
                     let proof = update.proof;
 

+ 55 - 14
target_chains/stylus/contracts/pyth-receiver/src/structs.rs

@@ -1,30 +1,71 @@
 use alloc::vec::Vec;
-use stylus_sdk::{prelude::*, storage::{StorageU64, StorageI32, StorageI64, StorageU16, StorageFixedBytes}};
-use stylus_sdk::alloy_primitives::{U64, I32, I64, U16, FixedBytes};
-use wormhole_contract::types::VerifiedVM;
+use stylus_sdk::{
+    prelude::*,
+    storage::{
+        StorageU64, StorageI32, StorageI64, StorageU16, StorageFixedBytes, StorageKey
+    }
+};
+use stylus_sdk::alloy_primitives::{U16, FixedBytes,U64, I32, I64, B256, U256, keccak256};
 
+#[derive(Debug)]
 #[storage]
 pub struct DataSourceStorage {
     pub chain_id: StorageU16,
     pub emitter_address: StorageFixedBytes<32>,
 }
 
-pub trait GetDataSource {
-    fn data_source(&self) -> DataSourceStorage;
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct DataSource {
+    pub chain_id: U16,
+    pub emitter_address: FixedBytes<32>,
+}
+
+impl StorageKey for DataSourceStorage {
+    fn to_slot(&self, root: B256) -> U256 {
+        let mut bytes = [0u8; 34];
+
+        let chain_id: u16 = self.chain_id.get().to::<u16>();
+        // now you can use `chain_id` as a regular u16
+        let chain_id_bytes = chain_id.to_be_bytes();
+        
+        bytes[0..2].copy_from_slice(&chain_id_bytes);
+        bytes[2..].copy_from_slice(self.emitter_address.get().as_slice());
+
+        keccak256(bytes).to_slot(root)
+    }
 }
 
-impl GetDataSource for VerifiedVM {
-    fn data_source(&self) -> DataSourceStorage {
-        let mut ds = DataSourceStorage {
-            chain_id: StorageU16::default(),
-            emitter_address: StorageFixedBytes::<32>::default(),
-        };
-        ds.chain_id.set(U16::from(self.emitter_chain_id));
-        ds.emitter_address.set(self.emitter_address);
-        ds
+impl StorageKey for DataSource {
+    fn to_slot(&self, root: B256) -> U256 {
+        let mut bytes = [0u8; 34];
+
+        let chain_id: u16 = self.chain_id.to::<u16>();
+        // now you can use `chain_id` as a regular u16
+        let chain_id_bytes = chain_id.to_be_bytes();
+        
+        bytes[0..2].copy_from_slice(&chain_id_bytes);
+        bytes[2..].copy_from_slice(self.emitter_address.as_slice());
+
+        keccak256(bytes).to_slot(root)
     }
 }
 
+// pub trait GetDataSource {
+//     fn data_source(&self) -> DataSourceStorage;
+// }
+
+// impl GetDataSource for VerifiedVM {
+//     fn data_source(&self) -> DataSourceStorage {
+//         let mut ds = DataSourceStorage {
+//             chain_id: StorageU16::new(storage_key!("chain_id")),
+//             emitter_address: StorageFixedBytes::<32>::new(storage_key!("emitter_address")),
+//         };
+//         ds.chain_id.set(self.emitter_chain_id.into());
+//         ds.emitter_address.set(self.emitter_address);
+//         ds
+//     }
+// }
+
 // PriceInfo struct storing price information
 #[storage]
 pub struct PriceInfoStorage {