Skip to content

Commit

Permalink
feat: add amendment info (#135)
Browse files Browse the repository at this point in the history
## High Level Overview of Change

<!--
Please include a summary/list of the changes.
If too broad, please consider splitting into multiple PRs.
If a relevant Asana task, please link it here.
-->
Add a table to store amendments information:

- Amendment’s hash

- Amendment’s name

- Enabled rippled version

This will also provide more stable source of truth for AmendmentEnabled
transaction in Explorer, which hits 2 repos every time it was called.

This information will be accessed via `/network/amendments/info`
endpoint.

### Type of Change

<!--
Please check relevant options, delete irrelevant ones.
-->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] 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
- [ ] Release

---------

Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
Co-authored-by: Caleb Kniffen <ckniffen@ripple.com>
  • Loading branch information
3 people authored Nov 9, 2023
1 parent 8c7d5e0 commit cb10166
Show file tree
Hide file tree
Showing 10 changed files with 425 additions and 0 deletions.
26 changes: 26 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ There are 3 folders in `src`, corresponding to the 3 processes that the VHS runs
* `/network/validator/:publicKey`: Returns information about a specific validator.
* `/network/validator/:publicKey/manifests`: Returns the manifests of a specific validator.
* `/network/validator/:publicKey/reports`: Returns more detailed information about the reliability of a specific validator.
* `/network/amendments/info`: Returns general information about known amendments.
* `/network/amendments/info/:param`: Returns general information about a specific amendment by name or ID.


## SQL Table Schemas
Expand Down Expand Up @@ -106,6 +108,30 @@ This table keeps track of the manifests of the validators.
| `revoked` |Whether the manifest has been revoked. |
| `seq` |The sequence number of this manifest. |

### `amendments_info`

This table keeps track of the general information of all known amendments.

| Key | Definition |
|----------------------|------------------------------------------------------------|
| `id` |The amendment id. |
| `name` |The name of the amendment. |
| `rippled_version` |The rippled version when the amendment is first enabled |
| `deprecated` |Whether the amendment has been deprecated/retired |

### `ballot`

This table keeps track of the most current voting data for the validators.

| Key | Definition |
|----------------------|-------------------------------------------------------------------|
| `signing_key` |The signing key of the validator. |
| `ledger_index` |The most recent ledger index where voting data was retrieved. |
| `amendments` |The amendments this validator wants to be added to the protocol. |
| `base_fee` |The unscaled transaction cost this validator wants to set. |
| `reserve_base` |The minimum reserve requirement this validator wants to set. |
| `reserve_inc` |The increment in the reserve requirement this validator wants to set.|


### `ballot`

Expand Down
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"homepage": "https://github.com/ripple/validator-history-service#readme",
"devDependencies": {
"@types/axios": "^0.14.0",
"@types/create-hash": "^1.2.2",
"@types/express": "4.17.20",
"@types/jest": "^26.0.19",
"@types/nconf": "^0.10.0",
Expand Down Expand Up @@ -61,6 +62,7 @@
"@types/bunyan": "^1.8.7",
"axios": "^0.21.1",
"bunyan": "^1.8.15",
"create-hash": "^1.2.0",
"dotenv": "^16.3.1",
"express": "4.18.2",
"knex": "2.5.1",
Expand Down
123 changes: 123 additions & 0 deletions src/api/routes/v1/amendments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { Request, Response } from 'express'

import { query } from '../../../shared/database'
import { AmendmentsInfo } from '../../../shared/types'
import { isEarlierVersion } from '../../../shared/utils'
import logger from '../../../shared/utils/logger'

interface AmendmentsInfoResponse {
result: 'success' | 'error'
count: number
amendments: AmendmentsInfo[]
}

interface SingleAmendmentInfoResponse {
result: 'success' | 'error'
amendment: AmendmentsInfo
}

interface Cache {
amendments: AmendmentsInfo[]
time: number
}

const log = logger({ name: 'api-amendments' })

const cache: Cache = {
amendments: [],
time: Date.now(),
}

/**
* Updates amendments in cache.
*
* @returns Void.
*/
async function cacheAmendmentsInfo(): Promise<void> {
try {
cache.amendments = await query('amendments_info').select('*')
cache.amendments.sort((prev: AmendmentsInfo, next: AmendmentsInfo) => {
if (isEarlierVersion(prev.rippled_version, next.rippled_version)) {
return 1
}
return -1
})
cache.time = Date.now()
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: clean up
} catch (err: any) {
log.error(err.toString())
}
}

void cacheAmendmentsInfo()

/**
* Handles Amendments Info request.
*
* @param _u - Unused express request.
* @param res - Express response.
*/
export async function handleAmendmentsInfo(
_u: Request,
res: Response,
): Promise<void> {
try {
if (Date.now() - cache.time > 60 * 1000) {
await cacheAmendmentsInfo()
}
const amendments: AmendmentsInfo[] = cache.amendments
const response: AmendmentsInfoResponse = {
result: 'success',
count: amendments.length,
amendments,
}
res.send(response)
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: clean up
} catch (err: any) {
res.send({ result: 'error', message: 'internal error' })
log.error(err.toString())
}
}

/**
* Handles Amendment Info request.
*
* @param req - Unused express request.
* @param res - Express response.
*/
export async function handleAmendmentInfo(
req: Request,
res: Response,
): Promise<void> {
try {
const { param } = req.params
if (Date.now() - cache.time > 60 * 1000) {
await cacheAmendmentsInfo()
}
const amendments: AmendmentsInfo[] = cache.amendments.filter(
(amend) => amend.name === param || amend.id === param,
)
if (amendments.length === 0) {
res.send({ result: 'error', message: "incorrect amendment's id/name" })
return
}
if (amendments.length > 1) {
res.send({
result: 'error',
message:
"there's a duplicate amendment's id/name on the server, please try again later",
})
log.error("there's a duplicate amendment's id/name on the server", param)
return
}
const response: SingleAmendmentInfoResponse = {
result: 'success',
amendment: amendments[0],
}
res.send(response)
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: clean up
} catch (err: any) {
res.send({ result: 'error', message: 'internal error' })
log.error(err.toString())
}
}
5 changes: 5 additions & 0 deletions src/api/routes/v1/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* eslint-disable import/max-dependencies -- Disabled since this module requires multiple dependencies. */
import { Router as createRouter } from 'express'

import { handleAmendmentsInfo, handleAmendmentInfo } from './amendments'
import handleDailyScores from './daily-report'
import getNetworkOrAdd from './get-network'
import handleHealth from './health'
Expand All @@ -12,6 +14,9 @@ const api = createRouter()

api.use('/health', handleHealth)
api.use('/network/validator_reports', handleDailyScores)
api.use('/network/amendment/info/:param', handleAmendmentInfo)
api.use('/network/amendments/info', handleAmendmentsInfo)

api.use('/network/get_network/:entryUrl', getNetworkOrAdd)

api.use('/network/topology/nodes/:network', handleNodes)
Expand Down
10 changes: 10 additions & 0 deletions src/api/routes/v1/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ const info = {
route: '/v1/network/validator_reports',
example: 'https://data.xrpl.org/v1/network/validator_reports',
},
{
action: 'Get Amendments General Information',
route: '/v1/network/amendments/info',
example: 'https://data.xrpl.org/v1/network/amendments/info',
},
{
action: 'Get Amendment General Information by Name or ID',
route: '/v1/network/amendment/info/{amendment}',
example: 'https://data.xrpl.org/v1/network/amendment/info/{amendment}',
},
],
}

Expand Down
Loading

0 comments on commit cb10166

Please sign in to comment.