Skip to content

Commit 1ceadcf

Browse files
committed
cleaned initialize and sorted out stylus storage type issue for now. also added wormhole integration temporarily
1 parent 2fb67fe commit 1ceadcf

File tree

4 files changed

+152
-41
lines changed

4 files changed

+152
-41
lines changed

target_chains/stylus/Cargo.lock

Lines changed: 74 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ alloy-sol-types = "=0.8.20"
1414
stylus-sdk = "0.9.0"
1515
hex = { version = "0.4", default-features = false }
1616
pythnet-sdk = { path = "../../../../pythnet/pythnet_sdk" }
17+
pyth-types = { path = "../pyth-types" }
18+
wormhole-vaas = "0.1.1"
1719
wormhole-contract = { path = "../../contracts/wormhole" }
1820

21+
1922
[dev-dependencies]
2023
alloy-primitives = { version = "=0.8.20", features = ["sha3-keccak"] }
2124
tokio = { version = "1.12.0", features = ["full"] }

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

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ mod structs;
99
mod error;
1010

1111
use alloc::vec::Vec;
12-
use stylus_sdk::{alloy_primitives::{U16, U32, U256, U64, I32, I64, FixedBytes, Bytes, Address},
12+
use stylus_sdk::{alloy_primitives::{U16, U32, U256, U64, I32, I64, FixedBytes, Address},
1313
prelude::*,
14-
storage::{StorageAddress, StorageVec, StorageMap, StorageUint, StorageBool, StorageU256, StorageU16, StorageFixedBytes},
14+
storage::{StorageGuardMut, StorageAddress, StorageVec, StorageMap, StorageUint, StorageBool, StorageU256, StorageU16, StorageFixedBytes},
1515
call::Call};
1616

17-
use structs::{PriceInfoReturn, PriceInfoStorage, DataSourceStorage};
17+
use structs::{PriceInfoReturn, PriceInfoStorage, DataSourceStorage, DataSource};
1818
use error::{PythReceiverError};
1919
use pythnet_sdk::{wire::{v1::{
2020
AccumulatorUpdateData, Proof,
2121
},
2222
},
2323
};
24+
use wormhole_vaas::{Readable, Vaa, VaaBody, VaaHeader};
2425

2526
sol_interface! {
2627
interface IWormholeContract {
@@ -36,7 +37,7 @@ sol_interface! {
3637
pub struct PythReceiver {
3738
pub wormhole: StorageAddress,
3839
pub valid_data_sources: StorageVec<DataSourceStorage>,
39-
pub is_valid_data_source: StorageMap<FixedBytes<32>, StorageBool>,
40+
pub is_valid_data_source: StorageMap<DataSource, StorageBool>,
4041
pub single_update_fee_in_wei: StorageU256,
4142
pub valid_time_period_seconds: StorageU256,
4243
pub governance_data_source_chain_id: StorageU16,
@@ -71,9 +72,15 @@ impl PythReceiver {
7172
let mut data_source = self.valid_data_sources.grow();
7273
data_source.chain_id.set(U16::from(*chain_id));
7374
data_source.emitter_address.set(emitter_address);
75+
76+
let data_source_key = DataSource {
77+
chain_id: U16::from(*chain_id),
78+
emitter_address: emitter_address,
79+
};
7480

81+
7582
self.is_valid_data_source
76-
.setter(emitter_address)
83+
.setter(data_source_key)
7784
.set(true);
7885
}
7986
}
@@ -121,15 +128,18 @@ impl PythReceiver {
121128
Proof::WormholeMerkle { vaa, updates } => {
122129
let wormhole: IWormholeContract = IWormholeContract::new(self.wormhole.get());
123130
let config = Call::new_in(self);
124-
let _parsed_vaa = wormhole.parse_and_verify_vm(config, Bytes::from(Vec::from(vaa))).map_err(|_| PythReceiverError::PriceUnavailable).unwrap();
125-
126-
if !self.is_valid_data_source.entry(_parsed_vaa.data_source()).read() {
127-
panic!("Update data source is not a valid data source.");
128-
}
131+
let parsed_vaa = wormhole.parse_and_verify_vm(config, Vec::from(vaa)).map_err(|_| PythReceiverError::PriceUnavailable).unwrap();
132+
let vaa = Vaa::read(&mut parsed_vaa.as_slice()).unwrap();
129133

130134
for update in updates {
131135
// fill in update processing logic.
132136
// update is a merkle price update
137+
138+
// pub struct MerklePriceUpdate {
139+
// pub message: PrefixedVec<u16, u8>,
140+
// pub proof: MerklePath<Keccak160>,
141+
// }
142+
133143
let message = update.message;
134144
let proof = update.proof;
135145

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

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,71 @@
11
use alloc::vec::Vec;
2-
use stylus_sdk::{prelude::*, storage::{StorageU64, StorageI32, StorageI64, StorageU16, StorageFixedBytes}};
3-
use stylus_sdk::alloy_primitives::{U64, I32, I64, U16, FixedBytes};
4-
use wormhole_contract::types::VerifiedVM;
2+
use stylus_sdk::{
3+
prelude::*,
4+
storage::{
5+
StorageU64, StorageI32, StorageI64, StorageU16, StorageFixedBytes, StorageKey
6+
}
7+
};
8+
use stylus_sdk::alloy_primitives::{U16, FixedBytes,U64, I32, I64, B256, U256, keccak256};
59

10+
#[derive(Debug)]
611
#[storage]
712
pub struct DataSourceStorage {
813
pub chain_id: StorageU16,
914
pub emitter_address: StorageFixedBytes<32>,
1015
}
1116

12-
pub trait GetDataSource {
13-
fn data_source(&self) -> DataSourceStorage;
17+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18+
pub struct DataSource {
19+
pub chain_id: U16,
20+
pub emitter_address: FixedBytes<32>,
21+
}
22+
23+
impl StorageKey for DataSourceStorage {
24+
fn to_slot(&self, root: B256) -> U256 {
25+
let mut bytes = [0u8; 34];
26+
27+
let chain_id: u16 = self.chain_id.get().to::<u16>();
28+
// now you can use `chain_id` as a regular u16
29+
let chain_id_bytes = chain_id.to_be_bytes();
30+
31+
bytes[0..2].copy_from_slice(&chain_id_bytes);
32+
bytes[2..].copy_from_slice(self.emitter_address.get().as_slice());
33+
34+
keccak256(bytes).to_slot(root)
35+
}
1436
}
1537

16-
impl GetDataSource for VerifiedVM {
17-
fn data_source(&self) -> DataSourceStorage {
18-
let mut ds = DataSourceStorage {
19-
chain_id: StorageU16::default(),
20-
emitter_address: StorageFixedBytes::<32>::default(),
21-
};
22-
ds.chain_id.set(U16::from(self.emitter_chain_id));
23-
ds.emitter_address.set(self.emitter_address);
24-
ds
38+
impl StorageKey for DataSource {
39+
fn to_slot(&self, root: B256) -> U256 {
40+
let mut bytes = [0u8; 34];
41+
42+
let chain_id: u16 = self.chain_id.to::<u16>();
43+
// now you can use `chain_id` as a regular u16
44+
let chain_id_bytes = chain_id.to_be_bytes();
45+
46+
bytes[0..2].copy_from_slice(&chain_id_bytes);
47+
bytes[2..].copy_from_slice(self.emitter_address.as_slice());
48+
49+
keccak256(bytes).to_slot(root)
2550
}
2651
}
2752

53+
// pub trait GetDataSource {
54+
// fn data_source(&self) -> DataSourceStorage;
55+
// }
56+
57+
// impl GetDataSource for VerifiedVM {
58+
// fn data_source(&self) -> DataSourceStorage {
59+
// let mut ds = DataSourceStorage {
60+
// chain_id: StorageU16::new(storage_key!("chain_id")),
61+
// emitter_address: StorageFixedBytes::<32>::new(storage_key!("emitter_address")),
62+
// };
63+
// ds.chain_id.set(self.emitter_chain_id.into());
64+
// ds.emitter_address.set(self.emitter_address);
65+
// ds
66+
// }
67+
// }
68+
2869
// PriceInfo struct storing price information
2970
#[storage]
3071
pub struct PriceInfoStorage {

0 commit comments

Comments
 (0)