Skip to content

Commit 0eb9d53

Browse files
authored
fix: add more guardrails for binary_request_receipt_for_tx endpoint (#338)
1 parent bb6e061 commit 0eb9d53

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

src/state-manager/AccountPatcher.ts

+47
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ import {
9191
import { BadRequest, InternalError, serializeResponseError } from '../types/ResponseError'
9292
import { Utils } from '@shardus/types'
9393
import { RepairOOSAccountsReq, deserializeRepairOOSAccountsReq, serializeRepairOOSAccountsReq } from '../types/RepairOOSAccountsReq'
94+
import { robustQuery } from '../p2p/Utils'
95+
import { RequestReceiptForTxReqSerialized, serializeRequestReceiptForTxReq } from '../types/RequestReceiptForTxReq'
96+
import { deserializeRequestReceiptForTxResp, RequestReceiptForTxRespSerialized } from '../types/RequestReceiptForTxResp'
97+
import { Node } from '../shardus/shardus-types'
9498

9599
type Line = {
96100
raw: string
@@ -569,6 +573,49 @@ class AccountPatcher {
569573
continue
570574
}
571575

576+
const queryFn = async (node: Node) => {
577+
const message = { txid: txId, timestamp: accountData.timestamp }
578+
return await this.p2p.askBinary<
579+
RequestReceiptForTxReqSerialized,
580+
RequestReceiptForTxRespSerialized
581+
>(
582+
node,
583+
InternalRouteEnum.binary_request_receipt_for_tx,
584+
message,
585+
serializeRequestReceiptForTxReq,
586+
deserializeRequestReceiptForTxResp,
587+
{}
588+
)
589+
}
590+
591+
// make sure tx hasn't been altered by robust querying for the proposal using request txid and timestamp
592+
const txReceipt = await robustQuery(storageNodes, queryFn)
593+
if (txReceipt.isRobustResult === false) {
594+
nestedCountersInstance.countEvent(
595+
'accountPatcher',
596+
`binary/repair_oos_accounts: robust query failed for txId: ${txId}`
597+
)
598+
continue
599+
}
600+
601+
if (txReceipt.topResult.success !== true
602+
|| txReceipt.topResult.receipt == null
603+
|| txReceipt.topResult.receipt.proposalHash == null) {
604+
nestedCountersInstance.countEvent(
605+
'accountPatcher',
606+
`binary/repair_oos_accounts: robust query couldn't find queueEntry for txId: ${txId}`
607+
)
608+
continue
609+
}
610+
611+
if (signedReceipt.proposalHash !== txReceipt.topResult.receipt.proposalHash) {
612+
nestedCountersInstance.countEvent(
613+
'accountPatcher',
614+
`binary/repair_oos_accounts: proposal hash mismatch for txId: ${txId}`
615+
)
616+
continue
617+
}
618+
572619
// if (receivedBestVote != null) {
573620
// Check if vote is from eligible list of voters for this TX
574621
// if (

src/state-manager/TransactionConsensus.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,13 @@ class TransactionConsenus {
17351735
voteHash: receipt.proposalHash,
17361736
voteTime: 0,
17371737
}
1738+
1739+
if (
1740+
receipt.proposalHash !==
1741+
this.stateManager.transactionConsensus.calculateVoteHash(receipt.proposal)
1742+
) {
1743+
return false
1744+
}
17381745

17391746
for (let i = 0; i < receipt.signaturePack.length; i++) {
17401747
const sign = receipt.signaturePack[i]

src/state-manager/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,15 @@ class StateManager {
14281428
return
14291429
}
14301430

1431+
if (queueEntry.acceptedTx?.timestamp !== deserialized.timestamp) {
1432+
response.note = `requested timestamp does not match txid: ${utils.stringifyReduce(deserialized.txid)}
1433+
request: ${deserialized.timestamp}
1434+
queueuEntry timestamp: ${queueEntry.acceptedTx?.timestamp}
1435+
dbg:${this.debugTXHistory[utils.stringifyReduce(deserialized.txid)]}`
1436+
respond(response, serializeRequestReceiptForTxResp)
1437+
return
1438+
}
1439+
14311440
response.receipt = this.getSignedReceipt(queueEntry)
14321441
if (response.receipt != null) {
14331442
response.success = true

0 commit comments

Comments
 (0)