Skip to content

Commit 54d4974

Browse files
authored
node, graph, chains: BlockchainBuilder to simplify instantiating chains (#4408)
* node, graph, chains: BuildableBlockchain abstraction * chains: replace Chain::new with Chain::build * chains, node, graph: BlockchainBuilder pattern
1 parent 3431f2c commit 54d4974

File tree

6 files changed

+85
-163
lines changed

6 files changed

+85
-163
lines changed

chain/arweave/src/chain.rs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use graph::blockchain::client::ChainClient;
2-
use graph::blockchain::{Block, BlockchainKind, EmptyNodeCapabilities};
2+
use graph::blockchain::{
3+
BasicBlockchainBuilder, Block, BlockchainBuilder, BlockchainKind, EmptyNodeCapabilities,
4+
};
35
use graph::cheap_clone::CheapClone;
46
use graph::data::subgraph::UnifiedMappingApiVersion;
5-
use graph::firehose::{FirehoseEndpoint, FirehoseEndpoints};
7+
use graph::firehose::FirehoseEndpoint;
68
use graph::prelude::MetricsRegistry;
79
use graph::{
810
blockchain::{
@@ -44,20 +46,14 @@ impl std::fmt::Debug for Chain {
4446
}
4547
}
4648

47-
impl Chain {
48-
pub fn new(
49-
logger_factory: LoggerFactory,
50-
name: String,
51-
chain_store: Arc<dyn ChainStore>,
52-
firehose_endpoints: FirehoseEndpoints,
53-
metrics_registry: Arc<dyn MetricsRegistry>,
54-
) -> Self {
49+
impl BlockchainBuilder<Chain> for BasicBlockchainBuilder {
50+
fn build(self) -> Chain {
5551
Chain {
56-
logger_factory,
57-
name,
58-
client: Arc::new(ChainClient::<Self>::new_firehose(firehose_endpoints)),
59-
chain_store,
60-
metrics_registry,
52+
logger_factory: self.logger_factory,
53+
name: self.name,
54+
client: Arc::new(ChainClient::<Chain>::new_firehose(self.firehose_endpoints)),
55+
chain_store: self.chain_store,
56+
metrics_registry: self.metrics_registry,
6157
}
6258
}
6359
}

chain/cosmos/src/chain.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::sync::Arc;
22

33
use graph::blockchain::block_stream::FirehoseCursor;
44
use graph::blockchain::client::ChainClient;
5+
use graph::blockchain::{BasicBlockchainBuilder, BlockchainBuilder};
56
use graph::cheap_clone::CheapClone;
67
use graph::data::subgraph::UnifiedMappingApiVersion;
78
use graph::prelude::MetricsRegistry;
@@ -16,7 +17,7 @@ use graph::{
1617
IngestorError, RuntimeAdapter as RuntimeAdapterTrait,
1718
},
1819
components::store::DeploymentLocator,
19-
firehose::{self, FirehoseEndpoint, FirehoseEndpoints, ForkStep},
20+
firehose::{self, FirehoseEndpoint, ForkStep},
2021
prelude::{async_trait, o, BlockNumber, ChainStore, Error, Logger, LoggerFactory},
2122
};
2223
use prost::Message;
@@ -42,20 +43,14 @@ impl std::fmt::Debug for Chain {
4243
}
4344
}
4445

45-
impl Chain {
46-
pub fn new(
47-
logger_factory: LoggerFactory,
48-
name: String,
49-
chain_store: Arc<dyn ChainStore>,
50-
firehose_endpoints: FirehoseEndpoints,
51-
metrics_registry: Arc<dyn MetricsRegistry>,
52-
) -> Self {
46+
impl BlockchainBuilder<Chain> for BasicBlockchainBuilder {
47+
fn build(self) -> Chain {
5348
Chain {
54-
logger_factory,
55-
name,
56-
client: Arc::new(ChainClient::new_firehose(firehose_endpoints)),
57-
chain_store,
58-
metrics_registry,
49+
logger_factory: self.logger_factory,
50+
name: self.name,
51+
client: Arc::new(ChainClient::new_firehose(self.firehose_endpoints)),
52+
chain_store: self.chain_store,
53+
metrics_registry: self.metrics_registry,
5954
}
6055
}
6156
}

chain/near/src/chain.rs

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use graph::blockchain::client::ChainClient;
2-
use graph::blockchain::BlockchainKind;
2+
use graph::blockchain::{BasicBlockchainBuilder, BlockchainBuilder, BlockchainKind};
33
use graph::cheap_clone::CheapClone;
44
use graph::data::subgraph::UnifiedMappingApiVersion;
5-
use graph::firehose::{FirehoseEndpoint, FirehoseEndpoints};
5+
use graph::firehose::FirehoseEndpoint;
66
use graph::prelude::{MetricsRegistry, TryFutureExt};
77
use graph::{
88
anyhow::Result,
@@ -105,22 +105,15 @@ impl std::fmt::Debug for Chain {
105105
}
106106
}
107107

108-
impl Chain {
109-
pub fn new(
110-
logger_factory: LoggerFactory,
111-
name: String,
112-
chain_store: Arc<dyn ChainStore>,
113-
firehose_endpoints: FirehoseEndpoints,
114-
metrics_registry: Arc<dyn MetricsRegistry>,
115-
block_stream_builder: Arc<dyn BlockStreamBuilder<Self>>,
116-
) -> Self {
108+
impl BlockchainBuilder<Chain> for BasicBlockchainBuilder {
109+
fn build(self) -> Chain {
117110
Chain {
118-
logger_factory,
119-
name,
120-
client: Arc::new(ChainClient::new_firehose(firehose_endpoints)),
121-
chain_store,
122-
metrics_registry,
123-
block_stream_builder,
111+
logger_factory: self.logger_factory,
112+
name: self.name,
113+
chain_store: self.chain_store,
114+
client: Arc::new(ChainClient::new_firehose(self.firehose_endpoints)),
115+
metrics_registry: self.metrics_registry,
116+
block_stream_builder: Arc::new(NearStreamBuilder {}),
124117
}
125118
}
126119
}

graph/src/blockchain/builder.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use super::Blockchain;
2+
use crate::{
3+
components::{metrics::MetricsRegistry, store::ChainStore},
4+
firehose::FirehoseEndpoints,
5+
prelude::LoggerFactory,
6+
};
7+
use std::sync::Arc;
8+
9+
/// An implementor of [`BlockchainBuilder`] for chains that don't require
10+
/// particularly fancy builder logic.
11+
pub struct BasicBlockchainBuilder {
12+
pub logger_factory: LoggerFactory,
13+
pub name: String,
14+
pub chain_store: Arc<dyn ChainStore>,
15+
pub firehose_endpoints: FirehoseEndpoints,
16+
pub metrics_registry: Arc<dyn MetricsRegistry>,
17+
}
18+
19+
/// Something that can build a [`Blockchain`].
20+
pub trait BlockchainBuilder<C>
21+
where
22+
C: Blockchain,
23+
{
24+
fn build(self) -> C;
25+
}

graph/src/blockchain/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! trait which is the centerpiece of this module.
44
55
pub mod block_stream;
6+
mod builder;
67
pub mod client;
78
mod empty_node_capabilities;
89
pub mod firehose_block_ingestor;
@@ -43,6 +44,7 @@ use std::{
4344
use web3::types::H256;
4445

4546
pub use block_stream::{ChainHeadUpdateListener, ChainHeadUpdateStream, TriggersAdapter};
47+
pub use builder::{BasicBlockchainBuilder, BlockchainBuilder};
4648
pub use empty_node_capabilities::EmptyNodeCapabilities;
4749
pub use types::{BlockHash, BlockPtr, ChainIdentifier};
4850

node/src/main.rs

Lines changed: 28 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use ethereum::{
77
use git_testament::{git_testament, render_testament};
88
use graph::blockchain::client::ChainClient;
99
use graph::blockchain::firehose_block_ingestor::{FirehoseBlockIngestor, Transforms};
10-
use graph::blockchain::{Block as BlockchainBlock, Blockchain, BlockchainKind, BlockchainMap};
10+
use graph::blockchain::{
11+
BasicBlockchainBuilder, Block as BlockchainBlock, Blockchain, BlockchainBuilder,
12+
BlockchainKind, BlockchainMap,
13+
};
1114
use graph::components::store::BlockStore;
1215
use graph::data::graphql::effort::LoadManager;
1316
use graph::env::EnvVars;
@@ -40,7 +43,6 @@ use graph_server_json_rpc::JsonRpcServer;
4043
use graph_server_metrics::PrometheusMetricsServer;
4144
use graph_server_websocket::SubscriptionServer as GraphQLSubscriptionServer;
4245
use graph_store_postgres::{register_jobs as register_store_jobs, ChainHeadUpdateListener, Store};
43-
use near::NearStreamBuilder;
4446
use std::collections::BTreeMap;
4547
use std::io::{BufRead, BufReader};
4648
use std::path::Path;
@@ -297,7 +299,7 @@ async fn main() {
297299

298300
let network_store = store_builder.network_store(network_identifiers);
299301

300-
let arweave_chains = arweave_networks_as_chains(
302+
let arweave_chains = networks_as_chains::<arweave::Chain>(
301303
&mut blockchain_map,
302304
&logger,
303305
&arweave_networks,
@@ -320,7 +322,7 @@ async fn main() {
320322
metrics_registry.clone(),
321323
);
322324

323-
let near_chains = near_networks_as_chains(
325+
let near_chains = networks_as_chains::<near::Chain>(
324326
&mut blockchain_map,
325327
&logger,
326328
&near_networks,
@@ -329,7 +331,7 @@ async fn main() {
329331
metrics_registry.clone(),
330332
);
331333

332-
let cosmos_chains = cosmos_networks_as_chains(
334+
let cosmos_chains = networks_as_chains::<cosmos::Chain>(
333335
&mut blockchain_map,
334336
&logger,
335337
&cosmos_networks,
@@ -613,15 +615,19 @@ async fn main() {
613615
futures::future::pending::<()>().await;
614616
}
615617

616-
/// Return the hashmap of Arweave chains and also add them to `blockchain_map`.
617-
fn arweave_networks_as_chains(
618+
/// Return the hashmap of chains and also add them to `blockchain_map`.
619+
fn networks_as_chains<C>(
618620
blockchain_map: &mut BlockchainMap,
619621
logger: &Logger,
620622
firehose_networks: &FirehoseNetworks,
621623
store: &Store,
622624
logger_factory: &LoggerFactory,
623625
metrics_registry: Arc<MetricsRegistry>,
624-
) -> HashMap<String, FirehoseChain<arweave::Chain>> {
626+
) -> HashMap<String, FirehoseChain<C>>
627+
where
628+
C: Blockchain,
629+
BasicBlockchainBuilder: BlockchainBuilder<C>,
630+
{
625631
let chains: Vec<_> = firehose_networks
626632
.networks
627633
.iter()
@@ -633,7 +639,9 @@ fn arweave_networks_as_chains(
633639
.or_else(|| {
634640
error!(
635641
logger,
636-
"No store configured for Arweave chain {}; ignoring this chain", chain_id
642+
"No store configured for {} chain {}; ignoring this chain",
643+
C::KIND,
644+
chain_id
637645
);
638646
None
639647
})
@@ -642,21 +650,24 @@ fn arweave_networks_as_chains(
642650
(
643651
chain_id.clone(),
644652
FirehoseChain {
645-
chain: Arc::new(arweave::Chain::new(
646-
logger_factory.clone(),
647-
chain_id.clone(),
648-
chain_store,
649-
endpoints.clone(),
650-
metrics_registry.clone(),
651-
)),
653+
chain: Arc::new(
654+
BasicBlockchainBuilder {
655+
logger_factory: logger_factory.clone(),
656+
name: chain_id.clone(),
657+
chain_store,
658+
firehose_endpoints: endpoints.clone(),
659+
metrics_registry: metrics_registry.clone(),
660+
}
661+
.build(),
662+
),
652663
firehose_endpoints: endpoints.clone(),
653664
},
654665
)
655666
})
656667
.collect();
657668

658669
for (chain_id, firehose_chain) in chains.iter() {
659-
blockchain_map.insert::<arweave::Chain>(chain_id.clone(), firehose_chain.chain.clone())
670+
blockchain_map.insert::<C>(chain_id.clone(), firehose_chain.chain.clone())
660671
}
661672

662673
HashMap::from_iter(chains)
@@ -764,106 +775,6 @@ fn ethereum_networks_as_chains(
764775
HashMap::from_iter(chains)
765776
}
766777

767-
fn cosmos_networks_as_chains(
768-
blockchain_map: &mut BlockchainMap,
769-
logger: &Logger,
770-
firehose_networks: &FirehoseNetworks,
771-
store: &Store,
772-
logger_factory: &LoggerFactory,
773-
metrics_registry: Arc<MetricsRegistry>,
774-
) -> HashMap<String, FirehoseChain<cosmos::Chain>> {
775-
let chains: Vec<_> = firehose_networks
776-
.networks
777-
.iter()
778-
.filter_map(|(network_name, firehose_endpoints)| {
779-
store
780-
.block_store()
781-
.chain_store(network_name)
782-
.map(|chain_store| (network_name, chain_store, firehose_endpoints))
783-
.or_else(|| {
784-
error!(
785-
logger,
786-
"No store configured for Cosmos chain {}; ignoring this chain",
787-
network_name
788-
);
789-
None
790-
})
791-
})
792-
.map(|(network_name, chain_store, firehose_endpoints)| {
793-
(
794-
network_name.clone(),
795-
FirehoseChain {
796-
chain: Arc::new(cosmos::Chain::new(
797-
logger_factory.clone(),
798-
network_name.clone(),
799-
chain_store,
800-
firehose_endpoints.clone(),
801-
metrics_registry.clone(),
802-
)),
803-
firehose_endpoints: firehose_endpoints.clone(),
804-
},
805-
)
806-
})
807-
.collect();
808-
809-
for (network_name, firehose_chain) in chains.iter() {
810-
blockchain_map.insert::<cosmos::Chain>(network_name.clone(), firehose_chain.chain.clone())
811-
}
812-
813-
HashMap::from_iter(chains)
814-
}
815-
816-
/// Return the hashmap of NEAR chains and also add them to `blockchain_map`.
817-
fn near_networks_as_chains(
818-
blockchain_map: &mut BlockchainMap,
819-
logger: &Logger,
820-
firehose_networks: &FirehoseNetworks,
821-
store: &Store,
822-
logger_factory: &LoggerFactory,
823-
metrics_registry: Arc<MetricsRegistry>,
824-
) -> HashMap<String, FirehoseChain<near::Chain>> {
825-
let chains: Vec<_> = firehose_networks
826-
.networks
827-
.iter()
828-
.filter_map(|(chain_id, endpoints)| {
829-
store
830-
.block_store()
831-
.chain_store(chain_id)
832-
.map(|chain_store| (chain_id, chain_store, endpoints))
833-
.or_else(|| {
834-
error!(
835-
logger,
836-
"No store configured for NEAR chain {}; ignoring this chain", chain_id
837-
);
838-
None
839-
})
840-
})
841-
.map(|(chain_id, chain_store, endpoints)| {
842-
(
843-
chain_id.clone(),
844-
FirehoseChain {
845-
chain: Arc::new(near::Chain::new(
846-
logger_factory.clone(),
847-
chain_id.clone(),
848-
chain_store,
849-
endpoints.clone(),
850-
metrics_registry.clone(),
851-
Arc::new(NearStreamBuilder {}),
852-
)),
853-
firehose_endpoints: endpoints.clone(),
854-
},
855-
)
856-
})
857-
.collect();
858-
859-
for (chain_id, firehose_chain) in chains.iter() {
860-
blockchain_map
861-
.insert::<graph_chain_near::Chain>(chain_id.clone(), firehose_chain.chain.clone())
862-
}
863-
864-
HashMap::from_iter(chains)
865-
}
866-
867778
fn start_block_ingestor(
868779
logger: &Logger,
869780
logger_factory: &LoggerFactory,

0 commit comments

Comments
 (0)