Skip to content

Commit 801b902

Browse files
committed
feat: fetch publisher buffer key
1 parent 0045bdc commit 801b902

File tree

5 files changed

+82
-24
lines changed

5 files changed

+82
-24
lines changed

src/agent/services/exporter.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ mod exporter {
261261
config.exporter.staleness_threshold,
262262
config.exporter.unchanged_publish_threshold,
263263
).await {
264+
let publisher_buffer_key = Exporter::get_publisher_buffer_key(&*state).await;
264265
if let Err(err) = publish_batches(
265266
state.clone(),
266267
client.clone(),
@@ -270,7 +271,7 @@ mod exporter {
270271
&publish_keypair,
271272
key_store.oracle_program_key,
272273
key_store.publish_program_key,
273-
key_store.publisher_buffer_key,
274+
publisher_buffer_key,
274275
config.exporter.max_batch_size,
275276
config.exporter.staleness_threshold,
276277
config.exporter.compute_unit_limit,

src/agent/services/oracle.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ where
6262
state.clone(),
6363
key_store.mapping_key,
6464
key_store.publish_keypair,
65+
key_store.publish_program_key,
6566
config.oracle.max_lookup_batch_size,
6667
)));
6768

@@ -159,6 +160,7 @@ async fn poller<S>(
159160
state: Arc<S>,
160161
mapping_key: Pubkey,
161162
publish_keypair: Option<Keypair>,
163+
publish_program_key: Option<Pubkey>,
162164
max_lookup_batch_size: usize,
163165
) where
164166
S: Oracle,
@@ -183,6 +185,7 @@ async fn poller<S>(
183185
network,
184186
mapping_key,
185187
publish_keypair.as_ref(),
188+
publish_program_key,
186189
&client,
187190
max_lookup_batch_size,
188191
)

src/agent/solana.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,6 @@ pub mod key_store {
103103
default
104104
)]
105105
pub publish_program_key: Option<Pubkey>,
106-
/// The public key of the publisher's buffer for the Publish program
107-
#[serde(
108-
serialize_with = "opt_pubkey_string_ser",
109-
deserialize_with = "opt_pubkey_string_de",
110-
default
111-
)]
112-
pub publisher_buffer_key: Option<Pubkey>,
113106
/// The public key of the root mapping account
114107
#[serde(
115108
serialize_with = "pubkey_string_ser",
@@ -129,18 +122,15 @@ pub mod key_store {
129122
/// The keypair used to publish price updates. When None,
130123
/// publishing will not start until a new keypair is supplied
131124
/// via the remote loading endpoint
132-
pub publish_keypair: Option<Keypair>,
125+
pub publish_keypair: Option<Keypair>,
133126
/// Public key of the Oracle program
134-
pub oracle_program_key: Pubkey,
127+
pub oracle_program_key: Pubkey,
135128
/// Public key of the Publish program
136-
pub publish_program_key: Option<Pubkey>,
137-
/// Public key of the publisher's buffer for the publish program
138-
pub publisher_buffer_key: Option<Pubkey>,
139-
129+
pub publish_program_key: Option<Pubkey>,
140130
/// Public key of the root mapping account
141-
pub mapping_key: Pubkey,
131+
pub mapping_key: Pubkey,
142132
/// Public key of the accumulator program (if provided)
143-
pub accumulator_key: Option<Pubkey>,
133+
pub accumulator_key: Option<Pubkey>,
144134
}
145135

146136
impl KeyStore {
@@ -161,7 +151,6 @@ pub mod key_store {
161151
publish_keypair,
162152
oracle_program_key: config.oracle_program_key,
163153
publish_program_key: config.publish_program_key,
164-
publisher_buffer_key: config.publisher_buffer_key,
165154
mapping_key: config.mapping_key,
166155
accumulator_key: config.accumulator_key,
167156
})

