Skip to content

Commit

Permalink
feat: subgraph deployment feature parity (#58)
Browse files Browse the repository at this point in the history
* feat: subgraph deployment feature parity

* fix: substreams graph remove keyword en
  • Loading branch information
sahra-karakoc authored Sep 27, 2023
1 parent 4fa37f2 commit eef2782
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 63 deletions.
7 changes: 7 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ substreams-entity-change = "1.3.0"
num-bigint = "0.4"
bigdecimal = "0.4.1"
tiny-keccak = "2.0.2"
base58 = "0.2.0"

[build-dependencies]
anyhow = "1"
Expand Down
40 changes: 27 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# Graph Network Subgraph fed by Substreams

Substreams based Graph Network subgraph and substreams.
Substreams based Graph Network subgraph and substreams.

[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

## Introduction
## Introduction

This project is a [subgraph](https://thegraph.com/docs/en/developing/creating-a-subgraph/) fed by [substreams](https://substreams.streamingfast.io/) that allows you to obtain data for The Graph Network.
This project is a [subgraph](https://thegraph.com/docs/en/developing/creating-a-subgraph/) fed by [substreams](https://substreams.streamingfast.io/) that allows you to obtain data for The Graph Network.

## Features
## Features

### Available Data
### Available Data

This subgraph makes available the following data:
- Total supply, total mints and burns of GRT,

- Total supply, total mints and burns of GRT,
- GRT balances of addresses
- In-protocol balances like indexer, delegator and curator stakes
- In-protocol balances like indexer, delegator and curator stakes

### Substreams Module Graph

Here is the graph of the modules of the substreams:
Here is the graph of the modules of the substreams:

```mermaid
graph LR;
Expand Down Expand Up @@ -57,6 +58,10 @@ graph LR;
map_events --> store_cumulative_curator_signalled;
store_subgraph_deployment_id[store: store_subgraph_deployment_id];
map_events --> store_subgraph_deployment_id;
store_subgraph_deployment_ipfs_hash[store: store_subgraph_deployment_ipfs_hash];
map_events --> store_subgraph_deployment_ipfs_hash;
store_subgraph_deployment_id[store: store_subgraph_deployment_id];
map_events --> store_subgraph_deployment_id;
store_cumulative_curator_burned[store: store_cumulative_curator_burned];
map_events --> store_cumulative_curator_burned;
store_query_fee_rebates[store: store_query_fee_rebates];
Expand Down Expand Up @@ -119,28 +124,37 @@ graph LR;
store_curator_rewards -- deltas --> graph_out;
store_signal_amount -- deltas --> graph_out;
store_subgraph_deployment_rewards -- deltas --> graph_out;
store_subgraph_deployment_ipfs_hash -- deltas --> graph_out;
map_indexing_rewards --> graph_out;
```

## Quickstart
To build and run the substream,

To build and run the substream,

1. [Install dependencies](https://substreams.streamingfast.io/developers-guide/installation-requirements).
2. [Get authentication](https://substreams.streamingfast.io/reference-and-specs/authentication).
3. Clone this repo

```console
git clone https://github.com/graphops/graph-network-substreams.git
```
4. Code gen with

4. Code gen with

```console
substreams protogen ./substreams.yaml
```
5. Build the substream with
```

5. Build the substream with

```console
cargo build --target wasm32-unknown-unknown --release
```
```

6. Run the graph_out module with

```console
substreams run -e mainnet.eth.streamingfast.io:443 \
substreams.yaml \
Expand Down
11 changes: 11 additions & 0 deletions proto/erc20.proto
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ message EpochLengthUpdatedEvents {
repeated EpochLengthUpdated epoch_length_updated_events = 1;
}

message RewardsDenyListUpdatedEvents {
repeated RewardsDenyListUpdated rewards_deny_list_updated_events = 1;
}

message IndexerStakes {
repeated IndexerStake indexer_stakes = 1;
}
Expand Down Expand Up @@ -119,6 +123,7 @@ message Events {
PauseChangedEvents pause_changed_events = 14;
PartialPauseChangedEvents partial_pause_changed_events = 15;
EpochLengthUpdatedEvents epoch_length_updated_events = 16;
RewardsDenyListUpdatedEvents rewards_deny_list_updated_events = 17;
}

message Transfer {
Expand Down Expand Up @@ -276,6 +281,12 @@ message EpochLengthUpdated {
uint64 ordinal = 4;
}

message RewardsDenyListUpdated {
string id = 1;
string denied_at = 2;
uint64 ordinal = 3;
}

message IndexerStake {
string id = 1;
bytes indexer = 2;
Expand Down
2 changes: 2 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ type SubgrapDeployment @entity {
id: ID!
"CURRENT total stake of all indexers on this Subgraph Deployment"
stakedTokens: BigInt!
"Allocations created by indexers for this Subgraph"
indexerAllocations: [Allocation!]! @derivedFrom(field: "subgraphDeployment")
"CURRENT signalled tokens in the bonding curve"
signalledTokens: BigInt!
"CURRENT curation signal for this subgraph deployment"
Expand Down
24 changes: 24 additions & 0 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,37 @@ pub fn graph_account_change(
}

pub fn subgraph_deployment_change(
events: Events,
subgraph_allocations: SubgraphAllocations,
curation_pools: CurationPools,
subgraph_deployment_rewards_deltas: Deltas<DeltaBigInt>,
curator_fee_rewards_deltas: Deltas<DeltaBigInt>,
signal_amount_deltas: Deltas<DeltaBigInt>,
ipfs_hash_deltas: Deltas<DeltaString>,
entity_changes: &mut EntityChanges,
) {
let rewards_denied_events = events.rewards_deny_list_updated_events.unwrap();
for rewards_denied in rewards_denied_events.rewards_deny_list_updated_events {
entity_changes
.push_change(
"SubgraphDeployment",
&rewards_denied.id,
rewards_denied.ordinal,
Operation::Update,
)
.change("deniedAt", rewards_denied.denied_at);
}
for delta in ipfs_hash_deltas.deltas {
entity_changes
.push_change(
"SubgraphDeployment",
&delta.key,
delta.ordinal,
Operation::Update,
)
.change("ipfsHash", delta)
.change("deniedAt", "0".to_string());
}
for subgraph_allocation in subgraph_allocations.subgraph_allocations {
entity_changes
.push_change(
Expand Down
4 changes: 3 additions & 1 deletion src/modules/graph_out.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use substreams::{
pb::substreams::Clock,
store::{DeltaBigInt, DeltaString, Deltas},
};

use substreams_entity_change::pb::entity::EntityChanges;

// -------------------- GRAPH_OUT --------------------
Expand Down Expand Up @@ -40,6 +39,7 @@ pub fn graph_out(
curator_rewards_deltas: Deltas<DeltaBigInt>,
signal_amount_deltas: Deltas<DeltaBigInt>,
subgraph_deployment_rewards_deltas: Deltas<DeltaBigInt>,
subgraph_deployment_ipfs_hash_deltas: Deltas<DeltaString>,
indexing_rewards: IndexingRewards,
) -> Result<EntityChanges, substreams::errors::Error> {
let mut graph_network_entity_changes: EntityChanges = Default::default();
Expand Down Expand Up @@ -89,11 +89,13 @@ pub fn graph_out(
let subgraph_allocations = storage_changes.subgraph_allocations.unwrap();
let curation_pools = storage_changes.curation_pools.unwrap();
db::subgraph_deployment_change(
events.clone(),
subgraph_allocations,
curation_pools,
subgraph_deployment_rewards_deltas,
curator_fee_rewards_deltas,
signal_amount_deltas,
subgraph_deployment_ipfs_hash_deltas,
&mut subgraph_deployment_entity_changes,
);

Expand Down
20 changes: 16 additions & 4 deletions src/modules/init_maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ fn map_events(blk: eth::Block) -> Result<Events, Error> {
let mut pause_changed_events = vec![];
let mut partial_pause_changed_events = vec![];
let mut epoch_length_updated_events = vec![];
let mut rewards_deny_list_updated_events = vec![];

// Potentially consider adding log.index() to the IDs, to have them be truly unique in
// transactions with potentially more than 1 of these messages
Expand Down Expand Up @@ -464,6 +465,16 @@ fn map_events(blk: eth::Block) -> Result<Events, Error> {
amount: event.amount.to_string(), // Tokens is origanally BigInt but proto does not have BigInt so we use string
ordinal: log.ordinal() as u64,
});
} else if let Some(event) =
abi::rewards_manager::events::RewardsDenylistUpdated::match_and_decode(log)
{
if event.since_block != BigInt::zero() {
rewards_deny_list_updated_events.push(RewardsDenyListUpdated {
id: Hex(&log.receipt.transaction.hash).to_string(), // Each event needs a unique id
denied_at: event.since_block.to_string(),
ordinal: log.ordinal() as u64,
});
}
} else if let Some(event) = abi::curation::events::Signalled::match_and_decode(log) {
signalled_events.push(Signalled {
id: Hex(&log.receipt.transaction.hash).to_string(), // Each event needs a unique id
Expand Down Expand Up @@ -499,14 +510,13 @@ fn map_events(blk: eth::Block) -> Result<Events, Error> {
})
} else if let Some(event) =
abi::epoch_manager::events::EpochLengthUpdate::match_and_decode(log)
{
epoch_length_updated_events.push(EpochLengthUpdated{
{
epoch_length_updated_events.push(EpochLengthUpdated {
id: Hex(&log.receipt.transaction.hash).to_string(),
last_length_update_block: blk.number.to_string(),
epoch_length: event.epoch_length.to_string(),
ordinal: log.ordinal() as u64,
})

}
}

Expand Down Expand Up @@ -562,6 +572,8 @@ fn map_events(blk: eth::Block) -> Result<Events, Error> {
events.epoch_length_updated_events = Some(EpochLengthUpdatedEvents {
epoch_length_updated_events: epoch_length_updated_events,
});

events.rewards_deny_list_updated_events = Some(RewardsDenyListUpdatedEvents {
rewards_deny_list_updated_events: rewards_deny_list_updated_events,
});
Ok(events)
}
15 changes: 14 additions & 1 deletion src/modules/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ fn store_total_delegated_stakes(storage_changes: StorageChanges, s: StoreAddBigI
}
}

// Indexer and GraphNetwork entities track the total delegated stake, not the cumulative amount
#[substreams::handlers::store]
fn store_subgraph_deployment_id(events: Events, s: StoreSetString) {
let allocation_created_events = events.allocation_created_events.unwrap();
Expand All @@ -147,6 +146,20 @@ fn store_subgraph_deployment_id(events: Events, s: StoreSetString) {
);
}
}

#[substreams::handlers::store]
fn store_subgraph_deployment_ipfs_hash(events: Events, s: StoreSetIfNotExistsString) {
let allocation_created_events = events.allocation_created_events.unwrap();

for allocation_created in allocation_created_events.allocation_created_events {
s.set_if_not_exists(
allocation_created.ordinal,
&Hex(&allocation_created.subgraph_deployment_id).to_string(),
&utils::generate_ipfs_hash(Hex(&allocation_created.subgraph_deployment_id).to_string()),
);
}
}

#[substreams::handlers::store]
fn store_query_fee_rebates(events: Events, store: StoreGetBigInt, s: StoreAddBigInt) {
let rebate_claimed_events = events.rebate_claimed_events.unwrap();
Expand Down
18 changes: 18 additions & 0 deletions src/pb/eth.erc20.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ pub struct EpochLengthUpdatedEvents {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct RewardsDenyListUpdatedEvents {
#[prost(message, repeated, tag="1")]
pub rewards_deny_list_updated_events: ::prost::alloc::vec::Vec<RewardsDenyListUpdated>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct IndexerStakes {
#[prost(message, repeated, tag="1")]
pub indexer_stakes: ::prost::alloc::vec::Vec<IndexerStake>,
Expand Down Expand Up @@ -186,6 +192,8 @@ pub struct Events {
pub partial_pause_changed_events: ::core::option::Option<PartialPauseChangedEvents>,
#[prost(message, optional, tag="16")]
pub epoch_length_updated_events: ::core::option::Option<EpochLengthUpdatedEvents>,
#[prost(message, optional, tag="17")]
pub rewards_deny_list_updated_events: ::core::option::Option<RewardsDenyListUpdatedEvents>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down Expand Up @@ -465,6 +473,16 @@ pub struct EpochLengthUpdated {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct RewardsDenyListUpdated {
#[prost(string, tag="1")]
pub id: ::prost::alloc::string::String,
#[prost(string, tag="2")]
pub denied_at: ::prost::alloc::string::String,
#[prost(uint64, tag="3")]
pub ordinal: u64,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct IndexerStake {
#[prost(string, tag="1")]
pub id: ::prost::alloc::string::String,
Expand Down
27 changes: 12 additions & 15 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use base58::ToBase58;
use hex::FromHex;
use substreams::Hex;
use tiny_keccak::{Hasher, Keccak};

Expand Down Expand Up @@ -62,25 +64,20 @@ pub fn generate_key_delegated_stake(delegator: &Vec<u8>, indexer: &Vec<u8>) -> S
}

pub fn generate_key_query_fee_rebates(who: String, id: &Vec<u8>) -> String {
return format!(
"{}:{}",
who,
Hex(id).to_string()
);
return format!("{}:{}", who, Hex(id).to_string());
}

pub fn generate_key_indexing_rewards(who: String, id: String) -> String {
return format!(
"{}:{}",
who,
id,
);
return format!("{}:{}", who, id,);
}

pub fn concat(first: String, second: String) -> String {
return format!(
"{}:{}",
first,
second,
);
return format!("{}:{}", first, second,);
}

pub fn generate_ipfs_hash(subgraph_id: String) -> String {
return Vec::from_hex(format!("{}{}", "1220", subgraph_id))
.unwrap()
.to_base58()
.to_string();
}
Loading

0 comments on commit eef2782

Please sign in to comment.