Blockchain infrastructure that keeps your chain data correct and current, on Solana and EVM chains
Every chain decides differently when a block can still change. Solana, Ethereum, Base, Polygon and Robinhood Chain each give a different answer, and that answer decides how your index stays correct, how you serve it and what it costs to run. I have worked on infrastructure for all five, and I start from those decisions.
What current and correct cost on each chain family
| Solana | EVM chains |
|---|---|
| SolanaProcessed data can vanish with its fork; finalized data is not rolled back | EVM chainsUnfinalized blocks can be reorged; on a rollup, a sequencer block is final only after Ethereum finalizes its batch |
| SolanaCurrent means reading at processed or confirmed and marking what is not finalized | EVM chainsCurrent means reading the latest block and marking what is not yet safe or finalized |
| SolanaCorrect means scoring every early read against the finalized stream | EVM chainsCorrect means keying records by block hash and taking back the logs a reorg removes |
| SolanaA filter that runs before it can see every account drops data and keeps running | EVM chainsA transaction replaced at the same nonce can succeed while the record says it failed |
Which chains you run on decides how long your data stays provisional
Solana reports a commitment level with every read. Processed data comes from a block the node has seen on the fork it currently follows, and it can disappear with that fork. Confirmed data has a supermajority of stake voting for its block. Finalized data has more confirmed blocks built on top, and it is the level that is not rolled back.
Ethereum marks blocks as latest, safe and finalized, and a block becomes final two to three epochs after it is proposed, roughly a quarter of an hour. Base and Robinhood Chain are rollups that settle on Ethereum: the sequencer confirms a transaction almost at once, and the block is final only once its batch is posted to Ethereum and Ethereum finalizes it. Polygon PoS runs its own validators, and since its finality upgrade a block is final within seconds.
So I choose the chains first and the infrastructure second. For each chain a product reads from, I write down what final means there, how long it takes and what the product shows until then, before any code reads a block.
A stage can filter only on what it can see, and zero output is an alarm
In a Solana trading system I built and run, I added a filter at the parser to skip transactions too simple to matter. It counted only the accounts a transaction lists directly. Newer transactions reference more accounts through Address Lookup Tables, which are resolved later in the pipeline, so every transaction looked too small and the filter dropped all of them. The pipeline kept running, processed everything it received, and produced no predictions at all.
Nothing crashed, so nothing alerted, and a run that is fast and empty passes a speed benchmark. The fix moved filtering to the later stages that see the full account list, wrote down what each stage drops, and made empty output count as a failure. Any Solana index or data pipeline can make the same mistake when it filters before the data it filters on exists.
A prediction from unconfirmed data is worth what its score against the confirmed stream says
The same system predicts a pool's next state from transactions it sees before they are confirmed. Each prediction is held apart per transaction, so one simulation cannot leak into another. When the authoritative account update arrives, the prediction is compared with it and both the error and the delay are logged, so accuracy is a running record rather than a belief.
Score it on the number the decision depends on. For one kind of pool the predicted balances disagreed materially with the confirmed ones while the price-relevant value matched. Judged on balances the model looked broken; judged on the value that drives the decision, it was right. I build that scoring loop before the fast path, because it is what tells you whether the speed is worth anything.
On EVM chains, an index has to be able to take a block back
A reorg replaces blocks an index has already stored. A log subscription resends the affected logs marked as removed, and a backfill that read by block number can hold logs from a block that is no longer on the chain. I key every stored record by block hash as well as number, keep the unfinalized tail apart from the finalized history, and roll back to the last common block when a hash stops matching.
What a transaction did has the same problem one level up. In a trading product I build and run, a position was recorded as failed while a replacement transaction with the same nonce had succeeded, and the recovery code dropped the success from the ledger. The rules that came out of it: persist the signed transaction before broadcasting it, rebroadcast the same signed bytes after an ambiguous response instead of signing a second one, and import the result by receipt, keyed on the transaction hash.
A quote that succeeds is not a swap that succeeds. The same product replays each approval-and-swap sequence against pinned chain state and checks the balance changes in integer units, because a quote can return cleanly and then revert on its minimum-output check, and a fee reported alongside a quote can disagree with the transfer that was mined.
How you serve chain data decides whether a consumer can tell current from last known
Serving starts with a choice between a provider's RPC endpoint and a node of your own. I start on a provider when a product reads recent state at modest volume. I move to an own node when log queries reach the provider's range and size caps, when the product needs history or traces a provider will not serve, or when the cost of polling grows faster than the product.
Whatever serves the data has to say what is missing. A feed I build and run gives every event a sequence number, resumes a consumer from the last one it saw, and sends an explicit gap event when history is gone. A bug once let a poll from the very start skip the gap check, so it returned a fraction of the stored events and reported itself complete. A new consumer would have believed it was current, with nothing to alert on.
After a disconnect that feed shows the previous price as last known, not as current. I put the block, its finality and the capture time next to every value a product serves, because an answer that looks current and is not is worse than no answer.
What it costs to run is mostly the waiting, the polling and the person at the apply
Being current costs either a wait or a rollback path. Reading only finalized data on Ethereum leaves a product a quarter of an hour behind, and its rollups wait at least as long. Reading the latest block means paying for the rollback path and showing which values can still change. I make that choice per chain and per screen, not once for the whole product.
Polling costs money as well as load. In a trading terminal I build, a cost review found every open tab polling every few seconds, hidden tabs included, which spent provider credits on screens nobody was looking at.
A node of your own is cloud infrastructure, and it fails at the apply. On an infrastructure-heavy platform I work on, bootstrapping production took a chain of small changes, each filed from the evidence of the previous failed apply. One change added a new kind of record that the deploying role had no permission to create, and it left state half built. I budget that loop at the speed of the person reading the apply, and I treat every new resource kind as a permission change.
A workflow review starts with the chains you run on, and production access stays with a person
I start with a workflow review of how work moves through your team, which chains your product reads and what my software factory can take on, and you leave with a plan either way.
The factory does the volume, I review what it produces, and each change reaches you as a reviewed pull request, with no constant meetings. Which steps are not automated is decided at the start and written into every ticket: the main-branch apply, the account-admin bootstrap and anything touching production identity stay with a person.
If your chain data cannot tell you how final it is, a workflow review is the place to start.
Capabilities
Solana
- Solana infrastructure and validator integrations
- Geyser and Yellowstone gRPC
- TPU and RPC integrations
- Address Lookup Tables and transaction optimisation
EVM chains
- Ethereum, Base, Polygon and Robinhood Chain infrastructure
- Reorg-safe indexing and backfills
- Transaction construction, replacement and receipt reconciliation
- RPC provider or own-node decisions
- Wallet and custody infrastructure
Data
- Blockchain data ingestion and streaming
- On-chain monitoring and indexing
- Analytics pipelines
Stack
- Solana
- Geyser
- Yellowstone gRPC
- Ethereum
- Base
- Polygon
- Robinhood Chain
- Rust
- Go
- TypeScript
- Kafka
- Postgres
