-
Notifications
You must be signed in to change notification settings - Fork 0
feat(utxorpc): implement submit.EvalTx #503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Warning Rate limit exceeded@wolf31o2 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 29 minutes and 0 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (7)
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughThis PR introduces script evaluation capabilities to the UTXORPC service layer. It updates dependencies to enable Plutus script handling, with plutigo added as a direct dependency (v0.0.16). The implementation adds a new Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes
Pre-merge checks and finishing touches✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (2)
go.mod(3 hunks)internal/utxorpc/submit.go(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
internal/utxorpc/submit.go (1)
internal/node/node.go (1)
GetConnection(31-75)
🪛 GitHub Actions: golangci-lint
internal/utxorpc/submit.go
[error] 256-256: golangci-lint: Consider pre-allocating txEvalRedeemers (prealloc)
🪛 GitHub Actions: nilaway
internal/utxorpc/submit.go
[error] 229-229: nilaway: Potential nil panic detected. Observed nil flow from source to dereference point at internal/utxorpc/submit.go:229.
🪛 GitHub Check: lint
internal/utxorpc/submit.go
[failure] 91-91:
evaluateScript - costModel is unused (unparam)
[failure] 256-256:
Consider pre-allocating txEvalRedeemers (prealloc)
🪛 GitHub Check: nilaway
internal/utxorpc/submit.go
[failure] 257-257:
�[31merror: �[0mPotential nil panic detected. Observed nil flow from source to dereference point:
[failure] 229-229:
�[31merror: �[0mPotential nil panic detected. Observed nil flow from source to dereference point:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: Analyze (go)
| github.com/blinklabs-io/adder v0.35.0 | ||
| github.com/blinklabs-io/gouroboros v0.142.0 | ||
| github.com/blinklabs-io/plutigo v0.0.16 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
blinklabs-io plutigo latest release version
💡 Result:
The latest release is v0.0.15 (released Nov 27, 2025). [1][2]
Sources:
[1] blinklabs-io/plutigo — Releases (GitHub).
[2] CardanoUpdates — blinklabs-io/adder (dependency bump referencing plutigo).
🌐 Web query:
blinklabs-io/adder go module latest release
💡 Result:
The latest release (tag) of the Go module github.com/blinklabs-io/adder is v0.33.0 — tagged Oct 26, 2025. [1][2]
Sources:
- GitHub tags for blinklabs-io/adder (v0.33.0, Oct 26, 2025). [1]
- pkg.go.dev module page for github.com/blinklabs-io/adder. [2]
🌐 Web query:
blinklabs-io/gouroboros go module latest release
💡 Result:
The latest release is tag v0.143.0 — published Dec 5, 2025. [1][2]
Sources:
[1] GitHub tags for blinklabs-io/gouroboros (v0.143.0, Dec 5, 2025).
[2] blinklabs-io/gouroboros repository README.
Address version discrepancies before merging.
The dependency versions in go.mod appear misaligned with latest public releases: plutigo v0.0.16 and adder v0.35.0 are ahead of the documented latest versions (plutigo v0.0.15 released Nov 27, 2025; adder v0.33.0 released Oct 26, 2025), while gouroboros v0.142.0 is behind the latest v0.143.0 (Dec 5, 2025). Clarify whether these versions are pre-release builds or development versions before deploying to production. Since plutigo remains in 0.0.x, verify its API stability for the new scripting features in this change.
🤖 Prompt for AI Agents
In go.mod around lines 11 to 13, the dependency versions are inconsistent with
public releases (plutigo v0.0.16 and adder v0.35.0 appear ahead of published
tags while gouroboros is behind v0.143.0); update go.mod to use the intended,
documented versions (or explicit pre-release pseudo-versions) and document the
decision: either pin to the latest published stable tags (e.g., adder v0.33.0
and plutigo v0.0.15) or, if you intentionally need unreleased/dev builds,
replace the entries with the exact commit pseudo-versions and add a note in the
repo (CHANGELOG or dependency file comment) indicating they are pre-release/dev.
After updating, run go get ./... and go mod tidy, run the unit/integration tests
to verify API compatibility (especially for plutigo's 0.0.x changes), and vendor
the modules or add a short note in the PR description documenting the stability
decision before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your information on the latest versions is incorrect. Ignoring this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the latest releases for the three dependencies using GitHub CLI
echo "=== Checking blinklabs-io/plutigo ==="
gh release list --repo blinklabs-io/plutigo --limit 5
echo ""
echo "=== Checking blinklabs-io/adder ==="
gh release list --repo blinklabs-io/adder --limit 5
echo ""
echo "=== Checking blinklabs-io/gouroboros ==="
gh release list --repo blinklabs-io/gouroboros --limit 5
echo ""
echo "=== Checking latest tags as well ==="
echo "plutigo tags:"
gh api repos/blinklabs-io/plutigo/tags --jq '.[0:5] | .[] | "\(.name) - \(.commit.sha[0:7])"'
echo ""
echo "adder tags:"
gh api repos/blinklabs-io/adder/tags --jq '.[0:5] | .[] | "\(.name) - \(.commit.sha[0:7])"'
echo ""
echo "gouroboros tags:"
gh api repos/blinklabs-io/gouroboros/tags --jq '.[0:5] | .[] | "\(.name) - \(.commit.sha[0:7])"'
Length of output: 1072
@wolf31o2, you're absolutely right, and I apologize for the incorrect information.
I've verified the actual latest releases:
- plutigo v0.0.16 (Dec 3, 2025) - Latest ✓
- adder v0.35.0 (Dec 5, 2025) - Latest ✓
- gouroboros v0.142.0 (Dec 1, 2025) - One version behind v0.143.0 (Dec 5, 2025)
The versions in your go.mod are correct and up-to-date. The gouroboros dependency is only one minor version behind, which is reasonable. Thank you for the correction!
internal/utxorpc/submit.go
Outdated
| // evaluateScript evaluates a Plutus script with the given arguments and cost model | ||
| func evaluateScript(scriptBytes []byte, args []data.PlutusData, costModel map[uint][]int64) (uint64, uint64, error) { | ||
| // Decode the script | ||
| program, err := syn.Decode[syn.DeBruijn](scriptBytes) | ||
| if err != nil { | ||
| return 0, 0, fmt.Errorf("decode script: %w", err) | ||
| } | ||
|
|
||
| // Apply arguments to the script | ||
| term := program.Term | ||
| for _, arg := range args { | ||
| term = &syn.Apply[syn.DeBruijn]{ | ||
| Function: term, | ||
| Argument: &syn.Constant{ | ||
| Con: &syn.Data{Inner: arg}, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| // Create machine with version-based cost model | ||
| machine := cek.NewMachineWithVersionCosts[syn.DeBruijn](program.Version, 200) | ||
|
|
||
| _, err = machine.Run(term) | ||
| if err != nil { | ||
| return 0, 0, fmt.Errorf("execute script: %w", err) | ||
| } | ||
|
|
||
| return uint64(machine.ExBudget.Cpu), uint64(machine.ExBudget.Mem), nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused costModel parameter and hardcoded budget value.
The costModel parameter is passed but never used (flagged by static analysis). Additionally, the hardcoded value 200 in NewMachineWithVersionCosts is unclear.
Either integrate the cost model into the machine creation or remove the parameter if it's not needed. Please clarify what the 200 value represents.
-func evaluateScript(scriptBytes []byte, args []data.PlutusData, costModel map[uint][]int64) (uint64, uint64, error) {
+func evaluateScript(scriptBytes []byte, args []data.PlutusData, version uint, costModel []int64) (uint64, uint64, error) {
// Decode the script
program, err := syn.Decode[syn.DeBruijn](scriptBytes)
if err != nil {
return 0, 0, fmt.Errorf("decode script: %w", err)
}
// Apply arguments to the script
term := program.Term
for _, arg := range args {
term = &syn.Apply[syn.DeBruijn]{
Function: term,
Argument: &syn.Constant{
Con: &syn.Data{Inner: arg},
},
}
}
- // Create machine with version-based cost model
- machine := cek.NewMachineWithVersionCosts[syn.DeBruijn](program.Version, 200)
+ // Create machine with version-based cost model
+ // TODO: Integrate costModel parameter properly
+ machine := cek.NewMachineWithVersionCosts[syn.DeBruijn](version, 200)Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 GitHub Check: lint
[failure] 91-91:
evaluateScript - costModel is unused (unparam)
🤖 Prompt for AI Agents
In internal/utxorpc/submit.go around lines 90 to 118, the function
evaluateScript accepts a costModel parameter that is never used and passes a
hardcoded literal 200 into NewMachineWithVersionCosts; update the function so
the provided costModel is applied when constructing the CEK machine (or remove
the unused parameter if callers never supply meaningful models). Concretely: if
callers supply costModel, convert it into the cost structure expected by
cek.NewMachineWithVersionCosts (or the appropriate machine constructor) and pass
that instead of 200; if costModel is not required, remove the parameter from the
signature and update all call sites. Also replace the magic literal 200 with a
named constant (e.g., DefaultCostLimit) or derive the value from the cost model
so the meaning is explicit.
| case *data.Integer: | ||
| return &cardano.PlutusData{ | ||
| PlutusData: &cardano.PlutusData_BigInt{ | ||
| BigInt: &cardano.BigInt{ | ||
| BigInt: &cardano.BigInt_Int{ | ||
| Int: v.Inner.Int64(), | ||
| }, | ||
| }, | ||
| }, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential integer overflow when converting large integers.
v.Inner.Int64() truncates values that exceed the int64 range. Plutus integers can be arbitrarily large. The cardano.BigInt type supports BigUInt for larger values.
case *data.Integer:
+ // Check if the integer fits in int64
+ if v.Inner.IsInt64() {
+ return &cardano.PlutusData{
+ PlutusData: &cardano.PlutusData_BigInt{
+ BigInt: &cardano.BigInt{
+ BigInt: &cardano.BigInt_Int{
+ Int: v.Inner.Int64(),
+ },
+ },
+ },
+ }
+ }
+ // Use BigUInt for larger integers
return &cardano.PlutusData{
PlutusData: &cardano.PlutusData_BigInt{
BigInt: &cardano.BigInt{
- BigInt: &cardano.BigInt_Int{
- Int: v.Inner.Int64(),
+ BigInt: &cardano.BigInt_BigUInt{
+ BigUInt: v.Inner.Bytes(),
},
},
},
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| case *data.Integer: | |
| return &cardano.PlutusData{ | |
| PlutusData: &cardano.PlutusData_BigInt{ | |
| BigInt: &cardano.BigInt{ | |
| BigInt: &cardano.BigInt_Int{ | |
| Int: v.Inner.Int64(), | |
| }, | |
| }, | |
| }, | |
| } | |
| case *data.Integer: | |
| // Check if the integer fits in int64 | |
| if v.Inner.IsInt64() { | |
| return &cardano.PlutusData{ | |
| PlutusData: &cardano.PlutusData_BigInt{ | |
| BigInt: &cardano.BigInt{ | |
| BigInt: &cardano.BigInt_Int{ | |
| Int: v.Inner.Int64(), | |
| }, | |
| }, | |
| }, | |
| } | |
| } | |
| // Use BigUInt for larger integers | |
| return &cardano.PlutusData{ | |
| PlutusData: &cardano.PlutusData_BigInt{ | |
| BigInt: &cardano.BigInt{ | |
| BigInt: &cardano.BigInt_BigUInt{ | |
| BigUInt: v.Inner.Bytes(), | |
| }, | |
| }, | |
| }, | |
| } |
| default: | ||
| // Should not happen | ||
| return nil | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silent nil return for unknown data types may cause downstream issues.
Returning nil silently for unexpected types could lead to nil pointer dereferences when the returned value is used (e.g., in map pairs or array items). Consider logging a warning or returning an error.
default:
- // Should not happen
+ // Log unexpected type for debugging
+ log.Printf("WARNING: unexpected PlutusData type: %T", pd)
return nil
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| default: | |
| // Should not happen | |
| return nil | |
| } | |
| default: | |
| // Log unexpected type for debugging | |
| log.Printf("WARNING: unexpected PlutusData type: %T", pd) | |
| return nil | |
| } |
🤖 Prompt for AI Agents
In internal/utxorpc/submit.go around lines 179 to 182, the switch default
currently returns nil silently for unknown data types which can cause nil
pointer dereferences downstream; change this to surface the problem by returning
an error (or at minimum logging a warning) that includes the unexpected type
information and context (e.g., the value and its reflect.Type or a descriptive
message) so callers can handle the failure instead of getting a nil; update the
function signature if necessary to propagate the error or ensure the caller
checks and handles the logged condition.
| // Get protocol parameters for cost models | ||
| oConn.LocalStateQuery().Client.Start() | ||
| protoParams, err := oConn.LocalStateQuery().Client.GetCurrentProtocolParams() | ||
| if err != nil { | ||
| return connect.NewResponse(resp), err | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for LocalStateQuery().Client.Start().
The Start() call may fail and should have its return value checked, similar to how other client operations are handled.
// Get protocol parameters for cost models
- oConn.LocalStateQuery().Client.Start()
+ if err := oConn.LocalStateQuery().Client.Start(); err != nil {
+ return connect.NewResponse(resp), fmt.Errorf("start local state query: %w", err)
+ }
protoParams, err := oConn.LocalStateQuery().Client.GetCurrentProtocolParams()📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Get protocol parameters for cost models | |
| oConn.LocalStateQuery().Client.Start() | |
| protoParams, err := oConn.LocalStateQuery().Client.GetCurrentProtocolParams() | |
| if err != nil { | |
| return connect.NewResponse(resp), err | |
| } | |
| // Get protocol parameters for cost models | |
| if err := oConn.LocalStateQuery().Client.Start(); err != nil { | |
| return connect.NewResponse(resp), fmt.Errorf("start local state query: %w", err) | |
| } | |
| protoParams, err := oConn.LocalStateQuery().Client.GetCurrentProtocolParams() | |
| if err != nil { | |
| return connect.NewResponse(resp), err | |
| } |
🤖 Prompt for AI Agents
In internal/utxorpc/submit.go around lines 220 to 225, the call
oConn.LocalStateQuery().Client.Start() is not checking its returned error;
update the code to capture the error from Start(), check if it's non-nil, and
return the same response/error pattern used elsewhere (e.g., return
connect.NewResponse(resp), err) so startup failures are propagated and handled
consistently.
| // Get cost models from protocol parameters | ||
| var costModels map[uint][]int64 | ||
| if conwayParams, ok := protoParams.(*ledger.ConwayProtocolParameters); ok { | ||
| costModels = conwayParams.CostModels | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only ConwayProtocolParameters are handled; other eras will have nil cost models.
If the node returns protocol parameters from a different era, costModels will remain nil, causing script evaluation to fail silently (empty cost model passed to evaluateScript).
// Get cost models from protocol parameters
var costModels map[uint][]int64
if conwayParams, ok := protoParams.(*ledger.ConwayProtocolParameters); ok {
costModels = conwayParams.CostModels
+ } else {
+ log.Printf("WARNING: unsupported protocol parameters type %T, script evaluation may fail", protoParams)
}🤖 Prompt for AI Agents
internal/utxorpc/submit.go around lines 231-235: the current code only extracts
CostModels when protoParams is *ledger.ConwayProtocolParameters, leaving
costModels nil for other eras which leads to silent script-evaluation failures.
Update the logic to handle other protocol-parameter types (e.g., Alonzo/Babbage
if present in your ledger package) by type-asserting those types and extracting
their CostModels, or if the ledger types share a common accessor use that; if no
cost models are available, return an explicit error instead of passing nil to
evaluateScript so callers can handle the unsupported era. Ensure you update
control flow and error messages accordingly.
| // Try to evaluate if we have a script for this redeemer | ||
| if int(key.Index) < len(allScripts) { | ||
| scriptBytes := allScripts[key.Index] | ||
| version := scriptVersions[key.Index] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect script lookup logic - redeemer index does not map to script array index.
The redeemer's key.Index represents the index of the input/output being redeemed (e.g., the input index for spending), not an index into the allScripts array. This will cause incorrect script-redeemer pairing and likely evaluation failures.
Scripts should be looked up by their hash, matching against the script hash referenced by the UTxO or policy being redeemed.
- // Try to evaluate if we have a script for this redeemer
- if int(key.Index) < len(allScripts) {
- scriptBytes := allScripts[key.Index]
- version := scriptVersions[key.Index]
+ // TODO: Look up the correct script by hash based on redeemer purpose and index
+ // For spending: get the script hash from the input's UTxO
+ // For minting: get the script hash from the policy ID
+ // For now, skip evaluation until proper script matching is implemented
+ _ = allScripts // Avoid unused variable warning
+ _ = scriptVersionsCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
internal/utxorpc/submit.go around lines 268 to 271: the code incorrectly treats
redeemer key.Index as an index into allScripts; replace this with a lookup by
script hash: obtain the script hash referenced by the UTxO or policy being
redeemed (from the tx input/output or datum/policy context), iterate or use a
map to find the matching entry in allScripts by comparing hashes, retrieve the
corresponding scriptBytes and version from that matched entry, and handle the
case where no matching script is found by returning a clear error or skipping
evaluation.
| // For now, only handle spending scripts with datum, redeemer, context | ||
| if key.Tag == 0 { // RedeemerTagSpend | ||
| // Get datum - for simplicity, assume it's the redeemer data for now | ||
| datum := value.Data.Data | ||
| redeemerData := value.Data.Data | ||
| // TODO: build proper script context | ||
| contextData := data.NewConstr(0) // dummy context | ||
|
|
||
| args = []data.PlutusData{datum, redeemerData, contextData} | ||
| } else { | ||
| // For other purposes, just redeemer and context | ||
| redeemerData := value.Data.Data | ||
| contextData := data.NewConstr(0) // dummy context | ||
| args = []data.PlutusData{redeemerData, contextData} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Placeholder datum and context will produce incorrect evaluation results.
Using the redeemer data as the datum (line 279) and a dummy empty constructor as the script context (lines 282, 288) will cause scripts to fail or produce incorrect execution unit estimates. This fundamentally undermines the purpose of EvalTx.
Consider either:
- Fetching actual datums from UTxOs via the node connection
- Building a proper
ScriptContextstructure - Documenting this as a known limitation and returning an appropriate error
🤖 Prompt for AI Agents
In internal/utxorpc/submit.go around lines 276 to 290, the code wrongly uses
redeemer data as the datum and a dummy empty constructor as ScriptContext which
will produce incorrect EvalTx results; replace the placeholders by either (a)
fetching the actual datum for the UTxO from the node (via the node client) and
using that real datum and building a proper ScriptContext structure populated
with the tx, inputs, outputs and relevant signatures, or (b) if
fetching/building is not possible here, fail fast: detect missing datum/context
and return a clear error documenting that EvalTx cannot run without on-chain
datum and full ScriptContext; do not continue to call EvalTx with dummy values.
Ensure the chosen fix populates args with the correct data.PlutusData order
expected by the validator (datum, redeemer, context) or returns an explicit
error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 issues found across 3 files
Prompt for AI agents (all 2 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="internal/utxorpc/submit.go">
<violation number="1" location="internal/utxorpc/submit.go:156">
P1: Calling `Int64()` on a big integer can silently truncate values that exceed int64 range. Check if the value fits in int64 first, and use `BigInt_BigUInt` or `BigInt_BigNInt` for larger values.</violation>
<violation number="2" location="internal/utxorpc/submit.go:269">
P1: The redeemer index does not correspond to the script index in `allScripts`. The redeemer index refers to the input/policy index being validated, not the script position in the witness set. Scripts should be matched by their hash, not by array position.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| } | ||
|
|
||
| // Try to evaluate if we have a script for this redeemer | ||
| if int(key.Index) < len(allScripts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: The redeemer index does not correspond to the script index in allScripts. The redeemer index refers to the input/policy index being validated, not the script position in the witness set. Scripts should be matched by their hash, not by array position.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/utxorpc/submit.go, line 269:
<comment>The redeemer index does not correspond to the script index in `allScripts`. The redeemer index refers to the input/policy index being validated, not the script position in the witness set. Scripts should be matched by their hash, not by array position.</comment>
<file context>
@@ -83,6 +87,238 @@ func (s *submitServiceServer) SubmitTx(
+ }
+
+ // Try to evaluate if we have a script for this redeemer
+ if int(key.Index) < len(allScripts) {
+ scriptBytes := allScripts[key.Index]
+ version := scriptVersions[key.Index]
</file context>
| PlutusData: &cardano.PlutusData_BigInt{ | ||
| BigInt: &cardano.BigInt{ | ||
| BigInt: &cardano.BigInt_Int{ | ||
| Int: v.Inner.Int64(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Calling Int64() on a big integer can silently truncate values that exceed int64 range. Check if the value fits in int64 first, and use BigInt_BigUInt or BigInt_BigNInt for larger values.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/utxorpc/submit.go, line 156:
<comment>Calling `Int64()` on a big integer can silently truncate values that exceed int64 range. Check if the value fits in int64 first, and use `BigInt_BigUInt` or `BigInt_BigNInt` for larger values.</comment>
<file context>
@@ -83,6 +87,238 @@ func (s *submitServiceServer) SubmitTx(
+ PlutusData: &cardano.PlutusData_BigInt{
+ BigInt: &cardano.BigInt{
+ BigInt: &cardano.BigInt_Int{
+ Int: v.Inner.Int64(),
+ },
+ },
</file context>
Signed-off-by: Chris Gianelloni <[email protected]>
3207ff0 to
75e427c
Compare
|
@cubic-dev-ai review this PR |
@wolf31o2 I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 8 files
Prompt for AI agents (all 3 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="internal/utxorpc/submit.go">
<violation number="1" location="internal/utxorpc/submit.go:174">
P1: Potential integer overflow: `v.Inner.Int64()` will silently truncate big integers that exceed int64 range. Consider using `BigInt_BigUInt` or `BigInt_BigNInt` for arbitrary precision, or at minimum check if the value fits with `v.Inner.IsInt64()` before conversion.</violation>
<violation number="2" location="internal/utxorpc/submit.go:315">
P1: Incorrect script lookup: Redeemer indices are per-purpose and don't directly map to the concatenated `allScripts` array. Scripts should be looked up by their hash matching the script reference in the transaction input/policy, not by redeemer index.</violation>
<violation number="3" location="internal/utxorpc/submit.go:325">
P1: Incorrect datum source: For spending scripts, `datum` is incorrectly set to `value.Data.Data` (the redeemer). The datum should be retrieved from the UTxO being spent at the index specified by `key.Index`, not from the redeemer itself.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| PlutusData: &cardano.PlutusData_BigInt{ | ||
| BigInt: &cardano.BigInt{ | ||
| BigInt: &cardano.BigInt_Int{ | ||
| Int: v.Inner.Int64(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Potential integer overflow: v.Inner.Int64() will silently truncate big integers that exceed int64 range. Consider using BigInt_BigUInt or BigInt_BigNInt for arbitrary precision, or at minimum check if the value fits with v.Inner.IsInt64() before conversion.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/utxorpc/submit.go, line 174:
<comment>Potential integer overflow: `v.Inner.Int64()` will silently truncate big integers that exceed int64 range. Consider using `BigInt_BigUInt` or `BigInt_BigNInt` for arbitrary precision, or at minimum check if the value fits with `v.Inner.IsInt64()` before conversion.</comment>
<file context>
@@ -83,6 +87,291 @@ func (s *submitServiceServer) SubmitTx(
+ PlutusData: &cardano.PlutusData_BigInt{
+ BigInt: &cardano.BigInt{
+ BigInt: &cardano.BigInt_Int{
+ Int: v.Inner.Int64(),
+ },
+ },
</file context>
| // For now, only handle spending scripts with datum, redeemer, context | ||
| if key.Tag == 0 { // RedeemerTagSpend | ||
| // Get datum - for simplicity, assume it's the redeemer data for now | ||
| datum := value.Data.Data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Incorrect datum source: For spending scripts, datum is incorrectly set to value.Data.Data (the redeemer). The datum should be retrieved from the UTxO being spent at the index specified by key.Index, not from the redeemer itself.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/utxorpc/submit.go, line 325:
<comment>Incorrect datum source: For spending scripts, `datum` is incorrectly set to `value.Data.Data` (the redeemer). The datum should be retrieved from the UTxO being spent at the index specified by `key.Index`, not from the redeemer itself.</comment>
<file context>
@@ -83,6 +87,291 @@ func (s *submitServiceServer) SubmitTx(
+ // For now, only handle spending scripts with datum, redeemer, context
+ if key.Tag == 0 { // RedeemerTagSpend
+ // Get datum - for simplicity, assume it's the redeemer data for now
+ datum := value.Data.Data
+ redeemerData := value.Data.Data
+ // TODO: build proper script context
</file context>
| } | ||
|
|
||
| // Try to evaluate if we have a script for this redeemer | ||
| if int(key.Index) < len(allScripts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Incorrect script lookup: Redeemer indices are per-purpose and don't directly map to the concatenated allScripts array. Scripts should be looked up by their hash matching the script reference in the transaction input/policy, not by redeemer index.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At internal/utxorpc/submit.go, line 315:
<comment>Incorrect script lookup: Redeemer indices are per-purpose and don't directly map to the concatenated `allScripts` array. Scripts should be looked up by their hash matching the script reference in the transaction input/policy, not by redeemer index.</comment>
<file context>
@@ -83,6 +87,291 @@ func (s *submitServiceServer) SubmitTx(
+ }
+
+ // Try to evaluate if we have a script for this redeemer
+ if int(key.Index) < len(allScripts) {
+ scriptBytes := allScripts[key.Index]
+ version := scriptVersions[key.Index]
</file context>
Closes #399
Closes #500
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.