|
|
@@ -1,16 +1,27 @@
|
|
|
use {
|
|
|
+ crate::{
|
|
|
+ governance::GovernanceAction::{
|
|
|
+ RequestGovernanceDataSourceTransfer,
|
|
|
+ SetValidPeriod,
|
|
|
+ },
|
|
|
+ state::PythDataSource,
|
|
|
+ },
|
|
|
byteorder::{
|
|
|
BigEndian,
|
|
|
ReadBytesExt,
|
|
|
WriteBytesExt,
|
|
|
},
|
|
|
+ cosmwasm_std::Binary,
|
|
|
p2w_sdk::ErrBox,
|
|
|
schemars::JsonSchema,
|
|
|
serde::{
|
|
|
Deserialize,
|
|
|
Serialize,
|
|
|
},
|
|
|
- std::io::Write,
|
|
|
+ std::{
|
|
|
+ convert::TryFrom,
|
|
|
+ io::Write,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
const PYTH_GOVERNANCE_MAGIC: &[u8] = b"PTGM";
|
|
|
@@ -46,14 +57,14 @@ impl GovernanceModule {
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
|
#[repr(u8)]
|
|
|
pub enum GovernanceAction {
|
|
|
- UpgradeContract, // 0
|
|
|
- AuthorizeGovernanceDataSourceTransfer, // 1
|
|
|
- SetDataSources, // 2
|
|
|
+ UpgradeContract { address: [u8; 20] }, // 0
|
|
|
+ AuthorizeGovernanceDataSourceTransfer { claim_vaa: Binary }, // 1
|
|
|
+ SetDataSources { data_sources: Vec<PythDataSource> }, // 2
|
|
|
// Set the fee to val * (10 ** expo)
|
|
|
SetFee { val: u64, expo: u64 }, // 3
|
|
|
// Set the default valid period to the provided number of seconds
|
|
|
SetValidPeriod { valid_seconds: u64 }, // 4
|
|
|
- RequestGovernanceDataSourceTransfer, // 5
|
|
|
+ RequestGovernanceDataSourceTransfer { governance_data_source_index: u32 }, // 5
|
|
|
}
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
|
@@ -86,13 +97,50 @@ impl GovernanceInstruction {
|
|
|
let target_chain_id: u16 = bytes.read_u16::<BigEndian>()?;
|
|
|
|
|
|
let action: Result<GovernanceAction, String> = match action_type {
|
|
|
+ 0 => {
|
|
|
+ let mut address: [u8; 20] = [0; 20];
|
|
|
+ bytes.read_exact(&mut address)?;
|
|
|
+ Ok(GovernanceAction::UpgradeContract { address })
|
|
|
+ }
|
|
|
+ 1 => {
|
|
|
+ let mut payload: Vec<u8> = vec![];
|
|
|
+ bytes.read_to_end(&mut payload)?;
|
|
|
+ Ok(GovernanceAction::AuthorizeGovernanceDataSourceTransfer {
|
|
|
+ claim_vaa: Binary::from(payload),
|
|
|
+ })
|
|
|
+ }
|
|
|
+ 2 => {
|
|
|
+ let num_data_sources = bytes.read_u8()?;
|
|
|
+ let mut data_sources: Vec<PythDataSource> = vec![];
|
|
|
+ for _ in 0..num_data_sources {
|
|
|
+ let chain_id = bytes.read_u16::<BigEndian>()?;
|
|
|
+ let mut emitter_address: [u8; 32] = [0; 32];
|
|
|
+ bytes.read_exact(&mut emitter_address)?;
|
|
|
+
|
|
|
+ data_sources.push(PythDataSource {
|
|
|
+ emitter: Binary::from(&emitter_address),
|
|
|
+ pyth_emitter_chain: chain_id,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ Ok(GovernanceAction::SetDataSources { data_sources })
|
|
|
+ }
|
|
|
3 => {
|
|
|
let val = bytes.read_u64::<BigEndian>()?;
|
|
|
let expo = bytes.read_u64::<BigEndian>()?;
|
|
|
Ok(GovernanceAction::SetFee { val, expo })
|
|
|
}
|
|
|
- // TODO: add parsing for additional actions
|
|
|
- _ => Err(format!("Bad governance action {action_type}",)),
|
|
|
+ 4 => {
|
|
|
+ let valid_seconds = bytes.read_u64::<BigEndian>()?;
|
|
|
+ Ok(SetValidPeriod { valid_seconds })
|
|
|
+ }
|
|
|
+ 5 => {
|
|
|
+ let governance_data_source_index = bytes.read_u32::<BigEndian>()?;
|
|
|
+ Ok(RequestGovernanceDataSourceTransfer {
|
|
|
+ governance_data_source_index,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ _ => Err(format!("Unknown governance action type: {action_type}",)),
|
|
|
};
|
|
|
|
|
|
Ok(GovernanceInstruction {
|
|
|
@@ -109,17 +157,24 @@ impl GovernanceInstruction {
|
|
|
buf.write_u8(self.module.to_u8())?;
|
|
|
|
|
|
match &self.action {
|
|
|
- GovernanceAction::UpgradeContract => {
|
|
|
+ GovernanceAction::UpgradeContract { address } => {
|
|
|
buf.write_u8(0)?;
|
|
|
buf.write_u16::<BigEndian>(self.target_chain_id)?;
|
|
|
+ buf.write_all(address)?;
|
|
|
}
|
|
|
- GovernanceAction::AuthorizeGovernanceDataSourceTransfer => {
|
|
|
+ GovernanceAction::AuthorizeGovernanceDataSourceTransfer { claim_vaa } => {
|
|
|
buf.write_u8(1)?;
|
|
|
buf.write_u16::<BigEndian>(self.target_chain_id)?;
|
|
|
+ buf.write_all(claim_vaa.as_slice())?;
|
|
|
}
|
|
|
- GovernanceAction::SetDataSources => {
|
|
|
+ GovernanceAction::SetDataSources { data_sources } => {
|
|
|
buf.write_u8(2)?;
|
|
|
buf.write_u16::<BigEndian>(self.target_chain_id)?;
|
|
|
+ buf.write_u8(u8::try_from(data_sources.len())?)?;
|
|
|
+ for data_source in &data_sources {
|
|
|
+ buf.write_u16::<BigEndian>(data_source.pyth_emitter_chain)?;
|
|
|
+ buf.write_all(data_source.emitter.as_slice())?;
|
|
|
+ }
|
|
|
}
|
|
|
GovernanceAction::SetFee { val, expo } => {
|
|
|
buf.write_u8(3)?;
|
|
|
@@ -136,9 +191,12 @@ impl GovernanceInstruction {
|
|
|
|
|
|
buf.write_u64::<BigEndian>(*new_valid_period)?;
|
|
|
}
|
|
|
- GovernanceAction::RequestGovernanceDataSourceTransfer => {
|
|
|
+ GovernanceAction::RequestGovernanceDataSourceTransfer {
|
|
|
+ governance_data_source_index,
|
|
|
+ } => {
|
|
|
buf.write_u8(5)?;
|
|
|
buf.write_u16::<BigEndian>(self.target_chain_id)?;
|
|
|
+ buf.write_u32::<BigEndian>(*governance_data_source_index)?;
|
|
|
}
|
|
|
}
|
|
|
|