Skip to content

Commit 8a570e3

Browse files
committed
all: Split store functions for chain id mgmt out of ChainStore
1 parent 52e1ce2 commit 8a570e3

File tree

12 files changed

+139
-67
lines changed

12 files changed

+139
-67
lines changed

graph/src/blockchain/mock.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use crate::{
22
bail,
33
components::{
44
link_resolver::LinkResolver,
5+
network_provider::ChainName,
56
store::{
6-
BlockNumber, ChainHeadStore, DeploymentCursorTracker, DeploymentLocator,
7+
BlockNumber, ChainHeadStore, ChainIdStore, DeploymentCursorTracker, DeploymentLocator,
78
SourceableStore,
89
},
910
subgraph::InstanceDSTemplateInfo,
@@ -569,10 +570,20 @@ impl ChainStore for MockChainStore {
569570
fn chain_identifier(&self) -> Result<ChainIdentifier, Error> {
570571
unimplemented!()
571572
}
572-
fn set_chain_identifier(&self, _ident: &ChainIdentifier) -> Result<(), Error> {
573-
unimplemented!()
574-
}
575573
fn as_head_store(self: Arc<Self>) -> Arc<dyn ChainHeadStore> {
576574
self.clone()
577575
}
578576
}
577+
578+
impl ChainIdStore for MockChainStore {
579+
fn chain_identifier(&self, _name: &ChainName) -> Result<ChainIdentifier, Error> {
580+
unimplemented!()
581+
}
582+
fn set_chain_identifier(
583+
&self,
584+
_name: &ChainName,
585+
_ident: &ChainIdentifier,
586+
) -> Result<(), Error> {
587+
unimplemented!()
588+
}
589+
}

graph/src/components/network_provider/chain_identifier_validator.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use anyhow::anyhow;
1+
use std::sync::Arc;
2+
23
use thiserror::Error;
34

45
use crate::blockchain::BlockHash;
56
use crate::blockchain::ChainIdentifier;
67
use crate::components::network_provider::ChainName;
7-
use crate::components::store::BlockStore;
8-
use crate::components::store::ChainStore;
8+
use crate::components::store::ChainIdStore;
99

1010
/// Additional requirements for stores that are necessary for provider checks.
1111
pub trait ChainIdentifierValidator: Send + Sync + 'static {
@@ -51,24 +51,29 @@ pub enum ChainIdentifierValidationError {
5151
Store(#[source] anyhow::Error),
5252
}
5353

54-
impl<C, B> ChainIdentifierValidator for B
55-
where
56-
C: ChainStore,
57-
B: BlockStore<ChainStore = C>,
58-
{
54+
pub fn chain_id_validator(store: Arc<dyn ChainIdStore>) -> Arc<dyn ChainIdentifierValidator> {
55+
Arc::new(ChainIdentifierStore::new(store))
56+
}
57+
58+
pub(crate) struct ChainIdentifierStore {
59+
store: Arc<dyn ChainIdStore>,
60+
}
61+
62+
impl ChainIdentifierStore {
63+
pub fn new(store: Arc<dyn ChainIdStore>) -> Self {
64+
Self { store }
65+
}
66+
}
67+
68+
impl ChainIdentifierValidator for ChainIdentifierStore {
5969
fn validate_identifier(
6070
&self,
6171
chain_name: &ChainName,
6272
chain_identifier: &ChainIdentifier,
6373
) -> Result<(), ChainIdentifierValidationError> {
64-
let chain_store = self.chain_store(&chain_name).ok_or_else(|| {
65-
ChainIdentifierValidationError::Store(anyhow!(
66-
"unable to get store for chain '{chain_name}'"
67-
))
68-
})?;
69-
70-
let store_identifier = chain_store
71-
.chain_identifier()
74+
let store_identifier = self
75+
.store
76+
.chain_identifier(chain_name)
7277
.map_err(|err| ChainIdentifierValidationError::Store(err))?;
7378

7479
if store_identifier.is_default() {
@@ -108,14 +113,8 @@ where
108113
chain_name: &ChainName,
109114
chain_identifier: &ChainIdentifier,
110115
) -> Result<(), ChainIdentifierValidationError> {
111-
let chain_store = self.chain_store(&chain_name).ok_or_else(|| {
112-
ChainIdentifierValidationError::Store(anyhow!(
113-
"unable to get store for chain '{chain_name}'"
114-
))
115-
})?;
116-
117-
chain_store
118-
.set_chain_identifier(chain_identifier)
116+
self.store
117+
.set_chain_identifier(chain_name, chain_identifier)
119118
.map_err(|err| ChainIdentifierValidationError::Store(err))
120119
}
121120
}

graph/src/components/network_provider/genesis_hash_check.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ use slog::error;
66
use slog::warn;
77
use slog::Logger;
88

9+
use crate::components::network_provider::chain_id_validator;
910
use crate::components::network_provider::ChainIdentifierValidationError;
1011
use crate::components::network_provider::ChainIdentifierValidator;
1112
use crate::components::network_provider::ChainName;
1213
use crate::components::network_provider::NetworkDetails;
1314
use crate::components::network_provider::ProviderCheck;
1415
use crate::components::network_provider::ProviderCheckStatus;
1516
use crate::components::network_provider::ProviderName;
17+
use crate::components::store::ChainIdStore;
1618

1719
/// Requires providers to have the same network version and genesis hash as one
1820
/// previously stored in the database.
@@ -26,6 +28,12 @@ impl GenesisHashCheck {
2628
chain_identifier_store,
2729
}
2830
}
31+
32+
pub fn from_id_store(id_store: Arc<dyn ChainIdStore>) -> Self {
33+
Self {
34+
chain_identifier_store: chain_id_validator(id_store),
35+
}
36+
}
2937
}
3038

3139
#[async_trait]

graph/src/components/network_provider/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod network_details;
55
mod provider_check;
66
mod provider_manager;
77

8+
pub use self::chain_identifier_validator::chain_id_validator;
89
pub use self::chain_identifier_validator::ChainIdentifierValidationError;
910
pub use self::chain_identifier_validator::ChainIdentifierValidator;
1011
pub use self::extended_blocks_check::ExtendedBlocksCheck;

graph/src/components/store/traits.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use super::*;
99
use crate::blockchain::block_stream::{EntitySourceOperation, FirehoseCursor};
1010
use crate::blockchain::{BlockTime, ChainIdentifier, ExtendedBlockPtr};
1111
use crate::components::metrics::stopwatch::StopwatchMetrics;
12+
use crate::components::network_provider::ChainName;
1213
use crate::components::server::index_node::VersionInfo;
1314
use crate::components::subgraph::SubgraphVersionSwitchingMode;
1415
use crate::components::transaction_receipt;
@@ -443,7 +444,7 @@ pub trait QueryStoreManager: Send + Sync + 'static {
443444
) -> Result<Arc<dyn QueryStore + Send + Sync>, QueryExecutionError>;
444445
}
445446

446-
pub trait BlockStore: Send + Sync + 'static {
447+
pub trait BlockStore: ChainIdStore + Send + Sync + 'static {
447448
type ChainStore: ChainStore;
448449

449450
fn create_chain_store(
@@ -481,6 +482,19 @@ pub trait ChainHeadStore: Send + Sync {
481482
) -> Result<(), Error>;
482483
}
483484

485+
#[async_trait]
486+
pub trait ChainIdStore: Send + Sync + 'static {
487+
/// Return the chain identifier for this store.
488+
fn chain_identifier(&self, chain_name: &ChainName) -> Result<ChainIdentifier, Error>;
489+
490+
/// Update the chain identifier for this store.
491+
fn set_chain_identifier(
492+
&self,
493+
chain_name: &ChainName,
494+
ident: &ChainIdentifier,
495+
) -> Result<(), Error>;
496+
}
497+
484498
/// Common trait for blockchain store implementations.
485499
#[async_trait]
486500
pub trait ChainStore: ChainHeadStore {
@@ -590,9 +604,6 @@ pub trait ChainStore: ChainHeadStore {
590604
/// Return the chain identifier for this store.
591605
fn chain_identifier(&self) -> Result<ChainIdentifier, Error>;
592606

593-
/// Update the chain identifier for this store.
594-
fn set_chain_identifier(&self, ident: &ChainIdentifier) -> Result<(), Error>;
595-
596607
/// Workaround for Rust issue #65991 that keeps us from using an
597608
/// `Arc<dyn ChainStore>` as an `Arc<dyn ChainHeadStore>`
598609
fn as_head_store(self: Arc<Self>) -> Arc<dyn ChainHeadStore>;

node/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ async fn main_inner() {
290290
let mut provider_checks: Vec<Arc<dyn network_provider::ProviderCheck>> = Vec::new();
291291

292292
if env_vars.genesis_validation_enabled {
293-
provider_checks.push(Arc::new(network_provider::GenesisHashCheck::new(
293+
provider_checks.push(Arc::new(network_provider::GenesisHashCheck::from_id_store(
294294
block_store.clone(),
295295
)));
296296
}

node/src/manager/commands/chain.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use graph::blockchain::BlockHash;
77
use graph::blockchain::BlockPtr;
88
use graph::blockchain::ChainIdentifier;
99
use graph::cheap_clone::CheapClone;
10-
use graph::components::network_provider::ChainIdentifierValidator;
1110
use graph::components::network_provider::ChainName;
11+
use graph::components::store::ChainIdStore;
1212
use graph::components::store::StoreError;
1313
use graph::prelude::BlockNumber;
1414
use graph::prelude::ChainStore as _;
@@ -164,7 +164,7 @@ pub fn remove(primary: ConnectionPool, store: Arc<BlockStore>, name: String) ->
164164
pub async fn update_chain_genesis(
165165
networks: &Networks,
166166
coord: Arc<PoolCoordinator>,
167-
store: Arc<BlockStore>,
167+
store: Arc<dyn ChainIdStore>,
168168
logger: &Logger,
169169
chain_id: ChainName,
170170
genesis_hash: BlockHash,
@@ -188,18 +188,14 @@ pub async fn update_chain_genesis(
188188
// Update the local shard's genesis, whether or not it is the primary.
189189
// The chains table is replicated from the primary and keeps another genesis hash.
190190
// To keep those in sync we need to update the primary and then refresh the shard tables.
191-
store.update_identifier(
191+
store.set_chain_identifier(
192192
&chain_id,
193193
&ChainIdentifier {
194194
net_version: ident.net_version.clone(),
195195
genesis_block_hash: genesis_hash,
196196
},
197197
)?;
198198

199-
// Update the primary public.chains
200-
println!("Updating primary public.chains");
201-
store.set_chain_identifier(chain_id, &ident)?;
202-
203199
// Refresh the new values
204200
println!("Refresh mappings");
205201
crate::manager::commands::database::remap(&coord, None, None, false).await?;

node/src/manager/commands/provider_checks.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::Arc;
22
use std::time::Duration;
33

4+
use graph::components::network_provider::chain_id_validator;
45
use graph::components::network_provider::ChainIdentifierValidator;
56
use graph::components::network_provider::ChainName;
67
use graph::components::network_provider::ExtendedBlocksCheck;
@@ -36,9 +37,10 @@ pub async fn execute(
3637
.providers_unchecked(chain_name)
3738
.unique_by(|x| x.provider_name())
3839
{
40+
let validator = chain_id_validator(store.clone());
3941
match tokio::time::timeout(
4042
timeout,
41-
run_checks(logger, chain_name, adapter, store.clone()),
43+
run_checks(logger, chain_name, adapter, validator.clone()),
4244
)
4345
.await
4446
{
@@ -56,11 +58,9 @@ pub async fn execute(
5658
.providers_unchecked(chain_name)
5759
.unique_by(|x| x.provider_name())
5860
{
59-
match tokio::time::timeout(
60-
timeout,
61-
run_checks(logger, chain_name, adapter, store.clone()),
62-
)
63-
.await
61+
let validator = chain_id_validator(store.clone());
62+
match tokio::time::timeout(timeout, run_checks(logger, chain_name, adapter, validator))
63+
.await
6464
{
6565
Ok(result) => {
6666
errors.extend(result);
@@ -76,9 +76,10 @@ pub async fn execute(
7676
.providers_unchecked(chain_name)
7777
.unique_by(|x| x.provider_name())
7878
{
79+
let validator = chain_id_validator(store.clone());
7980
match tokio::time::timeout(
8081
timeout,
81-
run_checks(logger, chain_name, adapter, store.clone()),
82+
run_checks(logger, chain_name, adapter, validator.clone()),
8283
)
8384
.await
8485
{

node/src/manager/commands/run.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::MetricsContext;
1010
use graph::anyhow::bail;
1111
use graph::cheap_clone::CheapClone;
1212
use graph::components::link_resolver::{ArweaveClient, FileSizeLimit};
13-
use graph::components::network_provider::ChainIdentifierValidator;
13+
use graph::components::network_provider::chain_id_validator;
1414
use graph::components::store::DeploymentLocator;
1515
use graph::components::subgraph::Settings;
1616
use graph::endpoint::EndpointMetrics;
@@ -98,8 +98,7 @@ pub async fn run(
9898
Vec::new();
9999

100100
if env_vars.genesis_validation_enabled {
101-
let store: Arc<dyn ChainIdentifierValidator> = network_store.block_store();
102-
101+
let store = chain_id_validator(network_store.block_store());
103102
provider_checks.push(Arc::new(
104103
graph::components::network_provider::GenesisHashCheck::new(store),
105104
));

store/postgres/src/block_store.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ use diesel::{
1010
r2d2::{ConnectionManager, PooledConnection},
1111
sql_query, ExpressionMethods as _, PgConnection, RunQueryDsl,
1212
};
13-
use graph::components::network_provider::ChainName;
1413
use graph::{
1514
blockchain::ChainIdentifier,
1615
components::store::{BlockStore as BlockStoreTrait, QueryPermit},
1716
prelude::{error, info, BlockNumber, BlockPtr, Logger, ENV_VARS},
1817
slog::o,
1918
};
19+
use graph::{
20+
components::{network_provider::ChainName, store::ChainIdStore},
21+
prelude::ChainStore as _,
22+
};
2023
use graph::{internal_error, prelude::CheapClone};
2124
use graph::{prelude::StoreError, util::timed_cache::TimedCache};
2225

@@ -605,3 +608,41 @@ impl BlockStoreTrait for BlockStore {
605608
.map_err(anyhow::Error::from)
606609
}
607610
}
611+
612+
impl ChainIdStore for BlockStore {
613+
fn chain_identifier(&self, chain_name: &ChainName) -> Result<ChainIdentifier, anyhow::Error> {
614+
let chain_store = self
615+
.chain_store(&chain_name)
616+
.ok_or_else(|| anyhow!("unable to get store for chain '{chain_name}'"))?;
617+
618+
chain_store.chain_identifier()
619+
}
620+
621+
fn set_chain_identifier(
622+
&self,
623+
chain_name: &ChainName,
624+
ident: &ChainIdentifier,
625+
) -> Result<(), anyhow::Error> {
626+
use primary::chains as c;
627+
628+
// Update the block shard first since that contains a copy from the primary
629+
let chain_store = self
630+
.chain_store(&chain_name)
631+
.ok_or_else(|| anyhow!("unable to get store for chain '{chain_name}'"))?;
632+
633+
chain_store.set_chain_identifier(ident)?;
634+
635+
// Update the master copy in the primary
636+
let primary_pool = self.pools.get(&*PRIMARY_SHARD).unwrap();
637+
let mut conn = primary_pool.get()?;
638+
639+
diesel::update(c::table.filter(c::name.eq(chain_name.as_str())))
640+
.set((
641+
c::genesis_block_hash.eq(ident.genesis_block_hash.hash_hex()),
642+
c::net_version.eq(&ident.net_version),
643+
))
644+
.execute(&mut conn)?;
645+
646+
Ok(())
647+
}
648+
}

0 commit comments

Comments
 (0)