Skip to content

refactor: Streams to make homepage startup instantly - #1232

Merged
ckeshava merged 36 commits into
stagingfrom
refactor/streams-take-3
Nov 17, 2025
Merged

ckeshava merged 36 commits into
stagingfrom
refactor/streams-take-3

Conversation

@ckniffen

@ckniffen ckniffen commented Aug 19, 2025 •

Copy link
Copy Markdown
Collaborator

High Level Overview of Change

Switch streams logic to a context/provider based architecture. This reduces a bunch of redundant logic and cleans up the state change tree. The moment the page loads the most recent validated ledger is loaded in to make the page look populated from the get go.

Summary of Changes in this PR

  • The source of the refactor lies in StreamsProvider.tsx and VHSValidatorsProvider.tsx files. The new provider/context hook is used in the rest of the React components by replacing the existing property-drilled implementations. These changes are implemented in the first 12 commits of this PR. The StreamsProvider and VHSValidatorsProvider components supply the explorer with Validation information from two different sources, i.e Validation-stream and the VHS APIs respectively.
  • Changes to the test files to accommodate the new behavior in the Explorer. The explorer "pre-fetches" the latest validated ledger to reduce the page-load latency time. Commits: 5ed5e58, 5573522
  • Updating the legacy Jest expect.<> matcher names. This is required for the CI to pass. Commit: 452fb55

cc @achowdhry-ripple @kuan121

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Translation Updates
  • Release

Codebase Modernization

  • Updated files to React Hooks
  • Updated files to TypeScript
  • Updated tests to React Testing Library

@ckniffen
ckniffen requested review from ckeshava and pdp2121 August 19, 2025 15:23

@ckeshava ckeshava left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @ckniffen , thank you for your work. The initial page latency has reduced drastically. This is a significant refactor and your work has been very helpful.

Let me know what you think of my observations.

onMouseMove={(e) =>
missing && missing.length && showTooltip('missing', e, { missing })
}
className={status.trustedCount < status.missing.length ? 'missed' : ''}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that this piece of logic has not been changed in this PR. However, it is incorrect even in the current staging branch of the code.

