@@ -30,6 +30,7 @@ impl PageState {
3030
3131pub 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
4345impl 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