Skip to content

Commit c5de54e

Browse files
authored
Merge pull request #1 from ideal-lab5/cm/acuity-index-poc
POC implementation to index Ideal Network Events using acuity substrate
2 parents 04a25a0 + 147efa3 commit c5de54e

File tree

30 files changed

+1695
-14
lines changed

30 files changed

+1695
-14
lines changed

Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[workspace]
2+
resolver = "2"
3+
4+
members = [
5+
"polkadot-metadata",
6+
"kusama-metadata",
7+
"rococo-metadata",
8+
"westend-metadata",
9+
"ideal-network-local-metadata",
10+
"indexer",
11+
]

Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM rust:slim
2+
3+
WORKDIR /usr/src/ideal-network-indexer
4+
5+
COPY . .
6+
7+
RUN cargo build --release -j 1
8+
9+
EXPOSE 8172

LICENSE

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,18 +175,7 @@
175175

176176
END OF TERMS AND CONDITIONS
177177

178-
APPENDIX: How to apply the Apache License to your work.
179-
180-
To apply the Apache License to your work, attach the following
181-
boilerplate notice, with the fields enclosed by brackets "[]"
182-
replaced with your own identifying information. (Don't include
183-
the brackets!) The text should be enclosed in the appropriate
184-
comment syntax for the file format. We also recommend that a
185-
file or class name and description of purpose be included on the
186-
same "printed page" as the copyright notice for easier
187-
identification within third-party archives.
188-
189-
Copyright [yyyy] [name of copyright owner]
178+
Copyright 2023-2024 Jonathan Brown
190179

191180
Licensed under the Apache License, Version 2.0 (the "License");
192181
you may not use this file except in compliance with the License.

