Skip to content

Commit 8f65f24

Browse files
pdp2121Patel-Raj
andauthored
fix: remove db access per validation for fee data (#328)
## 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. --> The validator table in database is being queried every time there's a new validation to retrieve fee data, which caused this error: `KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?` We can instead cache this validator-network data and update it every hour to reduce number of queries. ### Type of Change <!-- Please check relevant options, delete irrelevant ones. --> - [x] 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 - [ ] Release --------- Co-authored-by: Raj Patel <[email protected]>
1 parent a893d21 commit 8f65f24

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

src/connection-manager/agreement.ts

+34
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import {
1717
ValidationRaw,
1818
ValidatorKeys,
1919
Ballot,
20+
Chain,
2021
} from '../shared/types'
22+
import { getLists, overlaps } from '../shared/utils'
2123
import logger from '../shared/utils/logger'
2224

2325
import chains from './chains'
@@ -120,6 +122,30 @@ function isPreceedingFlagLedger(ledger_index: string): boolean {
120122
return parseInt(ledger_index, 10) % 256 === 255
121123
}
122124

125+
/**
126+
* Finds network name from chain id.
127+
*
128+
* @param chain - A chain object.
129+
* @returns String.
130+
*/
131+
async function getNetworkNameFromChainId(chain: Chain): Promise<string> {
132+
let id = chain.id
133+
const lists = await getLists().catch((err) => {
134+
log.error('Error getting validator lists', err)
135+
return undefined
136+
})
137+
138+
if (lists != null) {
139+
Object.entries(lists).forEach(([network, set]) => {
140+
if (overlaps(chain.validators, set)) {
141+
id = network
142+
}
143+
})
144+
}
145+
146+
return id
147+
}
148+
123149
/**
124150
*
125151
*/
@@ -153,6 +179,14 @@ class Agreement {
153179
for (const chain of agreementChains) {
154180
const ledger_hashes = chain.ledgers
155181

182+
const networkName = await getNetworkNameFromChainId(chain)
183+
184+
log.info(
185+
`Agreement: ${chain.id}:${networkName}:${Array.from(
186+
chain.validators,
187+
).join(',')}`,
188+
)
189+
156190
for (const signing_key of chain.validators) {
157191
promises.push(
158192
this.calculateValidatorAgreement(

src/connection-manager/connections.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const ports = [443, 80, 6005, 6006, 51233, 51234]
2727
const protocols = ['wss://', 'ws://']
2828
const connections: Map<string, WebSocket> = new Map()
2929
const networkFee: Map<string, FeeVote> = new Map()
30+
const validationNetworkDb: Map<string, string> = new Map()
3031
const CM_INTERVAL = 60 * 60 * 1000
3132
const WS_TIMEOUT = 10000
3233
const REPORTING_INTERVAL = 15 * 60 * 1000
@@ -60,12 +61,6 @@ async function setHandlers(
6061
isInitialNode = false,
6162
retryCount = 0,
6263
): Promise<void> {
63-
log.info(
64-
`Initiated Websocket connection for: ${ws_url} on ${
65-
networks ?? 'unknown network'
66-
}`,
67-
)
68-
6964
const ledger_hashes: string[] = []
7065
return new Promise(function setHandlersPromise(resolve, _reject) {
7166
ws.on('open', () => {
@@ -119,6 +114,7 @@ async function setHandlers(
119114
networks,
120115
networkFee,
121116
ws,
117+
validationNetworkDb,
122118
)
123119
}
124120
})
@@ -230,13 +226,23 @@ async function findConnection(node: WsNode): Promise<void> {
230226
return Promise.resolve()
231227
}
232228

229+
async function getValidationNetworkDb(): Promise<void> {
230+
const validatorNetwork: Array<{ signing_key: string; networks: string }> =
231+
await query('validators').select('signing_key', 'networks')
232+
for (const entry of validatorNetwork) {
233+
validationNetworkDb.set(entry.signing_key, entry.networks)
234+
}
235+
}
236+
233237
/**
234238
* Creates connections to nodes found in the database.
235239
*
236240
* @returns A promise that resolves to void once all possible connections have been created.
237241
*/
238242
async function createConnections(): Promise<void> {
239243
log.info('Finding Connections...')
244+
validationNetworkDb.clear()
245+
await getValidationNetworkDb()
240246
const tenMinutesAgo = new Date()
241247
tenMinutesAgo.setMinutes(tenMinutesAgo.getMinutes() - 10)
242248

src/connection-manager/wsHandling.ts

+5-14
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,13 @@ import {
99
import { AMENDMENTS_ID } from 'xrpl/dist/npm/models/ledger'
1010
import { LedgerResponseExpanded } from 'xrpl/dist/npm/models/methods/ledger'
1111

12-
import {
13-
query,
14-
saveAmendmentStatus,
15-
saveAmendmentsStatus,
16-
} from '../shared/database'
12+
import { saveAmendmentStatus, saveAmendmentsStatus } from '../shared/database'
1713
import {
1814
NETWORKS_HOSTS,
1915
deleteAmendmentStatus,
2016
} from '../shared/database/amendments'
2117
import {
2218
AmendmentStatus,
23-
DatabaseValidator,
2419
FeeVote,
2520
StreamLedger,
2621
StreamManifest,
@@ -106,6 +101,7 @@ function isFlagLedgerPlusOne(ledger_index: number): boolean {
106101
* @param networks - The networks of subscribed node.
107102
* @param network_fee - The map of default fee for the network to be used in case the validator does not vote for a new fee.
108103
* @param ws - The WebSocket message received from.
104+
* @param validationNetworkDb -- A map of validator signing_keys to their corresponding networks.
109105
* @returns Void.
110106
*/
111107
// eslint-disable-next-line max-params -- Disabled for this function.
@@ -115,22 +111,17 @@ export async function handleWsMessageSubscribeTypes(
115111
networks: string | undefined,
116112
network_fee: Map<string, FeeVote>,
117113
ws: WebSocket,
114+
validationNetworkDb: Map<string, string>,
118115
): Promise<void> {
119116
if (data.type === 'validationReceived') {
120117
const validationData = data as ValidationRaw
121118
if (ledger_hashes.includes(validationData.ledger_hash)) {
122119
validationData.networks = networks
123120
}
124121

125-
// Get network of the validation if ledger_hash is not in cache.
126-
const validationNetworkDb: DatabaseValidator | undefined = await query(
127-
'validators',
128-
)
129-
.select('*')
130-
.where('signing_key', validationData.validation_public_key)
131-
.first()
132122
const validationNetwork =
133-
validationNetworkDb?.networks ?? validationData.networks
123+
validationNetworkDb.get(validationData.validation_public_key) ??
124+
validationData.networks
134125

135126
// Get the fee for the network to be used in case the validator does not vote for a new fee.
136127
if (validationNetwork) {

0 commit comments

Comments
 (0)