@@ -14,7 +14,7 @@ use graph::slog::{debug, error, info, o, Logger};
1414use graph:: url:: Url ;
1515use graph:: util:: security:: SafeDisplay ;
1616use graph_chain_ethereum:: { self as ethereum, EthereumAdapterTrait , Transport } ;
17- use std:: collections:: { BTreeMap , HashMap } ;
17+ use std:: collections:: { btree_map , BTreeMap } ;
1818use std:: sync:: Arc ;
1919use std:: time:: Duration ;
2020
@@ -220,7 +220,7 @@ pub fn create_firehose_networks(
220220pub async fn connect_ethereum_networks (
221221 logger : & Logger ,
222222 mut eth_networks : EthereumNetworks ,
223- ) -> ( EthereumNetworks , Vec < ( String , Vec < ChainIdentifier > ) > ) {
223+ ) -> Result < ( EthereumNetworks , BTreeMap < String , ChainIdentifier > ) , anyhow :: Error > {
224224 // This has one entry for each provider, and therefore multiple entries
225225 // for each network
226226 let statuses = join_all (
@@ -268,10 +268,10 @@ pub async fn connect_ethereum_networks(
268268 . await ;
269269
270270 // Group identifiers by network name
271- let idents: HashMap < String , Vec < ChainIdentifier > > =
271+ let idents: BTreeMap < String , ChainIdentifier > =
272272 statuses
273273 . into_iter ( )
274- . fold ( HashMap :: new ( ) , |mut networks, status| {
274+ . try_fold ( BTreeMap :: new ( ) , |mut networks, status| {
275275 match status {
276276 ProviderNetworkStatus :: Broken {
277277 chain_id : network,
@@ -280,12 +280,25 @@ pub async fn connect_ethereum_networks(
280280 ProviderNetworkStatus :: Version {
281281 chain_id : network,
282282 ident,
283- } => networks. entry ( network) . or_default ( ) . push ( ident) ,
283+ } => match networks. entry ( network. clone ( ) ) {
284+ btree_map:: Entry :: Vacant ( entry) => {
285+ entry. insert ( ident) ;
286+ }
287+ btree_map:: Entry :: Occupied ( entry) => {
288+ if & ident != entry. get ( ) {
289+ return Err ( anyhow ! (
290+ "conflicting network identifiers for chain {}: `{}` != `{}`" ,
291+ network,
292+ ident,
293+ entry. get( )
294+ ) ) ;
295+ }
296+ }
297+ } ,
284298 }
285- networks
286- } ) ;
287- let idents: Vec < _ > = idents. into_iter ( ) . collect ( ) ;
288- ( eth_networks, idents)
299+ Ok ( networks)
300+ } ) ?;
301+ Ok ( ( eth_networks, idents) )
289302}
290303
291304/// Try to connect to all the providers in `firehose_networks` and get their net
@@ -299,7 +312,7 @@ pub async fn connect_ethereum_networks(
299312pub async fn connect_firehose_networks < M > (
300313 logger : & Logger ,
301314 mut firehose_networks : FirehoseNetworks ,
302- ) -> ( FirehoseNetworks , Vec < ( String , Vec < ChainIdentifier > ) > )
315+ ) -> Result < ( FirehoseNetworks , BTreeMap < String , ChainIdentifier > ) , Error >
303316where
304317 M : prost:: Message + BlockchainBlock + Default + ' static ,
305318{
@@ -341,6 +354,8 @@ where
341354 "genesis_block" => format_args!( "{}" , & ptr) ,
342355 ) ;
343356
357+ // BUG: Firehose doesn't provide the net_version.
358+ // See also: firehose-no-net-version
344359 let ident = ChainIdentifier {
345360 net_version : "0" . to_string ( ) ,
346361 genesis_block_hash : ptr. hash ,
@@ -354,20 +369,34 @@ where
354369 . await ;
355370
356371 // Group identifiers by chain id
357- let idents: HashMap < String , Vec < ChainIdentifier > > =
372+ let idents: BTreeMap < String , ChainIdentifier > =
358373 statuses
359374 . into_iter ( )
360- . fold ( HashMap :: new ( ) , |mut networks, status| {
375+ . try_fold ( BTreeMap :: new ( ) , |mut networks, status| {
361376 match status {
362377 ProviderNetworkStatus :: Broken { chain_id, provider } => {
363378 firehose_networks. remove ( & chain_id, & provider)
364379 }
365380 ProviderNetworkStatus :: Version { chain_id, ident } => {
366- networks. entry ( chain_id) . or_default ( ) . push ( ident)
381+ match networks. entry ( chain_id. clone ( ) ) {
382+ btree_map:: Entry :: Vacant ( entry) => {
383+ entry. insert ( ident) ;
384+ }
385+ btree_map:: Entry :: Occupied ( entry) => {
386+ if & ident != entry. get ( ) {
387+ return Err ( anyhow ! (
388+ "conflicting network identifiers for chain {}: `{}` != `{}`" ,
389+ chain_id,
390+ ident,
391+ entry. get( )
392+ ) ) ;
393+ }
394+ }
395+ }
367396 }
368397 }
369- networks
370- } ) ;
398+ Ok ( networks)
399+ } ) ? ;
371400
372401 // Clean-up chains with 0 provider
373402 firehose_networks. networks . retain ( |chain_id, endpoints| {
@@ -381,8 +410,7 @@ where
381410 endpoints. len ( ) > 0
382411 } ) ;
383412
384- let idents: Vec < _ > = idents. into_iter ( ) . collect ( ) ;
385- ( firehose_networks, idents)
413+ Ok ( ( firehose_networks, idents) )
386414}
387415
388416/// Parses all Ethereum connection strings and returns their network names and
0 commit comments