Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into docs/getting-started
Browse files Browse the repository at this point in the history
  • Loading branch information
tk-o committed Jan 21, 2025
2 parents 1d0c016 + bace0ab commit 37a0d6c
Show file tree
Hide file tree
Showing 32 changed files with 1,665 additions and 347 deletions.
51 changes: 36 additions & 15 deletions .env.local.example
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
# RPC configuration
# Follow the format: RPC_URL_{chainId}={rpcUrl}

RPC_URL_1=https://ethereum-rpc.publicnode.com
RPC_URL_8453=https://base-rpc.publicnode.com
RPC_URL_59144=https://linea-rpc.publicnode.com

# Identify which indexer plugin to activate (see `src/plugins` for available plugins)

ACTIVE_PLUGIN=base.eth
# For the RPC URL of each chain, follow the format: RPC_URL_{chainId}={rpcUrl}
RPC_URL_1=https://eth.drpc.org
RPC_URL_8453=https://base.drpc.org
RPC_URL_59144=https://linea.drpc.org
# For the RPC rate limits of each chain, follow the format:
# RPC_REQUEST_RATE_LIMIT_{chainId}={rateLimitInRequestsPerSecond}
# The rate limit is the maximum number of requests per second that can be made
# to the RPC endpoint. For public RPC endpoints, it is recommended to set
# a rate limit to low values (i.e. below 30 rps) to avoid being rate limited.
# For private RPC endpoints, the rate limit can be set to higher values,
# depending on the capacity of the endpoint. For example, 500 rps.
# If no rate limit is set for a given chainId, the DEFAULT_RPC_RATE_LIMIT value
# will be applied.
RPC_REQUEST_RATE_LIMIT_1=50
RPC_REQUEST_RATE_LIMIT_8453=20
RPC_REQUEST_RATE_LIMIT_59144=20

# Database configuration

# This is where the indexer will create the tables defined in ponder.schema.ts
# No two indexer instances can use the same database schema at the same time. This prevents data corruption.
# @link https://ponder.sh/docs/api-reference/database#database-schema-rules
DATABASE_SCHEMA=subname_index_base.eth
# The indexer will use Postgres with that as the connection string. If not defined, the indexer will use PSlite.
# This is a namespace for the tables that the indexer will create to store indexed data.
# It should be a string that is unique to the running indexer instance.
#
# Keeping the database schema unique to the indexer instance is important to
# 1) speed up indexing after a restart
# 2) prevent data corruption from multiple indexer app instances writing state
# concurrently to the same db schema
#
# No two indexer instances can use the same database schema at the same time.
#
# Read more about database schema rules here:
# https://ponder.sh/docs/api-reference/database#database-schema-rules
DATABASE_SCHEMA=ens
# This is the connection string for the database that the indexer will use to store data.
# It should be in the format of `postgresql://<username>:<password>@<host>:<port>/<database>`
DATABASE_URL=postgresql://dbuser:abcd1234@localhost:5432/my_database

# Plugin configuration
# Identify which indexer plugins to activate (see `src/plugins` for available plugins)
# This is a comma separated list of one or more available plugin names (case-sensitive).
ACTIVE_PLUGINS=eth,base.eth,linea.eth
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Default owners for everything in the repo

* @shrugs @tk-o @djstrong @BanaSeba @lightwalker-eth
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,3 @@ yarn-error.log*
# Ponder
/generated/
/.ponder/

checkpoints/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 NameHash

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
24 changes: 11 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ens-multichain indexer
# ENSNode

> powered by ponder
> a multichain ENS indexer, powered by Ponder
## Quick start

Expand Down Expand Up @@ -49,9 +49,9 @@ To learn more about those commands, go to https://ponder.sh/docs/api-reference/p

### `eth` plugin

estimated backfill time @ 50rps = 24-36 hours on M1 Macbook (~10x speedup)
estimated mainnet-only backfill time @ <=500rps = **~13 hours** on M1 Macbook (>10x speedup vs subgraph)

### goals
## goals

