Skip to content

Commit

Permalink
Updated the worker processes to not use main logger process to avoid …
Browse files Browse the repository at this point in the history
…multiple writers writing to a single log file
  • Loading branch information
jairajdev committed Aug 19, 2024
1 parent d9a31f8 commit c107ac0
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 163 deletions.
202 changes: 89 additions & 113 deletions src/Data/Collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ type GET_TX_RECEIPT_RESPONSE = {

export interface ReceiptVerificationResult {
success: boolean
failedReason?: string
nestedCounterMessage?: string
failedReasons?: string[]
nestedCounterMessages?: string[]
newReceipt?: Receipt.ArchiverReceipt
}

Expand Down Expand Up @@ -406,7 +406,9 @@ export const validateArchiverReceipt = (receipt: Receipt.ArchiverReceipt): boole

export const verifyReceiptData = async (
receipt: Receipt.ArchiverReceipt,
checkReceiptRobust = true
checkReceiptRobust = true,
failedReasons = [],
nestedCounterMessages = []
): Promise<{ success: boolean; newReceipt?: Receipt.ArchiverReceipt }> => {
const result = { success: false }
// Check the signed nodes are part of the execution group nodes of the tx
Expand All @@ -425,14 +427,14 @@ export const verifyReceiptData = async (
}
const currentCycle = getCurrentCycleCounter()
if (currentCycle - cycle > 2) {
Logger.mainLogger.error(
failedReasons.push(
`Found receipt with cycle older than 2 cycles ${txId}, ${cycle}, ${timestamp}, ${currentCycle}`
)
}
const cycleShardData = shardValuesByCycle.get(cycle)
if (!cycleShardData) {
Logger.mainLogger.error('Cycle shard data not found')
if (nestedCountersInstance) nestedCountersInstance.countEvent('receipt', 'Cycle_shard_data_not_found')
failedReasons.push('Cycle shard data not found')
nestedCounterMessages.push('Cycle_shard_data_not_found')
return result
}
// Determine the home partition index of the primary account (executionShardKey)
Expand All @@ -448,14 +450,12 @@ export const verifyReceiptData = async (
? Math.ceil(votingGroupCount * config.requiredVotesPercentage)
: Math.round(votingGroupCount * config.requiredVotesPercentage)
if (signatures.length < requiredSignatures) {
Logger.mainLogger.error(
failedReasons.push(
`Invalid receipt appliedReceipt signatures count is less than requiredSignatures, ${signatures.length}, ${requiredSignatures}`
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_appliedReceipt_signatures_count_less_than_requiredSignatures'
)
nestedCounterMessages.push(
'Invalid_receipt_appliedReceipt_signatures_count_less_than_requiredSignatures'
)
return result
}
// Refer to https://github.com/shardeum/shardus-core/blob/50b6d00f53a35996cd69210ea817bee068a893d6/src/state-manager/TransactionConsensus.ts#L2799
Expand All @@ -472,26 +472,18 @@ export const verifyReceiptData = async (
// Get the node id from the public key
const node = cycleShardData.nodes.find((node) => node.publicKey === nodePubKey)
if (node == null) {
Logger.mainLogger.error(
failedReasons.push(
`The node with public key ${nodePubKey} of the receipt ${txId}} with ${timestamp} is not in the active nodesList of cycle ${cycle}`
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'appliedReceipt_signature_owner_not_in_active_nodesList'
)
nestedCounterMessages.push('appliedReceipt_signature_owner_not_in_active_nodesList')
continue
}
// Check if the node is in the execution group
if (!cycleShardData.parititionShardDataMap.get(homePartition).coveredBy[node.id]) {
Logger.mainLogger.error(
failedReasons.push(
`The node with public key ${nodePubKey} of the receipt ${txId} with ${timestamp} is not in the execution group of the tx`
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'appliedReceipt_signature_node_not_in_execution_group_of_tx'
)
nestedCounterMessages.push('appliedReceipt_signature_node_not_in_execution_group_of_tx')
continue
}
if (Crypto.verify({ ...appliedVoteHash, sign: signature })) {
Expand All @@ -501,102 +493,75 @@ export const verifyReceiptData = async (
}
}
if (goodSignatures.size < requiredSignatures) {
Logger.mainLogger.error(
failedReasons.push(
`Invalid receipt appliedReceipt valid signatures count is less than requiredSignatures ${goodSignatures.size}, ${requiredSignatures}`
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_appliedReceipt_valid_signatures_count_less_than_requiredSignatures'
)
nestedCounterMessages.push(
'Invalid_receipt_appliedReceipt_valid_signatures_count_less_than_requiredSignatures'
)
return result
}
return { success: true }
}
const { confirmOrChallenge } = appliedReceipt
// Check if the appliedVote node is in the execution group
if (!cycleShardData.nodeShardDataMap.has(appliedVote.node_id)) {
Logger.mainLogger.error('Invalid receipt appliedReceipt appliedVote node is not in the active nodesList')
if (nestedCountersInstance)
nestedCountersInstance.countEvent('receipt', 'Invalid_receipt_appliedVote_node_not_in_active_nodesList')
failedReasons.push('Invalid receipt appliedReceipt appliedVote node is not in the active nodesList')
nestedCounterMessages.push('Invalid_receipt_appliedVote_node_not_in_active_nodesList')
return result
}
if (appliedVote.sign.owner !== cycleShardData.nodeShardDataMap.get(appliedVote.node_id).node.publicKey) {
Logger.mainLogger.error(
failedReasons.push(
'Invalid receipt appliedReceipt appliedVote node signature owner and node public key does not match'
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_appliedVote_node_signature_owner_and_node_public_key_does_not_match'
)
nestedCounterMessages.push(
'Invalid_receipt_appliedVote_node_signature_owner_and_node_public_key_does_not_match'
)
return result
}
if (!cycleShardData.parititionShardDataMap.get(homePartition).coveredBy[appliedVote.node_id]) {
Logger.mainLogger.error(
failedReasons.push(
'Invalid receipt appliedReceipt appliedVote node is not in the execution group of the tx'
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_appliedVote_node_not_in_execution_group_of_tx'
)
nestedCounterMessages.push('Invalid_receipt_appliedVote_node_not_in_execution_group_of_tx')
return result
}
if (!Crypto.verify(appliedVote)) {
Logger.mainLogger.error('Invalid receipt appliedReceipt appliedVote signature verification failed')
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_appliedVote_signature_verification_failed'
)
failedReasons.push('Invalid receipt appliedReceipt appliedVote signature verification failed')
nestedCounterMessages.push('Invalid_receipt_appliedVote_signature_verification_failed')
return result
}

// Check if the confirmOrChallenge node is in the execution group
if (!cycleShardData.nodeShardDataMap.has(confirmOrChallenge.nodeId)) {
Logger.mainLogger.error(
failedReasons.push(
'Invalid receipt appliedReceipt confirmOrChallenge node is not in the active nodesList'
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_confirmOrChallenge_node_not_in_active_nodesList'
)
nestedCounterMessages.push('Invalid_receipt_confirmOrChallenge_node_not_in_active_nodesList')
return result
}
if (
confirmOrChallenge.sign.owner !==
cycleShardData.nodeShardDataMap.get(confirmOrChallenge.nodeId).node.publicKey
) {
Logger.mainLogger.error(
failedReasons.push(
'Invalid receipt appliedReceipt confirmOrChallenge node signature owner and node public key does not match'
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_confirmOrChallenge_signature_owner_and_node_public_key_does_not_match'
)
nestedCounterMessages.push(
'Invalid_receipt_confirmOrChallenge_signature_owner_and_node_public_key_does_not_match'
)
return result
}
if (!cycleShardData.parititionShardDataMap.get(homePartition).coveredBy[confirmOrChallenge.nodeId]) {
Logger.mainLogger.error(
failedReasons.push(
'Invalid receipt appliedReceipt confirmOrChallenge node is not in the execution group of the tx'
)
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_confirmOrChallenge_node_not_in_execution_group_of_tx'
)
nestedCounterMessages.push('Invalid_receipt_confirmOrChallenge_node_not_in_execution_group_of_tx')
return result
}
if (!Crypto.verify(confirmOrChallenge)) {
Logger.mainLogger.error('Invalid receipt appliedReceipt confirmOrChallenge signature verification failed')
if (nestedCountersInstance)
nestedCountersInstance.countEvent(
'receipt',
'Invalid_receipt_confirmOrChallenge_signature_verification_failed'
)
failedReasons.push('Invalid receipt appliedReceipt confirmOrChallenge signature verification failed')
nestedCounterMessages.push('Invalid_receipt_confirmOrChallenge_signature_verification_failed')
return result
}

Expand All @@ -612,16 +577,15 @@ export const verifyReceiptData = async (
: Math.ceil(config.RECEIPT_CONFIRMATIONS / 2) // 3 out of 5 nodes
const { success, newReceipt } = await isReceiptRobust(receipt, executionGroupNodes, minConfirmations)
if (!success) {
Logger.mainLogger.error('Invalid receipt: Robust check failed')
if (nestedCountersInstance)
nestedCountersInstance.countEvent('receipt', 'Invalid_receipt_robust_check_failed')
failedReasons.push('Invalid receipt: Robust check failed')
nestedCounterMessages.push('Invalid_receipt_robust_check_failed')
return result
}
if (newReceipt) return { success: true, newReceipt }
return { success: true }
}

const calculateVoteHash = (vote: Receipt.AppliedVote): string => {
const calculateVoteHash = (vote: Receipt.AppliedVote, failedReasons = []): string => {
try {
if (config.usePOQo === true) {
const appliedHash = {
Expand All @@ -645,7 +609,7 @@ const calculateVoteHash = (vote: Receipt.AppliedVote): string => {
}
return Crypto.hashObj({ ...vote, node_id: '' })
} catch {
Logger.mainLogger.error('Error in calculateVoteHash', vote)
failedReasons.push('Error in calculateVoteHash', vote)
return ''
}
}
Expand All @@ -655,6 +619,8 @@ export const verifyArchiverReceipt = async (
): Promise<ReceiptVerificationResult> => {
const { txId, timestamp } = receipt.tx
const existingReceipt = await Receipt.queryReceiptByReceiptId(txId)
const failedReasons = []
const nestedCounterMessages = []
if (
config.usePOQo === false &&
existingReceipt &&
Expand All @@ -664,60 +630,65 @@ export const verifyArchiverReceipt = async (
) {
// If the existing receipt is confirmed, and the new receipt is challenged, then skip saving the new receipt
if (existingReceipt.appliedReceipt.confirmOrChallenge.message === 'confirm') {
const failedReason = `Existing receipt is confirmed, but new receipt is challenged ${txId}, ${receipt.cycle}, ${timestamp}`
const nestedCounterMessage = 'Existing_receipt_is_confirmed_but_new_receipt_is_challenged'
// if (nestedCountersInstance)
// nestedCountersInstance.countEvent(
// 'receipt',
// 'Existing_receipt_is_confirmed_but_new_receipt_is_challenged'
// )
return { success: false, failedReason, nestedCounterMessage }
failedReasons.push(
`Existing receipt is confirmed, but new receipt is challenged ${txId}, ${receipt.cycle}, ${timestamp}`
)
nestedCounterMessages.push('Existing_receipt_is_confirmed_but_new_receipt_is_challenged')
return { success: false, failedReasons, nestedCounterMessages }
}
}
if (config.verifyAppReceiptData) {

Check failure

Code scanning / CodeQL

User-controlled bypass of security check High

This condition guards a sensitive
action
, but a
user-provided value
controls it.
// if (profilerInstance) profilerInstance.profileSectionStart('Verify_app_receipt_data')
// if (nestedCountersInstance) nestedCountersInstance.countEvent('receipt', 'Verify_app_receipt_data')
const { valid, needToSave } = await verifyAppReceiptData(receipt, existingReceipt)
const { valid, needToSave } = await verifyAppReceiptData(
receipt,
existingReceipt,
failedReasons,
nestedCounterMessages
)
// if (profilerInstance) profilerInstance.profileSectionEnd('Verify_app_receipt_data')
if (!valid) {
const failedReason = `Invalid receipt: App Receipt Verification failed ${txId}, ${receipt.cycle}, ${timestamp}`
const nestedCounterMessage = 'Invalid_receipt_app_receipt_verification_failed'
// if (nestedCountersInstance)
// nestedCountersInstance.countEvent('receipt', 'Invalid_receipt_app_receipt_verification_failed')
return { success: false, failedReason, nestedCounterMessage }
failedReasons.push(
`Invalid receipt: App Receipt Verification failed ${txId}, ${receipt.cycle}, ${timestamp}`
)
nestedCounterMessages.push('Invalid_receipt_app_receipt_verification_failed')
return { success: false, failedReasons, nestedCounterMessages }
}
if (!needToSave) {
const failedReason = `Valid receipt: but no need to save ${txId}, ${receipt.cycle}, ${timestamp}`
const nestedCounterMessage = 'Valid_receipt_but_no_need_to_save'
// if (nestedCountersInstance)
// nestedCountersInstance.countEvent('receipt', 'Valid_receipt_but_no_need_to_save')
return { success: false, failedReason, nestedCounterMessage }
failedReasons.push(`Valid receipt: but no need to save ${txId}, ${receipt.cycle}, ${timestamp}`)
nestedCounterMessages.push('Valid_receipt_but_no_need_to_save')
return { success: false, failedReasons, nestedCounterMessages }
}
}
if (config.verifyAccountData) {

Check failure

Code scanning / CodeQL

User-controlled bypass of security check High

This condition guards a sensitive
action
, but a
user-provided value
controls it.
// if (profilerInstance) profilerInstance.profileSectionStart('Verify_receipt_account_data')
// if (nestedCountersInstance) nestedCountersInstance.countEvent('receipt', 'Verify_receipt_account_data')
const result = verifyAccountHash(receipt)
const result = verifyAccountHash(receipt, failedReasons, nestedCounterMessages)
// if (profilerInstance) profilerInstance.profileSectionEnd('Verify_receipt_account_data')
if (!result) {
const failedReason = `Invalid receipt: Account Verification failed ${txId}, ${receipt.cycle}, ${timestamp}`
const nestedCounterMessage = 'Invalid_receipt_account_verification_failed'
// if (nestedCountersInstance)
// nestedCountersInstance.countEvent('receipt', 'Invalid_receipt_account_verification_failed')
return { success: false, failedReason, nestedCounterMessage }
failedReasons.push(
`Invalid receipt: Account Verification failed ${txId}, ${receipt.cycle}, ${timestamp}`
)
nestedCounterMessages.push('Invalid_receipt_account_verification_failed')
return { success: false, failedReasons, nestedCounterMessages }
}
}
if (config.verifyReceiptData) {

Check failure

Code scanning / CodeQL

User-controlled bypass of security check High

This condition guards a sensitive
action
, but a
user-provided value
controls it.
// if (profilerInstance) profilerInstance.profileSectionStart('Verify_receipt_data')
// if (nestedCountersInstance) nestedCountersInstance.countEvent('receipt', 'Verify_receipt_data')
const { success, newReceipt } = await verifyReceiptData(receipt)
const { success, newReceipt } = await verifyReceiptData(
receipt,
true,
failedReasons,
nestedCounterMessages
)
// if (profilerInstance) profilerInstance.profileSectionEnd('Verify_receipt_data')
if (!success) {
const failedReason = `Invalid receipt: Verification failed ${txId}, ${receipt.cycle}, ${timestamp}`
const nestedCounterMessage = 'Invalid_receipt_verification_failed'
return { success: false, failedReason, nestedCounterMessage }
failedReasons.push(`Invalid receipt: Verification failed ${txId}, ${receipt.cycle}, ${timestamp}`)
nestedCounterMessages.push('Invalid_receipt_verification_failed')
return { success: false, failedReasons, nestedCounterMessages }
}
return { success: true, failedReason: '', nestedCounterMessage: '', newReceipt }
return { success: true, failedReasons, nestedCounterMessages, newReceipt }
}
return { success: true }
}
Expand Down Expand Up @@ -759,12 +730,17 @@ export const storeReceiptData = async (
continue
}

const stringifiedReceipt = StringUtils.safeStringify(receipt)
if (verifyData) {
const result = await offloadReceipt(receipt)
const result = await offloadReceipt(txId, timestamp, stringifiedReceipt, receipt)
if (result.success === false) {
receiptsInValidationMap.delete(txId)
Logger.mainLogger.error(result.failedReason)
if (nestedCountersInstance) nestedCountersInstance.countEvent('receipt', result.nestedCounterMessage)
for (const message of result.failedReasons) {
Logger.mainLogger.error(message)
}
for (const message of result.nestedCounterMessages) {
if (nestedCountersInstance) nestedCountersInstance.countEvent('receipt', message)
}
if (profilerInstance) profilerInstance.profileSectionEnd('Validate_receipt')
continue
}
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Cycles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ function updateShardValues(cycle: P2PTypes.CycleCreatorTypes.CycleData): void {
shardValuesByCycle.set(cycleShardData.cycleNumber, cycleShardData)
}

const cleanShardCycleData = (cycleNumber: number): void => {
export const cleanShardCycleData = (cycleNumber: number): void => {
for (const [key] of shardValuesByCycle) {
if (key < cycleNumber) {
shardValuesByCycle.delete(key)
Expand Down
Loading

0 comments on commit c107ac0

Please sign in to comment.