Abehjati/repo-improvement (#395)

* Use a new rustfmt file

* Run cosmwasm action only when needed

* Remove pre-commit from remote-executor action

* Fix formatting

* Run precommit for all files

As previous PR was merged without pre-commit
This commit is contained in:
Ali Behjati 2022-11-25 11:16:58 +01:00 committed by GitHub
parent c3fefc78fa
commit becc216853
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 1181 additions and 1195 deletions

View File

@ -2,9 +2,15 @@ name: Pyth CosmWasm Contract
on: on:
pull_request: pull_request:
paths:
- cosmwasm/**
- third_party/pyth/p2w-sdk/rust/**
push: push:
branches: branches:
- main - main
paths:
- cosmwasm/**
- third_party/pyth/p2w-sdk/rust/**
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always

View File

@ -17,7 +17,6 @@ jobs:
profile: minimal profile: minimal
toolchain: nightly toolchain: nightly
components: rustfmt, clippy components: rustfmt, clippy
- uses: pre-commit/action@v2.0.3
- name: Install Solana - name: Install Solana
run: | run: |
sh -c "$(curl -sSfL https://release.solana.com/stable/install)" sh -c "$(curl -sSfL https://release.solana.com/stable/install)"

View File

@ -17,10 +17,10 @@ repos:
- repo: local - repo: local
hooks: hooks:
# Hooks for the remote executor # Hooks for the remote executor
- id: cargo-fmt-executor - id: cargo-fmt-executor-remote-executor
name: Cargo format executor name: Cargo format executor for remote executor
language: "rust" language: "rust"
entry: cargo +nightly fmt --manifest-path ./pythnet/remote-executor/Cargo.toml --all entry: cargo +nightly fmt --manifest-path ./pythnet/remote-executor/Cargo.toml --all -- --config-path rustfmt.toml
pass_filenames: false pass_filenames: false
files: pythnet/remote-executor/ files: pythnet/remote-executor/
- id: cargo-clippy-executor - id: cargo-clippy-executor
@ -30,9 +30,16 @@ repos:
pass_filenames: false pass_filenames: false
files: pythnet/remote-executor/ files: pythnet/remote-executor/
# Hooks for the attester # Hooks for the attester
- id: cargo-fmt-executor - id: cargo-fmt-executor-attester
name: Cargo format executor name: Cargo format executor for attester
language: "rust" language: "rust"
entry: cargo +nightly fmt --manifest-path ./solana/pyth2wormhole/Cargo.toml --all entry: cargo +nightly fmt --manifest-path ./solana/pyth2wormhole/Cargo.toml --all -- --config-path rustfmt.toml
pass_filenames: false pass_filenames: false
files: solana/pyth2wormhole/ files: solana/pyth2wormhole/
# Hooks for cosmwasm contract
- id: cargo-fmt-executor-cosmwasm
name: Cargo format executor form cosmwasm contract
language: "rust"
entry: cargo +nightly fmt --manifest-path ./cosmwasm/Cargo.toml --all -- --config-path rustfmt.toml
pass_filenames: false
files: cosmwasm/

View File

@ -1,6 +1,25 @@
use std::collections::HashSet; use {
crate::{
use cosmwasm_std::{ error::PythContractError,
msg::{
ExecuteMsg,
InstantiateMsg,
MigrateMsg,
PriceFeedResponse,
QueryMsg,
},
state::{
config,
config_read,
price_info,
price_info_read,
ConfigInfo,
PriceInfo,
PythDataSource,
VALID_TIME_PERIOD,
},
},
cosmwasm_std::{
entry_point, entry_point,
to_binary, to_binary,
Binary, Binary,
@ -13,40 +32,21 @@ use cosmwasm_std::{
StdResult, StdResult,
Timestamp, Timestamp,
WasmQuery, WasmQuery,
}; },
p2w_sdk::BatchPriceAttestation,
use pyth_sdk_cw::{ pyth_sdk_cw::{
PriceFeed, PriceFeed,
PriceIdentifier, PriceIdentifier,
PriceStatus, PriceStatus,
ProductIdentifier, ProductIdentifier,
},
std::collections::HashSet,
wormhole::{
msg::QueryMsg as WormholeQueryMsg,
state::ParsedVAA,
},
}; };
use crate::msg::{
ExecuteMsg,
InstantiateMsg,
MigrateMsg,
PriceFeedResponse,
QueryMsg,
};
use crate::state::{
config,
config_read,
price_info,
price_info_read,
ConfigInfo,
PriceInfo,
PythDataSource,
VALID_TIME_PERIOD,
};
use crate::error::PythContractError;
use p2w_sdk::BatchPriceAttestation;
use wormhole::msg::QueryMsg as WormholeQueryMsg;
use wormhole::state::ParsedVAA;
#[cfg_attr(not(feature = "library"), entry_point)] #[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> { pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Response> {
Ok(Response::new()) Ok(Response::new())
@ -303,27 +303,28 @@ pub fn query_price_feed(deps: Deps, env: Env, address: &[u8]) -> StdResult<Price
price_feed: price_info.price_feed, price_feed: price_info.price_feed,
}) })
} }
Err(_) => Err(PythContractError::PriceFeedNotFound)? Err(_) => Err(PythContractError::PriceFeedNotFound)?,
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use cosmwasm_std::testing::{ use {
super::*,
cosmwasm_std::{
testing::{
mock_dependencies, mock_dependencies,
mock_env, mock_env,
mock_info, mock_info,
MockApi, MockApi,
MockQuerier, MockQuerier,
MockStorage, MockStorage,
}; },
use cosmwasm_std::{
Addr, Addr,
OwnedDeps, OwnedDeps,
},
}; };
use super::*;
fn setup_test() -> (OwnedDeps<MockStorage, MockApi, MockQuerier>, Env) { fn setup_test() -> (OwnedDeps<MockStorage, MockApi, MockQuerier>, Env) {
(mock_dependencies(), mock_env()) (mock_dependencies(), mock_env())
} }

View File

@ -1,5 +1,7 @@
use cosmwasm_std::StdError; use {
use thiserror::Error; cosmwasm_std::StdError,
thiserror::Error,
};
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum PythContractError { pub enum PythContractError {

View File

@ -1,12 +1,13 @@
use cosmwasm_std::Binary; use {
use schemars::JsonSchema; crate::state::PythDataSource,
use serde::{ cosmwasm_std::Binary,
schemars::JsonSchema,
serde::{
Deserialize, Deserialize,
Serialize, Serialize,
},
}; };
use crate::state::PythDataSource;
type HumanAddr = String; type HumanAddr = String;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]

View File

@ -1,21 +1,11 @@
use std::collections::HashSet; use {
use std::time::Duration; cosmwasm_std::{
use pyth_sdk_cw::PriceFeed;
use schemars::JsonSchema;
use serde::{
Deserialize,
Serialize,
};
use cosmwasm_std::{
Addr, Addr,
Binary, Binary,
Storage, Storage,
Timestamp, Timestamp,
}; },
cosmwasm_storage::{
use cosmwasm_storage::{
bucket, bucket,
bucket_read, bucket_read,
singleton, singleton,
@ -24,6 +14,17 @@ use cosmwasm_storage::{
ReadonlyBucket, ReadonlyBucket,
ReadonlySingleton, ReadonlySingleton,
Singleton, Singleton,
},
pyth_sdk_cw::PriceFeed,
schemars::JsonSchema,
serde::{
Deserialize,
Serialize,
},
std::{
collections::HashSet,
time::Duration,
},
}; };
pub static CONFIG_KEY: &[u8] = b"config"; pub static CONFIG_KEY: &[u8] = b"config";

View File

@ -1,22 +0,0 @@
# Merge similar crates together to avoid multiple use statements.
imports_granularity = "Module"
# Consistency in formatting makes tool based searching/editing better.
empty_item_single_line = false
# Easier editing when arbitrary mixed use statements do not collapse.
imports_layout = "Vertical"
# Default rustfmt formatting of match arms with branches is awful.
match_arm_leading_pipes = "Preserve"
# Align Fields
enum_discrim_align_threshold = 80
struct_field_align_threshold = 80
# Allow up to two blank lines for grouping.
blank_lines_upper_bound = 2
# Wrap comments
comment_width = 120
wrap_comments = true

View File

@ -1,11 +1,13 @@
//! CLI options //! CLI options
use clap::{ use {
clap::{
Parser, Parser,
Subcommand, Subcommand,
}; },
use solana_sdk::{ solana_sdk::{
commitment_config::CommitmentConfig, commitment_config::CommitmentConfig,
pubkey::Pubkey, pubkey::Pubkey,
},
}; };
#[derive(Parser, Debug)] #[derive(Parser, Debug)]

View File

@ -1,8 +1,7 @@
#![deny(warnings)] #![deny(warnings)]
pub mod cli; pub mod cli;
use std::str::FromStr; use {
anchor_client::{
use anchor_client::{
anchor_lang::{ anchor_lang::{
AccountDeserialize, AccountDeserialize,
AnchorDeserialize, AnchorDeserialize,
@ -12,22 +11,28 @@ use anchor_client::{
ToAccountMetas, ToAccountMetas,
}, },
solana_sdk::bpf_loader_upgradeable, solana_sdk::bpf_loader_upgradeable,
}; },
use clap::Parser; anyhow::Result,
use cli::{ clap::Parser,
cli::{
Action, Action,
Cli, Cli,
}; },
remote_executor::{
use anyhow::Result;
use remote_executor::{
accounts::ExecutePostedVaa, accounts::ExecutePostedVaa,
state::governance_payload::InstructionData, state::{
governance_payload::{
ExecutorPayload,
GovernanceHeader,
InstructionData,
},
posted_vaa::AnchorVaa,
},
EXECUTOR_KEY_SEED, EXECUTOR_KEY_SEED,
ID, ID,
}; },
use solana_client::rpc_client::RpcClient; solana_client::rpc_client::RpcClient,
use solana_sdk::{ solana_sdk::{
instruction::{ instruction::{
AccountMeta, AccountMeta,
Instruction, Instruction,
@ -38,11 +43,15 @@ use solana_sdk::{
Keypair, Keypair,
}, },
signer::Signer, signer::Signer,
system_instruction, system_instruction::{
system_instruction::transfer, self,
transfer,
},
transaction::Transaction, transaction::Transaction,
}; },
use wormhole_solana::{ std::str::FromStr,
wormhole::VAA,
wormhole_solana::{
instructions::{ instructions::{
post_message, post_message,
post_vaa, post_vaa,
@ -54,16 +63,8 @@ use wormhole_solana::{
FeeCollector, FeeCollector,
GuardianSet, GuardianSet,
VAA as PostedVAA, VAA as PostedVAA,
};
use remote_executor::state::{
governance_payload::{
ExecutorPayload,
GovernanceHeader,
}, },
posted_vaa::AnchorVaa,
}; };
use wormhole::VAA;
fn main() -> Result<()> { fn main() -> Result<()> {
let cli = Cli::parse(); let cli = Cli::parse();

View File

@ -1,19 +1,21 @@
#![deny(warnings)] #![deny(warnings)]
#![allow(clippy::result_large_err)] #![allow(clippy::result_large_err)]
use anchor_lang::{ use {
anchor_lang::{
prelude::*, prelude::*,
solana_program::borsh::get_packed_len, solana_program::borsh::get_packed_len,
system_program, system_program,
}; },
use error::ExecutorError; error::ExecutorError,
use state::{ state::{
claim_record::ClaimRecord, claim_record::ClaimRecord,
posted_vaa::AnchorVaa, posted_vaa::AnchorVaa,
}; },
use wormhole::Chain::{ wormhole::Chain::{
self, self,
Solana, Solana,
},
}; };
mod error; mod error;
@ -27,15 +29,15 @@ declare_id!("exe6S3AxPVNmy46L4Nj6HrnnAVQUhwyYzMSNcnRn3qq");
#[program] #[program]
pub mod remote_executor { pub mod remote_executor {
use anchor_lang::solana_program::{ use {
super::*,
crate::state::governance_payload::ExecutorPayload,
anchor_lang::solana_program::{
instruction::Instruction, instruction::Instruction,
program::invoke_signed, program::invoke_signed,
},
}; };
use crate::state::governance_payload::ExecutorPayload;
use super::*;
pub fn execute_posted_vaa(ctx: Context<ExecutePostedVaa>) -> Result<()> { pub fn execute_posted_vaa(ctx: Context<ExecutePostedVaa>) -> Result<()> {
let posted_vaa = &ctx.accounts.posted_vaa; let posted_vaa = &ctx.accounts.posted_vaa;
let claim_record = &mut ctx.accounts.claim_record; let claim_record = &mut ctx.accounts.claim_record;

View File

@ -1,18 +1,18 @@
use std::{ use {
crate::error::ExecutorError,
anchor_lang::{
prelude::*,
solana_program::instruction::Instruction,
},
boolinator::Boolinator,
std::{
io::ErrorKind, io::ErrorKind,
mem::size_of, mem::size_of,
ops::Deref, ops::Deref,
},
wormhole::Chain,
}; };
use anchor_lang::{
prelude::*,
solana_program::instruction::Instruction,
};
use boolinator::Boolinator;
use wormhole::Chain;
use crate::error::ExecutorError;
pub const MAGIC_NUMBER: u32 = 0x4d475450; // Reverse order of the solidity contract because borsh uses little endian numbers (the solidity contract uses 0x5054474d) pub const MAGIC_NUMBER: u32 = 0x4d475450; // Reverse order of the solidity contract because borsh uses little endian numbers (the solidity contract uses 0x5054474d)
#[derive(AnchorDeserialize, AnchorSerialize, Debug, PartialEq, Eq)] #[derive(AnchorDeserialize, AnchorSerialize, Debug, PartialEq, Eq)]
@ -170,17 +170,18 @@ impl ExecutorPayload {
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use crate::{ use {
super::ExecutorPayload,
crate::{
error, error,
error::ExecutorError, error::ExecutorError,
state::governance_payload::InstructionData, state::governance_payload::InstructionData,
}; },
anchor_lang::{
use super::ExecutorPayload;
use anchor_lang::{
prelude::Pubkey, prelude::Pubkey,
AnchorDeserialize, AnchorDeserialize,
AnchorSerialize, AnchorSerialize,
},
}; };
#[test] #[test]

View File

@ -1,10 +1,12 @@
use anchor_lang::prelude::*; use {
use std::{ anchor_lang::prelude::*,
std::{
io::Write, io::Write,
ops::Deref, ops::Deref,
str::FromStr, str::FromStr,
},
wormhole_solana::VAA,
}; };
use wormhole_solana::VAA;
// The current chain's wormhole bridge owns the VAA accounts // The current chain's wormhole bridge owns the VAA accounts
impl Owner for AnchorVaa { impl Owner for AnchorVaa {

View File

@ -1,4 +1,19 @@
use anchor_lang::{ use {
crate::{
error::ExecutorError,
state::{
claim_record::ClaimRecord,
governance_payload::{
ExecutorPayload,
GovernanceHeader,
InstructionData,
},
posted_vaa::AnchorVaa,
},
CLAIM_RECORD_SEED,
EXECUTOR_KEY_SEED,
},
anchor_lang::{
prelude::{ prelude::{
AccountMeta, AccountMeta,
ProgramError, ProgramError,
@ -14,16 +29,16 @@ use anchor_lang::{
Key, Key,
Owner, Owner,
ToAccountMetas, ToAccountMetas,
}; },
use solana_program_test::{ solana_program_test::{
find_file, find_file,
read_file, read_file,
BanksClient, BanksClient,
BanksClientError, BanksClientError,
ProgramTest, ProgramTest,
ProgramTestBanksClientExt, ProgramTestBanksClientExt,
}; },
use solana_sdk::{ solana_sdk::{
account::Account, account::Account,
bpf_loader_upgradeable, bpf_loader_upgradeable,
instruction::{ instruction::{
@ -38,24 +53,10 @@ use solana_sdk::{
Transaction, Transaction,
TransactionError, TransactionError,
}, },
};
use std::collections::HashMap;
use wormhole::Chain;
use wormhole_solana::VAA;
use crate::{
error::ExecutorError,
state::{
claim_record::ClaimRecord,
governance_payload::{
ExecutorPayload,
GovernanceHeader,
InstructionData,
}, },
posted_vaa::AnchorVaa, std::collections::HashMap,
}, wormhole::Chain,
CLAIM_RECORD_SEED, wormhole_solana::VAA,
EXECUTOR_KEY_SEED,
}; };
/// Bench for the tests, the goal of this struct is to be able to setup solana accounts before starting the local validator /// Bench for the tests, the goal of this struct is to be able to setup solana accounts before starting the local validator

View File

@ -1,21 +1,22 @@
use crate::error::ExecutorError; use {
super::executor_simulator::{
use super::executor_simulator::{
ExecutorAttack, ExecutorAttack,
ExecutorBench, ExecutorBench,
VaaAttack, VaaAttack,
}; },
use anchor_lang::prelude::{ crate::error::ExecutorError,
anchor_lang::prelude::{
ErrorCode, ErrorCode,
ProgramError, ProgramError,
Pubkey, Pubkey,
Rent, Rent,
}; },
use solana_sdk::{ solana_sdk::{
instruction::InstructionError, instruction::InstructionError,
native_token::LAMPORTS_PER_SOL, native_token::LAMPORTS_PER_SOL,
system_instruction::transfer, system_instruction::transfer,
transaction::TransactionError, transaction::TransactionError,
},
}; };
#[tokio::test] #[tokio::test]

View File

@ -1,13 +1,13 @@
use crate::{ use {
super::executor_simulator::ExecutorBench,
crate::{
error::ExecutorError, error::ExecutorError,
tests::executor_simulator::{ tests::executor_simulator::{
ExecutorAttack, ExecutorAttack,
VaaAttack, VaaAttack,
}, },
}; },
anchor_lang::{
use super::executor_simulator::ExecutorBench;
use anchor_lang::{
prelude::{ prelude::{
Pubkey, Pubkey,
Rent, Rent,
@ -16,12 +16,13 @@ use anchor_lang::{
system_instruction::create_account, system_instruction::create_account,
system_program, system_program,
}, },
}; },
use solana_sdk::{ solana_sdk::{
native_token::LAMPORTS_PER_SOL, native_token::LAMPORTS_PER_SOL,
signature::Keypair, signature::Keypair,
signer::Signer, signer::Signer,
system_instruction::transfer, system_instruction::transfer,
},
}; };
#[tokio::test] #[tokio::test]

View File

@ -1,11 +0,0 @@
# Merge similar crates together to avoid multiple use statements.
imports_granularity = "Crate"
# Consistency in formatting makes tool based searching/editing better.
empty_item_single_line = false
# Easier editing when arbitrary mixed use statements do not collapse.
imports_layout = "Vertical"
# Default rustfmt formatting of match arms with branches is awful.
match_arm_leading_pipes = "Preserve"

17
rustfmt.toml Normal file
View File

@ -0,0 +1,17 @@
# Merge all imports into a clean vertical list of module imports.
imports_granularity = "One"
group_imports = "One"
imports_layout = "Vertical"
# Better grep-ability.
empty_item_single_line = false
# Consistent pipe layout.
match_arm_leading_pipes = "Preserve"
# Align Fields
enum_discrim_align_threshold = 80
struct_field_align_threshold = 80
# Allow up to two blank lines for visual grouping.
blank_lines_upper_bound = 2

View File

@ -1,25 +1,24 @@
use std::{ use {
crate::BatchState,
log::info,
serde::{
de::Error,
Deserialize,
Deserializer,
Serialize,
Serializer,
},
solana_program::pubkey::Pubkey,
std::{
collections::{ collections::{
HashMap, HashMap,
HashSet, HashSet,
}, },
iter, iter,
str::FromStr, str::FromStr,
},
}; };
use log::info;
use serde::{
de::Error,
Deserialize,
Deserializer,
Serialize,
Serializer,
};
use solana_program::pubkey::Pubkey;
use crate::BatchState;
/// Pyth2wormhole config specific to attestation requests /// Pyth2wormhole config specific to attestation requests
#[derive(Clone, Debug, Hash, Deserialize, Serialize, PartialEq)] #[derive(Clone, Debug, Hash, Deserialize, Serialize, PartialEq)]
pub struct AttestationConfig { pub struct AttestationConfig {
@ -275,9 +274,10 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use {
super::*,
use solitaire::ErrBox; solitaire::ErrBox,
};
#[test] #[test]
fn test_sanity() -> Result<(), ErrBox> { fn test_sanity() -> Result<(), ErrBox> {

View File

@ -1,19 +1,18 @@
use log::{ use {
debug, crate::{
warn,
};
use solana_client::nonblocking::rpc_client::RpcClient;
use pyth_sdk_solana::state::PriceAccount;
use std::time::{
Duration,
Instant,
};
use crate::{
AttestationConditions, AttestationConditions,
P2WSymbol, P2WSymbol,
},
log::{
debug,
warn,
},
pyth_sdk_solana::state::PriceAccount,
solana_client::nonblocking::rpc_client::RpcClient,
std::time::{
Duration,
Instant,
},
}; };
/// Runtime representation of a batch. It refers to the original group /// Runtime representation of a batch. It refers to the original group

View File

@ -1,12 +1,13 @@
//! CLI options //! CLI options
use solana_program::pubkey::Pubkey; use {
use solana_sdk::commitment_config::CommitmentConfig; clap::{
use std::path::PathBuf;
use clap::{
Parser, Parser,
Subcommand, Subcommand,
},
solana_program::pubkey::Pubkey,
solana_sdk::commitment_config::CommitmentConfig,
std::path::PathBuf,
}; };
#[derive(Parser)] #[derive(Parser)]

View File

@ -3,22 +3,58 @@ pub mod batch_state;
pub mod message; pub mod message;
pub mod util; pub mod util;
use borsh::{ pub use {
attestation_cfg::{
AttestationConditions,
AttestationConfig,
P2WSymbol,
},
batch_state::BatchState,
message::P2WMessageQueue,
pyth2wormhole::Pyth2WormholeConfig,
util::{
RLMutex,
RLMutexGuard,
},
};
use {
borsh::{
BorshDeserialize, BorshDeserialize,
BorshSerialize, BorshSerialize,
}; },
use log::{ bridge::{
accounts::{
Bridge,
FeeCollector,
Sequence,
SequenceDerivationData,
},
types::ConsistencyLevel,
},
log::{
debug, debug,
trace, trace,
warn, warn,
}; },
use pyth_sdk_solana::state::{ p2w_sdk::P2WEmitter,
pyth2wormhole::{
config::{
OldP2WConfigAccount,
P2WConfigAccount,
},
message::{
P2WMessage,
P2WMessageDrvData,
},
AttestData,
},
pyth_sdk_solana::state::{
load_mapping_account, load_mapping_account,
load_price_account, load_price_account,
load_product_account, load_product_account,
}; },
use solana_client::nonblocking::rpc_client::RpcClient; solana_client::nonblocking::rpc_client::RpcClient,
use solana_program::{ solana_program::{
hash::Hash, hash::Hash,
instruction::{ instruction::{
AccountMeta, AccountMeta,
@ -30,64 +66,25 @@ use solana_program::{
clock, clock,
rent, rent,
}, },
}; },
use solana_sdk::{ solana_sdk::{
signer::{ signer::{
keypair::Keypair, keypair::Keypair,
Signer, Signer,
}, },
transaction::Transaction, transaction::Transaction,
}; },
use solitaire::{ solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
AccountState, AccountState,
ErrBox, ErrBox,
};
use bridge::{
accounts::{
Bridge,
FeeCollector,
Sequence,
SequenceDerivationData,
}, },
types::ConsistencyLevel, std::collections::{
};
use std::collections::{
HashMap, HashMap,
HashSet, HashSet,
};
use p2w_sdk::P2WEmitter;
use pyth2wormhole::{
config::{
OldP2WConfigAccount,
P2WConfigAccount,
}, },
message::{
P2WMessage,
P2WMessageDrvData,
},
AttestData,
}; };
pub use pyth2wormhole::Pyth2WormholeConfig;
pub use attestation_cfg::{
AttestationConditions,
AttestationConfig,
P2WSymbol,
};
pub use batch_state::BatchState;
pub use util::{
RLMutex,
RLMutexGuard,
};
pub use message::P2WMessageQueue;
/// Future-friendly version of solitaire::ErrBox /// Future-friendly version of solitaire::ErrBox
pub type ErrBoxSend = Box<dyn std::error::Error + Send + Sync>; pub type ErrBoxSend = Box<dyn std::error::Error + Send + Sync>;

View File

@ -1,67 +1,65 @@
pub mod cli; pub mod cli;
use std::{ use {
clap::Parser,
cli::{
Action,
Cli,
},
futures::future::{
Future,
TryFutureExt,
},
generic_array::GenericArray,
log::{
debug,
error,
info,
warn,
LevelFilter,
},
p2w_sdk::P2WEmitter,
pyth2wormhole::{
attest::P2W_MAX_BATCH_SIZE,
Pyth2WormholeConfig,
},
pyth2wormhole_client::*,
sha3::{
Digest,
Sha3_256,
},
solana_client::{
nonblocking::rpc_client::RpcClient,
rpc_config::RpcTransactionConfig,
},
solana_program::pubkey::Pubkey,
solana_sdk::{
commitment_config::CommitmentConfig,
signature::read_keypair_file,
signer::keypair::Keypair,
},
solana_transaction_status::UiTransactionEncoding,
solitaire::{
processors::seeded::Seeded,
ErrBox,
},
std::{
fs::File, fs::File,
sync::Arc, sync::Arc,
time::{ time::{
Duration, Duration,
Instant, Instant,
}, },
}; },
tokio::{
use clap::Parser;
use futures::future::{
Future,
TryFutureExt,
};
use generic_array::GenericArray;
use log::{
debug,
error,
info,
warn,
LevelFilter,
};
use sha3::{
Digest,
Sha3_256,
};
use solana_client::{
nonblocking::rpc_client::RpcClient,
rpc_config::RpcTransactionConfig,
};
use solana_program::pubkey::Pubkey;
use solana_sdk::{
commitment_config::CommitmentConfig,
signature::read_keypair_file,
signer::keypair::Keypair,
};
use solana_transaction_status::UiTransactionEncoding;
use solitaire::{
processors::seeded::Seeded,
ErrBox,
};
use tokio::{
sync::{ sync::{
Mutex, Mutex,
Semaphore, Semaphore,
}, },
task::JoinHandle, task::JoinHandle,
},
}; };
use cli::{
Action,
Cli,
};
use p2w_sdk::P2WEmitter;
use pyth2wormhole::{
attest::P2W_MAX_BATCH_SIZE,
Pyth2WormholeConfig,
};
use pyth2wormhole_client::*;
pub const SEQNO_PREFIX: &'static str = "Program log: Sequence: "; pub const SEQNO_PREFIX: &'static str = "Program log: Sequence: ";
#[tokio::main(flavor = "multi_thread")] #[tokio::main(flavor = "multi_thread")]

View File

@ -1,16 +1,17 @@
//! Re-usable message scheme for pyth2wormhole //! Re-usable message scheme for pyth2wormhole
use log::debug; use {
use std::{ crate::ErrBoxSend,
log::debug,
std::{
collections::VecDeque, collections::VecDeque,
time::{ time::{
Duration, Duration,
Instant, Instant,
}, },
},
}; };
use crate::ErrBoxSend;
/// One of the accounts tracked by the attestation client. /// One of the accounts tracked by the attestation client.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct P2WMessageAccount { pub struct P2WMessageAccount {

View File

@ -1,6 +1,6 @@
use log::trace; use {
log::trace,
use std::{ std::{
ops::{ ops::{
Deref, Deref,
DerefMut, DerefMut,
@ -9,10 +9,11 @@ use std::{
Duration, Duration,
Instant, Instant,
}, },
}; },
use tokio::sync::{ tokio::sync::{
Mutex, Mutex,
MutexGuard, MutexGuard,
},
}; };
/// Rate-limited mutex. Ensures there's a period of minimum rl_interval between lock acquisitions /// Rate-limited mutex. Ensures there's a period of minimum rl_interval between lock acquisitions

View File

@ -1,12 +1,13 @@
//! Trivial program for mocking other programs easily //! Trivial program for mocking other programs easily
use solana_program::{ use {
solana_program::{
account_info::AccountInfo, account_info::AccountInfo,
msg, msg,
program_error::ProgramError, program_error::ProgramError,
},
solana_program_test::*,
solana_sdk::pubkey::Pubkey,
}; };
use solana_sdk::pubkey::Pubkey;
use solana_program_test::*;
pub fn passthrough_entrypoint( pub fn passthrough_entrypoint(
program_id: &Pubkey, program_id: &Pubkey,

View File

@ -1,14 +1,7 @@
//! This module contains test fixtures for instantiating plausible //! This module contains test fixtures for instantiating plausible
//! Pyth accounts for testing purposes. //! Pyth accounts for testing purposes.
use solana_program_test::*; use {
pyth_client::{
use solana_sdk::{
account::Account,
pubkey::Pubkey,
rent::Rent,
};
use pyth_client::{
AccKey, AccKey,
AccountType, AccountType,
Price, Price,
@ -16,6 +9,13 @@ use pyth_client::{
MAGIC, MAGIC,
PROD_ATTR_SIZE, PROD_ATTR_SIZE,
VERSION, VERSION,
},
solana_program_test::*,
solana_sdk::{
account::Account,
pubkey::Pubkey,
rent::Rent,
},
}; };
/// Create a pair of brand new product/price accounts that point at each other /// Create a pair of brand new product/price accounts that point at each other

View File

@ -1,7 +1,22 @@
pub mod fixtures; pub mod fixtures;
use solana_program_test::*; use {
use solana_sdk::{ bridge::accounts::{
Bridge,
BridgeConfig,
BridgeData,
},
fixtures::{
passthrough,
pyth,
},
pyth2wormhole::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
},
pyth2wormhole_client as p2wc,
solana_program_test::*,
solana_sdk::{
account::Account, account::Account,
instruction::{ instruction::{
AccountMeta, AccountMeta,
@ -12,30 +27,13 @@ use solana_sdk::{
signature::Signer, signature::Signer,
signer::keypair::Keypair, signer::keypair::Keypair,
transaction::Transaction, transaction::Transaction,
}; },
solitaire::{
use bridge::accounts::{
Bridge,
BridgeConfig,
BridgeData,
};
use pyth2wormhole::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
};
use pyth2wormhole_client as p2wc;
use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
AccountState, AccountState,
BorshSerialize, BorshSerialize,
}; },
std::time::Duration,
use std::time::Duration;
use fixtures::{
passthrough,
pyth,
}; };
#[tokio::test] #[tokio::test]

View File

@ -2,9 +2,27 @@
pub mod fixtures; pub mod fixtures;
use solana_program::system_program; use {
use solana_program_test::*; bridge::accounts::{
use solana_sdk::{ Bridge,
BridgeConfig,
BridgeData,
},
fixtures::{
passthrough,
pyth,
},
log::info,
pyth2wormhole::config::{
OldP2WConfigAccount,
OldPyth2WormholeConfig,
P2WConfigAccount,
Pyth2WormholeConfig,
},
pyth2wormhole_client as p2wc,
solana_program::system_program,
solana_program_test::*,
solana_sdk::{
account::Account, account::Account,
instruction::{ instruction::{
AccountMeta, AccountMeta,
@ -15,32 +33,12 @@ use solana_sdk::{
signature::Signer, signature::Signer,
signer::keypair::Keypair, signer::keypair::Keypair,
transaction::Transaction, transaction::Transaction,
}; },
solitaire::{
use bridge::accounts::{
Bridge,
BridgeConfig,
BridgeData,
};
use log::info;
use pyth2wormhole::config::{
OldP2WConfigAccount,
OldPyth2WormholeConfig,
P2WConfigAccount,
Pyth2WormholeConfig,
};
use pyth2wormhole_client as p2wc;
use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
AccountState, AccountState,
BorshSerialize, BorshSerialize,
}; },
use fixtures::{
passthrough,
pyth,
}; };
#[tokio::test] #[tokio::test]

View File

@ -1,25 +1,26 @@
pub mod fixtures; pub mod fixtures;
use borsh::BorshDeserialize; use {
use p2wc::get_config_account; borsh::BorshDeserialize,
use solana_program_test::*; p2wc::get_config_account,
use solana_sdk::{ pyth2wormhole::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
},
pyth2wormhole_client as p2wc,
solana_program_test::*,
solana_sdk::{
account::Account, account::Account,
pubkey::Pubkey, pubkey::Pubkey,
rent::Rent, rent::Rent,
signature::Signer, signature::Signer,
signer::keypair::Keypair, signer::keypair::Keypair,
}; },
solitaire::{
use pyth2wormhole::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
};
use pyth2wormhole_client as p2wc;
use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
AccountState, AccountState,
BorshSerialize, BorshSerialize,
},
}; };
fn clone_keypair(keypair: &Keypair) -> Keypair { fn clone_keypair(keypair: &Keypair) -> Keypair {

View File

@ -1,11 +1,12 @@
//! CLI options //! CLI options
use clap::{ use {
clap::{
Parser, Parser,
Subcommand, Subcommand,
},
solana_sdk::pubkey::Pubkey,
}; };
use solana_sdk::pubkey::Pubkey;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[clap( #[clap(
about = "A cli for the remote executor", about = "A cli for the remote executor",

View File

@ -1,20 +1,21 @@
use anyhow::Result; use {
use clap::Parser; anyhow::Result,
use cli::{ borsh::BorshSerialize,
clap::Parser,
cli::{
Action, Action,
Cli, Cli,
}; },
use pyth2wormhole_client::{ pyth2wormhole_client::{
get_set_config_ix, get_set_config_ix,
get_set_is_active_ix,
Pyth2WormholeConfig, Pyth2WormholeConfig,
}; },
remote_executor::state::governance_payload::{
use borsh::BorshSerialize;
use pyth2wormhole_client::get_set_is_active_ix;
use remote_executor::state::governance_payload::{
ExecutorPayload, ExecutorPayload,
GovernanceHeader, GovernanceHeader,
InstructionData, InstructionData,
},
}; };
mod cli; mod cli;

View File

@ -1,15 +1,27 @@
use crate::{ use {
crate::{
config::P2WConfigAccount, config::P2WConfigAccount,
message::{ message::{
P2WMessage, P2WMessage,
P2WMessageDrvData, P2WMessageDrvData,
}, },
}; },
use borsh::{ borsh::{
BorshDeserialize, BorshDeserialize,
BorshSerialize, BorshSerialize,
}; },
use solana_program::{ bridge::{
accounts::BridgeData,
types::ConsistencyLevel,
PostMessageData,
},
p2w_sdk::{
BatchPriceAttestation,
Identifier,
P2WEmitter,
PriceAttestation,
},
solana_program::{
clock::Clock, clock::Clock,
instruction::{ instruction::{
AccountMeta, AccountMeta,
@ -24,22 +36,8 @@ use solana_program::{
rent::Rent, rent::Rent,
system_instruction, system_instruction,
sysvar::Sysvar as SolanaSysvar, sysvar::Sysvar as SolanaSysvar,
}; },
solitaire::{
use p2w_sdk::{
BatchPriceAttestation,
Identifier,
P2WEmitter,
PriceAttestation,
};
use bridge::{
accounts::BridgeData,
types::ConsistencyLevel,
PostMessageData,
};
use solitaire::{
invoke_seeded, invoke_seeded,
trace, trace,
AccountState, AccountState,
@ -55,6 +53,7 @@ use solitaire::{
Signer, Signer,
SolitaireError, SolitaireError,
Sysvar, Sysvar,
},
}; };
/// Important: must be manually maintained until native Solitaire /// Important: must be manually maintained until native Solitaire

View File

@ -20,17 +20,19 @@
//! 6. (optional) Remove/comment out config structs and aliases from //! 6. (optional) Remove/comment out config structs and aliases from
//! before version Y. //! before version Y.
use borsh::{ use {
borsh::{
BorshDeserialize, BorshDeserialize,
BorshSerialize, BorshSerialize,
}; },
use solana_program::pubkey::Pubkey; solana_program::pubkey::Pubkey,
use solitaire::{ solitaire::{
processors::seeded::AccountOwner, processors::seeded::AccountOwner,
AccountState, AccountState,
Data, Data,
Derive, Derive,
Owned, Owned,
},
}; };
/// Aliases for current config schema (to migrate into) /// Aliases for current config schema (to migrate into)

View File

@ -1,11 +1,16 @@
use solana_program::{ use {
crate::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
},
solana_program::{
program::invoke, program::invoke,
pubkey::Pubkey, pubkey::Pubkey,
rent::Rent, rent::Rent,
system_instruction, system_instruction,
sysvar::Sysvar, sysvar::Sysvar,
}; },
use solitaire::{ solitaire::{
trace, trace,
AccountState, AccountState,
CreationLamports, CreationLamports,
@ -17,11 +22,7 @@ use solitaire::{
Peel, Peel,
Result as SoliResult, Result as SoliResult,
Signer, Signer,
}; },
use crate::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
}; };
#[derive(FromAccounts)] #[derive(FromAccounts)]

View File

@ -8,33 +8,32 @@ pub mod set_config;
pub mod set_is_active; pub mod set_is_active;
use solitaire::solitaire; use solitaire::solitaire;
pub use {
pub use attest::{ attest::{
attest, attest,
Attest, Attest,
AttestData, AttestData,
}; },
pub use config::Pyth2WormholeConfig; config::Pyth2WormholeConfig,
pub use initialize::{ initialize::{
initialize, initialize,
Initialize, Initialize,
}; },
pub use migrate::{ migrate::{
migrate, migrate,
Migrate, Migrate,
}; },
pub use set_config::{ pyth_client,
set_config::{
set_config, set_config,
SetConfig, SetConfig,
}; },
set_is_active::{
pub use set_is_active::{
set_is_active, set_is_active,
SetIsActive, SetIsActive,
},
}; };
pub use pyth_client;
solitaire! { solitaire! {
Attest => attest, Attest => attest,
Initialize => initialize, Initialize => initialize,

View File

@ -7,19 +7,21 @@
//! derived with their address as message_owner in //! derived with their address as message_owner in
//! `P2WMessageDrvData`. //! `P2WMessageDrvData`.
use borsh::{ use {
borsh::{
BorshDeserialize, BorshDeserialize,
BorshSerialize, BorshSerialize,
}; },
use bridge::PostedMessageUnreliable; bridge::PostedMessageUnreliable,
use solana_program::pubkey::Pubkey; solana_program::pubkey::Pubkey,
use solitaire::{ solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
AccountState, AccountState,
Data, Data,
Info, Info,
Mut, Mut,
Signer, Signer,
},
}; };
pub type P2WMessage<'a> = Mut<PostedMessageUnreliable<'a, { AccountState::MaybeInitialized }>>; pub type P2WMessage<'a> = Mut<PostedMessageUnreliable<'a, { AccountState::MaybeInitialized }>>;

View File

@ -1,6 +1,13 @@
//! Instruction used to migrate on-chain configuration from an older format //! Instruction used to migrate on-chain configuration from an older format
use solana_program::{ use {
crate::config::{
OldP2WConfigAccount,
OldPyth2WormholeConfig,
P2WConfigAccount,
Pyth2WormholeConfig,
},
solana_program::{
program::invoke, program::invoke,
program_error::ProgramError, program_error::ProgramError,
pubkey::Pubkey, pubkey::Pubkey,
@ -8,9 +15,8 @@ use solana_program::{
system_instruction, system_instruction,
system_program, system_program,
sysvar::Sysvar, sysvar::Sysvar,
}; },
solitaire::{
use solitaire::{
trace, trace,
AccountSize, AccountSize,
AccountState, AccountState,
@ -24,13 +30,7 @@ use solitaire::{
Result as SoliResult, Result as SoliResult,
Signer, Signer,
SolitaireError, SolitaireError,
}; },
use crate::config::{
OldP2WConfigAccount,
OldPyth2WormholeConfig,
P2WConfigAccount,
Pyth2WormholeConfig,
}; };
/// Migration accounts meant to evolve with subsequent config accounts /// Migration accounts meant to evolve with subsequent config accounts

View File

@ -1,14 +1,18 @@
use borsh::BorshSerialize; use {
crate::config::{
use solana_program::{ P2WConfigAccount,
Pyth2WormholeConfig,
},
borsh::BorshSerialize,
solana_program::{
program::invoke, program::invoke,
program_error::ProgramError, program_error::ProgramError,
pubkey::Pubkey, pubkey::Pubkey,
rent::Rent, rent::Rent,
system_instruction, system_instruction,
sysvar::Sysvar, sysvar::Sysvar,
}; },
use solitaire::{ solitaire::{
trace, trace,
AccountState, AccountState,
ExecutionContext, ExecutionContext,
@ -20,15 +24,10 @@ use solitaire::{
Result as SoliResult, Result as SoliResult,
Signer, Signer,
SolitaireError, SolitaireError,
},
std::cmp::Ordering,
}; };
use crate::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
};
use std::cmp::Ordering;
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct SetConfig<'b> { pub struct SetConfig<'b> {
/// Current config used by the program /// Current config used by the program

View File

@ -1,4 +1,9 @@
use solitaire::{ use {
crate::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
},
solitaire::{
trace, trace,
AccountState, AccountState,
ExecutionContext, ExecutionContext,
@ -10,11 +15,7 @@ use solitaire::{
Result as SoliResult, Result as SoliResult,
Signer, Signer,
SolitaireError, SolitaireError,
}; },
use crate::config::{
P2WConfigAccount,
Pyth2WormholeConfig,
}; };
#[derive(FromAccounts)] #[derive(FromAccounts)]

View File

@ -1,11 +0,0 @@
# Merge similar crates together to avoid multiple use statements.
imports_granularity = "Crate"
# Consistency in formatting makes tool based searching/editing better.
empty_item_single_line = false
# Easier editing when arbitrary mixed use statements do not collapse.
imports_layout = "Vertical"
# Default rustfmt formatting of match arms with branches is awful.
match_arm_leading_pipes = "Preserve"

View File

@ -1,18 +0,0 @@
# Merge similar crates together to avoid multiple use statements.
imports_granularity = "Module"
# Consistency in formatting makes tool based searching/editing better.
empty_item_single_line = false
# Easier editing when arbitrary mixed use statements do not collapse.
imports_layout = "Vertical"
# Default rustfmt formatting of match arms with branches is awful.
match_arm_leading_pipes = "Preserve"
# Align Fields
enum_discrim_align_threshold = 80
struct_field_align_threshold = 80
# Allow up to two blank lines for grouping.
blank_lines_upper_bound = 2

View File

@ -6,29 +6,30 @@
//! similar human-readable names and provide a failsafe for some of //! similar human-readable names and provide a failsafe for some of
//! the probable adversarial scenarios. //! the probable adversarial scenarios.
use serde::{
Deserialize,
Serialize,
Serializer,
};
use std::borrow::Borrow;
use std::convert::TryInto;
use std::io::Read;
use std::iter::Iterator;
use std::mem;
pub use pyth_sdk::{ pub use pyth_sdk::{
Identifier, Identifier,
PriceStatus, PriceStatus,
UnixTimestamp, UnixTimestamp,
}; };
#[cfg(feature = "solana")] #[cfg(feature = "solana")]
use solitaire::{ use solitaire::{
Derive, Derive,
Info, Info,
}; };
use {
serde::{
Deserialize,
Serialize,
Serializer,
},
std::{
borrow::Borrow,
convert::TryInto,
io::Read,
iter::Iterator,
mem,
},
};
#[cfg(feature = "wasm")] #[cfg(feature = "wasm")]
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] #[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
@ -472,8 +473,10 @@ impl PriceAttestation {
/// using `cargo test -- --nocapture`. /// using `cargo test -- --nocapture`.
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use {
use pyth_sdk_solana::state::PriceStatus; super::*,
pyth_sdk_solana::state::PriceStatus,
};
fn mock_attestation(prod: Option<[u8; 32]>, price: Option<[u8; 32]>) -> PriceAttestation { fn mock_attestation(prod: Option<[u8; 32]>, price: Option<[u8; 32]>) -> PriceAttestation {
let product_id_bytes = prod.unwrap_or([21u8; 32]); let product_id_bytes = prod.unwrap_or([21u8; 32]);

View File

@ -1,13 +1,13 @@
use solana_program::pubkey::Pubkey; use {
use solitaire::Seeded; crate::{
use std::str::FromStr;
use wasm_bindgen::prelude::*;
use crate::{
BatchPriceAttestation, BatchPriceAttestation,
P2WEmitter, P2WEmitter,
PriceAttestation, PriceAttestation,
},
solana_program::pubkey::Pubkey,
solitaire::Seeded,
std::str::FromStr,
wasm_bindgen::prelude::*,
}; };
#[wasm_bindgen] #[wasm_bindgen]