pyth2wormhole: rustfmt --config-path solana/rustfmt.toml

commit-id:a4fae495
This commit is contained in:
Stan Drozd 2022-02-24 14:43:51 +01:00 committed by Reisen
parent b13c565e59
commit 0642288697
8 changed files with 109 additions and 71 deletions

View File

@ -35,10 +35,10 @@ pub struct Cli {
pub enum Action {
#[clap(about = "Initialize a pyth2wormhole program freshly deployed under <p2w_addr>")]
Init {
/// The bridge program account
#[clap(short = 'w', long = "wh-prog")]
wh_prog: Pubkey,
#[clap(short = 'o', long = "owner")]
/// The bridge program account
#[clap(short = 'w', long = "wh-prog")]
wh_prog: Pubkey,
#[clap(short = 'o', long = "owner")]
owner_addr: Pubkey,
#[clap(short = 'p', long = "pyth-owner")]
pyth_owner_addr: Pubkey,
@ -47,20 +47,22 @@ pub enum Action {
about = "Use an existing pyth2wormhole program to attest product price information to another chain"
)]
Attest {
#[clap(short = 'f', long = "--config", about = "Attestation YAML config")]
attestation_cfg: PathBuf,
#[clap(short = 'f', long = "--config", about = "Attestation YAML config")]
attestation_cfg: PathBuf,
},
#[clap(about = "Update an existing pyth2wormhole program's settings (currently set owner only)")]
#[clap(
about = "Update an existing pyth2wormhole program's settings (currently set owner only)"
)]
SetConfig {
/// Current owner keypair path
/// Current owner keypair path
#[clap(long = "owner", default_value = "~/.config/solana/id.json")]
owner: String,
/// New owner to set
owner: String,
/// New owner to set
#[clap(long = "new-owner")]
new_owner_addr: Pubkey,
new_owner_addr: Pubkey,
#[clap(long = "new-wh-prog")]
new_wh_prog: Pubkey,
new_wh_prog: Pubkey,
#[clap(long = "new-pyth-owner")]
new_pyth_owner_addr: Pubkey,
new_pyth_owner_addr: Pubkey,
},
}

View File

