Skip to content

audit transaction-block-array indexing for fork safety #963

@oskarszoon

Description

@oskarszoon

Problem

txMeta.BlockIDs and txMeta.BlockHeights are parallel arrays of every block a tx has been observed in, including orphans. Several call sites pick index [0] without checking main-chain membership. Under fork conditions, index 0 can be an orphan block.

The /merkle_proof instance is tracked separately. This issue is to audit the rest.

Call sites to review

  • services/validator/Validator.go:886utxoHeights[idx] = txMeta.BlockHeights[0]. Parent tx height used for UTXO maturity (coinbase 100-block rule) and locktime evaluation. If the parent crossed a fork boundary, height could be off-by-one or wrong-fork. Likely bug — coinbase maturity is consensus-critical.
  • services/blockvalidation/quick_validate.go:399, 400, 522, 523, 651, 652existingBlockID = uint64(existingMeta.BlockIDs[0]) and block.ID = existingMeta.BlockIDs[0] during retry-resume. If existing meta has multiple block IDs, wrong fork's ID may be adopted.
  • model/Block.go:969parentTxMeta.BlockIDs[0] == GenesisBlockID. Genesis check; probably fine since genesis cannot be in a fork, but worth a comment.

Action

For each call site, determine whether the index-0 assumption is safe (e.g., genesis special case) or needs a main-chain filter. Add a regression test per site touched.

Out of scope

stores/utxo writes that just track all blocks where a tx appears — these are correct as-is, no main-chain restriction wanted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions