Skip to content

Commit

Permalink
put archiver robust query behind flag
Browse files Browse the repository at this point in the history
  • Loading branch information
S0naliThakur committed Nov 26, 2024
1 parent b6f418a commit c131ed4
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export interface Config {
disableOffloadReceipt: boolean // To disable offloading of receipts globally
disableOffloadReceiptForGlobalModification: boolean // To disable offloading of receipts for global modifications receipts
restoreNGTsFromSnapshot: boolean // To restore NGTs from snapshot
useRobustQueryForReceipt: boolean // To enable receipt robust check
}

let config: Config = {
Expand Down Expand Up @@ -195,6 +196,7 @@ let config: Config = {
disableOffloadReceipt: false,
disableOffloadReceiptForGlobalModification: true,
restoreNGTsFromSnapshot: false,
useRobustQueryForReceipt: false,
}
// Override default config params from config file, env vars, and cli args
export async function overrideDefaultConfig(file: string): Promise<void> {
Expand Down
86 changes: 86 additions & 0 deletions src/Data/Collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ const isReceiptRobust = async (
executionGroupNodes: ConsensusNodeInfo[],
minConfirmations: number = config.RECEIPT_CONFIRMATIONS
): Promise<{ success: boolean; newReceipt?: Receipt.ArchiverReceipt }> => {
// If robustQuery is disabled, do offline verification
if (!config.useRobustQueryForReceipt) {

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.
return verifyReceiptOffline(receipt, executionGroupNodes, minConfirmations)
}

const result = { success: false }
// Created signedData with full_receipt = false outside of queryReceipt to avoid signing the same data multiple times
let signedData = Crypto.sign({
Expand Down Expand Up @@ -270,6 +275,87 @@ const isReceiptRobust = async (
return { success: true }
}

// Offline receipt verification
const verifyReceiptOffline = async (
receipt: Receipt.ArchiverReceipt,
executionGroupNodes: ConsensusNodeInfo[],
minConfirmations: number
): Promise<{ success: boolean; newReceipt?: Receipt.ArchiverReceipt }> => {
const { signedReceipt, globalModification } = receipt

if (globalModification) {
const globalReceipt = signedReceipt as P2PTypes.GlobalAccountsTypes.GlobalTxReceipt
// Verify global modification receipt has enough valid signatures
const validSigners = new Set<string>()

// Ensure signs array exists and is not empty
if (!globalReceipt.signs || !Array.isArray(globalReceipt.signs) || globalReceipt.signs.length === 0) {
return { success: false }
}

// Ensure tx exists and has required fields
if (!globalReceipt.tx || !globalReceipt.tx.address) {
return { success: false }
}

for (const sign of globalReceipt.signs) {
// Skip invalid signatures
if (!sign || !sign.owner) continue

const node = executionGroupNodes.find(n => n.publicKey === sign.owner)
if (!node) continue

try {
if (Crypto.verify({ ...globalReceipt.tx, sign })) {
validSigners.add(sign.owner)
}
} catch (error) {
console.error('Error verifying signature:', error)
continue
}
}

return {
success: validSigners.size >= minConfirmations
}
}

// Rest of the function remains the same...
// Code for normal receipts verification
const normalReceipt = signedReceipt as Receipt.SignedReceipt
const validSigners = new Set<string>()

if (!normalReceipt.signaturePack || !Array.isArray(normalReceipt.signaturePack)) {
return { success: false }
}

for (const signature of normalReceipt.signaturePack) {
if (!signature || !signature.owner) continue

const node = executionGroupNodes.find(n => n.publicKey === signature.owner)
if (!node) continue

try {
const voteHash = calculateVoteHash(normalReceipt.proposal)
const appliedVoteHash = {
txid: receipt.tx.txId,
voteHash
}

if (Crypto.verify({ ...appliedVoteHash, sign: signature })) {
validSigners.add(signature.owner)
}
} catch (error) {
console.error('Error verifying signature:', error)
continue
}
}

return {
success: validSigners.size >= minConfirmations
}
}

/**
* Validate type and field existence of the receipt data before processing it further
* @param receipt
Expand Down

0 comments on commit c131ed4

Please sign in to comment.