src/agent/state/exporter.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ use {
1515
},
1616
},
1717
anyhow::{
18-
anyhow, bail, Context, Result
18+
anyhow,
19+
bail,
20+
Context,
21+
Result,
1922
},
2023
bincode::Options,
21-
bytemuck::{bytes_of, cast_slice},
24+
bytemuck::{
25+
bytes_of,
26+
cast_slice,
27+
},
2228
chrono::Utc,
2329
futures_util::future::join_all,
2430
pyth_price_publisher::accounts::buffer::BufferedPrice,
@@ -81,6 +87,8 @@ pub struct ExporterState {
8187
/// Currently known permissioned prices of this publisher along with their market hours
8288
our_prices: RwLock<HashMap<Pubkey, PricePublishingMetadata>>,
8389

90+
publisher_buffer_key: RwLock<Option<Pubkey>>,
91+
8492
/// Recent compute unit price in micro lamports (set if dynamic compute unit pricing is enabled)
8593
recent_compute_unit_price_micro_lamports: RwLock<Option<u64>>,
8694
}
@@ -106,6 +114,7 @@ where
106114
staleness_threshold: Duration,
107115
unchanged_publish_threshold: Duration,
108116
) -> Result<Vec<PermissionedUpdate>>;
117+
async fn get_publisher_buffer_key(&self) -> Option<Pubkey>;
109118
async fn get_recent_compute_unit_price_micro_lamports(&self) -> Option<u64>;
110119
async fn update_recent_compute_unit_price(
111120
&self,
@@ -114,11 +123,12 @@ where
114123
staleness_threshold: Duration,
115124
unchanged_publish_threshold: Duration,
116125
) -> Result<()>;
117-
async fn update_permissions(
126+
async fn update_on_chain_state(
118127
&self,
119128
network: Network,
120129
publish_keypair: Option<&Keypair>,
121130
publisher_permissions: HashMap<Pubkey, HashMap<Pubkey, PricePublishingMetadata>>,
131+
publisher_buffer_key: Option<Pubkey>,
122132
) -> Result<()>;
123133
}
124134

@@ -267,6 +277,10 @@ where
267277
.collect::<Vec<_>>())
268278
}
269279

280+
async fn get_publisher_buffer_key(&self) -> Option<Pubkey> {
281+
*self.into().publisher_buffer_key.read().await
282+
}
283+
270284
async fn get_recent_compute_unit_price_micro_lamports(&self) -> Option<u64> {
271285
*self
272286
.into()
@@ -313,11 +327,12 @@ where
313327
}
314328

315329
#[instrument(skip(self, publish_keypair, publisher_permissions))]
316-
async fn update_permissions(
330+
async fn update_on_chain_state(
317331
&self,
318332
network: Network,
319333
publish_keypair: Option<&Keypair>,
320334
publisher_permissions: HashMap<Pubkey, HashMap<Pubkey, PricePublishingMetadata>>,
335+
publisher_buffer_key: Option<Pubkey>,
321336
) -> Result<()> {
322337
let publish_keypair = get_publish_keypair(self, network, publish_keypair).await?;
323338
*self.into().our_prices.write().await = publisher_permissions
@@ -330,6 +345,7 @@ where
330345
);
331346
HashMap::new()
332347
});
348+
*self.into().publisher_buffer_key.write().await = publisher_buffer_key;
333349

