Skip to content

Commit d728f10

Browse files
committed
add logic to get database number by block height or return error if
block garbage collected
1 parent cd140d5 commit d728f10

File tree

2 files changed

+162
-85
lines changed

2 files changed

+162
-85
lines changed

database/src/postgres/mod.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl PageState {
3030

3131
pub struct ShardIdPool<'a> {
3232
shard_id: near_primitives::types::ShardId,
33+
table_number: u64,
3334
pool: &'a sqlx::Pool<sqlx::Postgres>,
3435
}
3536

@@ -38,6 +39,7 @@ pub struct PostgresDBManager {
3839
shards_pool:
3940
std::collections::HashMap<near_primitives::types::ShardId, sqlx::Pool<sqlx::Postgres>>,
4041
meta_db_pool: sqlx::Pool<sqlx::Postgres>,
42+
earliest_available_block: Option<near_primitives::types::BlockHeight>,
4143
}
4244

4345
impl PostgresDBManager {
@@ -74,17 +76,66 @@ impl PostgresDBManager {
7476
async fn get_shard_connection(
7577
&self,
7678
account_id: &near_primitives::types::AccountId,
79+
block_height: &near_primitives::types::BlockHeight,
7780
) -> anyhow::Result<ShardIdPool> {
7881
let shard_id = self.shard_layout.account_id_to_shard_id(account_id);
7982
Ok(ShardIdPool {
8083
shard_id,
84+
table_number: self.get_table_number(block_height).await?,
8185
pool: self.shards_pool.get(&shard_id).ok_or(anyhow::anyhow!(
8286
"Database connection for Shard_{} not found",
8387
shard_id
8488
))?,
8589
})
8690
}
8791

92+
/// # Explanation of the logic:
93+
///
94+
/// 1. `block_height / 500000`
95+
///
96+
/// * This integer division truncates any remainder, effectively grouping numbers into bins of 500,000.
97+
///
98+
/// * Example: 73908345 / 500000 = 147 (as integer division discards the remainder).
99+
///
100+
/// 2. `* 5`
101+
///
102+
/// * Since each bin represents a multiple of 500,000, multiplying by 5 scales the result to match the pattern you provided.
103+
///
104+
/// # Example Calculations:
105+
/// Example 1: 73908345
106+
///
107+
/// 1. 73908345 / 500000 = 147
108+
///
109+
/// 2. 147 * 5 = 735
110+
///
111+
/// Output: 735
112+
///
113+
/// Example 2: 130501000
114+
///
115+
/// 1. 130501000 / 500000 = 261
116+
///
117+
/// 2. 261 * 5 = 1305
118+
///
119+
/// Output: 1305
120+
async fn get_table_number(
121+
&self,
122+
block_height: &near_primitives::types::BlockHeight,
123+
) -> anyhow::Result<u64> {
124+
if let Some(earliest_available_block) = self.earliest_available_block {
125+
if *block_height < earliest_available_block {
126+
anyhow::bail!(
127+
"Block {} has been garbage collected. The earliest available block is {}",
128+
block_height,
129+
earliest_available_block
130+
)
131+
} else {
132+
Ok((block_height / 500000) * 5)
133+
}
134+
} else {
135+
Ok((block_height / 500000) * 5)
136+
}
137+
}
138+
88139
async fn run_migrations(
89140
migrator: &sqlx::migrate::Migrator,
90141
pool: &sqlx::Pool<sqlx::Postgres>,
@@ -121,6 +172,10 @@ impl crate::BaseDbManager for PostgresDBManager {
121172
shard_layout,
122173
shards_pool,
123174
meta_db_pool,
175+
// TODO: This should be set from the config and not hardcoded
176+
// Should be updated when garbage collection is run
177+
// or should be None for archive node_mode
178+
earliest_available_block: None,
124179
}))
125180
}
126181
}

0 commit comments

Comments
 (0)