Skip to content

Commit e30a9bc

Browse files
Riatecheilya-bobyr
authored andcommitted
--- Batch publish (pyth-network#313) * feat: batch publish * feat: batch publish 2 (wip) * feat: verify that price feed index is set * refactor: add pyth module * feat: integrate pyth-price-publisher * refactor: rename and move get_accumulator_keys * test: make sure batch publish does not apply prices when price_index == 0 * chore: fix format * fix: update deps --- Update dependency, program id and test for pyth-price-store (pyth-network#314) * test: modify batch publish tests * chore: use real batch publish pid as default * chore: update pyth-price-store dependency --- Rename price store env var and bump version (pyth-network#315) * chore: rename variable for pyth store pid * chore: bump pythnet version to 1.14.179
1 parent 19f2407 commit e30a9bc

File tree

14 files changed

+526
-94
lines changed

14 files changed

+526
-94
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,21 @@ exclude = [
9797
# This prevents a Travis CI error when building for Windows.
9898
resolver = "2"
9999

100-
# At the moment, there is no `oracle-v2.33.1` release in the
101-
# `pyth-network/pyth-client` repository. This is an unreleased version that is
102-
# almost identical to `oracle-v2.33.0`, except that it removes strict version
103-
# constraints from the Solana dependencies.
100+
# At the moment, there is no `oracle-v2.33.1` or `oracle-v2.33.2` releases in
101+
# the `pyth-network/pyth-client` repository.
104102
#
103+
# `pythnet-update-oracle-v2.33.1` removes strict version constraints from the
104+
# Solana dependencies.
105+
#
106+
# `pythnet-update-oracle-v2.33.2` cheery picks
107+
# `256b575a13e29bec93ba592c8f86cc5fad521915` "Add feed index for batch
108+
# publish (#416)" on top.
109+
#
110+
# There is a similar override in `programs/bpf/Cargo.toml`. Please keep both in
111+
# sync.
105112
[patch."https://github.com/pyth-network/pyth-client".pyth-oracle]
106113
git = "https://github.com/ilya-bobyr/pyth-client"
107-
branch = "pythnet-update-oracle-v2.33.1"
114+
branch = "pythnet-update-oracle-v2.33.2"
108115

109116
[patch.crates-io]
110117
serde_wormhole = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1" }

core/src/validator.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use {
7676
accounts_db::{AccountShrinkThreshold, AccountsDbConfig},
7777
accounts_index::AccountSecondaryIndexes,
7878
accounts_update_notifier_interface::AccountsUpdateNotifier,
79-
bank::{pyth_accumulator, Bank},
79+
bank::{pyth, Bank},
8080
bank_forks::BankForks,
8181
commitment::BlockCommitmentCache,
8282
cost_model::CostModel,
@@ -1535,14 +1535,8 @@ fn load_blockstore(
15351535
}
15361536
}
15371537

1538-
for (key_name, pk_res) in pyth_accumulator::get_accumulator_keys() {
1539-
match pk_res {
1540-
Ok(pk) => info!("Accumulator {}: {}", key_name, pk),
1541-
Err(err) => {
1542-
error!("Failed to get Accumulator {}: {:?}", key_name, err);
1543-
std::process::abort();
1544-
}
1545-
}
1538+
for (key_name, pk) in pyth::get_pyth_keys() {
1539+
info!("Pyth key {}: {}", key_name, pk);
15461540
}
15471541

15481542
leader_schedule_cache.set_fixed_leader_schedule(config.fixed_leader_schedule.clone());

programs/bpf/Cargo.lock

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

programs/bpf/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ targets = ["x86_64-unknown-linux-gnu"]
104104
# sync.
105105
[patch."https://github.com/pyth-network/pyth-client".pyth-oracle]
106106
git = "https://github.com/ilya-bobyr/pyth-client"
107-
branch = "pythnet-update-oracle-v2.33.1"
107+
branch = "pythnet-update-oracle-v2.33.2"
108108

109109
[patch.crates-io]
110110
# See root level `Cargo.toml` for an explanation of this patch. Keep them in

runtime/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ num-traits = { version = "0.2" }
3636
num_cpus = "1.13.1"
3737
once_cell = "1.12.0"
3838
ouroboros = "0.15.0"
39-
pyth-oracle = { git = "https://github.com/pyth-network/pyth-client", tag = "oracle-v2.33.0", features = ["library"] }
39+
pyth-oracle = { git = "https://github.com/pyth-network/pyth-client", rev = "256b57", features = ["library"] }
4040
pythnet-sdk = { git = "https://github.com/pyth-network/pyth-crosschain", version = "1.13.6", rev = "33f901aa45f4f0005aa5a84a1479b78ca9033074" }
41+
pyth-price-store = "0.1.0"
4142
rand = "0.7.0"
4243
rayon = "1.5.3"
4344
regex = "1.5.6"

runtime/src/bank.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,7 @@ mod builtin_programs;
198198
mod sysvar_cache;
199199
mod transaction_account_state_info;
200200

201-
pub mod pyth_accumulator;
202-
203-
#[cfg(test)]
204-
mod pyth_accumulator_tests;
201+
pub mod pyth;
205202

206203
pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0;
207204

@@ -1410,7 +1407,7 @@ impl Bank {
14101407
// state before the accumulator is used. bank is in a fully
14111408
// updated state before the accumulator is used.
14121409
if !accumulator_moved_to_end_of_block {
1413-
pyth_accumulator::update_accumulator(&bank);
1410+
pyth::accumulator::update_accumulator(&bank);
14141411
}
14151412

14161413
bank
@@ -1796,7 +1793,7 @@ impl Bank {
17961793
// the accumulator sysvar updates. sysvars are in a fully updated
17971794
// state before the accumulator sysvar updates.
17981795
if !accumulator_moved_to_end_of_block {
1799-
pyth_accumulator::update_accumulator(&new);
1796+
pyth::accumulator::update_accumulator(&new);
18001797
}
18011798
});
18021799

@@ -3238,7 +3235,7 @@ impl Bank {
32383235
// other tasks when freezing to avoid any conflicts.
32393236
if accumulator_moved_to_end_of_block {
32403237
let mut measure = Measure::start("accumulator");
3241-
pyth_accumulator::update_accumulator(self);
3238+
pyth::accumulator::update_accumulator(self);
32423239
measure.stop();
32433240

32443241
debug!(

runtime/src/bank/pyth_accumulator.rs renamed to runtime/src/bank/pyth/accumulator.rs

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
use {
2-
super::Bank,
3-
crate::accounts_index::{IndexKey, ScanConfig, ScanError},
2+
super::batch_publish,
3+
crate::{
4+
accounts_index::{IndexKey, ScanConfig, ScanError},
5+
bank::Bank,
6+
},
47
borsh::BorshSerialize,
58
byteorder::{LittleEndian, ReadBytesExt},
9+
itertools::Itertools,
610
log::*,
711
pyth_oracle::validator::AggregationError,
812
pythnet_sdk::{
@@ -19,7 +23,10 @@ use {
1923
hash::hashv,
2024
pubkey::Pubkey,
2125
},
22-
std::env::{self, VarError},
26+
std::{
27+
collections::HashMap,
28+
env::{self, VarError},
29+
},
2330
};
2431

2532
pub const ACCUMULATOR_RING_SIZE: u32 = 10_000;
@@ -53,6 +60,12 @@ lazy_static! {
5360
.parse()
5461
.unwrap(),
5562
);
63+
pub static ref PRICE_STORE_PID: Pubkey = env_pubkey_or(
64+
"PRICE_STORE_PID",
65+
"3m6sv6HGqEbuyLV84mD7rJn4MAC9LhUa1y1AUNVqcPfr"
66+
.parse()
67+
.unwrap(),
68+
);
5669
}
5770

5871
/// Accumulator specific error type. It would be nice to use `transaction::Error` but it does
@@ -118,25 +131,6 @@ fn env_pubkey_or(var: &str, default: Pubkey) -> Pubkey {
118131
}
119132
}
120133

121-
/// Get all accumulator related pubkeys from environment variables
122-
/// or return default if the variable is not set.
123-
pub fn get_accumulator_keys() -> Vec<(
124-
&'static str,
125-
std::result::Result<Pubkey, AccumulatorUpdateErrorV1>,
126-
)> {
127-
vec![
128-
("MESSAGE_BUFFER_PID", Ok(*MESSAGE_BUFFER_PID)),
129-
("ACCUMULATOR_EMITTER_ADDR", Ok(*ACCUMULATOR_EMITTER_ADDR)),
130-
("ACCUMULATOR_SEQUENCE_ADDR", Ok(*ACCUMULATOR_SEQUENCE_ADDR)),
131-
("WORMHOLE_PID", Ok(*WORMHOLE_PID)),
132-
("ORACLE_PID", Ok(*ORACLE_PID)),
133-
(
134-
"STAKE_CAPS_PARAMETERS_ADDR",
135-
Ok(*STAKE_CAPS_PARAMETERS_ADDR),
136-
),
137-
]
138-
}
139-
140134
pub fn update_v1(
141135
bank: &Bank,
142136
v2_messages: &[Vec<u8>],
@@ -424,21 +418,37 @@ pub fn update_v2(bank: &Bank) -> std::result::Result<(), AccumulatorUpdateErrorV
424418
v2_messages.push(publisher_stake_caps_message);
425419
}
426420

427-
let mut measure = Measure::start("update_v2_aggregate_price");
421+
let mut measure = Measure::start("extract_batch_publish_prices");
422+
let mut new_prices = batch_publish::extract_batch_publish_prices(bank).unwrap_or_else(|err| {
423+
warn!("extract_batch_publish_prices failed: {}", err);
424+
HashMap::new()
425+
});
426+
measure.stop();
427+
debug!("batch publish: loaded prices in {}us", measure.as_us());
428428

429+
let mut measure = Measure::start("update_v2_aggregate_price");
429430
for (pubkey, mut account) in accounts {
430431
let mut price_account_data = account.data().to_owned();
432+
let price_account =
433+
match pyth_oracle::validator::checked_load_price_account_mut(&mut price_account_data) {
434+
Ok(data) => data,
435+
Err(_err) => {
436+
continue;
437+
}
438+
};
439+
440+
let mut need_save =
441+
batch_publish::apply_published_prices(price_account, &mut new_prices, bank.slot());
431442

432443
// Perform Accumulation
433444
match pyth_oracle::validator::aggregate_price(
434445
bank.slot(),
435446
bank.clock().unix_timestamp,
436447
&pubkey.to_bytes().into(),
437-
&mut price_account_data,
448+
price_account,
438449
) {
439450
Ok(messages) => {
440-
account.set_data(price_account_data);
441-
bank.store_account_and_update_capitalization(&pubkey, &account);
451+
need_save = true;
442452
v2_messages.extend(messages);
443453
}
444454
Err(err) => match err {
@@ -448,6 +458,16 @@ pub fn update_v2(bank: &Bank) -> std::result::Result<(), AccumulatorUpdateErrorV
448458
}
449459
},
450460
}
461+
if need_save {
462+
account.set_data(price_account_data);
463+
bank.store_account_and_update_capitalization(&pubkey, &account);
464+
}
465+
}
466+
if !new_prices.is_empty() {
467+
warn!(
468+
"pyth batch publish: missing price feed accounts for indexes: {}",
469+
new_prices.keys().join(", ")
470+
);
451471
}
452472

453473
measure.stop();

0 commit comments

Comments
 (0)