334350
Ok(())
335351
}
@@ -580,7 +596,8 @@ where
580596
let instruction = create_instruction_with_publish_program(
581597
publish_keypair.pubkey(),
582598
publish_program_key,
583-
publisher_buffer_key.context("must specify publisher_buffer_key if publish_program_key is specified")?,
599+
publisher_buffer_key
600+
.context("must specify publisher_buffer_key if publish_program_key is specified")?,
584601
updates,
585602
)?;
586603
instructions.push(instruction);
@@ -805,7 +822,11 @@ fn create_instruction_with_publish_program(
805822
publisher_buffer_key: Pubkey,
806823
prices: Vec<PermissionedUpdate>,
807824
) -> Result<Instruction> {
808-
use pyth_price_publisher::instruction::{Instruction as PublishInstruction, SubmitPricesArgsHeader, PUBLISHER_CONFIG_SEED};
825+
use pyth_price_publisher::instruction::{
826+
Instruction as PublishInstruction,
827+
SubmitPricesArgsHeader,
828+
PUBLISHER_CONFIG_SEED,
829+
};
809830
let (publisher_config_key, publisher_config_bump) = Pubkey::find_program_address(
810831
&[PUBLISHER_CONFIG_SEED.as_bytes(), &publish_pubkey.to_bytes()],
811832
&publish_program_key,

src/agent/state/oracle.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use {
1818
Context,
1919
Result,
2020
},
21+
pyth_price_publisher::instruction::PUBLISHER_CONFIG_SEED,
2122
pyth_sdk_solana::state::{
2223
load_mapping_account,
2324
load_product_account,
@@ -37,6 +38,7 @@ use {
3738
commitment_config::CommitmentLevel,
3839
pubkey::Pubkey,
3940
signature::Keypair,
41+
signer::Signer,
4042
},
4143
std::{
4244
collections::{
@@ -135,6 +137,7 @@ pub struct Data {
135137
pub price_accounts: HashMap<Pubkey, PriceEntry>,
136138
/// publisher => {their permissioned price accounts => price publishing metadata}
137139
pub publisher_permissions: HashMap<Pubkey, HashMap<Pubkey, PricePublishingMetadata>>,
140+
pub publisher_buffer_key: Option<Pubkey>,
138141
}
139142

140143
#[derive(Clone, Serialize, Deserialize, Debug)]
@@ -193,6 +196,7 @@ pub trait Oracle {
193196
network: Network,
194197
mapping_key: Pubkey,
195198
publish_keypair: Option<&Keypair>,
199+
publish_program_key: Option<Pubkey>,
196200
rpc_client: &RpcClient,
197201
max_lookup_batch_size: usize,
198202
) -> Result<()>;
@@ -267,6 +271,7 @@ where
267271
network: Network,
268272
mapping_key: Pubkey,
269273
publish_keypair: Option<&Keypair>,
274+
publish_program_key: Option<Pubkey>,
270275
rpc_client: &RpcClient,
271276
max_lookup_batch_size: usize,
272277
) -> Result<()> {
@@ -311,22 +316,44 @@ where
311316
}
312317
}
313318

319+
let mut publisher_buffer_key = None;
320+
if let (Some(publish_program_key), Some(publish_keypair)) =
321+
(publish_program_key, publish_keypair)
322+
{
323+
match fetch_publisher_buffer_key(
324+
rpc_client,
325+
publish_program_key,
326+
publish_keypair.pubkey(),
327+
)
328+
.await
329+
{
330+
Ok(r) => {
331+
publisher_buffer_key = Some(r);
332+
}
333+
Err(err) => {
334+
tracing::warn!("failed to fetch publisher buffer key: {:?}", err);
335+
}
336+
}
337+
}
338+
314339
let new_data = Data {
315340
mapping_accounts,
316341
product_accounts,
317342
price_accounts,
318343
publisher_permissions,
344+
publisher_buffer_key,
319345
};
320346

321347
let mut data = self.into().data.write().await;
322348
log_data_diff(&data, &new_data);
323349
*data = new_data;
324350

325-
Exporter::update_permissions(
351+
Exporter::update_on_chain_state(
326352
self,
327353
network,
328354
publish_keypair,
329355
data.publisher_permissions.clone(),
356+
data.publisher_buffer_key,
330357
)
331358
.await?;
332359

@@ -367,6 +394,23 @@ where
367394
}
368395
}
369396

397+
async fn fetch_publisher_buffer_key(
398+
rpc_client: &RpcClient,
399+
publish_program_key: Pubkey,
400+
publisher_pubkey: Pubkey,
401+
) -> Result<Pubkey> {
402+
let (publisher_config_key, _bump) = Pubkey::find_program_address(
403+
&[
404+
PUBLISHER_CONFIG_SEED.as_bytes(),
405+
&publisher_pubkey.to_bytes(),
406+
],
407+
&publish_program_key,
408+
);
409+
let data = rpc_client.get_account_data(&publisher_config_key).await?;
410+
let config = pyth_price_publisher::accounts::publisher_config::read(&data)?;
411+
Ok(config.buffer_account.into())
412+
}
413+
370414
#[instrument(skip(rpc_client))]
371415
async fn fetch_mapping_accounts(
372416
rpc_client: &RpcClient,

0 commit comments

Comments
 (0)