Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
31de8f5
feat(chain): init arweave from near
clearloop Apr 11, 2022
a7fa3fb
feat(chain): add arweave runtime abi
clearloop Apr 11, 2022
9b39306
feat(chain): add runtime abi for arweave block
clearloop Apr 11, 2022
ebfb4e1
feat(chain): implement BlockChain trait for Arweave
clearloop Apr 11, 2022
46d5a55
chore(subgraph): register arweave
clearloop Apr 13, 2022
6fbd820
chore(index-node): register arweave
clearloop Apr 13, 2022
770269d
feat(chain): use BigInt instead of number string in Arweave proto
clearloop Apr 13, 2022
ef16c8e
chore(node): register arweave
clearloop Apr 17, 2022
db0c533
feat(chain): add TransactionArray in arweave abi
clearloop Apr 20, 2022
fedccc8
workaround(blockchain)!: hack the block hash of arweave
clearloop Apr 20, 2022
ebf29b1
workaround(store)!: hack the block hash of arweave
clearloop Apr 21, 2022
a9dadb4
feat(node): update logs for arweave
clearloop Apr 21, 2022
8608952
docs(workaround)!: add FIXME
clearloop Apr 21, 2022
c1ed6a0
Merge branch 'master' into cs/arweave
clearloop Apr 21, 2022
c3f2a29
feat(chain): update TriggersAdapter in Arweave
clearloop Apr 26, 2022
cf7bf56
chore(chain): fix typos in arweave implementation
clearloop Apr 27, 2022
182779f
chore(chain): add gitignore in the arweave implementation
clearloop Apr 27, 2022
ae9c56a
feat(chain): add transaction filter for arweave
clearloop Apr 27, 2022
8da341d
Merge branch 'graphprotocol:master' into cs/arweave
clearloop May 6, 2022
770097e
feat(chain): update the tonic version in arweave
clearloop May 6, 2022
4898c65
chore(chain): skip fmt check for the generated proto file of arweave
clearloop May 6, 2022
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
31 changes: 31 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions chain/arweave/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
google.protobuf.rs
24 changes: 24 additions & 0 deletions chain/arweave/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "graph-chain-arweave"
version = "0.26.0"
edition = "2021"

[build-dependencies]
tonic-build = { version = "0.7.1", features = ["prost"]}

[dependencies]
base64-url = "1.4.13"
graph = { path = "../../graph" }
prost = "0.10.1"
prost-types = "0.10.1"
serde = "1.0"

graph-runtime-wasm = { path = "../../runtime/wasm" }
graph-runtime-derive = { path = "../../runtime/derive" }

[dev-dependencies]
diesel = { version = "1.4.7", features = ["postgres", "serde_json", "numeric", "r2d2"] }
graph-core = { path = "../../core" }
graph-store-postgres = { path = "../../store/postgres" }
pretty_assertions = "0.7.2"
test-store = { path = "../../store/test-store" }
7 changes: 7 additions & 0 deletions chain/arweave/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
println!("cargo:rerun-if-changed=proto");
tonic_build::configure()
.out_dir("src/protobuf")
.compile(&["proto/type.proto"], &["proto"])
.expect("Failed to compile Firehose Arweave proto(s)");
}
108 changes: 108 additions & 0 deletions chain/arweave/proto/type.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
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;
}
92 changes: 92 additions & 0 deletions chain/arweave/src/adapter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::capabilities::NodeCapabilities;
use crate::{data_source::DataSource, Chain};
use graph::blockchain as bc;
use graph::prelude::*;
use std::collections::HashSet;

#[derive(Clone, Debug, Default)]
pub struct TriggerFilter {
pub(crate) block_filter: ArweaveBlockFilter,
pub(crate) transaction_filter: ArweaveTransactionFilter,
}

impl bc::TriggerFilter<Chain> for TriggerFilter {
fn extend<'a>(&mut self, data_sources: impl Iterator<Item = &'a DataSource> + 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) -> NodeCapabilities {
NodeCapabilities {}
}

fn extend_with_template(
&mut self,
_data_source: impl Iterator<Item = <Chain as bc::Blockchain>::DataSourceTemplate>,
) {
}

fn to_firehose_filter(self) -> Vec<prost_types::Any> {
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: HashSet<Vec<u8>>,
}

impl ArweaveTransactionFilter {
pub fn matches(&self, owner: &[u8]) -> bool {
self.owners.contains(owner)
}

pub fn from_data_sources<'a>(iter: impl IntoIterator<Item = &'a DataSource>) -> Self {
let owners: Vec<Vec<u8>> = iter
.into_iter()
.filter(|data_source| {
data_source.source.owner.is_some()
&& !data_source.mapping.transaction_handlers.is_empty()
})
.map(|ds| {
base64_url::decode(&ds.source.owner.clone().unwrap_or_default()).unwrap_or_default()
})
.collect();

Self {
owners: HashSet::from_iter(owners),
}
}

pub fn extend(&mut self, other: ArweaveTransactionFilter) {
self.owners.extend(other.owners);
}
}

/// 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<Item = &'a DataSource>) -> 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;
}
}
37 changes: 37 additions & 0 deletions chain/arweave/src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use graph::{anyhow::Error, impl_slog_value};
use std::cmp::{Ordering, PartialOrd};
use std::fmt;
use std::str::FromStr;

use crate::data_source::DataSource;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct NodeCapabilities {}

impl PartialOrd for NodeCapabilities {
fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
None
}
}

impl FromStr for NodeCapabilities {
type Err = Error;

fn from_str(_s: &str) -> Result<Self, Self::Err> {
Ok(NodeCapabilities {})
}
}

impl fmt::Display for NodeCapabilities {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("arweave")
}
}

impl_slog_value!(NodeCapabilities, "{}");

impl graph::blockchain::NodeCapabilities<crate::Chain> for NodeCapabilities {
fn from_data_sources(_data_sources: &[DataSource]) -> Self {
NodeCapabilities {}
}
}
Loading