README.md

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,68 @@
1-
# idn-event-indexer
2-
Event indexer for Ideal Network.
1+
# Ideal Network Indexer
2+
3+
Event indexer for the Ideal Network.
4+
5+
## Architecture
6+
7+
![Hybrid Architecture](https://raw.githubusercontent.com/ethernomad/hybrid-diagram/main/hybrid.png)
8+
9+
IDN Indexer uses the [Hybrid Indexer](https://github.com/hybrid-explorer/hybrid-indexer) Rust library. It can be accessed using [Hybrid Dapp](https://github.com/hybrid-explorer/hybrid-dapp).
10+
11+
## Building
12+
13+
Ideal Network Indexer can be built using `cargo build`, however it is necessary to use the nightly `rustc`.
14+
15+
```sh
16+
rustup default nightly
17+
cargo build --release
18+
```
19+
20+
Compiling `metadata` can take a very long time.
21+
22+
## Running
23+
24+
```
25+
Usage: ideal-indexer [OPTIONS]
26+
27+
Options:
28+
-c, --chain <CHAIN> Chain to index [default: ideal] [possible values: ideal,polkadot, kusama, rococo, westend]
29+
-d, --db-path <DB_PATH> Database path
30+
-u, --url <URL> URL of Substrate node to connect to
31+
-b, --block-number <BLOCK_NUMBER> Block number to start indexing from
32+
--queue-depth <QUEUE_DEPTH> Maximum number of concurrent requests to the chain [default: 64]
33+
-p, --port <PORT> Port to open for WebSocket queries [default: 8172]
34+
-v, --verbose... More output per occurrence
35+
-q, --quiet... Less output per occurrence
36+
-h, --help Print help
37+
-V, --version Print version
38+
```
39+
40+
## Docker
41+
42+
First build the docker image:
43+
44+
```sh
45+
docker build .
46+
```
47+
48+
Run the docker image for each chain in a separate tab (replace `[image_hash]` with the hash of the docker image displayed at the end of the build):
49+
50+
```sh
51+
docker run --rm -p 8172:8172 [image_hash] -c ideal -b 16730000 -p 8172
52+
```
53+
54+
```sh
55+
docker run --rm -p 8172:8172 [image_hash] -c polkadot -b 16730000 -p 8172
56+
```
57+
58+
```sh
59+
docker run --rm -p 8172:8172 [image_hash] -c kusama -b 16730000 -p 8172
60+
```
61+
62+
```sh
63+
docker run --rm -p 8174:8174 [image_hash] -c rococo -b 6550000 -p 8174
64+
```
65+
66+
```sh
67+
docker run --rm -p 8175:8175 [image_hash] -c westend -b 16940000 -p 8175
68+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "ideal-network-local-metadata"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
subxt = "0.35.3"
119 KB
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#[subxt::subxt(runtime_metadata_path = "ideal.scale")]
2+
pub mod ideal_network_local_metadata {}

indexer/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "acuity-index-polkadot"
3+
version = "0.2.2"
4+
edition = "2021"
5+
6+
[dependencies]
7+
polkadot-metadata = { path = "../polkadot-metadata" }
8+
kusama-metadata = { path = "../kusama-metadata" }
9+
rococo-metadata = { path = "../rococo-metadata" }
10+
westend-metadata = { path = "../westend-metadata" }
11+
ideal-network-local-metadata = { path = "../ideal-network-local-metadata" }
12+
tokio = { version = "1.28.2", features = ["macros", "rt", "rt-multi-thread"] }
13+
subxt = "0.35.3"
14+
clap = { version = "4.3.19", features = ["derive"] }
15+
hex-literal = "0.4.1"
16+
clap-verbosity-flag = "2.0.1"
17+
sled = { version = "0.34.7", default-features = false }
18+
byte-unit = "4.0.19"
19+
serde = { version = "1.0.162", features = ["derive"] }
20+
zerocopy = "0.7.8"
21+
tracing-log = "0.2.0"
22+
acuity-index-substrate = { path = "../../idn-acuity-index-substrate" }

indexer/src/ideal.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use ideal_network_local_metadata::ideal_network_local_metadata::{
2+
runtime_types::{
3+
frame_system::pallet::Event as SystemEvent,
4+
pallet_balances::pallet::Event as BalancesEvent,
5+
// Add other relevant event imports for your ideal network
6+
},
7+
Event,
8+
};
9+
10+
use crate::*;
11+
use acuity_index_substrate::*;
12+
use hex_literal::hex;
13+
14+
pub struct IdealIndexer;
15+
16+
impl acuity_index_substrate::shared::RuntimeIndexer for IdealIndexer {
17+
type RuntimeConfig = subxt::PolkadotConfig; // You might need to adjust this based on your chain's configuration
18+
type ChainKey = ChainKey;
19+
20+
fn get_name() -> &'static str {
21+
"ideal"
22+
}
23+
24+
fn get_genesis_hash() -> <Self::RuntimeConfig as subxt::Config>::Hash {
25+
// Replace with your chain's genesis hash
26+
hex!["af97825bf72091072a08b9dbff88d6664e2061bcb4e28a90f17bd85572d8f8ae"].into() // Temporary placeholder
27+
}
28+
29+
fn get_versions() -> &'static [u32] {
30+
&[0]
31+
}
32+
33+
fn get_default_url() -> &'static str {
34+
"ws://127.0.0.1:1234" // Replace with your actual endpoint
35+
}
36+
37+
fn process_event(
38+
indexer: &acuity_index_substrate::substrate::Indexer<Self>,
39+
block_number: u32,
40+
event_index: u16,
41+
event: subxt::events::EventDetails<Self::RuntimeConfig>,
42+
) -> Result<u32, IndexError> {
43+
Ok(match event.as_root_event::<Event>()? {
44+
Event::System(event) => {
45+
index_system_event![SystemEvent, event, indexer, block_number, event_index]
46+
}
47+
Event::Balances(event) => {
48+
index_balances_event![BalancesEvent, event, indexer, block_number, event_index]
49+
}
50+
// Add other event handlers as needed
51+
_ => 0,
52+
})
53+
}
54+
}

indexer/src/kusama.rs

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
use kusama_metadata::kusama_metadata::{
2+
runtime_types::{
3+
frame_system::pallet::Event as SystemEvent,
4+
pallet_bags_list::pallet::Event as BagsListEvent,
5+
pallet_balances::pallet::Event as BalancesEvent,
6+
pallet_bounties::pallet::Event as BountiesEvent,
7+
pallet_child_bounties::pallet::Event as ChildBountiesEvent,
8+
pallet_election_provider_multi_phase::pallet::Event as ElectionProviderMultiPhaseEvent,
9+
pallet_fast_unstake::pallet::Event as FastUnstakeEvent,
10+
pallet_identity::pallet::Event as IdentityEvent,
11+
pallet_indices::pallet::Event as IndicesEvent,
12+
pallet_multisig::pallet::Event as MultisigEvent,
13+
pallet_nomination_pools::pallet::Event as NominationPoolsEvent,
14+
pallet_preimage::pallet::Event as PreimageEvent,
15+
pallet_proxy::pallet::Event as ProxyEvent,
16+
pallet_session::pallet::Event as SessionEvent,
17+
pallet_staking::pallet::pallet::Event as StakingEvent,
18+
pallet_transaction_payment::pallet::Event as TransactionPaymentEvent,
19+
pallet_treasury::pallet::Event as TreasuryEvent,
20+
pallet_vesting::pallet::Event as VestingEvent,
21+
polkadot_runtime_common::{
22+
auctions::pallet::Event as AuctionsEvent, claims::pallet::Event as ClaimsEvent,
23+
crowdloan::pallet::Event as CrowdloanEvent,
24+
paras_registrar::pallet::Event as ParasRegistrarEvent,
25+
slots::pallet::Event as SlotsEvent,
26+
},
27+
polkadot_runtime_parachains::{
28+
disputes::pallet::Event as DisputesEvent, hrmp::pallet::Event as HrmpEvent,
29+
paras::pallet::Event as ParasEvent,
30+
},
31+
},
32+
Event,
33+
};
34+
35+
use crate::*;
36+
use acuity_index_substrate::*;
37+
38+
use hex_literal::hex;
39+
40+
pub struct KusamaIndexer;
41+
42+
impl acuity_index_substrate::shared::RuntimeIndexer for KusamaIndexer {
43+
type RuntimeConfig = subxt::PolkadotConfig;
44+
type ChainKey = ChainKey;
45+
46+
fn get_name() -> &'static str {
47+
"kusama"
48+
}
49+
50+
fn get_genesis_hash() -> <Self::RuntimeConfig as subxt::Config>::Hash {
51+
hex!["b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe"].into()
52+
}
53+
54+
fn get_versions() -> &'static [u32] {
55+
&[0]
56+
}
57+
58+
fn get_default_url() -> &'static str {
59+
"wss://kusama-rpc.polkadot.io:443"
60+
}
61+
62+
fn process_event(
63+
indexer: &acuity_index_substrate::substrate::Indexer<Self>,
64+
block_number: u32,
65+
event_index: u16,
66+
event: subxt::events::EventDetails<Self::RuntimeConfig>,
67+
) -> Result<u32, IndexError> {
68+
Ok(match event.as_root_event::<Event>()? {
69+
// Substrate pallets.
70+
Event::System(event) => {
71+
index_system_event![SystemEvent, event, indexer, block_number, event_index]
72+
}
73+
Event::Preimage(event) => {
74+
index_preimage_event![PreimageEvent, event, indexer, block_number, event_index]
75+
}
76+
Event::Indices(event) => {
77+
index_indices_event![IndicesEvent, event, indexer, block_number, event_index]
78+
}
79+
Event::Balances(event) => {
80+
index_balances_event![BalancesEvent, event, indexer, block_number, event_index]
81+
}
82+
Event::TransactionPayment(event) => {
83+
index_transaction_payment_event![
84+
TransactionPaymentEvent,
85+
event,
86+
indexer,
87+
block_number,
88+
event_index
89+
]
90+
}
91+
Event::Staking(event) => {
92+
index_staking_event![StakingEvent, event, indexer, block_number, event_index]
93+
}
94+
Event::Session(event) => {
95+
index_session_event![SessionEvent, event, indexer, block_number, event_index]
96+
}
97+
Event::Treasury(event) => {
98+
index_treasury_event![TreasuryEvent, event, indexer, block_number, event_index]
99+
}
100+
Event::Vesting(event) => {
101+
index_vesting_event![VestingEvent, event, indexer, block_number, event_index]
102+
}
103+
Event::Identity(event) => {
104+
index_identity_event![IdentityEvent, event, indexer, block_number, event_index]
105+
}
106+
Event::Proxy(event) => {
107+
index_proxy_event![ProxyEvent, event, indexer, block_number, event_index]
108+
}
109+
Event::Multisig(event) => {
110+
index_multisig_event![MultisigEvent, event, indexer, block_number, event_index]
111+
}
112+
Event::Bounties(event) => {
113+
index_bounties_event![BountiesEvent, event, indexer, block_number, event_index]
114+
}
115+
Event::ChildBounties(event) => {
116+
index_child_bounties_event![
117+
ChildBountiesEvent,
118+
event,
119+
indexer,
120+
block_number,
121+
event_index
122+
]
123+
}
124+
Event::ElectionProviderMultiPhase(event) => {
125+
index_election_provider_multi_phase_event![
126+
ElectionProviderMultiPhaseEvent,
127+
event,
128+
indexer,
129+
block_number,
130+
event_index
131+
]
132+
}
133+
Event::VoterList(event) => {
134+
index_bags_list_event![BagsListEvent, event, indexer, block_number, event_index]
135+
}
136+
Event::NominationPools(event) => {
137+
index_nomination_pools_event![
138+
NominationPoolsEvent,
139+
event,
140+
indexer,
141+
block_number,
142+
event_index
143+
]
144+
}
145+
Event::FastUnstake(event) => {
146+
index_fast_unstake_event![
147+
FastUnstakeEvent,
148+
event,
149+
indexer,
150+
block_number,
151+
event_index
152+
]
153+
}
154+
// Polkadot pallets.
155+
Event::Claims(event) => {
156+
index_claims_event![ClaimsEvent, event, indexer, block_number, event_index]
157+
}
158+
Event::Paras(event) => {
159+
index_paras_event![ParasEvent, event, indexer, block_number, event_index]
160+
}
161+
Event::Hrmp(event) => {
162+
index_hrmp_event![HrmpEvent, event, indexer, block_number, event_index]
163+
}
164+
Event::ParasDisputes(event) => {
165+
index_disputes_event![DisputesEvent, event, indexer, block_number, event_index]
166+
}
167+
Event::Registrar(event) => {
168+
index_paras_registrar_event![
169+
ParasRegistrarEvent,
170+
event,
171+
indexer,
172+
block_number,
173+
event_index
174+
]
175+
}
176+
Event::Slots(event) => {
177+
index_slots_event![SlotsEvent, event, indexer, block_number, event_index]
178+
}
179+
Event::Auctions(event) => {
180+
index_auctions_event![AuctionsEvent, event, indexer, block_number, event_index]
181+
}
182+
Event::Crowdloan(event) => {
183+
index_crowdloan_event![CrowdloanEvent, event, indexer, block_number, event_index]
184+
}
185+
_ => 0,
186+
})
187+
}
188+
}

0 commit comments

Comments
 (0)