ETH-transactions-storage: optional address filter, lighter indexes, and a safer public API #76
adamant-al
started this conversation in
Ecosystem & Integrations
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
ETH-transactions-storage is a self-hosted Ethereum indexer: it follows an Ethereum node, stores native ETH and ERC-20
transfer(address,uint256)activity in PostgreSQL, and exposes it as a read-only REST API through PostgREST. Ethereum nodes do not answer “show me this address’s history,” so wallets, dapps, treasuries, and operators usually depend on a third-party explorer. This project is the alternative you run yourself — no API key vendor, no tracking, no telemetry.That stack now has an optional address filter, merged to
devin PR #29. Full-chain indexing remains the default (and is what ADAMANT wallets use). Filtered mode is for everyone who only needs a known set of addresses and does not want to store the rest of the chain.Why this exists
A public Ethereum indexer is a large database. On a one-year mainnet dataset (~490M rows) the old full index set was hundreds of gigabytes. Many operators do not need that:
The filter keeps the same API contract. Clients still query
/ethtxs,/max_block, and/aval. You change what is stored, not how it is read.Address filter
Disabled by default (
ADDRESS_FILTER_ENABLED=false). Enable it and pointADDRESS_FILTER_FILEat a private list (defaultfilter/addresses.txt, gitignored, not copied into the Docker image).Behavior:
0x-prefixed 40-hex-character address per line; blank lines and#comments are ignoredtxfromortxtotransfer(address,uint256)calls match the sender (txfrom), the token contract (txto), and the ABI-encoded recipient (contract_to)What it does not do (existing indexer limits, unchanged):
transfer(address,uint256)(transferFrom, routers, multisigs, batch/aggregator calls)Enabling the filter does not delete already stored rows. Rebuild is a manual operator step: stop the indexer, truncate both
ethtxsandsync_statein one transaction (or rewind both to blockN), setSTART_BLOCK, restart. Truncating onlyethtxswill not rescan — the checkpoint still says the chain is done.Durable sync progress
Filtered and empty blocks used to look like “nothing happened,” so the indexer could rescan them.
devnow keeps a single-rowpublic.sync_statecheckpoint, updated in the same PostgreSQL transaction as the inserts for that block./max_blockstill returns{ max, version };maxisGREATEST(MAX(ethtxs.block), sync_state.last_block)create_tables.sqlis idempotent: it createssync_state, initializes it from the existing highest transaction block, and grants DML toapi_user/app_userwhen those roles existweb_anoncannot read or writesync_statedirectlyAlso on
dev: indexes, API hardening, operationsThe address filter sits on top of the other
devwork from PR #28 (not yet a GitHub Release; latest tag remains v2.4.1):web_anon: PostgREST anonymous role isSELECT-only onethtxs,aval, andmax_blockdb-max-rows = 10000: caps serialized result size so an unboundedGET /ethtxscannot OOM the APIGET/HEAD/OPTIONS), requiretxfromortxtoon/ethtxs, rejectPrefer: count=exactand huge offsets.envworkflow: documented template, secrets stay out of Git, Compose no longer ships a hardcoded database passwordAGENTS.md: contributor and operator contract for the repoExisting systemd hosts should keep their current unit during the code/schema upgrade. Apply
create_tables.sqlwithON_ERROR_STOPbefore starting the new indexer. Do not copy the repositoryethsync.serviceuntil a production.envwith equivalent values exists.Who this is for
ADAMANT uses this indexer so adamant-im and adamant-iOS can show Ethereum and ERC-20 history without a centralized explorer. The same binary is a general-purpose open-source service: wallets, payment processors, token issuers, and anyone who wants address-indexed Ethereum history under their own PostgreSQL and their own access policy.
Self-host it, keep full-chain mode for a public API, or turn the filter on and store only the addresses you actually serve.
Links
Questions and operator reports welcome below. Historical rescan/backfill is out of scope for this change; if you need it, say so in the thread.
All reactions