solana_geyser_plugin_postgres/postgres_client/
postgres_client_block_metadata.rs1use {
2 crate::{
3 geyser_plugin_postgres::{GeyserPluginPostgresConfig, GeyserPluginPostgresError},
4 postgres_client::{
5 postgres_client_transaction::DbReward, SimplePostgresClient, UpdateBlockMetadataRequest,
6 },
7 },
8 chrono::Utc,
9 log::*,
10 postgres::{Client, Statement},
11 solana_geyser_plugin_interface::geyser_plugin_interface::{
12 GeyserPluginError, ReplicaBlockInfo,
13 },
14};
15
16#[derive(Clone, Debug)]
17pub struct DbBlockInfo {
18 pub slot: i64,
19 pub blockhash: String,
20 pub rewards: Vec<DbReward>,
21 pub block_time: Option<i64>,
22 pub block_height: Option<i64>,
23}
24
25impl<'a> From<&ReplicaBlockInfo<'a>> for DbBlockInfo {
26 fn from(block_info: &ReplicaBlockInfo) -> Self {
27 Self {
28 slot: block_info.slot as i64,
29 blockhash: block_info.blockhash.to_string(),
30 rewards: block_info.rewards.iter().map(DbReward::from).collect(),
31 block_time: block_info.block_time,
32 block_height: block_info
33 .block_height
34 .map(|block_height| block_height as i64),
35 }
36 }
37}
38
39impl SimplePostgresClient {
40 pub(crate) fn build_block_metadata_upsert_statement(
41 client: &mut Client,
42 config: &GeyserPluginPostgresConfig,
43 ) -> Result<Statement, GeyserPluginError> {
44 let stmt =
45 "INSERT INTO block (slot, blockhash, rewards, block_time, block_height, updated_on) \
46 VALUES ($1, $2, $3, $4, $5, $6)";
47
48 let stmt = client.prepare(stmt);
49
50 match stmt {
51 Err(err) => {
52 return Err(GeyserPluginError::Custom(Box::new(GeyserPluginPostgresError::DataSchemaError {
53 msg: format!(
54 "Error in preparing for the block metadata update PostgreSQL database: ({}) host: {:?} user: {:?} config: {:?}",
55 err, config.host, config.user, config
56 ),
57 })));
58 }
59 Ok(stmt) => Ok(stmt),
60 }
61 }
62
63 pub(crate) fn update_block_metadata_impl(
64 &mut self,
65 block_info: UpdateBlockMetadataRequest,
66 ) -> Result<(), GeyserPluginError> {
67 let client = self.client.get_mut().unwrap();
68 let statement = &client.update_block_metadata_stmt;
69 let client = &mut client.client;
70 let updated_on = Utc::now().naive_utc();
71
72 let block_info = block_info.block_info;
73 let result = client.query(
74 statement,
75 &[
76 &block_info.slot,
77 &block_info.blockhash,
78 &block_info.rewards,
79 &block_info.block_time,
80 &block_info.block_height,
81 &updated_on,
82 ],
83 );
84
85 if let Err(err) = result {
86 let msg = format!(
87 "Failed to persist the update of block metadata to the PostgreSQL database. Error: {:?}",
88 err);
89 error!("{}", msg);
90 return Err(GeyserPluginError::AccountsUpdateError { msg });
91 }
92
93 Ok(())
94 }
95}