Suggested change
className={status.trustedCount < status.missing.length ? 'missed' : ''}
className={ status.missing.length > 0 ? 'missed' : ''}
onMouseMove={(e) => {
const { missing } = status
missing.length && showTooltip('missing', e, { missing })
}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue is fixed in this commit: 5ed5e58

@@ -1,146 +1,121 @@
import { useContext, useState } from 'react'
import axios from 'axios'
import './css/style.scss'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, I'm unable to load the Network > Validators page in this build of the Explorer. I get a blank screen.

Image

Here is the associated error in the console:

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `ValidatorsTable`. See https://reactjs.org/link/warning-keys for more information.
    at tr
    at ValidatorsTable (http://localhost:3000/containers/Network/ValidatorsTable.tsx:54:23)
    at div
    at div
    at Validators (http://localhost:3000/containers/Network/Validators.tsx:45:25)
    at VHSValidatorsProvider (http://localhost:3000/containers/shared/components/VHSValidators/VHSValidatorsProvider.tsx:25:41)
    at StreamsProvider (http://localhost:3000/containers/shared/components/Streams/StreamsProvider.tsx:47:35)
    at ValidatorsPage
    at RenderedRoute (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/chunk-IUD5A7RD.js?v=ab94eb5d:4082:5)
    at Outlet (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/chunk-IUD5A7RD.js?v=ab94eb5d:4559:26)
    at div
    at NetworkProvider (http://localhost:3000/containers/shared/NetworkContext.tsx:36:3)
    at SocketProvider (http://localhost:3000/containers/shared/SocketContext.tsx:55:3)
    at _c (http://localhost:3000/containers/App/App.tsx:24:11)
    at RenderedRoute (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/chunk-IUD5A7RD.js?v=ab94eb5d:4082:5)
    at Routes (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/chunk-IUD5A7RD.js?v=ab94eb5d:4623:5)
    at div
    at AppErrorBoundary (http://localhost:3000/containers/App/AppErrorBoundary.tsx:5:1)
    at div
    at QueryClientProvider2 (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/react-query.js?v=ab94eb5d:2646:21)
    at _a (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/react-helmet-async.js?v=ab94eb5d:625:5)
    at AppWrapper (http://localhost:3000/containers/App/index.tsx:64:26)
    at Router (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/chunk-IUD5A7RD.js?v=ab94eb5d:4566:15)
    at BrowserRouter (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/react-router-dom.js?v=ab94eb5d:557:5)
    at I18nextProvider (http://localhost:3000/@fs/Users/ckeshavabs/explorer/node_modules/.vite/deps/react-i18next.js?v=ab94eb5d:782:3)
    at Suspense

Uncaught Error: Missing ":identifier" param
    at invariant (chunk-IUD5A7RD.js?v=ab94eb5d:202:11)
    at chunk-IUD5A7RD.js?v=ab94eb5d:639:7
    at Array.map (<anonymous>)
    at generatePath (chunk-IUD5A7RD.js?v=ab94eb5d:629:38)
    at buildPath (routing.tsx:35:10)
    at ExplorerLink (routing.tsx:73:16)

I suspect this has something to do with the removal of the key parameter in some of the React components in this PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because the signing_key is not always populated. One of my last commits introduced this error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue has been fixed in the commit: b748b23

Comment thread src/containers/shared/components/Streams/StreamsProvider.tsx Outdated
Comment thread src/containers/Ledgers/Ledgers.tsx
Comment thread src/containers/Ledgers/LedgerEntryHashTrustedCount.tsx
Co-authored-by: Chenna Keshava B S <21219765+ckeshava@users.noreply.github.com>
@ckeshava

Copy link
Copy Markdown
Contributor

As far as tests are concerned, I'll need to write components/Streams/test and components/VHSValidators/test. All the other modified files already have dedicated tests associated with them.

@ripple ripple deleted a comment from whatever1341132 Aug 23, 2025
ckeshava and others added 9 commits September 3, 2025 09:19
2. Refactor the LedgerPages tests to accomodate the refactored StreamsProvider
3. Update LedgerEntryValidator to retain previous behavior (display validator signing key in class-name)
4. Fix the crashing behavior inside StreamsProvider.processValidationQueue (set up default hashes[])
@ckeshava
ckeshava marked this pull request as ready for review October 30, 2025 03:53
@ckeshava

Copy link
Copy Markdown
Contributor

@ckniffen Thank you very much for your work. Let me know if you'd like to include any other ideas into this PR.

Comment thread package.json
"react18-json-view": "^0.2.8",
"recharts": "^2.15.3",
"ripple-address-codec": "^5.0.0",
"ripple-binary-codec": "^2.4.1",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

package changes should be in a separate PR

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I have reverted the changes pertaining to package.json and package-lock.json file in this commit: 9a3be32

@ckeshava

ckeshava commented Nov 5, 2025

Copy link
Copy Markdown
Contributor

The new context is used in the rest of the React components by replacing the existing property-drilled implementations

@ckeshava What're property-drilled implementations? Is this new context approach directly related to the constant startup?

I'm referring to this practice as prop-drilling in react: https://react.dev/learn/passing-data-deeply-with-context

Yes, I believe the new context based approach contributes significantly to the low startup time of the page. The SocketContext and the associated ledgers/validations are passed akin to "global variables", instead of being passed into every react component explicitly.

There are also other optimizations thrown in (like pre-fetching the latest validated ledger after initialization of the StreamsProvider component) that helps with the low startup time.

@kuan121 kuan121 Nov 5, 2025 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we include this irrelevant change in this PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I think we should have a separate PR for this so that the team is explicitly aware that we will remove it, since this was a higher up ask

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR will need a few days for all the reviewers to read+approve the changes. Retaining the LedgerCountdownBanner code will need a non-trivial usage of the StreamsProvider component.

I would like to instead wait for the removal of the LedgerCountdownBanner and then merge this PR.


expect(wrapper.find('.validation').length).toBe(0)
expect(wrapper.find('.txn').length).toBe(0)
// Recent refactor of the StreamsProvider eagerly fetches the latest validated ledger. The objective is to reduce the latency of displaying the first validated ledger. Consequently, loading the page fetches the latest validated ledger.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate these comments for the lengthier tests!

@achowdhry-ripple

Copy link
Copy Markdown
Contributor

nit: since this PR contains a lot of different refactors/cleanups, could you list them in the PR description? Would make it easier to follow specifically what is changing intentionally and why

refetchQuorum()
}

// TODO: Set fields before getting full ledger info

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this todo still relevant?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, removed it in 2cc86ce

txCount: ledgerSummary.transactions.length,
closeTime: convertRippleDate(ledgerSummary.ledger_time),
transactions: ledgerSummary.transactions,
totalFees: ledgerSummary.total_fees, // fix type

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, is the typing fix still relevant?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, updated in 2cc86ce

@achowdhry-ripple achowdhry-ripple left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! A few comment cleanup nits, but overall great cleanup, thanks @ckeshava @ckniffen for this effort

@ckeshava

Copy link
Copy Markdown
Contributor

Note: The changes in this PR can be viewed in the dev environment of the Explorer: https://livenet.dev.ripplex.io/

@ckeshava ckeshava left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing my "Request Changes" older PR review because it is blocking the merge of this PR

@ckeshava
ckeshava merged commit 4421ed0 into staging Nov 17, 2025
5 checks passed
@ckeshava
ckeshava deleted the refactor/streams-take-3 branch November 17, 2025 16:41
@ckeshava

Copy link
Copy Markdown
Contributor

Thank you @ckniffen and the PR reviewers for your help with this work.

@Patel-Raj11 Patel-Raj11 mentioned this pull request Dec 5, 2025
2 of 11 tasks
@kuan121 kuan121 mentioned this pull request Mar 5, 2026
2 of 11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants