@@ -202,6 +202,75 @@ impl<S: Store> IndexNodeResolver<S> {
202202 } )
203203 }
204204
205+ async fn resolve_block_hash_from_number (
206+ & self ,
207+ field : & a:: Field ,
208+ ) -> Result < r:: Value , QueryExecutionError > {
209+ let network = field
210+ . get_required :: < String > ( "network" )
211+ . expect ( "Valid network required" ) ;
212+ let block_number = field
213+ . get_required :: < BlockNumber > ( "blockNumber" )
214+ . expect ( "Valid blockNumber required" ) ;
215+
216+ macro_rules! try_resolve_for_chain {
217+ ( $typ: path ) => {
218+ let blockchain = self . blockchain_map. get:: <$typ>( network. to_string( ) ) . ok( ) ;
219+
220+ if let Some ( blockchain) = blockchain {
221+ debug!(
222+ self . logger,
223+ "Fetching block hash from number" ;
224+ "network" => & network,
225+ "block_number" => block_number,
226+ ) ;
227+
228+ let block_ptr_res = blockchain
229+ . block_pointer_from_number( & self . logger, block_number)
230+ . await ;
231+
232+ if let Err ( e) = block_ptr_res {
233+ warn!(
234+ self . logger,
235+ "Failed to fetch block hash from number" ;
236+ "network" => & network,
237+ "chain" => <$typ as Blockchain >:: KIND . to_string( ) ,
238+ "block_number" => block_number,
239+ "error" => e. to_string( ) ,
240+ ) ;
241+ return Ok ( r:: Value :: Null ) ;
242+ }
243+
244+ let block_ptr = block_ptr_res. unwrap( ) ;
245+ return Ok ( r:: Value :: String ( block_ptr. hash_hex( ) ) ) ;
246+ }
247+ } ;
248+ }
249+
250+ // Ugly, but we can't get back an object trait from the `BlockchainMap`,
251+ // so this seems like the next best thing.
252+ try_resolve_for_chain ! ( graph_chain_ethereum:: Chain ) ;
253+ try_resolve_for_chain ! ( graph_chain_arweave:: Chain ) ;
254+ try_resolve_for_chain ! ( graph_chain_cosmos:: Chain ) ;
255+ try_resolve_for_chain ! ( graph_chain_near:: Chain ) ;
256+
257+ // If you're adding support for a new chain and this `match` clause just
258+ // gave you a compiler error, then this message is for you! You need to
259+ // add a new `try_resolve!` macro invocation above for your new chain
260+ // type.
261+ match BlockchainKind :: Ethereum {
262+ // Note: we don't actually care about substreams here.
263+ BlockchainKind :: Substreams
264+ | BlockchainKind :: Arweave
265+ | BlockchainKind :: Ethereum
266+ | BlockchainKind :: Cosmos
267+ | BlockchainKind :: Near => ( ) ,
268+ }
269+
270+ // The given network does not exist.
271+ Ok ( r:: Value :: Null )
272+ }
273+
205274 async fn resolve_cached_ethereum_calls (
206275 & self ,
207276 field : & a:: Field ,
@@ -734,7 +803,7 @@ impl<S: Store> Resolver for IndexNodeResolver<S> {
734803 }
735804
736805 /// Resolves a scalar value for a given scalar type.
737- fn resolve_scalar_value (
806+ async fn resolve_scalar_value (
738807 & self ,
739808 parent_object_type : & s:: ObjectType ,
740809 field : & a:: Field ,
@@ -748,6 +817,9 @@ impl<S: Store> Resolver for IndexNodeResolver<S> {
748817 ) {
749818 ( "Query" , "proofOfIndexing" , "Bytes" ) => self . resolve_proof_of_indexing ( field) ,
750819 ( "Query" , "blockData" , "JSONObject" ) => self . resolve_block_data ( field) ,
820+ ( "Query" , "blockHashFromNumber" , "Bytes" ) => {
821+ self . resolve_block_hash_from_number ( field) . await
822+ }
751823
752824 // Fallback to the same as is in the default trait implementation. There
753825 // is no way to call back into the default implementation for the trait.
0 commit comments