Skip to content

chore: request attestation bounded#1347

Merged
MicBun merged 3 commits into
mainfrom
boundedAttestation
Mar 30, 2026
Merged

chore: request attestation bounded#1347
MicBun merged 3 commits into
mainfrom
boundedAttestation

Conversation

@MicBun
Copy link
Copy Markdown
Contributor

@MicBun MicBun commented Mar 30, 2026

resolves: https://github.com/truflation/website/issues/3565

Summary by CodeRabbit

  • New Features

    • Enforced attestation date-range validation with a 90-day maximum and strict from/to rules.
  • Changes

    • Several query result sets are now capped at 10,000 rows to prevent unbounded results.
    • Date-range validation runs earlier in request processing; some action types intentionally bypass the range check.
  • Tests

    • Added integration tests covering attestation date-range scenarios and edge cases.

@MicBun MicBun requested a review from pr-time-tracker March 30, 2026 12:57
@MicBun MicBun self-assigned this Mar 30, 2026
@holdex
Copy link
Copy Markdown

holdex Bot commented Mar 30, 2026

Time Submission Status

Member Status Time Action Last Update
MicBun ✅ Submitted 5h Update time Mar 30, 2026, 2:39 PM

You can submit time with the command. Example:

@holdex pr submit-time 15m

See available commands to help comply with our Guidelines.

@MicBun
Copy link
Copy Markdown
Contributor Author

MicBun commented Mar 30, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Adds a new VIEW precompile validate_attestation_date_range (90‑day max) and invokes it from request_attestation; introduces LIMIT 10000 caps to several record/composed query actions; and adds integration tests and test helpers to validate attestation date‑range behavior.

Changes

Cohort / File(s) Summary
Precompile: attestation date-range
extensions/tn_utils/precompiles.go
Added MaxAttestationDateRangeSeconds constant, validate_attestation_date_range method registration, validateAttestationDateRangeHandler, and derefIntPtr helper. Handler decodes action_id/args_bytes, validates only action IDs 1–3, requires both-or-none bounds, enforces from<=to and max 90‑day window.
Attestation SQL integration
internal/migrations/024-attestation-actions.sql
Inserted call to tn_utils.validate_attestation_date_range($action_id, $args_bytes) into request_attestation immediately after computing $stream_bytes to cause early failure on invalid ranges.
Query result caps (LIMIT 10000)
internal/migrations/005-primitive-query.sql, internal/migrations/006-composed-query.sql, internal/migrations/007-composed-query-derivate.sql, internal/migrations/009-truflation-query.sql
Added LIMIT 10000 to final SELECTs in multiple primitive/composed/truflation actions to cap returned rows.
Integration tests: attestation
tests/streams/attestation/attestation_date_range_test.go
Added TestAttestationDateRangeValidation covering valid/over-limit ranges, null-bounds rules, boundary conditions, binary-action bypasses, and other action behavior.
Test helpers
tests/streams/attestation/request_attestation_fee_test.go
Added requestAttestationWithArgsBytes and insertTestDataPoint helpers and an import for typed decimals to support pre-encoded args and inserting test data.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Engine
  participant Precompile as tn_utils.validate_attestation_date_range
  participant DB as Postgres

  Client->>Engine: CALL request_attestation(action_id, args_bytes, ...)
  Engine->>Precompile: tn_utils.validate_attestation_date_range(action_id, args_bytes)
  Precompile->>Precompile: decode action_id and args_bytes
  alt action_id in [1..3]
    Precompile->>Precompile: extract from/to, validate both-or-none, from<=to, range<=90d
    Precompile-->>Engine: return error (if invalid) or success
  else other action_id
    Precompile-->>Engine: return success (no validation)
  end
  Engine->>DB: dispatch attestation/query (if precompile returned success)
  DB-->>Engine: query result
  Engine-->>Client: result or error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • outerlook
  • pr-time-tracker

Poem

