Add clippy to all rust projects (#400)
This commit is contained in:
parent
895f053e00
commit
51514dcd9b
|
@ -17,29 +17,56 @@ repos:
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
# Hooks for the remote executor
|
# Hooks for the remote executor
|
||||||
- id: cargo-fmt-executor-remote-executor
|
- id: cargo-fmt-remote-executor
|
||||||
name: Cargo format executor for remote executor
|
name: Cargo format for remote executor
|
||||||
language: "rust"
|
language: "rust"
|
||||||
entry: cargo +nightly fmt --manifest-path ./pythnet/remote-executor/Cargo.toml --all -- --config-path rustfmt.toml
|
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-remote-executor
|
||||||
name: Cargo clippy executor
|
name: Cargo clippy for remote executor
|
||||||
language: "rust"
|
language: "rust"
|
||||||
entry: cargo +nightly clippy --manifest-path ./pythnet/remote-executor/Cargo.toml -- -D warnings
|
entry: cargo +nightly clippy --manifest-path ./pythnet/remote-executor/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
|
||||||
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-attester
|
- id: cargo-fmt-attester
|
||||||
name: Cargo format executor for attester
|
name: Cargo format for attester
|
||||||
language: "rust"
|
language: "rust"
|
||||||
entry: cargo +nightly fmt --manifest-path ./solana/pyth2wormhole/Cargo.toml --all -- --config-path rustfmt.toml
|
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/
|
||||||
|
- id: cargo-clippy-attester
|
||||||
|
name: Cargo clippy for attester
|
||||||
|
language: "rust"
|
||||||
|
entry: |
|
||||||
|
bash -c 'EMITTER_ADDRESS=0 BRIDGE_ADDRESS=0 cargo +nightly clippy --manifest-path \
|
||||||
|
./solana/pyth2wormhole/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings'
|
||||||
|
pass_filenames: false
|
||||||
|
files: solana/pyth2wormhole/
|
||||||
# Hooks for cosmwasm contract
|
# Hooks for cosmwasm contract
|
||||||
- id: cargo-fmt-executor-cosmwasm
|
- id: cargo-fmt-cosmwasm
|
||||||
name: Cargo format executor form cosmwasm contract
|
name: Cargo format for cosmwasm contract
|
||||||
language: "rust"
|
language: "rust"
|
||||||
entry: cargo +nightly fmt --manifest-path ./cosmwasm/Cargo.toml --all -- --config-path rustfmt.toml
|
entry: cargo +nightly fmt --manifest-path ./cosmwasm/Cargo.toml --all -- --config-path rustfmt.toml
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
files: cosmwasm/
|
files: cosmwasm/
|
||||||
|
- id: cargo-clippy-cosmwasm
|
||||||
|
name: Cargo clippy for cosmwasm contract
|
||||||
|
language: "rust"
|
||||||
|
entry: cargo +nightly clippy --manifest-path ./cosmwasm/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
|
||||||
|
pass_filenames: false
|
||||||
|
files: cosmwasm/
|
||||||
|
# Hooks for p2w-sdk/rust
|
||||||
|
- id: cargo-fmt-p2w-sdk
|
||||||
|
name: Cargo format for p2w-sdk
|
||||||
|
language: "rust"
|
||||||
|
entry: cargo +nightly fmt --manifest-path ./third_party/pyth/p2w-sdk/rust/Cargo.toml --all -- --config-path rustfmt.toml
|
||||||
|
pass_filenames: false
|
||||||
|
files: third_party/pyth/p2w-sdk/rust/
|
||||||
|
- id: cargo-clippy-p2w-sdk
|
||||||
|
name: Cargo clippy for p2w-sdk
|
||||||
|
language: "rust"
|
||||||
|
entry: cargo +nightly clippy --manifest-path ./third_party/pyth/p2w-sdk/rust/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
|
||||||
|
pass_filenames: false
|
||||||
|
files: third_party/pyth/p2w-sdk/rust/
|
||||||
|
|
|
@ -124,11 +124,11 @@ impl ExecutorBench {
|
||||||
program_test.add_account(program_key, program_account);
|
program_test.add_account(program_key, program_account);
|
||||||
program_test.add_account(programdata_key, programdata_account);
|
program_test.add_account(programdata_key, programdata_account);
|
||||||
|
|
||||||
return ExecutorBench {
|
ExecutorBench {
|
||||||
program_test,
|
program_test,
|
||||||
program_id: program_key.key(),
|
program_id: program_key.key(),
|
||||||
seqno: HashMap::<Pubkey, u64>::new(),
|
seqno: HashMap::<Pubkey, u64>::new(),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start local validator based on the current bench
|
/// Start local validator based on the current bench
|
||||||
|
@ -136,12 +136,12 @@ impl ExecutorBench {
|
||||||
// Start validator
|
// Start validator
|
||||||
let (banks_client, genesis_keypair, recent_blockhash) = self.program_test.start().await;
|
let (banks_client, genesis_keypair, recent_blockhash) = self.program_test.start().await;
|
||||||
|
|
||||||
return ExecutorSimulator {
|
ExecutorSimulator {
|
||||||
banks_client,
|
banks_client,
|
||||||
payer: genesis_keypair,
|
payer: genesis_keypair,
|
||||||
last_blockhash: recent_blockhash,
|
last_blockhash: recent_blockhash,
|
||||||
program_id: self.program_id,
|
program_id: self.program_id,
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add VAA account with emitter and instructions for consumption by the remote_executor
|
/// Add VAA account with emitter and instructions for consumption by the remote_executor
|
||||||
|
@ -168,10 +168,7 @@ impl ExecutorBench {
|
||||||
|
|
||||||
let payload = ExecutorPayload {
|
let payload = ExecutorPayload {
|
||||||
header: GovernanceHeader::executor_governance_header(),
|
header: GovernanceHeader::executor_governance_header(),
|
||||||
instructions: instructions
|
instructions: instructions.iter().map(InstructionData::from).collect(),
|
||||||
.iter()
|
|
||||||
.map(|x| InstructionData::from(x))
|
|
||||||
.collect(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let payload_bytes = payload.try_to_vec().unwrap();
|
let payload_bytes = payload.try_to_vec().unwrap();
|
||||||
|
@ -185,7 +182,7 @@ impl ExecutorBench {
|
||||||
vaa_signature_account: Pubkey::new_unique(),
|
vaa_signature_account: Pubkey::new_unique(),
|
||||||
submission_time: 0,
|
submission_time: 0,
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
sequence: self.seqno.get(&emitter).unwrap_or(&0) + 1,
|
sequence: self.seqno.get(emitter).unwrap_or(&0) + 1,
|
||||||
emitter_chain,
|
emitter_chain,
|
||||||
emitter_address: emitter.to_bytes(),
|
emitter_address: emitter.to_bytes(),
|
||||||
payload: payload_bytes,
|
payload: payload_bytes,
|
||||||
|
@ -211,7 +208,7 @@ impl ExecutorBench {
|
||||||
|
|
||||||
let vaa_pubkey = Pubkey::new_unique();
|
let vaa_pubkey = Pubkey::new_unique();
|
||||||
self.program_test.add_account(vaa_pubkey, vaa_account);
|
self.program_test.add_account(vaa_pubkey, vaa_account);
|
||||||
return vaa_pubkey;
|
vaa_pubkey
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get executor key of an emitter, useful to construct instructions that will be in the VAA
|
// Get executor key of an emitter, useful to construct instructions that will be in the VAA
|
||||||
|
@ -298,7 +295,7 @@ impl ExecutorSimulator {
|
||||||
&self.program_id,
|
&self.program_id,
|
||||||
&self.payer.pubkey(),
|
&self.payer.pubkey(),
|
||||||
&Pubkey::new(&posted_vaa_data.emitter_address),
|
&Pubkey::new(&posted_vaa_data.emitter_address),
|
||||||
&posted_vaa_address,
|
posted_vaa_address,
|
||||||
)
|
)
|
||||||
.to_account_metas(None);
|
.to_account_metas(None);
|
||||||
|
|
||||||
|
@ -383,12 +380,12 @@ impl ExecutorSimulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<TransactionError> for ExecutorError {
|
impl From<ExecutorError> for TransactionError {
|
||||||
fn into(self) -> TransactionError {
|
fn from(val: ExecutorError) -> Self {
|
||||||
TransactionError::InstructionError(
|
TransactionError::InstructionError(
|
||||||
0,
|
0,
|
||||||
InstructionError::try_from(u64::from(ProgramError::from(
|
InstructionError::try_from(u64::from(ProgramError::from(
|
||||||
anchor_lang::prelude::Error::from(self),
|
anchor_lang::prelude::Error::from(val),
|
||||||
)))
|
)))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -41,7 +41,7 @@ async fn test_adversarial() {
|
||||||
&emitter,
|
&emitter,
|
||||||
&vec![transfer(
|
&vec![transfer(
|
||||||
&executor_key,
|
&executor_key,
|
||||||
&&receiver,
|
&receiver,
|
||||||
Rent::default().minimum_balance(0),
|
Rent::default().minimum_balance(0),
|
||||||
)],
|
)],
|
||||||
VaaAttack::None,
|
VaaAttack::None,
|
||||||
|
@ -50,7 +50,7 @@ async fn test_adversarial() {
|
||||||
&emitter,
|
&emitter,
|
||||||
&vec![transfer(
|
&vec![transfer(
|
||||||
&executor_key,
|
&executor_key,
|
||||||
&&receiver,
|
&receiver,
|
||||||
Rent::default().minimum_balance(0),
|
Rent::default().minimum_balance(0),
|
||||||
)],
|
)],
|
||||||
VaaAttack::WrongData,
|
VaaAttack::WrongData,
|
||||||
|
@ -59,7 +59,7 @@ async fn test_adversarial() {
|
||||||
&emitter,
|
&emitter,
|
||||||
&vec![transfer(
|
&vec![transfer(
|
||||||
&executor_key,
|
&executor_key,
|
||||||
&&receiver,
|
&receiver,
|
||||||
Rent::default().minimum_balance(0),
|
Rent::default().minimum_balance(0),
|
||||||
)],
|
)],
|
||||||
VaaAttack::WrongOwner,
|
VaaAttack::WrongOwner,
|
||||||
|
@ -68,7 +68,7 @@ async fn test_adversarial() {
|
||||||
&emitter,
|
&emitter,
|
||||||
&vec![transfer(
|
&vec![transfer(
|
||||||
&executor_key,
|
&executor_key,
|
||||||
&&receiver,
|
&receiver,
|
||||||
Rent::default().minimum_balance(0),
|
Rent::default().minimum_balance(0),
|
||||||
)],
|
)],
|
||||||
VaaAttack::WrongEmitterChain,
|
VaaAttack::WrongEmitterChain,
|
||||||
|
@ -78,7 +78,7 @@ async fn test_adversarial() {
|
||||||
&emitter,
|
&emitter,
|
||||||
&vec![transfer(
|
&vec![transfer(
|
||||||
&executor_key,
|
&executor_key,
|
||||||
&&receiver,
|
&receiver,
|
||||||
Rent::default().minimum_balance(0),
|
Rent::default().minimum_balance(0),
|
||||||
)],
|
)],
|
||||||
VaaAttack::WrongVaaMagic,
|
VaaAttack::WrongVaaMagic,
|
||||||
|
|
|
@ -2632,22 +2632,6 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44de48029c54ec1ca570786b5baeb906b0fc2409c8e0145585e287ee7a526c72"
|
checksum = "44de48029c54ec1ca570786b5baeb906b0fc2409c8e0145585e287ee7a526c72"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pyth-client"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "398f9e51e126a13903254c56f75b3201583db075d0fbb77e931f7515af9b3d16"
|
|
||||||
dependencies = [
|
|
||||||
"borsh",
|
|
||||||
"borsh-derive",
|
|
||||||
"bytemuck",
|
|
||||||
"num-derive",
|
|
||||||
"num-traits",
|
|
||||||
"serde",
|
|
||||||
"solana-program",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyth-sdk"
|
name = "pyth-sdk"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -2714,7 +2698,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"p2w-sdk",
|
"p2w-sdk",
|
||||||
"pyth-client 0.2.2",
|
"pyth-client",
|
||||||
"rocksalt",
|
"rocksalt",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -2738,7 +2722,6 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"p2w-sdk",
|
"p2w-sdk",
|
||||||
"prometheus",
|
"prometheus",
|
||||||
"pyth-client 0.5.1",
|
|
||||||
"pyth-sdk-solana 0.6.1",
|
"pyth-sdk-solana 0.6.1",
|
||||||
"pyth2wormhole",
|
"pyth2wormhole",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -39,6 +39,5 @@ warp = "0.3.3"
|
||||||
http = "0.2.8"
|
http = "0.2.8"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pyth-client = "0.5.0"
|
|
||||||
solana-program-test = "=1.10.31"
|
solana-program-test = "=1.10.31"
|
||||||
solana-sdk = "=1.10.31"
|
solana-sdk = "=1.10.31"
|
||||||
|
|
|
@ -71,8 +71,7 @@ impl AttestationConfig {
|
||||||
// Turn the pruned symbols into P2WSymbol structs
|
// Turn the pruned symbols into P2WSymbol structs
|
||||||
let mut new_symbols_vec = new_symbols
|
let mut new_symbols_vec = new_symbols
|
||||||
.drain() // Makes us own the elements and lets us move them
|
.drain() // Makes us own the elements and lets us move them
|
||||||
.map(|(prod, prices)| iter::zip(iter::repeat(prod), prices)) // Convert to iterator over flat (prod, price) tuples
|
.flat_map(|(prod, prices)| iter::zip(iter::repeat(prod), prices)) // Flatten the tuple iterators
|
||||||
.flatten() // Flatten the tuple iterators
|
|
||||||
.map(|(prod, price)| P2WSymbol {
|
.map(|(prod, price)| P2WSymbol {
|
||||||
name: None,
|
name: None,
|
||||||
product_addr: prod,
|
product_addr: prod,
|
||||||
|
@ -87,7 +86,7 @@ impl AttestationConfig {
|
||||||
.find(|g| g.group_name == group_name) // Advances the iterator and returns Some(item) on first hit
|
.find(|g| g.group_name == group_name) // Advances the iterator and returns Some(item) on first hit
|
||||||
{
|
{
|
||||||
Some(existing_group) => existing_group.symbols.append(&mut new_symbols_vec),
|
Some(existing_group) => existing_group.symbols.append(&mut new_symbols_vec),
|
||||||
None if new_symbols_vec.len() != 0 => {
|
None if !new_symbols_vec.is_empty() => {
|
||||||
// Group does not exist, assume defaults
|
// Group does not exist, assume defaults
|
||||||
let new_group = SymbolGroup {
|
let new_group = SymbolGroup {
|
||||||
group_name,
|
group_name,
|
||||||
|
@ -104,7 +103,7 @@ impl AttestationConfig {
|
||||||
pub fn as_batches(&self, max_batch_size: usize) -> Vec<BatchState> {
|
pub fn as_batches(&self, max_batch_size: usize) -> Vec<BatchState> {
|
||||||
self.symbol_groups
|
self.symbol_groups
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |g| {
|
.flat_map(move |g| {
|
||||||
let conditions4closure = g.conditions.clone();
|
let conditions4closure = g.conditions.clone();
|
||||||
let name4closure = g.group_name.clone();
|
let name4closure = g.group_name.clone();
|
||||||
|
|
||||||
|
@ -113,12 +112,11 @@ impl AttestationConfig {
|
||||||
// Divide group into batches
|
// Divide group into batches
|
||||||
g.symbols
|
g.symbols
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.chunks(max_batch_size.clone())
|
.chunks(max_batch_size)
|
||||||
.map(move |symbols| {
|
.map(move |symbols| {
|
||||||
BatchState::new(name4closure.clone(), symbols, conditions4closure.clone())
|
BatchState::new(name4closure.clone(), symbols, conditions4closure.clone())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.flatten()
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +255,7 @@ fn opt_pubkey_string_ser<S>(k_opt: &Option<Pubkey>, ser: S) -> Result<S::Ok, S::
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let k_str_opt = k_opt.clone().map(|k| k.to_string());
|
let k_str_opt = (*k_opt).map(|k| k.to_string());
|
||||||
|
|
||||||
Option::<String>::serialize(&k_str_opt, ser)
|
Option::<String>::serialize(&k_str_opt, ser)
|
||||||
}
|
}
|
||||||
|
@ -352,7 +350,7 @@ mod tests {
|
||||||
mock_prod_bytes[31] = sym_idx;
|
mock_prod_bytes[31] = sym_idx;
|
||||||
|
|
||||||
let mut mock_prices = HashSet::new();
|
let mut mock_prices = HashSet::new();
|
||||||
for px_idx in 1..=5 {
|
for _px_idx in 1..=5 {
|
||||||
let mut mock_price_bytes = [0u8; 32];
|
let mut mock_price_bytes = [0u8; 32];
|
||||||
mock_price_bytes[31] = sym_idx;
|
mock_price_bytes[31] = sym_idx;
|
||||||
mock_prices.insert(Pubkey::new_from_array(mock_price_bytes));
|
mock_prices.insert(Pubkey::new_from_array(mock_price_bytes));
|
||||||
|
@ -370,7 +368,7 @@ mod tests {
|
||||||
|
|
||||||
// Should not be created because there's no new symbols to add
|
// Should not be created because there's no new symbols to add
|
||||||
// (we're adding identical mock_new_symbols again)
|
// (we're adding identical mock_new_symbols again)
|
||||||
config2.add_symbols(mock_new_symbols.clone(), "default2".to_owned());
|
config2.add_symbols(mock_new_symbols, "default2".to_owned());
|
||||||
|
|
||||||
assert_ne!(config1, empty_config); // Check that config grows from empty
|
assert_ne!(config1, empty_config); // Check that config grows from empty
|
||||||
assert_eq!(config1, config2); // Check that no changes are made if all symbols are already in there
|
assert_eq!(config1, config2); // Check that no changes are made if all symbols are already in there
|
||||||
|
|
|
@ -157,6 +157,6 @@ impl<'a> BatchState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ pub fn get_set_config_ix(
|
||||||
let acc_metas = vec![
|
let acc_metas = vec![
|
||||||
// config
|
// config
|
||||||
AccountMeta::new(
|
AccountMeta::new(
|
||||||
P2WConfigAccount::<{ AccountState::Initialized }>::key(None, &p2w_addr),
|
P2WConfigAccount::<{ AccountState::Initialized }>::key(None, p2w_addr),
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
// current_owner
|
// current_owner
|
||||||
|
@ -181,7 +181,7 @@ pub fn get_set_is_active_ix(
|
||||||
let acc_metas = vec![
|
let acc_metas = vec![
|
||||||
// config
|
// config
|
||||||
AccountMeta::new(
|
AccountMeta::new(
|
||||||
P2WConfigAccount::<{ AccountState::Initialized }>::key(None, &p2w_addr),
|
P2WConfigAccount::<{ AccountState::Initialized }>::key(None, p2w_addr),
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
// ops_owner
|
// ops_owner
|
||||||
|
@ -323,13 +323,12 @@ pub fn gen_attest_tx(
|
||||||
let mut padded_symbols = {
|
let mut padded_symbols = {
|
||||||
let mut not_padded: Vec<_> = symbols
|
let mut not_padded: Vec<_> = symbols
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| {
|
.flat_map(|s| {
|
||||||
vec![
|
vec![
|
||||||
AccountMeta::new_readonly(s.product_addr, false),
|
AccountMeta::new_readonly(s.product_addr, false),
|
||||||
AccountMeta::new_readonly(s.price_addr, false),
|
AccountMeta::new_readonly(s.price_addr, false),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.flatten()
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Align to max batch size with null accounts
|
// Align to max batch size with null accounts
|
||||||
|
@ -392,7 +391,7 @@ pub fn gen_attest_tx(
|
||||||
let tx_signed = Transaction::new_signed_with_payer::<Vec<&Keypair>>(
|
let tx_signed = Transaction::new_signed_with_payer::<Vec<&Keypair>>(
|
||||||
&[ix],
|
&[ix],
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
&vec![&payer],
|
&vec![payer],
|
||||||
latest_blockhash,
|
latest_blockhash,
|
||||||
);
|
);
|
||||||
Ok(tx_signed)
|
Ok(tx_signed)
|
||||||
|
@ -410,7 +409,7 @@ pub async fn crawl_pyth_mapping(
|
||||||
let mut n_products_total = 0; // Grand total products in all mapping accounts
|
let mut n_products_total = 0; // Grand total products in all mapping accounts
|
||||||
let mut n_prices_total = 0; // Grand total prices in all product accounts in all mapping accounts
|
let mut n_prices_total = 0; // Grand total prices in all product accounts in all mapping accounts
|
||||||
|
|
||||||
let mut mapping_addr = first_mapping_addr.clone();
|
let mut mapping_addr = *first_mapping_addr;
|
||||||
|
|
||||||
// loop until the last non-zero MappingAccount.next account
|
// loop until the last non-zero MappingAccount.next account
|
||||||
loop {
|
loop {
|
||||||
|
@ -440,7 +439,7 @@ pub async fn crawl_pyth_mapping(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut price_addr = prod.px_acc.clone();
|
let mut price_addr = prod.px_acc;
|
||||||
let mut n_prod_prices = 0;
|
let mut n_prod_prices = 0;
|
||||||
|
|
||||||
// the product might have no price, can happen in tilt due to race-condition, failed tx to add price, ...
|
// the product might have no price, can happen in tilt due to race-condition, failed tx to add price, ...
|
||||||
|
@ -466,7 +465,7 @@ pub async fn crawl_pyth_mapping(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Append to existing set or create a new map entry
|
// Append to existing set or create a new map entry
|
||||||
ret.entry(prod_addr.clone())
|
ret.entry(*prod_addr)
|
||||||
.or_insert(HashSet::new())
|
.or_insert(HashSet::new())
|
||||||
.insert(price_addr);
|
.insert(price_addr);
|
||||||
|
|
||||||
|
@ -481,7 +480,7 @@ pub async fn crawl_pyth_mapping(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
price_addr = price.next.clone();
|
price_addr = price.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
n_prices_total += n_prod_prices;
|
n_prices_total += n_prod_prices;
|
||||||
|
@ -499,7 +498,7 @@ pub async fn crawl_pyth_mapping(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mapping_addr = mapping.next.clone();
|
mapping_addr = mapping.next;
|
||||||
n_mappings += 1;
|
n_mappings += 1;
|
||||||
}
|
}
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -68,7 +68,7 @@ use {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SEQNO_PREFIX: &'static str = "Program log: Sequence: ";
|
pub const SEQNO_PREFIX: &str = "Program log: Sequence: ";
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref ATTESTATIONS_OK_CNT: IntCounter =
|
static ref ATTESTATIONS_OK_CNT: IntCounter =
|
||||||
|
@ -99,7 +99,7 @@ async fn main() -> Result<(), ErrBox> {
|
||||||
|
|
||||||
let payer = read_keypair_file(&*shellexpand::tilde(&cli.payer))?;
|
let payer = read_keypair_file(&*shellexpand::tilde(&cli.payer))?;
|
||||||
|
|
||||||
let rpc_client = RpcClient::new_with_commitment(cli.rpc_url.clone(), cli.commitment.clone());
|
let rpc_client = RpcClient::new_with_commitment(cli.rpc_url.clone(), cli.commitment);
|
||||||
|
|
||||||
let p2w_addr = cli.p2w_addr;
|
let p2w_addr = cli.p2w_addr;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ async fn main() -> Result<(), ErrBox> {
|
||||||
RpcCfg {
|
RpcCfg {
|
||||||
url: cli.rpc_url,
|
url: cli.rpc_url,
|
||||||
timeout: Duration::from_secs(confirmation_timeout_secs),
|
timeout: Duration::from_secs(confirmation_timeout_secs),
|
||||||
commitment: cli.commitment.clone(),
|
commitment: cli.commitment,
|
||||||
},
|
},
|
||||||
Duration::from_millis(attestation_cfg.min_rpc_interval_ms),
|
Duration::from_millis(attestation_cfg.min_rpc_interval_ms),
|
||||||
));
|
));
|
||||||
|
@ -474,13 +474,13 @@ async fn handle_attest_non_daemon_mode(
|
||||||
let retry_jobs = batches.into_iter().enumerate().map(|(idx, batch_state)| {
|
let retry_jobs = batches.into_iter().enumerate().map(|(idx, batch_state)| {
|
||||||
attestation_retry_job(AttestationRetryJobArgs {
|
attestation_retry_job(AttestationRetryJobArgs {
|
||||||
batch_no: idx + 1,
|
batch_no: idx + 1,
|
||||||
batch_count: batch_count.clone(),
|
batch_count,
|
||||||
group_name: batch_state.group_name,
|
group_name: batch_state.group_name,
|
||||||
symbols: batch_state.symbols.clone(),
|
symbols: batch_state.symbols,
|
||||||
n_retries,
|
n_retries,
|
||||||
retry_interval: retry_interval.clone(),
|
retry_interval,
|
||||||
rpc_cfg: rpc_cfg.clone(),
|
rpc_cfg: rpc_cfg.clone(),
|
||||||
p2w_addr: p2w_addr.clone(),
|
p2w_addr,
|
||||||
p2w_config: p2w_cfg.clone(),
|
p2w_config: p2w_cfg.clone(),
|
||||||
payer: Keypair::from_bytes(&payer.to_bytes()).unwrap(),
|
payer: Keypair::from_bytes(&payer.to_bytes()).unwrap(),
|
||||||
message_q_mtx: message_q_mtx.clone(),
|
message_q_mtx: message_q_mtx.clone(),
|
||||||
|
@ -536,7 +536,7 @@ fn prepare_attestation_sched_jobs(
|
||||||
batch_no: idx + 1,
|
batch_no: idx + 1,
|
||||||
batch_count,
|
batch_count,
|
||||||
rpc_cfg: rpc_cfg.clone(),
|
rpc_cfg: rpc_cfg.clone(),
|
||||||
p2w_addr: p2w_addr.clone(),
|
p2w_addr: *p2w_addr,
|
||||||
config: p2w_cfg.clone(),
|
config: p2w_cfg.clone(),
|
||||||
payer: Keypair::from_bytes(&payer.to_bytes()).unwrap(),
|
payer: Keypair::from_bytes(&payer.to_bytes()).unwrap(),
|
||||||
message_q_mtx: message_q_mtx.clone(),
|
message_q_mtx: message_q_mtx.clone(),
|
||||||
|
@ -638,8 +638,8 @@ async fn attestation_sched_job(args: AttestationSchedJobArgs) -> Result<(), ErrB
|
||||||
// leave this code block.
|
// leave this code block.
|
||||||
let _permit4sched = sema.acquire().await?;
|
let _permit4sched = sema.acquire().await?;
|
||||||
|
|
||||||
let batch_no4err_msg = batch_no.clone();
|
let batch_no4err_msg = batch_no;
|
||||||
let batch_count4err_msg = batch_count.clone();
|
let batch_count4err_msg = batch_count;
|
||||||
let group_name4err_msg = batch.group_name.clone();
|
let group_name4err_msg = batch.group_name.clone();
|
||||||
|
|
||||||
// We never get to error reporting in daemon mode, attach a map_err
|
// We never get to error reporting in daemon mode, attach a map_err
|
||||||
|
@ -689,10 +689,11 @@ async fn attestation_retry_job(args: AttestationRetryJobArgs) -> Result<(), ErrB
|
||||||
message_q_mtx,
|
message_q_mtx,
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
let mut res = Err(format!(
|
let mut res = Err(
|
||||||
"attestation_retry_job INTERNAL: Could not get a single attestation job result"
|
"attestation_retry_job INTERNAL: Could not get a single attestation job result"
|
||||||
)
|
.to_string()
|
||||||
.into());
|
.into(),
|
||||||
|
);
|
||||||
|
|
||||||
for _i in 0..=n_retries {
|
for _i in 0..=n_retries {
|
||||||
res = attestation_job(AttestationJobArgs {
|
res = attestation_job(AttestationJobArgs {
|
||||||
|
@ -757,7 +758,7 @@ async fn attestation_job(args: AttestationJobArgs) -> Result<(), ErrBoxSend> {
|
||||||
"Batch {}/{}, group {:?}: Starting attestation job",
|
"Batch {}/{}, group {:?}: Starting attestation job",
|
||||||
batch_no, batch_count, group_name
|
batch_no, batch_count, group_name
|
||||||
);
|
);
|
||||||
let rpc = lock_and_make_rpc(&*rlmtx).await; // Reuse the same lock for the blockhash/tx/get_transaction
|
let rpc = lock_and_make_rpc(&rlmtx).await; // Reuse the same lock for the blockhash/tx/get_transaction
|
||||||
let latest_blockhash = rpc
|
let latest_blockhash = rpc
|
||||||
.get_latest_blockhash()
|
.get_latest_blockhash()
|
||||||
.map_err(|e| -> ErrBoxSend { e.into() })
|
.map_err(|e| -> ErrBoxSend { e.into() })
|
||||||
|
@ -801,7 +802,7 @@ async fn attestation_job(args: AttestationJobArgs) -> Result<(), ErrBoxSend> {
|
||||||
}
|
}
|
||||||
seqno
|
seqno
|
||||||
})
|
})
|
||||||
.ok_or_else(|| -> ErrBoxSend { format!("No seqno in program logs").into() })?;
|
.ok_or_else(|| -> ErrBoxSend { "No seqno in program logs".to_string().into() })?;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Batch {}/{}, group {:?} OK",
|
"Batch {}/{}, group {:?} OK",
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl<T> RLMutex<T> {
|
||||||
pub fn new(val: T, rl_interval: Duration) -> Self {
|
pub fn new(val: T, rl_interval: Duration) -> Self {
|
||||||
Self {
|
Self {
|
||||||
mtx: Mutex::new(RLMutexState {
|
mtx: Mutex::new(RLMutexState {
|
||||||
last_released: Instant::now() - rl_interval,
|
last_released: Instant::now().checked_sub(rl_interval).unwrap(),
|
||||||
val,
|
val,
|
||||||
}),
|
}),
|
||||||
rl_interval,
|
rl_interval,
|
||||||
|
|
|
@ -12,7 +12,7 @@ use {
|
||||||
pub fn passthrough_entrypoint(
|
pub fn passthrough_entrypoint(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
account_infos: &[AccountInfo],
|
account_infos: &[AccountInfo],
|
||||||
data: &[u8],
|
_data: &[u8],
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
msg!(&format!("Program {}", program_id));
|
msg!(&format!("Program {}", program_id));
|
||||||
msg!(&format!("account_infos {:?}", account_infos));
|
msg!(&format!("account_infos {:?}", account_infos));
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
//! 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 {
|
use {
|
||||||
pyth_client::{
|
pyth_sdk_solana::state::{
|
||||||
AccKey,
|
|
||||||
AccountType,
|
AccountType,
|
||||||
Price,
|
PriceAccount,
|
||||||
Product,
|
ProductAccount,
|
||||||
MAGIC,
|
MAGIC,
|
||||||
PROD_ATTR_SIZE,
|
PROD_ATTR_SIZE,
|
||||||
VERSION,
|
VERSION,
|
||||||
|
@ -26,25 +25,21 @@ pub fn add_test_symbol(pt: &mut ProgramTest, owner: &Pubkey) -> (Pubkey, Pubkey)
|
||||||
|
|
||||||
// Instantiate
|
// Instantiate
|
||||||
let prod = {
|
let prod = {
|
||||||
Product {
|
ProductAccount {
|
||||||
magic: MAGIC,
|
magic: MAGIC,
|
||||||
ver: VERSION,
|
ver: VERSION,
|
||||||
atype: AccountType::Product as u32,
|
atype: AccountType::Product as u32,
|
||||||
size: 0,
|
size: 0,
|
||||||
px_acc: AccKey {
|
px_acc: price_id,
|
||||||
val: price_id.to_bytes(),
|
|
||||||
},
|
|
||||||
attr: [0u8; PROD_ATTR_SIZE],
|
attr: [0u8; PROD_ATTR_SIZE],
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut price = Price {
|
let price = PriceAccount {
|
||||||
magic: MAGIC,
|
magic: MAGIC,
|
||||||
ver: VERSION,
|
ver: VERSION,
|
||||||
atype: AccountType::Price as u32,
|
atype: AccountType::Price as u32,
|
||||||
prod: AccKey {
|
prod: prod_id,
|
||||||
val: prod_id.to_bytes(),
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,17 +60,17 @@ pub fn add_test_symbol(pt: &mut ProgramTest, owner: &Pubkey) -> (Pubkey, Pubkey)
|
||||||
let price_lamports = Rent::default().minimum_balance(price_bytes.len());
|
let price_lamports = Rent::default().minimum_balance(price_bytes.len());
|
||||||
|
|
||||||
// Populate the accounts
|
// Populate the accounts
|
||||||
let mut prod_acc = Account {
|
let prod_acc = Account {
|
||||||
lamports: prod_lamports,
|
lamports: prod_lamports,
|
||||||
data: (*prod_bytes).to_vec(),
|
data: (*prod_bytes).to_vec(),
|
||||||
owner: owner.clone(),
|
owner: *owner,
|
||||||
rent_epoch: 0,
|
rent_epoch: 0,
|
||||||
executable: false,
|
executable: false,
|
||||||
};
|
};
|
||||||
let mut price_acc = Account {
|
let price_acc = Account {
|
||||||
lamports: price_lamports,
|
lamports: price_lamports,
|
||||||
data: (*price_bytes).to_vec(),
|
data: (*price_bytes).to_vec(),
|
||||||
owner: owner.clone(),
|
owner: *owner,
|
||||||
rent_epoch: 0,
|
rent_epoch: 0,
|
||||||
executable: false,
|
executable: false,
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,22 +18,14 @@ use {
|
||||||
solana_program_test::*,
|
solana_program_test::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
instruction::{
|
|
||||||
AccountMeta,
|
|
||||||
Instruction,
|
|
||||||
},
|
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
signature::Signer,
|
|
||||||
signer::keypair::Keypair,
|
|
||||||
transaction::Transaction,
|
|
||||||
},
|
},
|
||||||
solitaire::{
|
solitaire::{
|
||||||
processors::seeded::Seeded,
|
processors::seeded::Seeded,
|
||||||
AccountState,
|
AccountState,
|
||||||
BorshSerialize,
|
BorshSerialize,
|
||||||
},
|
},
|
||||||
std::time::Duration,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -104,7 +96,7 @@ async fn test_happy_path() -> Result<(), p2wc::ErrBoxSend> {
|
||||||
passthrough::add_passthrough(&mut p2w_test, "wormhole", wh_fixture_program_id);
|
passthrough::add_passthrough(&mut p2w_test, "wormhole", wh_fixture_program_id);
|
||||||
let (prod_id, price_id) = pyth::add_test_symbol(&mut p2w_test, &pyth_owner);
|
let (prod_id, price_id) = pyth::add_test_symbol(&mut p2w_test, &pyth_owner);
|
||||||
|
|
||||||
let mut ctx = p2w_test.start_with_context().await;
|
let ctx = p2w_test.start_with_context().await;
|
||||||
|
|
||||||
let symbols = vec![p2wc::P2WSymbol {
|
let symbols = vec![p2wc::P2WSymbol {
|
||||||
name: Some("Mock symbol".to_owned()),
|
name: Some("Mock symbol".to_owned()),
|
||||||
|
@ -112,7 +104,7 @@ async fn test_happy_path() -> Result<(), p2wc::ErrBoxSend> {
|
||||||
price_addr: price_id,
|
price_addr: price_id,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let attest_tx = p2wc::gen_attest_tx(
|
let _attest_tx = p2wc::gen_attest_tx(
|
||||||
p2w_program_id,
|
p2w_program_id,
|
||||||
&p2w_config,
|
&p2w_config,
|
||||||
&ctx.payer,
|
&ctx.payer,
|
||||||
|
|
|
@ -3,15 +3,7 @@
|
||||||
pub mod fixtures;
|
pub mod fixtures;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
bridge::accounts::{
|
fixtures::passthrough,
|
||||||
Bridge,
|
|
||||||
BridgeConfig,
|
|
||||||
BridgeData,
|
|
||||||
},
|
|
||||||
fixtures::{
|
|
||||||
passthrough,
|
|
||||||
pyth,
|
|
||||||
},
|
|
||||||
log::info,
|
log::info,
|
||||||
pyth2wormhole::config::{
|
pyth2wormhole::config::{
|
||||||
OldP2WConfigAccount,
|
OldP2WConfigAccount,
|
||||||
|
@ -24,15 +16,10 @@ use {
|
||||||
solana_program_test::*,
|
solana_program_test::*,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
instruction::{
|
|
||||||
AccountMeta,
|
|
||||||
Instruction,
|
|
||||||
},
|
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
signature::Signer,
|
signature::Signer,
|
||||||
signer::keypair::Keypair,
|
signer::keypair::Keypair,
|
||||||
transaction::Transaction,
|
|
||||||
},
|
},
|
||||||
solitaire::{
|
solitaire::{
|
||||||
processors::seeded::Seeded,
|
processors::seeded::Seeded,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
pub mod fixtures;
|
pub mod fixtures;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
borsh::BorshDeserialize,
|
|
||||||
p2wc::get_config_account,
|
|
||||||
pyth2wormhole::config::{
|
pyth2wormhole::config::{
|
||||||
P2WConfigAccount,
|
P2WConfigAccount,
|
||||||
Pyth2WormholeConfig,
|
Pyth2WormholeConfig,
|
||||||
|
|
|
@ -13,7 +13,6 @@ use {
|
||||||
bridge::{
|
bridge::{
|
||||||
accounts::BridgeData,
|
accounts::BridgeData,
|
||||||
types::ConsistencyLevel,
|
types::ConsistencyLevel,
|
||||||
PostMessageData,
|
|
||||||
},
|
},
|
||||||
p2w_sdk::{
|
p2w_sdk::{
|
||||||
BatchPriceAttestation,
|
BatchPriceAttestation,
|
||||||
|
@ -23,25 +22,18 @@ use {
|
||||||
},
|
},
|
||||||
solana_program::{
|
solana_program::{
|
||||||
clock::Clock,
|
clock::Clock,
|
||||||
instruction::{
|
|
||||||
AccountMeta,
|
|
||||||
Instruction,
|
|
||||||
},
|
|
||||||
program::{
|
program::{
|
||||||
invoke,
|
invoke,
|
||||||
invoke_signed,
|
invoke_signed,
|
||||||
},
|
},
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::Pubkey,
|
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
system_instruction,
|
system_instruction,
|
||||||
sysvar::Sysvar as SolanaSysvar,
|
sysvar::Sysvar as SolanaSysvar,
|
||||||
},
|
},
|
||||||
solitaire::{
|
solitaire::{
|
||||||
invoke_seeded,
|
|
||||||
trace,
|
trace,
|
||||||
AccountState,
|
AccountState,
|
||||||
Derive,
|
|
||||||
ExecutionContext,
|
ExecutionContext,
|
||||||
FromAccounts,
|
FromAccounts,
|
||||||
Info,
|
Info,
|
||||||
|
@ -185,7 +177,7 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
|
||||||
// accs.pyth_price10.as_ref(),
|
// accs.pyth_price10.as_ref(),
|
||||||
];
|
];
|
||||||
|
|
||||||
let price_pairs: Vec<_> = price_pair_opts.into_iter().filter_map(|acc| *acc).collect();
|
let price_pairs: Vec<_> = price_pair_opts.iter().filter_map(|acc| *acc).collect();
|
||||||
|
|
||||||
if price_pairs.len() % 2 != 0 {
|
if price_pairs.len() % 2 != 0 {
|
||||||
trace!(&format!(
|
trace!(&format!(
|
||||||
|
@ -210,13 +202,13 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
|
||||||
product, price,
|
product, price,
|
||||||
accs.config.pyth_owner, product.owner, price.owner
|
accs.config.pyth_owner, product.owner, price.owner
|
||||||
));
|
));
|
||||||
return Err(SolitaireError::InvalidOwner(accs.pyth_price.owner.clone()).into());
|
return Err(SolitaireError::InvalidOwner(*accs.pyth_price.owner));
|
||||||
}
|
}
|
||||||
|
|
||||||
let attestation = PriceAttestation::from_pyth_price_bytes(
|
let attestation = PriceAttestation::from_pyth_price_bytes(
|
||||||
Identifier::new(price.key.to_bytes()),
|
Identifier::new(price.key.to_bytes()),
|
||||||
accs.clock.unix_timestamp,
|
accs.clock.unix_timestamp,
|
||||||
&*price.try_borrow_data()?,
|
&price.try_borrow_data()?,
|
||||||
)
|
)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
trace!(&e.to_string());
|
trace!(&e.to_string());
|
||||||
|
@ -264,7 +256,7 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let wh_msg_drv_data = P2WMessageDrvData {
|
let wh_msg_drv_data = P2WMessageDrvData {
|
||||||
message_owner: accs.payer.key.clone(),
|
message_owner: *accs.payer.key,
|
||||||
batch_size: batch_attestation.price_attestations.len() as u16,
|
batch_size: batch_attestation.price_attestations.len() as u16,
|
||||||
id: data.message_account_id,
|
id: data.message_account_id,
|
||||||
};
|
};
|
||||||
|
@ -290,7 +282,7 @@ pub fn attest(ctx: &ExecutionContext, accs: &mut Attest, data: AttestData) -> So
|
||||||
*accs.wh_message.info().key,
|
*accs.wh_message.info().key,
|
||||||
0,
|
0,
|
||||||
payload,
|
payload,
|
||||||
data.consistency_level.clone(),
|
data.consistency_level,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
trace!(&format!(
|
trace!(&format!(
|
||||||
|
|
|
@ -37,8 +37,8 @@ use {
|
||||||
|
|
||||||
/// Aliases for current config schema (to migrate into)
|
/// Aliases for current config schema (to migrate into)
|
||||||
pub type Pyth2WormholeConfig = Pyth2WormholeConfigV3;
|
pub type Pyth2WormholeConfig = Pyth2WormholeConfigV3;
|
||||||
pub type P2WConfigAccount<'b, const IsInitialized: AccountState> =
|
pub type P2WConfigAccount<'b, const IS_INITIALIZED: AccountState> =
|
||||||
P2WConfigAccountV3<'b, IsInitialized>;
|
P2WConfigAccountV3<'b, IS_INITIALIZED>;
|
||||||
|
|
||||||
impl Owned for Pyth2WormholeConfig {
|
impl Owned for Pyth2WormholeConfig {
|
||||||
fn owner(&self) -> AccountOwner {
|
fn owner(&self) -> AccountOwner {
|
||||||
|
@ -69,8 +69,8 @@ pub struct Pyth2WormholeConfigV1 {
|
||||||
pub max_batch_size: u16,
|
pub max_batch_size: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type P2WConfigAccountV1<'b, const IsInitialized: AccountState> =
|
pub type P2WConfigAccountV1<'b, const IS_INITIALIZED: AccountState> =
|
||||||
Derive<Data<'b, Pyth2WormholeConfigV1, { IsInitialized }>, "pyth2wormhole-config">;
|
Derive<Data<'b, Pyth2WormholeConfigV1, { IS_INITIALIZED }>, "pyth2wormhole-config">;
|
||||||
|
|
||||||
/// Added is_active
|
/// Added is_active
|
||||||
#[derive(Clone, Default, BorshDeserialize, BorshSerialize)]
|
#[derive(Clone, Default, BorshDeserialize, BorshSerialize)]
|
||||||
|
@ -98,8 +98,8 @@ pub struct Pyth2WormholeConfigV2 {
|
||||||
/// usually easier to change the seed slightly
|
/// usually easier to change the seed slightly
|
||||||
/// (e.g. pyth2wormhole-config-v2 -> pyth2wormhole-config-v2.1). This
|
/// (e.g. pyth2wormhole-config-v2 -> pyth2wormhole-config-v2.1). This
|
||||||
/// saves a lot of time coding around this edge case.
|
/// saves a lot of time coding around this edge case.
|
||||||
pub type P2WConfigAccountV2<'b, const IsInitialized: AccountState> =
|
pub type P2WConfigAccountV2<'b, const IS_INITIALIZED: AccountState> =
|
||||||
Derive<Data<'b, Pyth2WormholeConfigV2, { IsInitialized }>, "pyth2wormhole-config-v2.1">;
|
Derive<Data<'b, Pyth2WormholeConfigV2, { IS_INITIALIZED }>, "pyth2wormhole-config-v2.1">;
|
||||||
|
|
||||||
impl From<Pyth2WormholeConfigV1> for Pyth2WormholeConfigV2 {
|
impl From<Pyth2WormholeConfigV1> for Pyth2WormholeConfigV2 {
|
||||||
fn from(old: Pyth2WormholeConfigV1) -> Self {
|
fn from(old: Pyth2WormholeConfigV1) -> Self {
|
||||||
|
@ -144,8 +144,8 @@ pub struct Pyth2WormholeConfigV3 {
|
||||||
pub ops_owner: Option<Pubkey>,
|
pub ops_owner: Option<Pubkey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type P2WConfigAccountV3<'b, const IsInitialized: AccountState> =
|
pub type P2WConfigAccountV3<'b, const IS_INITIALIZED: AccountState> =
|
||||||
Derive<Data<'b, Pyth2WormholeConfigV3, { IsInitialized }>, "pyth2wormhole-config-v3">;
|
Derive<Data<'b, Pyth2WormholeConfigV3, { IS_INITIALIZED }>, "pyth2wormhole-config-v3">;
|
||||||
|
|
||||||
impl From<Pyth2WormholeConfigV2> for Pyth2WormholeConfigV3 {
|
impl From<Pyth2WormholeConfigV2> for Pyth2WormholeConfigV3 {
|
||||||
fn from(old: Pyth2WormholeConfigV2) -> Self {
|
fn from(old: Pyth2WormholeConfigV2) -> Self {
|
||||||
|
@ -154,7 +154,7 @@ impl From<Pyth2WormholeConfigV2> for Pyth2WormholeConfigV3 {
|
||||||
wh_prog,
|
wh_prog,
|
||||||
pyth_owner,
|
pyth_owner,
|
||||||
max_batch_size,
|
max_batch_size,
|
||||||
is_active,
|
is_active: _,
|
||||||
} = old;
|
} = old;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -5,7 +5,6 @@ use {
|
||||||
},
|
},
|
||||||
solana_program::{
|
solana_program::{
|
||||||
program::invoke,
|
program::invoke,
|
||||||
pubkey::Pubkey,
|
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
system_instruction,
|
system_instruction,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(incomplete_features)]
|
||||||
#![feature(adt_const_params)]
|
#![feature(adt_const_params)]
|
||||||
pub mod attest;
|
pub mod attest;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
|
|
@ -17,10 +17,7 @@ use {
|
||||||
solitaire::{
|
solitaire::{
|
||||||
processors::seeded::Seeded,
|
processors::seeded::Seeded,
|
||||||
AccountState,
|
AccountState,
|
||||||
Data,
|
|
||||||
Info,
|
|
||||||
Mut,
|
Mut,
|
||||||
Signer,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ use {
|
||||||
solana_program::{
|
solana_program::{
|
||||||
program::invoke,
|
program::invoke,
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::Pubkey,
|
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
system_instruction,
|
system_instruction,
|
||||||
system_program,
|
system_program,
|
||||||
|
@ -51,7 +50,7 @@ pub struct Migrate<'b> {
|
||||||
pub system_program: Info<'b>,
|
pub system_program: Info<'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, data: ()) -> SoliResult<()> {
|
pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, _data: ()) -> SoliResult<()> {
|
||||||
let old_config: &OldPyth2WormholeConfig = &accs.old_config.1;
|
let old_config: &OldPyth2WormholeConfig = &accs.old_config.1;
|
||||||
|
|
||||||
if &old_config.owner != accs.current_owner.info().key {
|
if &old_config.owner != accs.current_owner.info().key {
|
||||||
|
@ -60,7 +59,7 @@ pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, data: ()) -> SoliResu
|
||||||
old_config.owner
|
old_config.owner
|
||||||
);
|
);
|
||||||
return Err(SolitaireError::InvalidSigner(
|
return Err(SolitaireError::InvalidSigner(
|
||||||
accs.current_owner.info().key.clone(),
|
*accs.current_owner.info().key,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +69,7 @@ pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, data: ()) -> SoliResu
|
||||||
system_program::id(),
|
system_program::id(),
|
||||||
accs.system_program.key
|
accs.system_program.key
|
||||||
);
|
);
|
||||||
return Err(SolitaireError::InvalidSigner(
|
return Err(SolitaireError::InvalidSigner(*accs.system_program.key));
|
||||||
accs.system_program.key.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate new config
|
// Populate new config
|
||||||
|
@ -83,11 +80,11 @@ pub fn migrate(ctx: &ExecutionContext, accs: &mut Migrate, data: ()) -> SoliResu
|
||||||
// Adjust new config lamports
|
// Adjust new config lamports
|
||||||
// NOTE(2022-09-29): Necessary due to PythNet rent calculation
|
// NOTE(2022-09-29): Necessary due to PythNet rent calculation
|
||||||
// differences, remove when solitaire supports Rent::get()?
|
// differences, remove when solitaire supports Rent::get()?
|
||||||
let mut acc_lamports = accs.new_config.info().lamports();
|
let acc_lamports = accs.new_config.info().lamports();
|
||||||
|
|
||||||
let new_lamports = Rent::get()?.minimum_balance(accs.new_config.size());
|
let new_lamports = Rent::get()?.minimum_balance(accs.new_config.size());
|
||||||
|
|
||||||
let diff_lamports: u64 = (acc_lamports as i64 - new_lamports as i64).abs() as u64;
|
let diff_lamports: u64 = (acc_lamports as i64 - new_lamports as i64).unsigned_abs();
|
||||||
|
|
||||||
if acc_lamports < new_lamports {
|
if acc_lamports < new_lamports {
|
||||||
// Less than enough lamports, debit the payer
|
// Less than enough lamports, debit the payer
|
||||||
|
|
|
@ -6,8 +6,6 @@ use {
|
||||||
borsh::BorshSerialize,
|
borsh::BorshSerialize,
|
||||||
solana_program::{
|
solana_program::{
|
||||||
program::invoke,
|
program::invoke,
|
||||||
program_error::ProgramError,
|
|
||||||
pubkey::Pubkey,
|
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
system_instruction,
|
system_instruction,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
|
@ -25,7 +23,6 @@ use {
|
||||||
Signer,
|
Signer,
|
||||||
SolitaireError,
|
SolitaireError,
|
||||||
},
|
},
|
||||||
std::cmp::Ordering,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(FromAccounts)]
|
#[derive(FromAccounts)]
|
||||||
|
@ -46,14 +43,14 @@ pub fn set_config(
|
||||||
accs: &mut SetConfig,
|
accs: &mut SetConfig,
|
||||||
data: Pyth2WormholeConfig,
|
data: Pyth2WormholeConfig,
|
||||||
) -> SoliResult<()> {
|
) -> SoliResult<()> {
|
||||||
let cfgStruct: &Pyth2WormholeConfig = &accs.config; // unpack Data via nested Deref impls
|
let cfg_struct: &Pyth2WormholeConfig = &accs.config; // unpack Data via nested Deref impls
|
||||||
if &cfgStruct.owner != accs.current_owner.info().key {
|
if &cfg_struct.owner != accs.current_owner.info().key {
|
||||||
trace!(
|
trace!(
|
||||||
"Current owner account mismatch (expected {:?})",
|
"Current owner account mismatch (expected {:?})",
|
||||||
cfgStruct.owner
|
cfg_struct.owner
|
||||||
);
|
);
|
||||||
return Err(SolitaireError::InvalidSigner(
|
return Err(SolitaireError::InvalidSigner(
|
||||||
accs.current_owner.info().key.clone(),
|
*accs.current_owner.info().key,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +65,11 @@ pub fn set_config(
|
||||||
accs.config.1 = data;
|
accs.config.1 = data;
|
||||||
|
|
||||||
// Adjust lamports
|
// Adjust lamports
|
||||||
let mut acc_lamports = accs.config.info().lamports();
|
let acc_lamports = accs.config.info().lamports();
|
||||||
|
|
||||||
let new_lamports = Rent::get()?.minimum_balance(new_size);
|
let new_lamports = Rent::get()?.minimum_balance(new_size);
|
||||||
|
|
||||||
let diff_lamports: u64 = (acc_lamports as i64 - new_lamports as i64).abs() as u64;
|
let diff_lamports: u64 = (acc_lamports as i64 - new_lamports as i64).unsigned_abs();
|
||||||
|
|
||||||
if acc_lamports < new_lamports {
|
if acc_lamports < new_lamports {
|
||||||
// Less than enough lamports, debit the payer
|
// Less than enough lamports, debit the payer
|
||||||
|
|
|
@ -42,7 +42,7 @@ use wasm_bindgen::prelude::*;
|
||||||
pub type ErrBox = Box<dyn std::error::Error>;
|
pub type ErrBox = Box<dyn std::error::Error>;
|
||||||
|
|
||||||
/// Precedes every message implementing the p2w serialization format
|
/// Precedes every message implementing the p2w serialization format
|
||||||
pub const P2W_MAGIC: &'static [u8] = b"P2WH";
|
pub const P2W_MAGIC: &[u8] = b"P2WH";
|
||||||
|
|
||||||
/// Format version used and understood by this codebase
|
/// Format version used and understood by this codebase
|
||||||
pub const P2W_FORMAT_VER_MAJOR: u16 = 3;
|
pub const P2W_FORMAT_VER_MAJOR: u16 = 3;
|
||||||
|
@ -352,7 +352,7 @@ impl PriceAttestation {
|
||||||
buf.extend_from_slice(&ema_conf.to_be_bytes()[..]);
|
buf.extend_from_slice(&ema_conf.to_be_bytes()[..]);
|
||||||
|
|
||||||
// status
|
// status
|
||||||
buf.push(status.clone() as u8);
|
buf.push(*status as u8);
|
||||||
|
|
||||||
// num_publishers
|
// num_publishers
|
||||||
buf.extend_from_slice(&num_publishers.to_be_bytes()[..]);
|
buf.extend_from_slice(&num_publishers.to_be_bytes()[..]);
|
||||||
|
@ -456,7 +456,7 @@ impl PriceAttestation {
|
||||||
expo,
|
expo,
|
||||||
ema_price,
|
ema_price,
|
||||||
ema_conf,
|
ema_conf,
|
||||||
status: status.into(),
|
status,
|
||||||
num_publishers,
|
num_publishers,
|
||||||
max_num_publishers,
|
max_num_publishers,
|
||||||
attestation_time,
|
attestation_time,
|
||||||
|
@ -489,7 +489,7 @@ mod tests {
|
||||||
ema_price: -42,
|
ema_price: -42,
|
||||||
ema_conf: 42,
|
ema_conf: 42,
|
||||||
expo: -3,
|
expo: -3,
|
||||||
status: PriceStatus::Trading.into(),
|
status: PriceStatus::Trading,
|
||||||
num_publishers: 123212u32,
|
num_publishers: 123212u32,
|
||||||
max_num_publishers: 321232u32,
|
max_num_publishers: 321232u32,
|
||||||
attestation_time: (0xdeadbeeffadedeedu64) as i64,
|
attestation_time: (0xdeadbeeffadedeedu64) as i64,
|
||||||
|
|
Loading…
Reference in New Issue