> an optimized, multichain ens indexer that the community loves and integrates
Expand All @@ -61,7 +61,7 @@ estimated backfill time @ 50rps = 24-36 hours on M1 Macbook (~10x speedup)
- 1:1 equivalency of results for queries via ensjs
- 100% ensjs, ens-app-v3 test suites passing
- should 'just work', following [this documentation](https://github.com/ensdomains/ensjs/blob/main/docs/basics/custom-subgraph-uris.md)
- ensjs equivalency confirmed via [ens-indexer-transition-tools](https://github.com/namehash/ens-indexer-transition-tools)
- ensjs equivalency confirmed via [ens-subgraph-transition-tools](https://github.com/namehash/ens-subgraph-transition-tools)
- v2 — **optimized multichain indexer w/ unified namespace**
- true multichain indexing (mainnet, base, linea, etc)
- flattened, unified, multichain namespace
Expand All @@ -70,26 +70,24 @@ estimated backfill time @ 50rps = 24-36 hours on M1 Macbook (~10x speedup)
- (possible) continued backwards compatibility with subgraph
- support indexing subset of data, i.e. only domains under parent node

#### next up
## next up

- [ ] `_nocase` case-insensitive where filters
- not used interally but ensjs does technically expose this as an available filter to users
- [ ] confirm all the schema relations are configured correctly
- [ ] integrate rainbow tables for label healing
- load the table dump into pglite (or just postgres) & query synchronously to match existing behavior
- https://github.com/graphprotocol/ens-rainbow
- [ ] subgraph graphql implementation within ponder
- [ ] implement subgraph-style pagination api
- [ ] support the well-known queries in `GRAPHQL.md`
- [ ] support collection queries as well, to power `snapshot-eq`
- [ ] CI/CD with indexing?
- more recent endlbock for gut checks
- integrate index to recent block (10m?) and validate with `snapshot-eq` b4 passing
- [ ] better understand reverse resolution & how that pertains to L2 primary names and impacts the future schema, etc

### notes
## notes

- eth registry is ERC721, has many controllers (), no knowledge of pricing — delegated to registrar controllers
- eth old registry & new registry migration due to security issue, new then fallback to old, therefore ignore all old evens on domains that have been seen by new registry

### ENSIP Ideas
## ENSIP Ideas

- unable to automatically identify subname registries via onchain event, CCIP standard dosn't include any info about data source, so we'll need to encode manually for now
- ENSIP - shared interface for subdomain registrars
Expand Down
15 changes: 15 additions & 0 deletions docs/GRAPHQL.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# graphql info/spec

## backwards-compatibility notes

the following features of the subgraph graphql api are explicitly unsupported, because they are not used by ensjs or ens-app-v3

- [fulltext search queries](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/#fulltext-search-queries)
- [1-level-nested Entity `_orderBy` param](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/#example-for-nested-entity-sorting)
- [subgraph `_Meta_` object](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/#subgraph-metadata) (ponder's `_meta` is available)
- [time travel queries](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/#time-travel-queries)
- [_change_block filtering](https://thegraph.com/docs/en/subgraphs/querying/graphql-api/#example-for-block-filtering)

## notes

- offset queries slow? `CLUSTER` your table so scans are faster
- `CLUSTER public.domains USING domains_pkey;`

## goals

1. ponder indexer 1:1 equivalency of results as compared to subgraph
Expand Down
4 changes: 4 additions & 0 deletions docs/V2.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ the 'empty' domains should be handled more accurately, depending on how importan
- removes need to increment during domain creation
- new impl likely needs to exclude 'empty' domains (see registry notes for context)

domain createdAt should not update on re-registration, should be original createdAt

various resources use both null and zeroAddress to indicate emptiness, this is horrible and creates numerous checks like [this](https://github.com/ensdomains/ensjs/blob/main/packages/ensjs/src/functions/subgraph/getNamesForAddress.ts#L255) where they check for `!== NULL && !== zeroAddress`

wrappedOwnerId should not be materialized onto domain, should just be resolved through wrappedDomain.owner
Expand Down Expand Up @@ -75,6 +77,8 @@ any resolver that implements the CCIP Read standard will have to have its record

in the subgraph implementation, resolver handlers must upsert resolvers because people can set records etc for a node that has not (yet) specified this resolver as active, meaning the create in `Registry:NewResolver` has yet to fire. in the ideal scenario, this lookup is keyed only by `(chainId, address)` and we can use pure updates instead of an upsert

v1: resolvers are discovered by tracking all emissions of events that look like resolver spec events. very inefficient, as a resolver is only relevant to the protocol once it's been set as a resolver. for v2, we could use factory like normal, starting to track events on `Registry#NewResolver` and then backfilling the events (using the same handlers) with ponder's cached viem client. not sure if this is more or less intensive than just parsing every event ever

### registrar

the subgraph implements all of the BaseRegistrar, EthRegistrarController, and EthRegistrarControllerOld logic together
Expand Down
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "ens-multichain",
"name": "ensnode",
"version": "0.0.1",
"private": true,
"type": "module",
Expand All @@ -13,8 +13,18 @@
},
"dependencies": {
"@ensdomains/ensjs": "^4.0.2",
"@escape.tech/graphql-armor-max-aliases": "^2.6.0",
"@escape.tech/graphql-armor-max-depth": "^2.4.0",
"@escape.tech/graphql-armor-max-tokens": "^2.5.0",
"change-case": "^5.4.4",
"dataloader": "^2.2.3",
"drizzle-orm": "^0.38.3",
"graphql": "^16.10.0",
"graphql-scalars": "^1.24.0",
"graphql-yoga": "^5.10.9",
"hono": "^4.6.14",
"ponder": "^0.8.17",
"ponder": "^0.8.26",
"ts-deepmerge": "^7.0.2",
"viem": "^2.21.57"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 37a0d6c

Please sign in to comment.