transactions table: Store hash as BYTEA#495
transactions table: Store hash as BYTEA#495aditya1702 wants to merge 14 commits intoaccountid-bytea-txnsfrom
transactions table: Store hash as BYTEA#495Conversation
Implements Scan, Value, and String methods following the AddressBytea pattern. Stores 32-byte raw SHA-256 hash in database, represents as 64-character hex string in Go.
Changes the Hash field from string to HashBytea for automatic BYTEA serialization/deserialization in the database.
Converts the ingest transaction hash to HashBytea type for proper database serialization.
Converts HashBytea to string for use as map key since HashBytea is not directly comparable as a map key type.
- GetByHash: Convert input hash string to HashBytea for query - BatchInsert: Convert hashes to [][]byte, use bytea[] in SQL, return hex-encoded hashes - BatchCopy: Convert hash to bytes using Hash.Value()
Stores 32-byte raw SHA-256 hash instead of 64-char hex string, reducing storage by ~50%.
Tests for Scan, Value, Roundtrip, and String methods following the same pattern as AddressBytea tests.
All test files now use valid hex strings that can be converted to 32-byte BYTEA values instead of simple strings like "tx1", "tx2".
hash as BYTEAtransactions table: Store hash as BYTEA
There was a problem hiding this comment.
Pull request overview
This PR updates the codebase to store transactions.hash as BYTEA (raw 32 bytes) in Postgres while keeping the Go/GraphQL-facing representation as a 64-char hex string.
Changes:
- Introduces
types.HashByteawithsql.Scanner/driver.Valuerimplementations and updatestypes.Transaction.Hashto use it. - Updates transaction ingestion and data-layer inserts/queries to bind hashes as
BYTEA/bytea[](plus corresponding test updates). - Updates GraphQL schema/resolvers so
Transaction.hashcontinues to resolve as aStringdespite the underlying Go type change.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/db/migrations/2025-06-10.2-transactions.sql | Changes transactions.hash column type to BYTEA in the migration script. |
| internal/indexer/types/types.go | Adds HashBytea and switches Transaction.Hash to HashBytea. |
| internal/indexer/types/types_test.go | Adds unit tests for HashBytea Scan/Value/roundtrip/String. |
| internal/indexer/processors/utils.go | Converts ingested transaction hashes to types.HashBytea. |
| internal/indexer/indexer_buffer.go | Adjusts buffer keying to use transaction.Hash.String(). |
| internal/indexer/indexer_buffer_test.go | Updates buffer tests to use valid 64-char hex hashes. |
| internal/data/transactions.go | Updates GetByHash, BatchInsert, and BatchCopy to bind hash as BYTEA. |
| internal/data/transactions_test.go | Updates transaction model tests to use valid hex hashes and HashBytea comparisons. |
| internal/data/statechanges.go | Updates tx-hash filtering to bind as types.HashBytea. |
| internal/data/statechanges_test.go | Updates state change tests/fixtures to insert/query BYTEA hashes. |
| internal/data/operations_test.go | Updates operation tests/fixtures to insert BYTEA hashes. |
| internal/data/accounts_test.go | Updates account tests/fixtures to insert BYTEA hashes. |
| internal/services/ingest_test.go | Updates ingest tests to use hex hashes and bind hash params as HashBytea/[]byte. |
| internal/serve/graphql/schema/transaction.graphqls | Forces resolver for Transaction.hash to keep GraphQL type String!. |
| internal/serve/graphql/resolvers/transaction.resolvers.go | Adds Hash() field resolver returning obj.Hash.String(). |
| internal/serve/graphql/generated/generated.go | Regenerates gqlgen output to route hash through the new resolver. |
| internal/serve/graphql/resolvers/test_utils.go | Updates GraphQL test DB setup to insert types.HashBytea hashes and adds shared hash constants. |
| internal/serve/graphql/resolvers/*_test.go | Updates GraphQL resolver tests to compare/use hex hashes via .String(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| CREATE TABLE transactions ( | ||
| to_id BIGINT PRIMARY KEY, | ||
| hash TEXT NOT NULL UNIQUE, | ||
| hash BYTEA NOT NULL UNIQUE, |
There was a problem hiding this comment.
This change edits an existing migration file (2025-06-10.2-transactions.sql) to switch transactions.hash from TEXT to BYTEA. If this migration has already been applied in any environment, changing it won’t update existing databases and will instead desync schema history from code expectations. Add a new forward migration that ALTER TABLE transactions ALTER COLUMN hash TYPE BYTEA USING decode(hash, 'hex') (and handle/recreate the UNIQUE constraint/index as needed), and keep historical migrations immutable.
| }} | ||
| // ToID=toid.New(1000, 1, 0) matches the test data setup in test_utils.go (testLedger=1000, i=0) | ||
| parentTx := &types.Transaction{Hash: "tx1", ToID: toid.New(1000, 1, 0).ToInt64()} | ||
| parentTx := &types.Transaction{Hash: "1376b7b0133690fbfb2de8fa9ca2273cb4f2e29447e0cf0e14a5f82d0daa4877", ToID: toid.New(1000, 1, 0).ToInt64()} |
There was a problem hiding this comment.
The parentTx.Hash value here is hard-coded to a hash that doesn’t match the hashes inserted by setupDB() (which uses the 3476...487%x pattern exposed as testTxHash1..4). The nearby comment says it matches the setup data, but it currently doesn’t, which makes the fixture relationship unclear and could hide issues if hash starts being used by these resolvers later. Prefer using testTxHash1 (and similarly update the other parentTx occurrences in this file) to keep tests consistent with the shared DB setup.
| parentTx := &types.Transaction{Hash: "1376b7b0133690fbfb2de8fa9ca2273cb4f2e29447e0cf0e14a5f82d0daa4877", ToID: toid.New(1000, 1, 0).ToInt64()} | |
| parentTx := &types.Transaction{Hash: testTxHash1, ToID: toid.New(1000, 1, 0).ToInt64()} |
What
[TODO: Short statement about what is changing.]
Why
[TODO: Why this change is being made. Include any context required to understand the why.]
Known limitations
[TODO or N/A]
Issue that this PR addresses
[TODO: Attach the link to the GitHub issue or task. Include the priority of the task here in addition to the link.]
Checklist
PR Structure
allif the changes are broad or impact many packages.Thoroughness
Release