@ -1,6 +1,9 @@
use crate::{
config::P2WConfigAccount,
types::{PriceAttestation, batch_serialize},
types::{
batch_serialize,
PriceAttestation,
},
};
use borsh::{
BorshDeserialize,
@ -97,7 +100,6 @@ pub struct Attest<'b> {
// pub pyth_product10: Option<Info<'b>>,
// pub pyth_price10: Option<Info<'b>>,
pub clock: Sysvar<'b, Clock>,
/// Wormhole program address - must match the config value
@ -108,7 +110,6 @@ pub struct Attest<'b> {
// This contract makes no attempt to exhaustively validate
// Wormhole's account inputs. Only the wormhole contract address
// is validated (see above).
/// Bridge config needed for fee calculation
pub wh_bridge: Mut<Info<'b>>,
@ -162,9 +163,8 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
accs.pyth_price4.as_ref(),
accs.pyth_product5.as_ref(),
accs.pyth_price5.as_ref(),
// Did you read the comment near `pyth_product`?
// accs.pyth_product6.as_ref(),
// Did you read the comment near `pyth_product`?
// accs.pyth_product6.as_ref(),
// accs.pyth_price6.as_ref(),
// accs.pyth_product7.as_ref(),
// accs.pyth_price7.as_ref(),
@ -192,45 +192,41 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
let mut attestations = Vec::with_capacity(price_pairs.len() / 2);
for pair in price_pairs.as_slice().chunks_exact(2) {
let product = pair[0];
let price = pair[1];
let product = pair[0];
let price = pair[1];
if accs.config.pyth_owner != *price.owner
|| accs.config.pyth_owner != *product.owner
{
if accs.config.pyth_owner != *price.owner || accs.config.pyth_owner != *product.owner {
trace!(&format!(
"Pair {:?} - {:?}: pyth_owner pubkey mismatch (expected {:?}, got product owner {:?} and price owner {:?}",
product, price,
product, price,
accs.config.pyth_owner, product.owner, price.owner
));
return Err(SolitaireError::InvalidOwner(accs.pyth_price.owner.clone()).into());
}
let attestation = PriceAttestation::from_pyth_price_bytes(
price.key.clone(),
accs.clock.unix_timestamp,
&*price.try_borrow_data()?,
)?;
let attestation = PriceAttestation::from_pyth_price_bytes(
price.key.clone(),
accs.clock.unix_timestamp,
&*price.try_borrow_data()?,
)?;
// The following check is crucial against poorly ordered
// account inputs, e.g. [Some(prod1), Some(price1),
// Some(prod2), None, None, Some(price)], interpreted by
// earlier logic as [(prod1, price1), (prod2, price3)].
//
// Failing to verify the product/price relationship could lead
// to mismatched product/price metadata, which would result in
// a false attestation.
if &attestation.product_id != product.key {
trace!(&format!(
"Price's product_id does not match the pased account (points at {:?} instead)",
attestation.product_id
));
return Err(ProgramError::InvalidAccountData.into());
}
// The following check is crucial against poorly ordered
// account inputs, e.g. [Some(prod1), Some(price1),
// Some(prod2), None, None, Some(price)], interpreted by
// earlier logic as [(prod1, price1), (prod2, price3)].
//
// Failing to verify the product/price relationship could lead
// to mismatched product/price metadata, which would result in
// a false attestation.
if &attestation.product_id != product.key {
trace!(&format!(
"Price's product_id does not match the pased account (points at {:?} instead)",
attestation.product_id
));
return Err(ProgramError::InvalidAccountData.into());
}
attestations.push(attestation);
attestations.push(attestation);
}
trace!("Attestations successfully created");
@ -249,12 +245,12 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
let post_message_data = (
bridge::instruction::Instruction::PostMessage,
PostMessageData {
nonce: 0, // Superseded by the sequence number
nonce: 0, // Superseded by the sequence number
payload: batch_serialize(attestations.as_slice().iter()).map_err(|e| {
trace!(e.to_string());
ProgramError::InvalidAccountData
})?,
consistency_level: data.consistency_level,
trace!(e.to_string());
ProgramError::InvalidAccountData
})?,
consistency_level: data.consistency_level,
},
);

View File

@ -5,9 +5,18 @@
//! problems related to max batch size mismatches between config and
//! contract logic. See attest.rs for details.
use borsh::{BorshDeserialize, BorshSerialize};
use borsh::{
BorshDeserialize,
BorshSerialize,
};
use solana_program::pubkey::Pubkey;
use solitaire::{processors::seeded::AccountOwner, AccountState, Data, Derive, Owned};
use solitaire::{
processors::seeded::AccountOwner,
AccountState,
Data,
Derive,
Owned,
};
#[derive(Default, BorshDeserialize, BorshSerialize)]
pub struct Pyth2WormholeConfig {

View File

@ -1,11 +1,27 @@
use solana_program::pubkey::Pubkey;
use solitaire::{AccountState, CreationLamports, ExecutionContext, FromAccounts, Info, InstructionContext, Keyed, Mut, Peel, Result as SoliResult, Signer, ToInstruction};
use solitaire::{
AccountState,
CreationLamports,
ExecutionContext,
FromAccounts,
Info,
InstructionContext,
Keyed,
Mut,
Peel,
Result as SoliResult,
Signer,
ToInstruction,
};
use crate::config::{P2WConfigAccount, Pyth2WormholeConfig};
use crate::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
};
#[derive(FromAccounts, ToInstruction)]
pub struct Initialize<'b> {
pub new_config: Mut<P2WConfigAccount<'b, {AccountState::Uninitialized}>>,
pub new_config: Mut<P2WConfigAccount<'b, { AccountState::Uninitialized }>>,
pub payer: Mut<Signer<Info<'b>>>,
}

View File

@ -1,4 +1,3 @@
#![feature(adt_const_params)]
pub mod attest;
pub mod config;
@ -29,7 +28,6 @@ solitaire! {
SetConfig(Pyth2WormholeConfig) => set_config,
}
#[cfg(feature = "wasm")]
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
pub mod wasm;

View File

@ -47,7 +47,6 @@ use self::pyth_extensions::{
P2WPriceType,
};
/// Precedes every message implementing the p2w serialization format
pub const P2W_MAGIC: &'static [u8] = b"P2WH";

View File

@ -1,7 +1,11 @@
//! This module contains 1:1 (or close) copies of selected Pyth types
//! with quick and dirty enhancements.
use std::{convert::TryInto, io::Read, mem};
use std::{
convert::TryInto,
io::Read,
mem,
};
use pyth_client::{
CorpAction,
@ -13,7 +17,10 @@ use solitaire::ErrBox;
/// 1:1 Copy of pyth_client::PriceType with derived additional traits.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "wasm", derive(serde_derive::Serialize, serde_derive::Deserialize))]
#[cfg_attr(
feature = "wasm",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[repr(u8)]
pub enum P2WPriceType {
Unknown,
@ -37,7 +44,10 @@ impl Default for P2WPriceType {
/// 1:1 Copy of pyth_client::PriceStatus with derived additional traits.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "wasm", derive(serde_derive::Serialize, serde_derive::Deserialize))]
#[cfg_attr(
feature = "wasm",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum P2WPriceStatus {
Unknown,
Trading,
@ -64,7 +74,10 @@ impl Default for P2WPriceStatus {
/// 1:1 Copy of pyth_client::CorpAction with derived additional traits.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "wasm", derive(serde_derive::Serialize, serde_derive::Deserialize))]
#[cfg_attr(
feature = "wasm",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub enum P2WCorpAction {
NoCorpAct,
}
@ -85,7 +98,10 @@ impl From<&CorpAction> for P2WCorpAction {
/// 1:1 Copy of pyth_client::Ema with all-pub fields.
#[derive(Clone, Default, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "wasm", derive(serde_derive::Serialize, serde_derive::Deserialize))]
#[cfg_attr(
feature = "wasm",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[repr(C)]
pub struct P2WEma {
pub val: i64,
@ -146,7 +162,7 @@ impl P2WEma {
let mut val_vec = vec![0u8; mem::size_of::<i64>()];
bytes.read_exact(val_vec.as_mut_slice())?;
let val = i64::from_be_bytes(val_vec.as_slice().try_into()?);
let mut numer_vec = vec![0u8; mem::size_of::<i64>()];
bytes.read_exact(numer_vec.as_mut_slice())?;
let numer = i64::from_be_bytes(numer_vec.as_slice().try_into()?);

View File

@ -1,10 +1,13 @@
use solitaire::Seeded;
use solana_program::pubkey::Pubkey;
use solitaire::Seeded;
use wasm_bindgen::prelude::*;
use std::str::FromStr;
use crate::{attest::P2WEmitter, types};
use crate::{
attest::P2WEmitter,
types,
};
#[wasm_bindgen]
pub fn get_emitter_address(program_id: String) -> Vec<u8> {
@ -17,14 +20,13 @@ pub fn get_emitter_address(program_id: String) -> Vec<u8> {
#[wasm_bindgen]
pub fn parse_attestation(bytes: Vec<u8>) -> JsValue {
let a = types::PriceAttestation::deserialize(bytes.as_slice()).unwrap();
JsValue::from_serde(&a).unwrap()
}
#[wasm_bindgen]
pub fn parse_batch_attestation(bytes: Vec<u8>) -> JsValue {
let a = types::batch_deserialize(bytes.as_slice()).unwrap();
JsValue::from_serde(&a).unwrap()
}