🐰 I hopped through code to guard the span,
Ninety days kept tidy by my tiny hand.
Ten‑thousand rows trimmed to keep things light,
Bounds checked and balanced, morning to night.
A carrot for tests — all green and right. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.92% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'chore: request attestation bounded' is generic and vague. While it hints at attestation bounding, it does not clearly convey the main scope of changes, which include precompile registration, SQL query result limits, validation logic, and comprehensive testing. Consider a more descriptive title such as 'Add attestation date-range validation with bounded query results' to better reflect the scope of changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch boundedAttestation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MicBun MicBun changed the title chore: reqest attestation bounded chore: request attestation bounded Mar 30, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
extensions/tn_utils/precompiles.go (1)

807-810: Consider validating that from is not greater than to.

The validation checks if dateRange > MaxAttestationDateRangeSeconds, but if from > to, dateRange becomes negative and passes the check. While downstream queries may handle this gracefully (returning empty results), an explicit validation would provide a clearer error message.

Proposed fix
 	dateRange := toTS - fromTS
+	if dateRange < 0 {
+		return fmt.Errorf("attestation 'from' timestamp (%d) must not be greater than 'to' timestamp (%d)", fromTS, toTS)
+	}
 	if dateRange > MaxAttestationDateRangeSeconds {
 		return fmt.Errorf("attestation date range of %d seconds exceeds maximum of %d seconds (90 days)", dateRange, MaxAttestationDateRangeSeconds)
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@extensions/tn_utils/precompiles.go` around lines 807 - 810, Add an explicit
check that fromTS is not greater than toTS before computing dateRange in the
attestation validation logic (around the dateRange := toTS - fromTS block); if
fromTS > toTS return a clear error (e.g., "invalid attestation date range: from
is after to") instead of allowing a negative dateRange to bypass
MaxAttestationDateRangeSeconds; reference the variables fromTS, toTS, dateRange
and the constant MaxAttestationDateRangeSeconds when implementing this
validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/streams/attestation/attestation_date_range_test.go`:
- Around line 144-156: Update the inline signature comment for get_last_record
to include the missing $use_cache parameter: change the comment currently above
the test (referencing get_last_record and the test variables lastRecordArgs,
argsBytes, tn_utils.EncodeActionArgs, and requestAttestationWithArgsBytes) from
four parameters to five by appending ", $use_cache BOOL" so it matches the
actual arguments passed in the test.

In `@tests/streams/attestation/request_attestation_fee_test.go`:
- Around line 460-472: The new helper calling platform.Engine.Call for
"request_attestation" passes dataProvider with different casing than the
existing callRequestAttestationActionWithTimeRange; normalize dataProvider by
lowercasing it (e.g., use strings.ToLower(dataProvider)) before passing to
platform.Engine.Call so it matches the other helper and avoids hash/lookup
mismatches; update the call in this helper to use the lowercased dataProvider
variable (and add the strings import if missing).

---

Nitpick comments:
In `@extensions/tn_utils/precompiles.go`:
- Around line 807-810: Add an explicit check that fromTS is not greater than
toTS before computing dateRange in the attestation validation logic (around the
dateRange := toTS - fromTS block); if fromTS > toTS return a clear error (e.g.,
"invalid attestation date range: from is after to") instead of allowing a
negative dateRange to bypass MaxAttestationDateRangeSeconds; reference the
variables fromTS, toTS, dateRange and the constant
MaxAttestationDateRangeSeconds when implementing this validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c272be1f-7bcc-4301-b1d8-5d344cc652d7

📥 Commits

Reviewing files that changed from the base of the PR and between 3c75c95 and f2db065.

📒 Files selected for processing (8)
  • extensions/tn_utils/precompiles.go
  • internal/migrations/005-primitive-query.sql
  • internal/migrations/006-composed-query.sql
  • internal/migrations/007-composed-query-derivate.sql
  • internal/migrations/009-truflation-query.sql
  • internal/migrations/024-attestation-actions.sql
  • tests/streams/attestation/attestation_date_range_test.go
  • tests/streams/attestation/request_attestation_fee_test.go

Comment thread tests/streams/attestation/attestation_date_range_test.go
Comment thread tests/streams/attestation/request_attestation_fee_test.go
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/streams/attestation/request_attestation_fee_test.go (1)

439-482: Extract a shared request_attestation call helper.

This duplicates the TxContext + platform.Engine.Call(...) setup from callRequestAttestationActionWithTimeRange almost verbatim. A single helper that takes pre-encoded argsBytes would keep normalization/auth/proposer changes from drifting between the two paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/streams/attestation/request_attestation_fee_test.go` around lines 439 -
482, The test contains duplicated setup for TxContext and calling the engine
between requestAttestationWithArgsBytes and
callRequestAttestationActionWithTimeRange; extract a shared helper (e.g.,
makeRequestAttestationCall or reuse requestAttestationWithArgsBytes) that builds
the common TxContext/EngineContext (using TxContext, BlockContext, Signer,
Caller, TxID, Authenticator) and invokes platform.Engine.Call with the
pre-encoded argsBytes, then have both callRequestAttestationActionWithTimeRange
and requestAttestationWithArgsBytes delegate to that helper to avoid drift in
normalization/auth/proposer logic.
tests/streams/attestation/attestation_date_range_test.go (1)

137-155: Add a get_change_over_time case here too.

This is the only range-validated action family member that still is not exercised end-to-end. Since the precompile branches on action IDs 1..3, one analogous success/failure case for get_change_over_time would pin that remaining mapping down as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/streams/attestation/attestation_date_range_test.go` around lines 137 -
155, Add an end-to-end test exercising the range-validated action
"get_change_over_time" alongside the existing get_index/get_last_record tests:
construct appropriate args (matching the signature used by
get_change_over_time), encode them with tn_utils.EncodeActionArgs, and call
requestAttestationWithTimeRange (for the failure case with from180/to180) and
requestAttestationWithArgsBytes (for the success/skip case if applicable) using
the same ctx, platform, &systemAdmin, systemAdmin.Address(), and streamID
variables; ensure you assert the expected failure contains "exceeds maximum" for
the 180-day range and a successful NoError where validation should be skipped,
mirroring the pattern used for "get_index" and "get_last_record".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@extensions/tn_utils/precompiles.go`:
- Around line 785-805: fromVal/toVal parsing currently only unwraps *int/*int64
and then calls toInt64, which misses integer shapes DecodeActionArgs can produce
(int8,int16,int32,uint,uint8,uint16,uint32,uint64 and pointer variants); update
the parsing to normalize every supported integer shape into a single int64
value: either extend toInt64 to accept all integer kinds (and pointer forms) via
a comprehensive type switch or update derefIntPtr to return the raw value and
perform a type switch that converts int8/int16/int32/uint*/uint64/etc. to int64
before using it; ensure you update both the shown range-checking block
(variables fromVal/toVal) and the other similar parsing site handling ranges so
all integer widths and pointer variants from DecodeActionArgs are handled
consistently.

---

Nitpick comments:
In `@tests/streams/attestation/attestation_date_range_test.go`:
- Around line 137-155: Add an end-to-end test exercising the range-validated
action "get_change_over_time" alongside the existing get_index/get_last_record
tests: construct appropriate args (matching the signature used by
get_change_over_time), encode them with tn_utils.EncodeActionArgs, and call
requestAttestationWithTimeRange (for the failure case with from180/to180) and
requestAttestationWithArgsBytes (for the success/skip case if applicable) using
the same ctx, platform, &systemAdmin, systemAdmin.Address(), and streamID
variables; ensure you assert the expected failure contains "exceeds maximum" for
the 180-day range and a successful NoError where validation should be skipped,
mirroring the pattern used for "get_index" and "get_last_record".

In `@tests/streams/attestation/request_attestation_fee_test.go`:
- Around line 439-482: The test contains duplicated setup for TxContext and
calling the engine between requestAttestationWithArgsBytes and
callRequestAttestationActionWithTimeRange; extract a shared helper (e.g.,
makeRequestAttestationCall or reuse requestAttestationWithArgsBytes) that builds
the common TxContext/EngineContext (using TxContext, BlockContext, Signer,
Caller, TxID, Authenticator) and invokes platform.Engine.Call with the
pre-encoded argsBytes, then have both callRequestAttestationActionWithTimeRange
and requestAttestationWithArgsBytes delegate to that helper to avoid drift in
normalization/auth/proposer logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cd6022b1-3be1-425b-9ffb-60ca301adfcb

📥 Commits

Reviewing files that changed from the base of the PR and between f2db065 and a064179.

📒 Files selected for processing (3)
  • extensions/tn_utils/precompiles.go
  • tests/streams/attestation/attestation_date_range_test.go
  • tests/streams/attestation/request_attestation_fee_test.go

Comment thread extensions/tn_utils/precompiles.go
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
extensions/tn_utils/precompiles.go (1)

797-803: ⚠️ Potential issue | 🟠 Major

Integer-shape normalization is still incomplete for from/to conversion.

derefIntPtr now unwraps *int16, *int8, and *uint, but toInt64 still rejects int16, int8, and uint. Those valid decoded shapes will still fail during validation.

🔧 Proposed fix
 func toInt64(value any) (int64, error) {
 	switch v := value.(type) {
 	case int64:
 		return v, nil
 	case int32:
 		return int64(v), nil
+	case int16:
+		return int64(v), nil
+	case int8:
+		return int64(v), nil
 	case int:
 		return int64(v), nil
+	case uint:
+		if uint64(v) > math.MaxInt64 {
+			return 0, fmt.Errorf("value %d exceeds int64 max", v)
+		}
+		return int64(v), nil
 	case uint64:
 		if v > math.MaxInt64 {
 			return 0, fmt.Errorf("value %d exceeds int64 max", v)
 		}
 		return int64(v), nil
 	case uint32:
 		return int64(v), nil
 	case uint16:
 		return int64(v), nil
 	case uint8:
 		return int64(v), nil
 	default:
 		return 0, fmt.Errorf("expected integer type, got %T", value)
 	}
 }

Also applies to: 821-889

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@extensions/tn_utils/precompiles.go` around lines 797 - 803, The validation
fails because derefIntPtr now returns pointer types like *int16, *int8 and *uint
but toInt64 still rejects those shapes; update the toInt64 function (used when
parsing fromVal/toVal into fromTS/toTS) to accept and correctly convert int8,
int16, and uint (and their pointer-unwrapped equivalents) to int64 (handling
unsigned-to-signed conversion safely) so the decoded shapes accepted by
derefIntPtr no longer cause errors; also apply the same broadened type handling
to the other toInt64 usages in the adjacent block (the region corresponding to
the 821–889 diff).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@extensions/tn_utils/precompiles.go`:
- Around line 797-803: The validation fails because derefIntPtr now returns
pointer types like *int16, *int8 and *uint but toInt64 still rejects those
shapes; update the toInt64 function (used when parsing fromVal/toVal into
fromTS/toTS) to accept and correctly convert int8, int16, and uint (and their
pointer-unwrapped equivalents) to int64 (handling unsigned-to-signed conversion
safely) so the decoded shapes accepted by derefIntPtr no longer cause errors;
also apply the same broadened type handling to the other toInt64 usages in the
adjacent block (the region corresponding to the 821–889 diff).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2cfbdfb0-4f77-4279-8939-5f5695a875ec

📥 Commits

Reviewing files that changed from the base of the PR and between a064179 and d2e7eb0.

📒 Files selected for processing (2)
  • extensions/tn_utils/precompiles.go
  • tests/streams/attestation/attestation_date_range_test.go
✅ Files skipped from review due to trivial changes (1)
  • tests/streams/attestation/attestation_date_range_test.go

@MicBun MicBun merged commit 489f99b into main Mar 30, 2026
8 checks passed
@MicBun MicBun deleted the boundedAttestation branch March 30, 2026 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant