Skip to content

perf: cache txid() and hash() to avoid redundant serialize + SHA256#171

Open
ALiberalVoluntarist wants to merge 1 commit into
masterfrom
perf/txid-cache
Open

perf: cache txid() and hash() to avoid redundant serialize + SHA256#171
ALiberalVoluntarist wants to merge 1 commit into
masterfrom
perf/txid-cache

Conversation

@ALiberalVoluntarist

Copy link
Copy Markdown
Collaborator

Summary

  • txid() previously recomputed serialize() + double SHA256 on every call with no caching
  • In BEEF workflows with deep ancestor chains, the same tx objects have txid() called 3–6 times across chain building, topology sorting, MP resolution, and verification — all redundant after the first computation
  • Add _cached_hash / _cached_txid fields to Transaction with invalidation on mutation methods (add_input, add_output, sign, _apply_fee_amount)

Benchmark results

Test Cached Uncached Speedup
Chain walk (depth=100, 5 iterations) 0.05 ms 1.90 ms 38x
Single tx repeated calls (1000x) 0.05 ms 3.49 ms 73x

Test plan

  • New test class TestTxidCache — correctness (7 tests) + benchmarks (2 tests)
  • Cache returns correct value matching manual hash256(serialize())
  • Cache invalidated on add_input(), add_output()
  • from_reader / from_hex starts with clean cache
  • Cached txid() returns same object identity (is)
  • Full existing test suite passes (5083 passed, 0 regressions)

🤖 Generated with Claude Code

txid() previously recomputed serialize() + double SHA256 on every call.
In BEEF workflows with deep ancestor chains (depth=100), the same tx
objects have txid() called 3-6 times across chain building, topology
sorting, MP resolution, and verification — all redundant after the
first computation.

Add _cached_hash and _cached_txid fields with invalidation on
add_input(), add_output(), sign(), and _apply_fee_amount().
Deserialized transactions (from_reader/from_hex/from_beef) are
effectively immutable, so the cache persists for their entire lifetime.

Benchmark results (depth=100 chain, 5 walks):
  Cached:   0.05 ms  vs  Uncached: 1.90 ms  → 38x speedup
  Single tx 1000 calls: 73x speedup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

Test Coverage Report

📊 Coverage: 84.7%

View the full coverage report in the build artifacts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants