Skip to content

Subgraph composition : TriggersAdapter wrapper #5695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions chain/arweave/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use graph::blockchain::client::ChainClient;
use graph::blockchain::firehose_block_ingestor::FirehoseBlockIngestor;
use graph::blockchain::{
BasicBlockchainBuilder, Block, BlockIngestor, BlockchainBuilder, BlockchainKind,
EmptyNodeCapabilities, NoopDecoderHook, NoopRuntimeAdapter,
EmptyNodeCapabilities, NoopDecoderHook, NoopRuntimeAdapter, TriggerFilterWrapper,
};
use graph::cheap_clone::CheapClone;
use graph::components::network_provider::ChainName;
use graph::components::store::DeploymentCursorTracker;
use graph::components::store::{DeploymentCursorTracker, ReadStore};
use graph::data::subgraph::UnifiedMappingApiVersion;
use graph::env::EnvVars;
use graph::firehose::FirehoseEndpoint;
use graph::prelude::MetricsRegistry;
use graph::prelude::{DeploymentHash, MetricsRegistry};
use graph::substreams::Clock;
use graph::{
blockchain::{
Expand All @@ -27,11 +27,13 @@ use graph::{
prelude::{async_trait, o, BlockNumber, ChainStore, Error, Logger, LoggerFactory},
};
use prost::Message;
use std::collections::HashSet;
use std::sync::Arc;

use crate::adapter::TriggerFilter;
use crate::data_source::{DataSourceTemplate, UnresolvedDataSourceTemplate};
use crate::trigger::{self, ArweaveTrigger};
use crate::Block as ArweaveBlock;
use crate::{
codec,
data_source::{DataSource, UnresolvedDataSource},
Expand Down Expand Up @@ -119,7 +121,8 @@ impl Blockchain for Chain {
deployment: DeploymentLocator,
store: impl DeploymentCursorTracker,
start_blocks: Vec<BlockNumber>,
filter: Arc<Self::TriggerFilter>,
_source_subgraph_stores: Vec<(DeploymentHash, Arc<dyn ReadStore>)>,
filter: Arc<TriggerFilterWrapper<Self>>,
unified_api_version: UnifiedMappingApiVersion,
) -> Result<Box<dyn BlockStream<Self>>, Error> {
let adapter = self
Expand All @@ -135,7 +138,10 @@ impl Blockchain for Chain {
.subgraph_logger(&deployment)
.new(o!("component" => "FirehoseBlockStream"));

let firehose_mapper = Arc::new(FirehoseMapper { adapter, filter });
let firehose_mapper = Arc::new(FirehoseMapper {
adapter,
filter: filter.chain_filter.clone(),
});

Ok(Box::new(FirehoseBlockStream::new(
deployment.hash,
Expand Down Expand Up @@ -199,6 +205,10 @@ impl TriggersAdapterTrait<Chain> for TriggersAdapter {
panic!("Should never be called since not used by FirehoseBlockStream")
}

async fn chain_head_ptr(&self) -> Result<Option<BlockPtr>, Error> {
unimplemented!()
}

async fn triggers_in_block(
&self,
logger: &Logger,
Expand Down Expand Up @@ -258,6 +268,14 @@ impl TriggersAdapterTrait<Chain> for TriggersAdapter {
number: block.number.saturating_sub(1),
}))
}

async fn load_blocks_by_numbers(
&self,
_logger: Logger,
_block_numbers: HashSet<BlockNumber>,
) -> Result<Vec<ArweaveBlock>, Error> {
todo!()
}
}

pub struct FirehoseMapper {
Expand Down
43 changes: 33 additions & 10 deletions chain/cosmos/src/chain.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use graph::blockchain::firehose_block_ingestor::FirehoseBlockIngestor;
use graph::blockchain::{BlockIngestor, NoopDecoderHook};
use graph::blockchain::{BlockIngestor, NoopDecoderHook, TriggerFilterWrapper};
use graph::components::network_provider::ChainName;
use graph::env::EnvVars;
use graph::prelude::MetricsRegistry;
use graph::prelude::{DeploymentHash, MetricsRegistry};
use graph::substreams::Clock;
use std::collections::HashSet;
use std::convert::TryFrom;
use std::sync::Arc;

use graph::blockchain::block_stream::{BlockStreamError, BlockStreamMapper, FirehoseCursor};
use graph::blockchain::client::ChainClient;
use graph::blockchain::{BasicBlockchainBuilder, BlockchainBuilder, NoopRuntimeAdapter};
use graph::cheap_clone::CheapClone;
use graph::components::store::DeploymentCursorTracker;
use graph::components::store::{DeploymentCursorTracker, ReadStore};
use graph::data::subgraph::UnifiedMappingApiVersion;
use graph::{
blockchain::{
Expand All @@ -33,7 +34,7 @@ use crate::data_source::{
DataSource, DataSourceTemplate, EventOrigin, UnresolvedDataSource, UnresolvedDataSourceTemplate,
};
use crate::trigger::CosmosTrigger;
use crate::{codec, TriggerFilter};
use crate::{codec, Block, TriggerFilter};

pub struct Chain {
logger_factory: LoggerFactory,
Expand Down Expand Up @@ -113,7 +114,8 @@ impl Blockchain for Chain {
deployment: DeploymentLocator,
store: impl DeploymentCursorTracker,
start_blocks: Vec<BlockNumber>,
filter: Arc<Self::TriggerFilter>,
_source_subgraph_stores: Vec<(DeploymentHash, Arc<dyn ReadStore>)>,
filter: Arc<TriggerFilterWrapper<Self>>,
unified_api_version: UnifiedMappingApiVersion,
) -> Result<Box<dyn BlockStream<Self>>, Error> {
let adapter = self
Expand All @@ -129,7 +131,10 @@ impl Blockchain for Chain {
.subgraph_logger(&deployment)
.new(o!("component" => "FirehoseBlockStream"));

let firehose_mapper = Arc::new(FirehoseMapper { adapter, filter });
let firehose_mapper = Arc::new(FirehoseMapper {
adapter,
filter: filter.chain_filter.clone(),
});

Ok(Box::new(FirehoseBlockStream::new(
deployment.hash,
Expand Down Expand Up @@ -193,6 +198,18 @@ impl TriggersAdapterTrait<Chain> for TriggersAdapter {
panic!("Should never be called since not used by FirehoseBlockStream")
}

async fn load_blocks_by_numbers(
&self,
_logger: Logger,
_block_numbers: HashSet<BlockNumber>,
) -> Result<Vec<Block>, Error> {
unimplemented!()
}

async fn chain_head_ptr(&self) -> Result<Option<BlockPtr>, Error> {
unimplemented!()
}

async fn scan_triggers(
&self,
_from: BlockNumber,
Expand Down Expand Up @@ -467,9 +484,12 @@ impl FirehoseMapperTrait<Chain> for FirehoseMapper {

#[cfg(test)]
mod test {
use graph::prelude::{
slog::{o, Discard, Logger},
tokio,
use graph::{
blockchain::Trigger,
prelude::{
slog::{o, Discard, Logger},
tokio,
},
};

use super::*;
Expand Down Expand Up @@ -600,7 +620,10 @@ mod test {
// they may not be in the same order
for trigger in expected_triggers {
assert!(
triggers.trigger_data.contains(&trigger),
triggers.trigger_data.iter().any(|t| match t {
Trigger::Chain(t) => t == &trigger,
_ => false,
}),
"Expected trigger list to contain {:?}, but it only contains: {:?}",
trigger,
triggers.trigger_data
Expand Down
7 changes: 7 additions & 0 deletions chain/ethereum/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,13 @@ pub trait EthereumAdapter: Send + Sync + 'static {
block_hash: H256,
) -> Box<dyn Future<Item = LightEthereumBlock, Error = Error> + Send>;

async fn load_blocks_by_numbers(
&self,
_logger: Logger,
_chain_store: Arc<dyn ChainStore>,
_block_numbers: HashSet<BlockNumber>,
) -> Box<dyn Stream<Item = Arc<LightEthereumBlock>, Error = Error> + Send>;

/// Load Ethereum blocks in bulk, returning results as they come back as a Stream.
/// May use the `chain_store` as a cache.
async fn load_blocks(
Expand Down
107 changes: 91 additions & 16 deletions chain/ethereum/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ use anyhow::{Context, Error};
use graph::blockchain::client::ChainClient;
use graph::blockchain::firehose_block_ingestor::{FirehoseBlockIngestor, Transforms};
use graph::blockchain::{
BlockIngestor, BlockTime, BlockchainKind, ChainIdentifier, TriggersAdapterSelector,
BlockIngestor, BlockTime, BlockchainKind, ChainIdentifier, TriggerFilterWrapper,
TriggersAdapterSelector,
};
use graph::components::network_provider::ChainName;
use graph::components::store::DeploymentCursorTracker;
use graph::components::store::{DeploymentCursorTracker, ReadStore};
use graph::data::subgraph::UnifiedMappingApiVersion;
use graph::firehose::{FirehoseEndpoint, ForkStep};
use graph::futures03::compat::Future01CompatExt;
use graph::prelude::{
BlockHash, ComponentLoggerConfig, ElasticComponentLoggerConfig, EthereumBlock,
BlockHash, ComponentLoggerConfig, DeploymentHash, ElasticComponentLoggerConfig, EthereumBlock,
EthereumCallCache, LightEthereumBlock, LightEthereumBlockExt, MetricsRegistry,
};
use graph::schema::InputSchema;
Expand Down Expand Up @@ -61,6 +62,7 @@ use crate::{BufferedCallCache, NodeCapabilities};
use crate::{EthereumAdapter, RuntimeAdapter};
use graph::blockchain::block_stream::{
BlockStream, BlockStreamBuilder, BlockStreamError, BlockStreamMapper, FirehoseCursor,
TriggersAdapterWrapper,
};

/// Celo Mainnet: 42220, Testnet Alfajores: 44787, Testnet Baklava: 62320
Expand Down Expand Up @@ -121,24 +123,50 @@ impl BlockStreamBuilder<Chain> for EthereumStreamBuilder {
unimplemented!()
}

async fn build_subgraph_block_stream(
&self,
chain: &Chain,
deployment: DeploymentLocator,
start_blocks: Vec<BlockNumber>,
source_subgraph_stores: Vec<(DeploymentHash, Arc<dyn ReadStore>)>,
subgraph_current_block: Option<BlockPtr>,
filter: Arc<TriggerFilterWrapper<Chain>>,
unified_api_version: UnifiedMappingApiVersion,
) -> Result<Box<dyn BlockStream<Chain>>> {
self.build_polling(
chain,
deployment,
start_blocks,
source_subgraph_stores,
subgraph_current_block,
filter,
unified_api_version,
)
.await
}

async fn build_polling(
&self,
chain: &Chain,
deployment: DeploymentLocator,
start_blocks: Vec<BlockNumber>,
source_subgraph_stores: Vec<(DeploymentHash, Arc<dyn ReadStore>)>,
subgraph_current_block: Option<BlockPtr>,
filter: Arc<<Chain as Blockchain>::TriggerFilter>,
filter: Arc<TriggerFilterWrapper<Chain>>,
unified_api_version: UnifiedMappingApiVersion,
) -> Result<Box<dyn BlockStream<Chain>>> {
let requirements = filter.node_capabilities();
let adapter = chain
.triggers_adapter(&deployment, &requirements, unified_api_version.clone())
.unwrap_or_else(|_| {
panic!(
"no adapter for network {} with capabilities {}",
chain.name, requirements
)
});
let requirements = filter.chain_filter.node_capabilities();
let adapter = TriggersAdapterWrapper::new(
chain
.triggers_adapter(&deployment, &requirements, unified_api_version.clone())
.unwrap_or_else(|_| {
panic!(
"no adapter for network {} with capabilities {}",
chain.name, requirements
)
}),
source_subgraph_stores,
);

let logger = chain
.logger_factory
Expand Down Expand Up @@ -172,7 +200,7 @@ impl BlockStreamBuilder<Chain> for EthereumStreamBuilder {
Ok(Box::new(PollingBlockStream::new(
chain_store,
chain_head_update_stream,
adapter,
Arc::new(adapter),
chain.node_id.clone(),
deployment.hash,
filter,
Expand Down Expand Up @@ -409,17 +437,35 @@ impl Blockchain for Chain {
deployment: DeploymentLocator,
store: impl DeploymentCursorTracker,
start_blocks: Vec<BlockNumber>,
filter: Arc<Self::TriggerFilter>,
source_subgraph_stores: Vec<(DeploymentHash, Arc<dyn ReadStore>)>,
filter: Arc<TriggerFilterWrapper<Self>>,
unified_api_version: UnifiedMappingApiVersion,
) -> Result<Box<dyn BlockStream<Self>>, Error> {
let current_ptr = store.block_ptr();

if !filter.subgraph_filter.is_empty() {
return self
.block_stream_builder
.build_subgraph_block_stream(
self,
deployment,
start_blocks,
source_subgraph_stores,
current_ptr,
filter,
unified_api_version,
)
.await;
}

match self.chain_client().as_ref() {
ChainClient::Rpc(_) => {
self.block_stream_builder
.build_polling(
self,
deployment,
start_blocks,
source_subgraph_stores,
current_ptr,
filter,
unified_api_version,
Expand All @@ -434,7 +480,7 @@ impl Blockchain for Chain {
store.firehose_cursor(),
start_blocks,
current_ptr,
filter,
filter.chain_filter.clone(),
unified_api_version,
)
.await
Expand Down Expand Up @@ -689,6 +735,35 @@ impl TriggersAdapterTrait<Chain> for TriggersAdapter {
.await
}

async fn load_blocks_by_numbers(
&self,
logger: Logger,
block_numbers: HashSet<BlockNumber>,
) -> Result<Vec<BlockFinality>> {
use graph::futures01::stream::Stream;

let adapter = self
.chain_client
.rpc()?
.cheapest_with(&self.capabilities)
.await?;

let blocks = adapter
.load_blocks_by_numbers(logger, self.chain_store.clone(), block_numbers)
.await
.map(|block| BlockFinality::Final(block))
.collect()
.compat()
.await?;

Ok(blocks)
}

async fn chain_head_ptr(&self) -> Result<Option<BlockPtr>, Error> {
let chain_store = self.chain_store.clone();
chain_store.chain_head_ptr().await
}

async fn triggers_in_block(
&self,
logger: &Logger,
Expand Down
Loading