diff --git a/Cargo.lock b/Cargo.lock index 33815c70807..751b4750043 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,15 +476,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64-url" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2b6c78c06f7288d5e3c3d683bde35a79531127c83b087e5d0d77c974b4b28" -dependencies = [ - "base64 0.22.1", -] - [[package]] name = "beef" version = "0.5.2" @@ -1895,22 +1886,6 @@ dependencies = [ "wiremock", ] -[[package]] -name = "graph-chain-arweave" -version = "0.36.0" -dependencies = [ - "base64-url", - "diesel", - "graph", - "graph-runtime-derive", - "graph-runtime-wasm", - "prost", - "prost-types", - "serde", - "sha2", - "tonic-build", -] - [[package]] name = "graph-chain-common" version = "0.36.0" @@ -1986,7 +1961,6 @@ dependencies = [ "bytes", "cid", "graph", - "graph-chain-arweave", "graph-chain-ethereum", "graph-chain-near", "graph-chain-substreams", @@ -2022,7 +1996,6 @@ dependencies = [ "env_logger", "git-testament", "graph", - "graph-chain-arweave", "graph-chain-ethereum", "graph-chain-near", "graph-chain-substreams", @@ -2105,7 +2078,6 @@ dependencies = [ "blake3 1.6.1", "git-testament", "graph", - "graph-chain-arweave", "graph-chain-ethereum", "graph-chain-near", "graph-chain-substreams", diff --git a/Cargo.toml b/Cargo.toml index b938992bc30..948e838848f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ members = [ "core", "core/graphman", "core/graphman_store", - "chain/arweave", "chain/common", "chain/ethereum", "chain/near", diff --git a/chain/arweave/.gitignore b/chain/arweave/.gitignore deleted file mode 100644 index 97442b5f148..00000000000 --- a/chain/arweave/.gitignore +++ /dev/null @@ -1 +0,0 @@ -google.protobuf.rs \ No newline at end of file diff --git a/chain/arweave/Cargo.toml b/chain/arweave/Cargo.toml deleted file mode 100644 index 1240520fc01..00000000000 --- a/chain/arweave/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "graph-chain-arweave" -version.workspace = true -edition.workspace = true - -[build-dependencies] -tonic-build = { workspace = true } - -[dependencies] -base64-url = "3.0.0" -graph = { path = "../../graph" } -prost = { workspace = true } -prost-types = { workspace = true } -serde = { workspace = true } -sha2 = "0.10.8" - -graph-runtime-wasm = { path = "../../runtime/wasm" } -graph-runtime-derive = { path = "../../runtime/derive" } - -[dev-dependencies] -diesel = { workspace = true } diff --git a/chain/arweave/build.rs b/chain/arweave/build.rs deleted file mode 100644 index c0abc5fb8c9..00000000000 --- a/chain/arweave/build.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - println!("cargo:rerun-if-changed=proto"); - tonic_build::configure() - .out_dir("src/protobuf") - .compile_protos(&["proto/arweave.proto"], &["proto"]) - .expect("Failed to compile Firehose Arweave proto(s)"); -} diff --git a/chain/arweave/proto/arweave.proto b/chain/arweave/proto/arweave.proto deleted file mode 100644 index b3a41a4a56a..00000000000 --- a/chain/arweave/proto/arweave.proto +++ /dev/null @@ -1,108 +0,0 @@ -syntax = "proto3"; - -package sf.arweave.type.v1; - -option go_package = "github.com/ChainSafe/firehose-arweave/pb/sf/arweave/type/v1;pbcodec"; - -message BigInt { - bytes bytes = 1; -} - -message Block { - // Firehose block version (unrelated to Arweave block version) - uint32 ver = 1; - // The block identifier - bytes indep_hash = 2; - // The nonce chosen to solve the mining problem - bytes nonce = 3; - // `indep_hash` of the previous block in the weave - bytes previous_block = 4; - // POSIX time of block discovery - uint64 timestamp = 5; - // POSIX time of the last difficulty retarget - uint64 last_retarget = 6; - // Mining difficulty; the number `hash` must be greater than. - BigInt diff = 7; - // How many blocks have passed since the genesis block - uint64 height = 8; - // Mining solution hash of the block; must satisfy the mining difficulty - bytes hash = 9; - // Merkle root of the tree of Merkle roots of block's transactions' data. - bytes tx_root = 10; - // Transactions contained within this block - repeated Transaction txs = 11; - // The root hash of the Merkle Patricia Tree containing - // all wallet (account) balances and the identifiers - // of the last transactions posted by them; if any. - bytes wallet_list = 12; - // (string or) Address of the account to receive the block rewards. Can also be unclaimed which is encoded as a null byte - bytes reward_addr = 13; - // Tags that a block producer can add to a block - repeated Tag tags = 14; - // Size of reward pool - BigInt reward_pool = 15; - // Size of the weave in bytes - BigInt weave_size = 16; - // Size of this block in bytes - BigInt block_size = 17; - // Required after the version 1.8 fork. Zero otherwise. - // The sum of the average number of hashes computed - // by the network to produce the past blocks including this one. - BigInt cumulative_diff = 18; - // Required after the version 1.8 fork. Null byte otherwise. - // The Merkle root of the block index - the list of {`indep_hash`; `weave_size`; `tx_root`} triplets - bytes hash_list_merkle = 20; - // The proof of access; Used after v2.4 only; set as defaults otherwise - ProofOfAccess poa = 21; -} - -// A succinct proof of access to a recall byte found in a TX -message ProofOfAccess { - // The recall byte option chosen; global offset of index byte - string option = 1; - // The path through the Merkle tree of transactions' `data_root`s; - // from the `data_root` being proven to the corresponding `tx_root` - bytes tx_path = 2; - // The path through the Merkle tree of identifiers of chunks of the - // corresponding transaction; from the chunk being proven to the - // corresponding `data_root`. - bytes data_path = 3; - // The data chunk. - bytes chunk = 4; -} - -message Transaction { - // 1 or 2 for v1 or v2 transactions. More allowable in the future - uint32 format = 1; - // The transaction identifier. - bytes id = 2; - // Either the identifier of the previous transaction from the same - // wallet or the identifier of one of the last ?MAX_TX_ANCHOR_DEPTH blocks. - bytes last_tx = 3; - // The public key the transaction is signed with. - bytes owner = 4; - // A list of arbitrary key-value pairs - repeated Tag tags = 5; - // The address of the recipient; if any. The SHA2-256 hash of the public key. - bytes target = 6; - // The amount of Winstons to send to the recipient; if any. - BigInt quantity = 7; - // The data to upload; if any. For v2 transactions; the field is optional - // - a fee is charged based on the `data_size` field; - // data may be uploaded any time later in chunks. - bytes data = 8; - // Size in bytes of the transaction data. - BigInt data_size = 9; - // The Merkle root of the Merkle tree of data chunks. - bytes data_root = 10; - // The signature. - bytes signature = 11; - // The fee in Winstons. - BigInt reward = 12; -} - - -message Tag { - bytes name = 1; - bytes value = 2; -} diff --git a/chain/arweave/src/adapter.rs b/chain/arweave/src/adapter.rs deleted file mode 100644 index 9b25016b4c6..00000000000 --- a/chain/arweave/src/adapter.rs +++ /dev/null @@ -1,262 +0,0 @@ -use crate::{data_source::DataSource, Chain}; -use graph::blockchain as bc; -use graph::prelude::*; -use sha2::{Digest, Sha256}; -use std::collections::HashSet; - -const MATCH_ALL_WILDCARD: &str = ""; -// Size of sha256(pubkey) -const SHA256_LEN: usize = 32; - -#[derive(Clone, Debug, Default)] -pub struct TriggerFilter { - pub(crate) block_filter: ArweaveBlockFilter, - pub(crate) transaction_filter: ArweaveTransactionFilter, -} - -impl bc::TriggerFilter for TriggerFilter { - fn extend<'a>(&mut self, data_sources: impl Iterator + Clone) { - let TriggerFilter { - block_filter, - transaction_filter, - } = self; - - block_filter.extend(ArweaveBlockFilter::from_data_sources(data_sources.clone())); - transaction_filter.extend(ArweaveTransactionFilter::from_data_sources(data_sources)); - } - - fn node_capabilities(&self) -> bc::EmptyNodeCapabilities { - bc::EmptyNodeCapabilities::default() - } - - fn extend_with_template( - &mut self, - _data_source: impl Iterator::DataSourceTemplate>, - ) { - } - - fn to_firehose_filter(self) -> Vec { - vec![] - } -} - -/// ArweaveBlockFilter will match every block regardless of source being set. -/// see docs: https://thegraph.com/docs/en/supported-networks/arweave/ -#[derive(Clone, Debug, Default)] -pub(crate) struct ArweaveTransactionFilter { - owners_pubkey: HashSet>, - owners_sha: HashSet>, - match_all: bool, -} - -impl ArweaveTransactionFilter { - pub fn matches(&self, owner: &[u8]) -> bool { - if self.match_all { - return true; - } - - if owner.len() == SHA256_LEN { - return self.owners_sha.contains(owner); - } - - self.owners_pubkey.contains(owner) || self.owners_sha.contains(&sha256(owner)) - } - - pub fn from_data_sources<'a>(iter: impl IntoIterator) -> Self { - let owners: Vec> = iter - .into_iter() - .filter(|data_source| { - data_source.source.owner.is_some() - && !data_source.mapping.transaction_handlers.is_empty() - }) - .map(|ds| match &ds.source.owner { - Some(str) if MATCH_ALL_WILDCARD.eq(str) => MATCH_ALL_WILDCARD.as_bytes().to_owned(), - owner => base64_url::decode(&owner.clone().unwrap_or_default()).unwrap_or_default(), - }) - .collect(); - - let (owners_sha, long) = owners - .into_iter() - .partition::>, _>(|owner| owner.len() == SHA256_LEN); - - let (owners_pubkey, wildcard) = long - .into_iter() - .partition::>, _>(|long| long.len() != MATCH_ALL_WILDCARD.len()); - - let match_all = !wildcard.is_empty(); - - let owners_sha: Vec> = owners_sha - .into_iter() - .chain::>>(owners_pubkey.iter().map(|long| sha256(long)).collect()) - .collect(); - - Self { - match_all, - owners_pubkey: HashSet::from_iter(owners_pubkey), - owners_sha: HashSet::from_iter(owners_sha), - } - } - - pub fn extend(&mut self, other: ArweaveTransactionFilter) { - let ArweaveTransactionFilter { - owners_pubkey, - owners_sha, - match_all, - } = self; - - owners_pubkey.extend(other.owners_pubkey); - owners_sha.extend(other.owners_sha); - *match_all = *match_all || other.match_all; - } -} - -/// ArweaveBlockFilter will match every block regardless of source being set. -/// see docs: https://thegraph.com/docs/en/supported-networks/arweave/ -#[derive(Clone, Debug, Default)] -pub(crate) struct ArweaveBlockFilter { - pub trigger_every_block: bool, -} - -impl ArweaveBlockFilter { - pub fn from_data_sources<'a>(iter: impl IntoIterator) -> Self { - Self { - trigger_every_block: iter - .into_iter() - .any(|data_source| !data_source.mapping.block_handlers.is_empty()), - } - } - - pub fn extend(&mut self, other: ArweaveBlockFilter) { - self.trigger_every_block = self.trigger_every_block || other.trigger_every_block; - } -} - -fn sha256(bs: &[u8]) -> Vec { - let mut hasher = Sha256::new(); - hasher.update(bs); - let res = hasher.finalize(); - res.to_vec() -} - -#[cfg(test)] -mod test { - use std::sync::Arc; - - use graph::{prelude::Link, semver::Version}; - - use crate::data_source::{DataSource, Mapping, Source, TransactionHandler}; - - use super::{ArweaveTransactionFilter, MATCH_ALL_WILDCARD}; - - const ARWEAVE_PUBKEY_EXAMPLE: &str = "x-62w7g2yKACOgP_d04bhG8IX-AWgPrxHl2JgZBDdNLfAsidiiAaoIZPeM8K5gGvl7-8QVk79YV4OC878Ey0gXi7Atj5BouRyXnFMjJcPVXVyBoYCBuG7rJDDmh4_Ilon6vVOuHVIZ47Vb0tcgsxgxdvVFC2mn9N_SBl23pbeICNJZYOH57kf36gicuV_IwYSdqlQ0HQ_psjmg8EFqO7xzvAMP5HKW3rqTrYZxbCew2FkM734ysWckT39TpDBPx3HrFOl6obUdQWkHNOeKyzcsKFDywNgVWZOb89CYU7JFYlwX20io39ZZv0UJUOEFNjtVHkT_s0_A2O9PltsrZLLlQXZUuYASdbAPD2g_qXfhmPBZ0SXPWCDY-UVwVN1ncwYmk1F_i35IA8kAKsajaltD2wWDQn9g5mgJAWWn2xhLqkbwGbdwQMRD0-0eeuy1uzCooJQCC_bPJksoqkYwB9SGOjkayf4r4oZ2QDY4FicCsswz4Od_gud30ZWyHjWgqGzSFYFzawDBS1Gr_nu_q5otFrv20ZGTxYqGsLHWq4VHs6KjsQvzgBjfyb0etqHQEPJJmbQmY3LSogR4bxdReUHhj2EK9xIB-RKzDvDdL7fT5K0V9MjbnC2uktA0VjLlvwJ64_RhbQhxdp_zR39r-zyCXT-brPEYW1-V7Ey9K3XUE"; - const ARWEAVE_SHA_EXAMPLE: &str = "ahLxjCMCHr1ZE72VDDoaK4IKiLUUpeuo8t-M6y23DXw"; - - #[test] - fn transaction_filter_wildcard_matches_all() { - let dss = vec![ - new_datasource(None, 10), - new_datasource(Some(base64_url::encode(MATCH_ALL_WILDCARD)), 10), - new_datasource(Some(base64_url::encode("owner")), 10), - new_datasource(Some(ARWEAVE_PUBKEY_EXAMPLE.into()), 10), - ]; - - let dss: Vec<&DataSource> = dss.iter().collect(); - - let filter = ArweaveTransactionFilter::from_data_sources(dss); - assert_eq!(true, filter.matches("asdas".as_bytes())) - } - - #[test] - fn transaction_filter_match() { - let dss = vec![ - new_datasource(None, 10), - new_datasource(Some(ARWEAVE_PUBKEY_EXAMPLE.into()), 10), - ]; - - let dss: Vec<&DataSource> = dss.iter().collect(); - - let filter = ArweaveTransactionFilter::from_data_sources(dss); - assert_eq!(false, filter.matches("asdas".as_bytes())); - assert_eq!( - true, - filter.matches( - &base64_url::decode(ARWEAVE_SHA_EXAMPLE).expect("failed to parse sha example") - ) - ); - assert_eq!( - true, - filter.matches( - &base64_url::decode(ARWEAVE_PUBKEY_EXAMPLE).expect("failed to parse PK example") - ) - ) - } - - #[test] - fn transaction_filter_extend_match() { - let dss = vec![ - new_datasource(None, 10), - new_datasource(Some(ARWEAVE_SHA_EXAMPLE.into()), 10), - ]; - - let dss: Vec<&DataSource> = dss.iter().collect(); - - let filter = ArweaveTransactionFilter::from_data_sources(dss); - assert_eq!(false, filter.matches("asdas".as_bytes())); - assert_eq!( - true, - filter.matches( - &base64_url::decode(ARWEAVE_SHA_EXAMPLE).expect("failed to parse sha example") - ) - ); - assert_eq!( - true, - filter.matches( - &base64_url::decode(ARWEAVE_PUBKEY_EXAMPLE).expect("failed to parse PK example") - ) - ) - } - - #[test] - fn transaction_filter_extend_wildcard_matches_all() { - let dss = vec![ - new_datasource(None, 10), - new_datasource(Some(MATCH_ALL_WILDCARD.into()), 10), - new_datasource(Some("owner".into()), 10), - ]; - - let dss: Vec<&DataSource> = dss.iter().collect(); - - let mut filter = ArweaveTransactionFilter::default(); - - filter.extend(ArweaveTransactionFilter::from_data_sources(dss)); - assert_eq!(true, filter.matches("asdas".as_bytes())); - assert_eq!(true, filter.matches(ARWEAVE_PUBKEY_EXAMPLE.as_bytes())); - assert_eq!(true, filter.matches(ARWEAVE_SHA_EXAMPLE.as_bytes())) - } - - fn new_datasource(owner: Option, start_block: i32) -> DataSource { - DataSource { - kind: "".into(), - network: None, - name: "".into(), - source: Source { - owner, - start_block, - end_block: None, - }, - mapping: Mapping { - api_version: Version::new(1, 2, 3), - language: "".into(), - entities: vec![], - block_handlers: vec![], - transaction_handlers: vec![TransactionHandler { - handler: "my_handler".into(), - }], - runtime: Arc::new(vec![]), - link: Link { link: "".into() }, - }, - context: Arc::new(None), - creation_block: None, - } - } -} diff --git a/chain/arweave/src/chain.rs b/chain/arweave/src/chain.rs deleted file mode 100644 index 40f2538a400..00000000000 --- a/chain/arweave/src/chain.rs +++ /dev/null @@ -1,413 +0,0 @@ -use graph::anyhow; -use graph::blockchain::client::ChainClient; -use graph::blockchain::firehose_block_ingestor::FirehoseBlockIngestor; -use graph::blockchain::{ - BasicBlockchainBuilder, Block, BlockIngestor, BlockchainBuilder, BlockchainKind, - EmptyNodeCapabilities, NoopDecoderHook, NoopRuntimeAdapter, TriggerFilterWrapper, -}; -use graph::cheap_clone::CheapClone; -use graph::components::network_provider::ChainName; -use graph::components::store::{DeploymentCursorTracker, SourceableStore}; -use graph::data::subgraph::UnifiedMappingApiVersion; -use graph::env::EnvVars; -use graph::firehose::FirehoseEndpoint; -use graph::prelude::MetricsRegistry; -use graph::substreams::Clock; -use graph::{ - blockchain::{ - block_stream::{ - BlockStreamEvent, BlockWithTriggers, FirehoseError, - FirehoseMapper as FirehoseMapperTrait, TriggersAdapter as TriggersAdapterTrait, - }, - firehose_block_stream::FirehoseBlockStream, - BlockHash, BlockPtr, Blockchain, IngestorError, RuntimeAdapter as RuntimeAdapterTrait, - }, - components::store::DeploymentLocator, - firehose::{self as firehose, ForkStep}, - prelude::{async_trait, o, BlockNumber, ChainStore, Error, Logger, LoggerFactory}, -}; -use prost::Message; -use std::collections::BTreeSet; -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}, -}; -use graph::blockchain::block_stream::{ - BlockStream, BlockStreamError, BlockStreamMapper, FirehoseCursor, -}; - -pub struct Chain { - logger_factory: LoggerFactory, - name: ChainName, - client: Arc>, - chain_store: Arc, - metrics_registry: Arc, -} - -impl std::fmt::Debug for Chain { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "chain: arweave") - } -} - -#[async_trait] -impl BlockchainBuilder for BasicBlockchainBuilder { - async fn build(self, _config: &Arc) -> Chain { - Chain { - logger_factory: self.logger_factory, - name: self.name, - client: Arc::new(ChainClient::::new_firehose(self.firehose_endpoints)), - chain_store: self.chain_store, - metrics_registry: self.metrics_registry, - } - } -} - -#[async_trait] -impl Blockchain for Chain { - const KIND: BlockchainKind = BlockchainKind::Arweave; - - type Client = (); - type Block = codec::Block; - - type DataSource = DataSource; - - type UnresolvedDataSource = UnresolvedDataSource; - - type DataSourceTemplate = DataSourceTemplate; - - type UnresolvedDataSourceTemplate = UnresolvedDataSourceTemplate; - - type TriggerData = crate::trigger::ArweaveTrigger; - - type MappingTrigger = crate::trigger::ArweaveTrigger; - - type TriggerFilter = crate::adapter::TriggerFilter; - - type NodeCapabilities = EmptyNodeCapabilities; - - type DecoderHook = NoopDecoderHook; - - fn triggers_adapter( - &self, - _loc: &DeploymentLocator, - _capabilities: &Self::NodeCapabilities, - _unified_api_version: UnifiedMappingApiVersion, - ) -> Result>, Error> { - let adapter = TriggersAdapter {}; - Ok(Arc::new(adapter)) - } - - fn is_refetch_block_required(&self) -> bool { - false - } - - async fn refetch_firehose_block( - &self, - _logger: &Logger, - _cursor: FirehoseCursor, - ) -> Result { - unimplemented!("This chain does not support Dynamic Data Sources. is_refetch_block_required always returns false, this shouldn't be called.") - } - - async fn new_block_stream( - &self, - deployment: DeploymentLocator, - store: impl DeploymentCursorTracker, - start_blocks: Vec, - _source_subgraph_stores: Vec>, - filter: Arc>, - unified_api_version: UnifiedMappingApiVersion, - ) -> Result>, Error> { - let adapter = self - .triggers_adapter( - &deployment, - &EmptyNodeCapabilities::default(), - unified_api_version, - ) - .unwrap_or_else(|_| panic!("no adapter for network {}", self.name)); - - let logger = self - .logger_factory - .subgraph_logger(&deployment) - .new(o!("component" => "FirehoseBlockStream")); - - let firehose_mapper = Arc::new(FirehoseMapper { - adapter, - filter: filter.chain_filter.clone(), - }); - - Ok(Box::new(FirehoseBlockStream::new( - deployment.hash, - self.chain_client(), - store.block_ptr(), - store.firehose_cursor(), - firehose_mapper, - start_blocks, - logger, - self.metrics_registry.clone(), - ))) - } - - fn chain_store(&self) -> Arc { - self.chain_store.clone() - } - - async fn block_pointer_from_number( - &self, - logger: &Logger, - number: BlockNumber, - ) -> Result { - self.client - .firehose_endpoint() - .await? - .block_ptr_for_number::(logger, number) - .await - .map_err(Into::into) - } - - fn runtime(&self) -> anyhow::Result<(Arc>, Self::DecoderHook)> { - Ok((Arc::new(NoopRuntimeAdapter::default()), NoopDecoderHook)) - } - - fn chain_client(&self) -> Arc> { - self.client.clone() - } - - async fn block_ingestor(&self) -> anyhow::Result> { - let ingestor = FirehoseBlockIngestor::::new( - self.chain_store.cheap_clone(), - self.chain_client(), - self.logger_factory - .component_logger("ArweaveFirehoseBlockIngestor", None), - self.name.clone(), - ); - Ok(Box::new(ingestor)) - } -} - -pub struct TriggersAdapter {} - -#[async_trait] -impl TriggersAdapterTrait for TriggersAdapter { - async fn scan_triggers( - &self, - _from: BlockNumber, - _to: BlockNumber, - _filter: &TriggerFilter, - ) -> Result<(Vec>, BlockNumber), Error> { - panic!("Should never be called since not used by FirehoseBlockStream") - } - - async fn chain_head_ptr(&self) -> Result, Error> { - unimplemented!() - } - - async fn triggers_in_block( - &self, - logger: &Logger, - block: codec::Block, - filter: &TriggerFilter, - ) -> Result, Error> { - // TODO: Find the best place to introduce an `Arc` and avoid this clone. - let shared_block = Arc::new(block.clone()); - - let TriggerFilter { - block_filter, - transaction_filter, - } = filter; - - let txs = block - .clone() - .txs - .into_iter() - .filter(|tx| transaction_filter.matches(&tx.owner)) - .map(|tx| trigger::TransactionWithBlockPtr { - tx: Arc::new(tx), - block: shared_block.clone(), - }) - .collect::>(); - - let mut trigger_data: Vec<_> = txs - .into_iter() - .map(|tx| ArweaveTrigger::Transaction(Arc::new(tx))) - .collect(); - - if block_filter.trigger_every_block { - trigger_data.push(ArweaveTrigger::Block(shared_block.cheap_clone())); - } - - Ok(BlockWithTriggers::new(block, trigger_data, logger)) - } - - async fn is_on_main_chain(&self, _ptr: BlockPtr) -> Result { - panic!("Should never be called since not used by FirehoseBlockStream") - } - - async fn ancestor_block( - &self, - _ptr: BlockPtr, - _offset: BlockNumber, - _root: Option, - ) -> Result, Error> { - panic!("Should never be called since FirehoseBlockStream cannot resolve it") - } - - /// Panics if `block` is genesis. - /// But that's ok since this is only called when reverting `block`. - async fn parent_ptr(&self, block: &BlockPtr) -> Result, Error> { - // FIXME (Arweave): Might not be necessary for Arweave support for now - Ok(Some(BlockPtr { - hash: BlockHash::from(vec![0xff; 48]), - number: block.number.saturating_sub(1), - })) - } - - async fn load_block_ptrs_by_numbers( - &self, - _logger: Logger, - _block_numbers: BTreeSet, - ) -> Result, Error> { - todo!() - } -} - -pub struct FirehoseMapper { - adapter: Arc>, - filter: Arc, -} - -#[async_trait] -impl BlockStreamMapper for FirehoseMapper { - fn decode_block( - &self, - output: Option<&[u8]>, - ) -> Result, BlockStreamError> { - let block = match output { - Some(block) => codec::Block::decode(block)?, - None => { - return Err(anyhow::anyhow!( - "Arweave mapper is expected to always have a block" - ))? - } - }; - - Ok(Some(block)) - } - - async fn block_with_triggers( - &self, - logger: &Logger, - block: codec::Block, - ) -> Result, BlockStreamError> { - self.adapter - .triggers_in_block(logger, block, self.filter.as_ref()) - .await - .map_err(BlockStreamError::from) - } - async fn handle_substreams_block( - &self, - _logger: &Logger, - _clock: Clock, - _cursor: FirehoseCursor, - _block: Vec, - ) -> Result, BlockStreamError> { - unimplemented!() - } -} - -#[async_trait] -impl FirehoseMapperTrait for FirehoseMapper { - fn trigger_filter(&self) -> &TriggerFilter { - self.filter.as_ref() - } - - async fn to_block_stream_event( - &self, - logger: &Logger, - response: &firehose::Response, - ) -> Result, FirehoseError> { - let step = ForkStep::try_from(response.step).unwrap_or_else(|_| { - panic!( - "unknown step i32 value {}, maybe you forgot update & re-regenerate the protobuf definitions?", - response.step - ) - }); - - let any_block = response - .block - .as_ref() - .expect("block payload information should always be present"); - - // Right now, this is done in all cases but in reality, with how the BlockStreamEvent::Revert - // is defined right now, only block hash and block number is necessary. However, this information - // is not part of the actual bstream::BlockResponseV2 payload. As such, we need to decode the full - // block which is useless. - // - // Check about adding basic information about the block in the bstream::BlockResponseV2 or maybe - // define a slimmed down stuct that would decode only a few fields and ignore all the rest. - // unwrap: Input cannot be None so output will be error or block. - let block = self - .decode_block(Some(&any_block.value.as_ref())) - .map_err(Error::from)? - .unwrap(); - - use ForkStep::*; - match step { - StepNew => Ok(BlockStreamEvent::ProcessBlock( - self.block_with_triggers(&logger, block) - .await - .map_err(Error::from)?, - FirehoseCursor::from(response.cursor.clone()), - )), - - StepUndo => { - let parent_ptr = block - .parent_ptr() - .expect("Genesis block should never be reverted"); - - Ok(BlockStreamEvent::Revert( - parent_ptr, - FirehoseCursor::from(response.cursor.clone()), - )) - } - - StepFinal => { - panic!("irreversible step is not handled and should not be requested in the Firehose request") - } - - StepUnset => { - panic!("unknown step should not happen in the Firehose response") - } - } - } - - async fn block_ptr_for_number( - &self, - logger: &Logger, - endpoint: &Arc, - number: BlockNumber, - ) -> Result { - endpoint - .block_ptr_for_number::(logger, number) - .await - } - - // # FIXME - // - // the final block of arweave is itself in the current implementation - async fn final_block_ptr_for( - &self, - _logger: &Logger, - _endpoint: &Arc, - block: &codec::Block, - ) -> Result { - Ok(block.ptr()) - } -} diff --git a/chain/arweave/src/codec.rs b/chain/arweave/src/codec.rs deleted file mode 100644 index 3df276f309b..00000000000 --- a/chain/arweave/src/codec.rs +++ /dev/null @@ -1,45 +0,0 @@ -#[rustfmt::skip] -#[path = "protobuf/sf.arweave.r#type.v1.rs"] -mod pbcodec; - -use graph::{ - blockchain::Block as BlockchainBlock, - blockchain::{BlockPtr, BlockTime}, - prelude::BlockNumber, -}; - -pub use pbcodec::*; - -impl BlockchainBlock for Block { - fn number(&self) -> i32 { - BlockNumber::try_from(self.height).unwrap() - } - - fn ptr(&self) -> BlockPtr { - BlockPtr { - hash: self.indep_hash.clone().into(), - number: self.number(), - } - } - - fn parent_ptr(&self) -> Option { - if self.height == 0 { - return None; - } - - Some(BlockPtr { - hash: self.previous_block.clone().into(), - number: self.number().saturating_sub(1), - }) - } - - fn timestamp(&self) -> BlockTime { - BlockTime::since_epoch(i64::try_from(self.timestamp).unwrap(), 0) - } -} - -impl AsRef<[u8]> for BigInt { - fn as_ref(&self) -> &[u8] { - self.bytes.as_ref() - } -} diff --git a/chain/arweave/src/data_source.rs b/chain/arweave/src/data_source.rs deleted file mode 100644 index f94d6260785..00000000000 --- a/chain/arweave/src/data_source.rs +++ /dev/null @@ -1,408 +0,0 @@ -use graph::anyhow::Context; -use graph::blockchain::{Block, TriggerWithHandler}; -use graph::components::store::StoredDynamicDataSource; -use graph::components::subgraph::InstanceDSTemplateInfo; -use graph::data::subgraph::DataSourceContext; -use graph::prelude::SubgraphManifestValidationError; -use graph::{ - anyhow::{anyhow, Error}, - blockchain::{self, Blockchain}, - prelude::{async_trait, BlockNumber, CheapClone, Deserialize, Link, LinkResolver, Logger}, - semver, -}; -use std::collections::HashSet; -use std::sync::Arc; - -use crate::chain::Chain; -use crate::trigger::ArweaveTrigger; - -pub const ARWEAVE_KIND: &str = "arweave"; -const BLOCK_HANDLER_KIND: &str = "block"; -const TRANSACTION_HANDLER_KIND: &str = "transaction"; -/// Runtime representation of a data source. -#[derive(Clone, Debug)] -pub struct DataSource { - pub kind: String, - pub network: Option, - pub name: String, - pub(crate) source: Source, - pub mapping: Mapping, - pub context: Arc>, - pub creation_block: Option, -} - -impl blockchain::DataSource for DataSource { - fn from_template_info( - _info: InstanceDSTemplateInfo, - _template: &graph::data_source::DataSourceTemplate, - ) -> Result { - Err(anyhow!("Arweave subgraphs do not support templates")) - } - - // FIXME - // - // need to decode the base64url encoding? - fn address(&self) -> Option<&[u8]> { - self.source.owner.as_ref().map(String::as_bytes) - } - - fn start_block(&self) -> BlockNumber { - self.source.start_block - } - - fn handler_kinds(&self) -> HashSet<&str> { - let mut kinds = HashSet::new(); - - if self.handler_for_block().is_some() { - kinds.insert(BLOCK_HANDLER_KIND); - } - - if self.handler_for_transaction().is_some() { - kinds.insert(TRANSACTION_HANDLER_KIND); - } - - kinds - } - - fn end_block(&self) -> Option { - self.source.end_block - } - - fn match_and_decode( - &self, - trigger: &::TriggerData, - block: &Arc<::Block>, - _logger: &Logger, - ) -> Result>, Error> { - if self.source.start_block > block.number() { - return Ok(None); - } - - let handler = match trigger { - // A block trigger matches if a block handler is present. - ArweaveTrigger::Block(_) => match self.handler_for_block() { - Some(handler) => &handler.handler, - None => return Ok(None), - }, - // A transaction trigger matches if a transaction handler is present. - ArweaveTrigger::Transaction(_) => match self.handler_for_transaction() { - Some(handler) => &handler.handler, - None => return Ok(None), - }, - }; - - Ok(Some(TriggerWithHandler::::new( - trigger.cheap_clone(), - handler.clone(), - block.ptr(), - block.timestamp(), - ))) - } - - fn name(&self) -> &str { - &self.name - } - - fn kind(&self) -> &str { - &self.kind - } - - fn network(&self) -> Option<&str> { - self.network.as_deref() - } - - fn context(&self) -> Arc> { - self.context.cheap_clone() - } - - fn creation_block(&self) -> Option { - self.creation_block - } - - fn is_duplicate_of(&self, other: &Self) -> bool { - let DataSource { - kind, - network, - name, - source, - mapping, - context, - - // The creation block is ignored for detection duplicate data sources. - // Contract ABI equality is implicit in `source` and `mapping.abis` equality. - creation_block: _, - } = self; - - // mapping_request_sender, host_metrics, and (most of) host_exports are operational structs - // used at runtime but not needed to define uniqueness; each runtime host should be for a - // unique data source. - kind == &other.kind - && network == &other.network - && name == &other.name - && source == &other.source - && mapping.block_handlers == other.mapping.block_handlers - && context == &other.context - } - - fn as_stored_dynamic_data_source(&self) -> StoredDynamicDataSource { - // FIXME (Arweave): Implement me! - todo!() - } - - fn from_stored_dynamic_data_source( - _template: &DataSourceTemplate, - _stored: StoredDynamicDataSource, - ) -> Result { - // FIXME (Arweave): Implement me correctly - todo!() - } - - fn validate(&self, _: &semver::Version) -> Vec { - let mut errors = Vec::new(); - - if self.kind != ARWEAVE_KIND { - errors.push(anyhow!( - "data source has invalid `kind`, expected {} but found {}", - ARWEAVE_KIND, - self.kind - )) - } - - // Validate that there is a `source` address if there are transaction handlers - let no_source_address = self.address().is_none(); - let has_transaction_handlers = !self.mapping.transaction_handlers.is_empty(); - if no_source_address && has_transaction_handlers { - errors.push(SubgraphManifestValidationError::SourceAddressRequired.into()); - }; - - // Validate that there are no more than one of both block handlers and transaction handlers - if self.mapping.block_handlers.len() > 1 { - errors.push(anyhow!("data source has duplicated block handlers")); - } - if self.mapping.transaction_handlers.len() > 1 { - errors.push(anyhow!("data source has duplicated transaction handlers")); - } - - errors - } - - fn api_version(&self) -> semver::Version { - self.mapping.api_version.clone() - } - - fn runtime(&self) -> Option>> { - Some(self.mapping.runtime.cheap_clone()) - } -} - -impl DataSource { - fn from_manifest( - kind: String, - network: Option, - name: String, - source: Source, - mapping: Mapping, - context: Option, - ) -> Result { - // Data sources in the manifest are created "before genesis" so they have no creation block. - let creation_block = None; - - Ok(DataSource { - kind, - network, - name, - source, - mapping, - context: Arc::new(context), - creation_block, - }) - } - - fn handler_for_block(&self) -> Option<&MappingBlockHandler> { - self.mapping.block_handlers.first() - } - - fn handler_for_transaction(&self) -> Option<&TransactionHandler> { - self.mapping.transaction_handlers.first() - } -} - -#[derive(Clone, Debug, Eq, PartialEq, Deserialize)] -pub struct UnresolvedDataSource { - pub kind: String, - pub network: Option, - pub name: String, - pub(crate) source: Source, - pub mapping: UnresolvedMapping, - pub context: Option, -} - -#[async_trait] -impl blockchain::UnresolvedDataSource for UnresolvedDataSource { - async fn resolve( - self, - resolver: &Arc, - logger: &Logger, - _manifest_idx: u32, - ) -> Result { - let UnresolvedDataSource { - kind, - network, - name, - source, - mapping, - context, - } = self; - - let mapping = mapping.resolve(resolver, logger).await.with_context(|| { - format!( - "failed to resolve data source {} with source_address {:?} and start_block {}", - name, - base64_url::encode(&source.owner.clone().unwrap_or_default()), - source.start_block - ) - })?; - - DataSource::from_manifest(kind, network, name, source, mapping, context) - } -} - -#[derive(Clone, Debug, Default, Hash, Eq, PartialEq, Deserialize)] -pub struct BaseDataSourceTemplate { - pub kind: String, - pub network: Option, - pub name: String, - pub mapping: M, -} - -pub type UnresolvedDataSourceTemplate = BaseDataSourceTemplate; -pub type DataSourceTemplate = BaseDataSourceTemplate; - -#[async_trait] -impl blockchain::UnresolvedDataSourceTemplate for UnresolvedDataSourceTemplate { - async fn resolve( - self, - resolver: &Arc, - logger: &Logger, - _manifest_idx: u32, - ) -> Result { - let UnresolvedDataSourceTemplate { - kind, - network, - name, - mapping, - } = self; - - let mapping = mapping - .resolve(resolver, logger) - .await - .with_context(|| format!("failed to resolve data source template {}", name))?; - - Ok(DataSourceTemplate { - kind, - network, - name, - mapping, - }) - } -} - -impl blockchain::DataSourceTemplate for DataSourceTemplate { - fn name(&self) -> &str { - &self.name - } - - fn api_version(&self) -> semver::Version { - self.mapping.api_version.clone() - } - - fn runtime(&self) -> Option>> { - Some(self.mapping.runtime.cheap_clone()) - } - - fn manifest_idx(&self) -> u32 { - unreachable!("arweave does not support dynamic data sources") - } - - fn kind(&self) -> &str { - &self.kind - } -} - -#[derive(Clone, Debug, Default, Hash, Eq, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct UnresolvedMapping { - pub api_version: String, - pub language: String, - pub entities: Vec, - #[serde(default)] - pub block_handlers: Vec, - #[serde(default)] - pub transaction_handlers: Vec, - pub file: Link, -} - -impl UnresolvedMapping { - pub async fn resolve( - self, - resolver: &Arc, - logger: &Logger, - ) -> Result { - let UnresolvedMapping { - api_version, - language, - entities, - block_handlers, - transaction_handlers, - file: link, - } = self; - - let api_version = semver::Version::parse(&api_version)?; - - let module_bytes = resolver - .cat(logger, &link) - .await - .with_context(|| format!("failed to resolve mapping {}", link.link))?; - - Ok(Mapping { - api_version, - language, - entities, - block_handlers, - transaction_handlers, - runtime: Arc::new(module_bytes), - link, - }) - } -} - -#[derive(Clone, Debug)] -pub struct Mapping { - pub api_version: semver::Version, - pub language: String, - pub entities: Vec, - pub block_handlers: Vec, - pub transaction_handlers: Vec, - pub runtime: Arc>, - pub link: Link, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Deserialize)] -pub struct MappingBlockHandler { - pub handler: String, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Deserialize)] -pub struct TransactionHandler { - pub handler: String, -} - -#[derive(Clone, Debug, Hash, Eq, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct Source { - // A data source that does not have an owner can only have block handlers. - pub(crate) owner: Option, - #[serde(default)] - pub(crate) start_block: BlockNumber, - pub(crate) end_block: Option, -} diff --git a/chain/arweave/src/lib.rs b/chain/arweave/src/lib.rs deleted file mode 100644 index 77e63bc51ab..00000000000 --- a/chain/arweave/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -mod adapter; -mod chain; -mod codec; -mod data_source; -mod runtime; -mod trigger; - -pub use crate::chain::Chain; -pub use codec::Block; diff --git a/chain/arweave/src/protobuf/sf.arweave.r#type.v1.rs b/chain/arweave/src/protobuf/sf.arweave.r#type.v1.rs deleted file mode 100644 index 17f44498491..00000000000 --- a/chain/arweave/src/protobuf/sf.arweave.r#type.v1.rs +++ /dev/null @@ -1,142 +0,0 @@ -// This file is @generated by prost-build. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct BigInt { - #[prost(bytes = "vec", tag = "1")] - pub bytes: ::prost::alloc::vec::Vec, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Block { - /// Firehose block version (unrelated to Arweave block version) - #[prost(uint32, tag = "1")] - pub ver: u32, - /// The block identifier - #[prost(bytes = "vec", tag = "2")] - pub indep_hash: ::prost::alloc::vec::Vec, - /// The nonce chosen to solve the mining problem - #[prost(bytes = "vec", tag = "3")] - pub nonce: ::prost::alloc::vec::Vec, - /// `indep_hash` of the previous block in the weave - #[prost(bytes = "vec", tag = "4")] - pub previous_block: ::prost::alloc::vec::Vec, - /// POSIX time of block discovery - #[prost(uint64, tag = "5")] - pub timestamp: u64, - /// POSIX time of the last difficulty retarget - #[prost(uint64, tag = "6")] - pub last_retarget: u64, - /// Mining difficulty; the number `hash` must be greater than. - #[prost(message, optional, tag = "7")] - pub diff: ::core::option::Option, - /// How many blocks have passed since the genesis block - #[prost(uint64, tag = "8")] - pub height: u64, - /// Mining solution hash of the block; must satisfy the mining difficulty - #[prost(bytes = "vec", tag = "9")] - pub hash: ::prost::alloc::vec::Vec, - /// Merkle root of the tree of Merkle roots of block's transactions' data. - #[prost(bytes = "vec", tag = "10")] - pub tx_root: ::prost::alloc::vec::Vec, - /// Transactions contained within this block - #[prost(message, repeated, tag = "11")] - pub txs: ::prost::alloc::vec::Vec, - /// The root hash of the Merkle Patricia Tree containing - /// all wallet (account) balances and the identifiers - /// of the last transactions posted by them; if any. - #[prost(bytes = "vec", tag = "12")] - pub wallet_list: ::prost::alloc::vec::Vec, - /// (string or) Address of the account to receive the block rewards. Can also be unclaimed which is encoded as a null byte - #[prost(bytes = "vec", tag = "13")] - pub reward_addr: ::prost::alloc::vec::Vec, - /// Tags that a block producer can add to a block - #[prost(message, repeated, tag = "14")] - pub tags: ::prost::alloc::vec::Vec, - /// Size of reward pool - #[prost(message, optional, tag = "15")] - pub reward_pool: ::core::option::Option, - /// Size of the weave in bytes - #[prost(message, optional, tag = "16")] - pub weave_size: ::core::option::Option, - /// Size of this block in bytes - #[prost(message, optional, tag = "17")] - pub block_size: ::core::option::Option, - /// Required after the version 1.8 fork. Zero otherwise. - /// The sum of the average number of hashes computed - /// by the network to produce the past blocks including this one. - #[prost(message, optional, tag = "18")] - pub cumulative_diff: ::core::option::Option, - /// Required after the version 1.8 fork. Null byte otherwise. - /// The Merkle root of the block index - the list of {`indep_hash`; `weave_size`; `tx_root`} triplets - #[prost(bytes = "vec", tag = "20")] - pub hash_list_merkle: ::prost::alloc::vec::Vec, - /// The proof of access; Used after v2.4 only; set as defaults otherwise - #[prost(message, optional, tag = "21")] - pub poa: ::core::option::Option, -} -/// A succinct proof of access to a recall byte found in a TX -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProofOfAccess { - /// The recall byte option chosen; global offset of index byte - #[prost(string, tag = "1")] - pub option: ::prost::alloc::string::String, - /// The path through the Merkle tree of transactions' `data_root`s; - /// from the `data_root` being proven to the corresponding `tx_root` - #[prost(bytes = "vec", tag = "2")] - pub tx_path: ::prost::alloc::vec::Vec, - /// The path through the Merkle tree of identifiers of chunks of the - /// corresponding transaction; from the chunk being proven to the - /// corresponding `data_root`. - #[prost(bytes = "vec", tag = "3")] - pub data_path: ::prost::alloc::vec::Vec, - /// The data chunk. - #[prost(bytes = "vec", tag = "4")] - pub chunk: ::prost::alloc::vec::Vec, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Transaction { - /// 1 or 2 for v1 or v2 transactions. More allowable in the future - #[prost(uint32, tag = "1")] - pub format: u32, - /// The transaction identifier. - #[prost(bytes = "vec", tag = "2")] - pub id: ::prost::alloc::vec::Vec, - /// Either the identifier of the previous transaction from the same - /// wallet or the identifier of one of the last ?MAX_TX_ANCHOR_DEPTH blocks. - #[prost(bytes = "vec", tag = "3")] - pub last_tx: ::prost::alloc::vec::Vec, - /// The public key the transaction is signed with. - #[prost(bytes = "vec", tag = "4")] - pub owner: ::prost::alloc::vec::Vec, - /// A list of arbitrary key-value pairs - #[prost(message, repeated, tag = "5")] - pub tags: ::prost::alloc::vec::Vec, - /// The address of the recipient; if any. The SHA2-256 hash of the public key. - #[prost(bytes = "vec", tag = "6")] - pub target: ::prost::alloc::vec::Vec, - /// The amount of Winstons to send to the recipient; if any. - #[prost(message, optional, tag = "7")] - pub quantity: ::core::option::Option, - /// The data to upload; if any. For v2 transactions; the field is optional - /// - a fee is charged based on the `data_size` field; - /// data may be uploaded any time later in chunks. - #[prost(bytes = "vec", tag = "8")] - pub data: ::prost::alloc::vec::Vec, - /// Size in bytes of the transaction data. - #[prost(message, optional, tag = "9")] - pub data_size: ::core::option::Option, - /// The Merkle root of the Merkle tree of data chunks. - #[prost(bytes = "vec", tag = "10")] - pub data_root: ::prost::alloc::vec::Vec, - /// The signature. - #[prost(bytes = "vec", tag = "11")] - pub signature: ::prost::alloc::vec::Vec, - /// The fee in Winstons. - #[prost(message, optional, tag = "12")] - pub reward: ::core::option::Option, -} -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct Tag { - #[prost(bytes = "vec", tag = "1")] - pub name: ::prost::alloc::vec::Vec, - #[prost(bytes = "vec", tag = "2")] - pub value: ::prost::alloc::vec::Vec, -} diff --git a/chain/arweave/src/runtime/abi.rs b/chain/arweave/src/runtime/abi.rs deleted file mode 100644 index 616cfa70b8c..00000000000 --- a/chain/arweave/src/runtime/abi.rs +++ /dev/null @@ -1,191 +0,0 @@ -use crate::codec; -use crate::trigger::TransactionWithBlockPtr; -use graph::runtime::gas::GasCounter; -use graph::runtime::{asc_new, AscHeap, AscPtr, HostExportError, ToAscObj}; -use graph_runtime_wasm::asc_abi::class::{Array, Uint8Array}; - -pub(crate) use super::generated::*; - -impl ToAscObj for codec::Tag { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - Ok(AscTag { - name: asc_new(heap, self.name.as_slice(), gas)?, - value: asc_new(heap, self.value.as_slice(), gas)?, - }) - } -} - -impl ToAscObj for Vec> { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - let content = self - .iter() - .map(|x| asc_new(heap, x.as_slice(), gas)) - .collect::>, _>>()?; - Ok(AscTransactionArray(Array::new(&content, heap, gas)?)) - } -} - -impl ToAscObj for Vec { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - let content = self - .iter() - .map(|x| asc_new(heap, x, gas)) - .collect::, _>>()?; - Ok(AscTagArray(Array::new(&content, heap, gas)?)) - } -} - -impl ToAscObj for codec::ProofOfAccess { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - Ok(AscProofOfAccess { - option: asc_new(heap, &self.option, gas)?, - tx_path: asc_new(heap, self.tx_path.as_slice(), gas)?, - data_path: asc_new(heap, self.data_path.as_slice(), gas)?, - chunk: asc_new(heap, self.chunk.as_slice(), gas)?, - }) - } -} - -impl ToAscObj for codec::Transaction { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - Ok(AscTransaction { - format: self.format, - id: asc_new(heap, self.id.as_slice(), gas)?, - last_tx: asc_new(heap, self.last_tx.as_slice(), gas)?, - owner: asc_new(heap, self.owner.as_slice(), gas)?, - tags: asc_new(heap, &self.tags, gas)?, - target: asc_new(heap, self.target.as_slice(), gas)?, - quantity: asc_new( - heap, - self.quantity - .as_ref() - .map(|b| b.as_ref()) - .unwrap_or_default(), - gas, - )?, - data: asc_new(heap, self.data.as_slice(), gas)?, - data_size: asc_new( - heap, - self.data_size - .as_ref() - .map(|b| b.as_ref()) - .unwrap_or_default(), - gas, - )?, - data_root: asc_new(heap, self.data_root.as_slice(), gas)?, - signature: asc_new(heap, self.signature.as_slice(), gas)?, - reward: asc_new( - heap, - self.reward.as_ref().map(|b| b.as_ref()).unwrap_or_default(), - gas, - )?, - }) - } -} - -impl ToAscObj for codec::Block { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - Ok(AscBlock { - indep_hash: asc_new(heap, self.indep_hash.as_slice(), gas)?, - nonce: asc_new(heap, self.nonce.as_slice(), gas)?, - previous_block: asc_new(heap, self.previous_block.as_slice(), gas)?, - timestamp: self.timestamp, - last_retarget: self.last_retarget, - diff: asc_new( - heap, - self.diff.as_ref().map(|b| b.as_ref()).unwrap_or_default(), - gas, - )?, - height: self.height, - hash: asc_new(heap, self.hash.as_slice(), gas)?, - tx_root: asc_new(heap, self.tx_root.as_slice(), gas)?, - txs: asc_new( - heap, - &self - .txs - .iter() - .map(|tx| tx.id.clone()) - .collect::>>(), - gas, - )?, - wallet_list: asc_new(heap, self.wallet_list.as_slice(), gas)?, - reward_addr: asc_new(heap, self.reward_addr.as_slice(), gas)?, - tags: asc_new(heap, &self.tags, gas)?, - reward_pool: asc_new( - heap, - self.reward_pool - .as_ref() - .map(|b| b.as_ref()) - .unwrap_or_default(), - gas, - )?, - weave_size: asc_new( - heap, - self.weave_size - .as_ref() - .map(|b| b.as_ref()) - .unwrap_or_default(), - gas, - )?, - block_size: asc_new( - heap, - self.block_size - .as_ref() - .map(|b| b.as_ref()) - .unwrap_or_default(), - gas, - )?, - cumulative_diff: asc_new( - heap, - self.cumulative_diff - .as_ref() - .map(|b| b.as_ref()) - .unwrap_or_default(), - gas, - )?, - hash_list_merkle: asc_new(heap, self.hash_list_merkle.as_slice(), gas)?, - poa: self - .poa - .as_ref() - .map(|poa| asc_new(heap, poa, gas)) - .unwrap_or(Ok(AscPtr::null()))?, - }) - } -} - -impl ToAscObj for TransactionWithBlockPtr { - fn to_asc_obj( - &self, - heap: &mut H, - gas: &GasCounter, - ) -> Result { - Ok(AscTransactionWithBlockPtr { - tx: asc_new(heap, &self.tx.as_ref(), gas)?, - block: asc_new(heap, self.block.as_ref(), gas)?, - }) - } -} diff --git a/chain/arweave/src/runtime/generated.rs b/chain/arweave/src/runtime/generated.rs deleted file mode 100644 index e8a10fdb158..00000000000 --- a/chain/arweave/src/runtime/generated.rs +++ /dev/null @@ -1,128 +0,0 @@ -use graph::runtime::{AscIndexId, AscPtr, AscType, DeterministicHostError, IndexForAscTypeId}; -use graph::semver::Version; -use graph_runtime_derive::AscType; -use graph_runtime_wasm::asc_abi::class::{Array, AscString, Uint8Array}; - -#[repr(C)] -#[derive(AscType, Default)] -pub struct AscBlock { - pub timestamp: u64, - pub last_retarget: u64, - pub height: u64, - pub indep_hash: AscPtr, - pub nonce: AscPtr, - pub previous_block: AscPtr, - pub diff: AscPtr, - pub hash: AscPtr, - pub tx_root: AscPtr, - pub txs: AscPtr, - pub wallet_list: AscPtr, - pub reward_addr: AscPtr, - pub tags: AscPtr, - pub reward_pool: AscPtr, - pub weave_size: AscPtr, - pub block_size: AscPtr, - pub cumulative_diff: AscPtr, - pub hash_list_merkle: AscPtr, - pub poa: AscPtr, -} - -impl AscIndexId for AscBlock { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveBlock; -} - -#[repr(C)] -#[derive(AscType)] -pub struct AscProofOfAccess { - pub option: AscPtr, - pub tx_path: AscPtr, - pub data_path: AscPtr, - pub chunk: AscPtr, -} - -impl AscIndexId for AscProofOfAccess { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveProofOfAccess; -} - -#[repr(C)] -#[derive(AscType)] -pub struct AscTransaction { - pub format: u32, - pub id: AscPtr, - pub last_tx: AscPtr, - pub owner: AscPtr, - pub tags: AscPtr, - pub target: AscPtr, - pub quantity: AscPtr, - pub data: AscPtr, - pub data_size: AscPtr, - pub data_root: AscPtr, - pub signature: AscPtr, - pub reward: AscPtr, -} - -impl AscIndexId for AscTransaction { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveTransaction; -} - -#[repr(C)] -#[derive(AscType)] -pub struct AscTag { - pub name: AscPtr, - pub value: AscPtr, -} - -impl AscIndexId for AscTag { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveTag; -} - -#[repr(C)] -pub struct AscTransactionArray(pub(crate) Array>); - -impl AscType for AscTransactionArray { - fn to_asc_bytes(&self) -> Result, DeterministicHostError> { - self.0.to_asc_bytes() - } - - fn from_asc_bytes( - asc_obj: &[u8], - api_version: &Version, - ) -> Result { - Ok(Self(Array::from_asc_bytes(asc_obj, api_version)?)) - } -} - -impl AscIndexId for AscTransactionArray { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveTransactionArray; -} - -#[repr(C)] -pub struct AscTagArray(pub(crate) Array>); - -impl AscType for AscTagArray { - fn to_asc_bytes(&self) -> Result, DeterministicHostError> { - self.0.to_asc_bytes() - } - - fn from_asc_bytes( - asc_obj: &[u8], - api_version: &Version, - ) -> Result { - Ok(Self(Array::from_asc_bytes(asc_obj, api_version)?)) - } -} - -impl AscIndexId for AscTagArray { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveTagArray; -} - -#[repr(C)] -#[derive(AscType)] -pub struct AscTransactionWithBlockPtr { - pub tx: AscPtr, - pub block: AscPtr, -} - -impl AscIndexId for AscTransactionWithBlockPtr { - const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::ArweaveTransactionWithBlockPtr; -} diff --git a/chain/arweave/src/runtime/mod.rs b/chain/arweave/src/runtime/mod.rs deleted file mode 100644 index 31e18de7dd8..00000000000 --- a/chain/arweave/src/runtime/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod abi; - -mod generated; diff --git a/chain/arweave/src/trigger.rs b/chain/arweave/src/trigger.rs deleted file mode 100644 index 186bb857009..00000000000 --- a/chain/arweave/src/trigger.rs +++ /dev/null @@ -1,144 +0,0 @@ -use graph::blockchain::Block; -use graph::blockchain::MappingTriggerTrait; -use graph::blockchain::TriggerData; -use graph::derive::CheapClone; -use graph::prelude::web3::types::H256; -use graph::prelude::BlockNumber; -use graph::runtime::asc_new; -use graph::runtime::gas::GasCounter; -use graph::runtime::AscHeap; -use graph::runtime::AscPtr; -use graph::runtime::HostExportError; -use graph_runtime_wasm::module::ToAscPtr; -use std::{cmp::Ordering, sync::Arc}; - -use crate::codec; - -// Logging the block is too verbose, so this strips the block from the trigger for Debug. -impl std::fmt::Debug for ArweaveTrigger { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - #[allow(unused)] - #[derive(Debug)] - pub enum MappingTriggerWithoutBlock { - Block, - Transaction(Arc), - } - - let trigger_without_block = match self { - ArweaveTrigger::Block(_) => MappingTriggerWithoutBlock::Block, - ArweaveTrigger::Transaction(tx) => { - MappingTriggerWithoutBlock::Transaction(tx.tx.clone()) - } - }; - - write!(f, "{:?}", trigger_without_block) - } -} - -impl ToAscPtr for ArweaveTrigger { - fn to_asc_ptr( - self, - heap: &mut H, - gas: &GasCounter, - ) -> Result, HostExportError> { - Ok(match self { - ArweaveTrigger::Block(block) => asc_new(heap, block.as_ref(), gas)?.erase(), - ArweaveTrigger::Transaction(tx) => asc_new(heap, tx.as_ref(), gas)?.erase(), - }) - } -} - -#[derive(Clone, CheapClone)] -pub enum ArweaveTrigger { - Block(Arc), - Transaction(Arc), -} - -impl PartialEq for ArweaveTrigger { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::Block(a_ptr), Self::Block(b_ptr)) => a_ptr == b_ptr, - (Self::Transaction(a_tx), Self::Transaction(b_tx)) => a_tx.tx.id == b_tx.tx.id, - _ => false, - } - } -} - -impl Eq for ArweaveTrigger {} - -impl ArweaveTrigger { - pub fn block_number(&self) -> BlockNumber { - match self { - ArweaveTrigger::Block(block) => block.number(), - ArweaveTrigger::Transaction(tx) => tx.block.number(), - } - } - - pub fn block_hash(&self) -> H256 { - match self { - ArweaveTrigger::Block(block) => block.ptr().hash_as_h256(), - ArweaveTrigger::Transaction(tx) => tx.block.ptr().hash_as_h256(), - } - } - - fn error_context(&self) -> std::string::String { - match self { - ArweaveTrigger::Block(..) => { - format!("Block #{} ({})", self.block_number(), self.block_hash()) - } - ArweaveTrigger::Transaction(tx) => { - format!( - "Tx #{}, block #{}({})", - base64_url::encode(&tx.tx.id), - self.block_number(), - self.block_hash() - ) - } - } - } -} - -impl Ord for ArweaveTrigger { - fn cmp(&self, other: &Self) -> Ordering { - match (self, other) { - // Keep the order when comparing two block triggers - (Self::Block(..), Self::Block(..)) => Ordering::Equal, - - // Block triggers always come last - (Self::Block(..), _) => Ordering::Greater, - (_, Self::Block(..)) => Ordering::Less, - - // Execution outcomes have no intrinsic ordering information so we keep the order in - // which they are included in the `txs` field of `Block`. - (Self::Transaction(..), Self::Transaction(..)) => Ordering::Equal, - } - } -} - -impl PartialOrd for ArweaveTrigger { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl TriggerData for ArweaveTrigger { - fn error_context(&self) -> String { - self.error_context() - } - - fn address_match(&self) -> Option<&[u8]> { - None - } -} - -impl MappingTriggerTrait for ArweaveTrigger { - fn error_context(&self) -> String { - self.error_context() - } -} - -pub struct TransactionWithBlockPtr { - // REVIEW: Do we want to actually also have those two below behind an `Arc` wrapper? - pub tx: Arc, - pub block: Arc, -} diff --git a/core/Cargo.toml b/core/Cargo.toml index 4140b37ffbe..1aa8ad94d16 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -8,9 +8,6 @@ async-trait = "0.1.50" atomic_refcell = "0.1.13" bytes = "1.0" graph = { path = "../graph" } -# This dependency is temporary. The multiblockchain refactoring is not -# finished as long as this dependency exists -graph-chain-arweave = { path = "../chain/arweave" } graph-chain-ethereum = { path = "../chain/ethereum" } graph-chain-near = { path = "../chain/near" } graph-chain-substreams = { path = "../chain/substreams" } diff --git a/core/src/subgraph/instance_manager.rs b/core/src/subgraph/instance_manager.rs index 8c2b76e5b6c..9ca3430a5fb 100644 --- a/core/src/subgraph/instance_manager.rs +++ b/core/src/subgraph/instance_manager.rs @@ -79,21 +79,6 @@ impl SubgraphInstanceManagerTrait for SubgraphInstanceManager< async move { match BlockchainKind::from_manifest(&manifest)? { - BlockchainKind::Arweave => { - let runner = instance_manager - .build_subgraph_runner::( - logger.clone(), - self.env_vars.cheap_clone(), - loc.clone(), - manifest, - stop_block, - Box::new(SubgraphTriggerProcessor {}), - deployment_status_metric, - ) - .await?; - - self.start_subgraph_inner(logger, loc, runner).await - } BlockchainKind::Ethereum => { let runner = instance_manager .build_subgraph_runner::( diff --git a/core/src/subgraph/registrar.rs b/core/src/subgraph/registrar.rs index 3a712b6daa9..f0b8107b18f 100644 --- a/core/src/subgraph/registrar.rs +++ b/core/src/subgraph/registrar.rs @@ -313,24 +313,6 @@ where history_blocks.or(self.settings.for_name(&name).map(|c| c.history_blocks)); let deployment_locator = match kind { - BlockchainKind::Arweave => { - create_subgraph_version::( - &logger, - self.store.clone(), - self.chains.cheap_clone(), - name.clone(), - hash.cheap_clone(), - start_block_override, - graft_block_override, - raw, - node_id, - debug_fork, - self.version_switching_mode, - &self.resolver, - history_blocks, - ) - .await? - } BlockchainKind::Ethereum => { create_subgraph_version::( &logger, diff --git a/graph/src/blockchain/mod.rs b/graph/src/blockchain/mod.rs index 25a7d147540..84c1d42688c 100644 --- a/graph/src/blockchain/mod.rs +++ b/graph/src/blockchain/mod.rs @@ -556,9 +556,6 @@ pub trait NodeCapabilities { #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum BlockchainKind { - /// Arweave chains that are compatible. - Arweave, - /// Ethereum itself or chains that are compatible. Ethereum, @@ -571,7 +568,6 @@ pub enum BlockchainKind { impl fmt::Display for BlockchainKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let value = match self { - BlockchainKind::Arweave => "arweave", BlockchainKind::Ethereum => "ethereum", BlockchainKind::Near => "near", BlockchainKind::Substreams => "substreams", @@ -585,7 +581,6 @@ impl FromStr for BlockchainKind { fn from_str(s: &str) -> Result { match s { - "arweave" => Ok(BlockchainKind::Arweave), "ethereum" => Ok(BlockchainKind::Ethereum), "near" => Ok(BlockchainKind::Near), "substreams" => Ok(BlockchainKind::Substreams), diff --git a/node/Cargo.toml b/node/Cargo.toml index 444b18784fc..2e8e947476c 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -22,7 +22,6 @@ lazy_static = "1.5.0" url = "2.5.4" graph = { path = "../graph" } graph-core = { path = "../core" } -graph-chain-arweave = { path = "../chain/arweave" } graph-chain-ethereum = { path = "../chain/ethereum" } graph-chain-near = { path = "../chain/near" } graph-chain-substreams = { path = "../chain/substreams" } diff --git a/node/src/chain.rs b/node/src/chain.rs index 4ff45b8211a..a57d294f5c3 100644 --- a/node/src/chain.rs +++ b/node/src/chain.rs @@ -388,35 +388,6 @@ pub async fn networks_as_chains( } match kind { - BlockchainKind::Arweave => { - let firehose_endpoints = networks.firehose_endpoints(chain_id.clone()); - - blockchain_map.insert::( - chain_id.clone(), - Arc::new( - BasicBlockchainBuilder { - logger_factory: logger_factory.clone(), - name: chain_id.clone(), - chain_store: chain_store.cheap_clone(), - firehose_endpoints, - metrics_registry: metrics_registry.clone(), - } - .build(config) - .await, - ), - ); - - add_substreams::( - networks, - config, - chain_id.clone(), - blockchain_map, - logger_factory.clone(), - chain_store, - metrics_registry.clone(), - ) - .await; - } BlockchainKind::Ethereum => { // polling interval is set per chain so if set all adapter configuration will have // the same value. diff --git a/node/src/network_setup.rs b/node/src/network_setup.rs index 1ebe2b5109c..d3ffbb8f4ae 100644 --- a/node/src/network_setup.rs +++ b/node/src/network_setup.rs @@ -327,10 +327,6 @@ impl Networks { let mut res = vec![]; for ((kind, id), chain) in blockchain_map.iter() { match kind { - BlockchainKind::Arweave => { - block_ingestor::(logger, id, chain, &mut res) - .await? - } BlockchainKind::Ethereum => { block_ingestor::(logger, id, chain, &mut res) .await? diff --git a/server/index-node/Cargo.toml b/server/index-node/Cargo.toml index 72b7ff869f7..033f599ed70 100644 --- a/server/index-node/Cargo.toml +++ b/server/index-node/Cargo.toml @@ -7,7 +7,6 @@ edition.workspace = true blake3 = "1.6" graph = { path = "../../graph" } graph-graphql = { path = "../../graphql" } -graph-chain-arweave = { path = "../../chain/arweave" } graph-chain-ethereum = { path = "../../chain/ethereum" } graph-chain-near = { path = "../../chain/near" } graph-chain-substreams = { path = "../../chain/substreams" } diff --git a/server/index-node/src/resolver.rs b/server/index-node/src/resolver.rs index 7974afe41db..e8bd7260508 100644 --- a/server/index-node/src/resolver.rs +++ b/server/index-node/src/resolver.rs @@ -540,23 +540,6 @@ impl IndexNodeResolver { ) .await? } - BlockchainKind::Arweave => { - let unvalidated_subgraph_manifest = - UnvalidatedSubgraphManifest::::resolve( - deployment_hash.clone(), - raw_yaml, - &self.link_resolver, - &self.logger, - max_spec_version, - ) - .await?; - - Self::validate_and_extract_features( - &self.store.subgraph_store(), - unvalidated_subgraph_manifest, - ) - .await? - } BlockchainKind::Substreams => { let unvalidated_subgraph_manifest = UnvalidatedSubgraphManifest::::resolve( @@ -680,7 +663,6 @@ impl IndexNodeResolver { // Ugly, but we can't get back an object trait from the `BlockchainMap`, // so this seems like the next best thing. try_resolve_for_chain!(graph_chain_ethereum::Chain); - try_resolve_for_chain!(graph_chain_arweave::Chain); try_resolve_for_chain!(graph_chain_near::Chain); // If you're adding support for a new chain and this `match` clause just @@ -689,10 +671,7 @@ impl IndexNodeResolver { // type. match BlockchainKind::Ethereum { // Note: we don't actually care about substreams here. - BlockchainKind::Substreams - | BlockchainKind::Arweave - | BlockchainKind::Ethereum - | BlockchainKind::Near => (), + BlockchainKind::Substreams | BlockchainKind::Ethereum | BlockchainKind::Near => (), } // The given network does not exist.