Skip to content

Conversation

@Azorlogh
Copy link

  • renamed fundsStack to fundsQueue to mirror how it's actually used
  • change fundsQueue to use a slice
  • renamed send-related interpreter functions to mirror the naming logic: "take from a source" and "send to a destination"
  • moved CurrentAsset into the fundsQueue

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 13, 2025

Walkthrough

Replaces a stack-based funds implementation with a queue-based one (introduces fundsQueue and Sender), removes the old stack file, updates interpreter logic to use fundsQueue.asset for balance queries, and updates tests to the new queue API.

Changes

Cohort / File(s) Summary of changes
Funds queue added & stack removed
internal/interpreter/funds_queue.go, internal/interpreter/funds_stack.go
Adds Sender and fundsQueue (push/pull/clone/string, color-aware, amount-splitting) and deletes the previous funds_stack implementation.
Tests updated for queue API
internal/interpreter/funds_queue_test.go
Replaces stack-based test usages with queue equivalents and updates method calls/expectations to the new API.
Interpreter integration
internal/interpreter/interpreter.go
Rewires interpreter send/receive paths to use fundsQueue, renames related helpers, and propagates asset via fundsQueue.asset.
Balance query asset source update
internal/interpreter/batch_balances_query.go
Reads asset from st.fundsQueue.asset instead of st.CurrentAsset when queuing balance queries.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Program
  participant Interpreter
  participant fundsQueue
  participant BalanceQuery

  Program->>Interpreter: Execute script
  Interpreter->>fundsQueue: Push(Sender{name, amount, color})
  note right of fundsQueue #DDEBF7: merge adjacent same name/color\nignore zero amounts
  Interpreter->>fundsQueue: Pull(maxAmount, color?)
  alt color provided
    fundsQueue-->>Interpreter: Selected senders (filtered, split if needed)
  else no color
    fundsQueue-->>Interpreter: Selected senders (FIFO, split if needed)
  end
  Interpreter->>BalanceQuery: Queue balance checks using fundsQueue.asset
  BalanceQuery-->>Interpreter: Balances
  Interpreter-->>Program: Return result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • altitude
  • gfyrag

Poem

I hop through queues where colors gleam,
Out with the stack, in with a stream.
Senders split and merge in line,
Assets travel with the queue's sign.
Thump-thump — a rabbit's tidy scheme. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly summarizes the primary change of refactoring the interpreter by simplifying the fundsQueue implementation and improving naming conventions, directly reflecting the core changes in the pull request.
Description Check ✅ Passed The description clearly lists the key refactoring steps including renaming fundsStack to fundsQueue, switching to a slice implementation, renaming interpreter functions, and moving CurrentAsset, so it is directly relevant to the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/interpreter-send-readability

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.

@codecov
Copy link

codecov bot commented Oct 13, 2025

Codecov Report

❌ Patch coverage is 91.39073% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.07%. Comparing base (b0aa0df) to head (a24050d).

Files with missing lines Patch % Lines
internal/interpreter/funds_queue.go 86.02% 13 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #100      +/-   ##
==========================================
- Coverage   70.49%   70.07%   -0.42%     
==========================================
  Files          43       43              
  Lines        4982     4956      -26     
==========================================
- Hits         3512     3473      -39     
- Misses       1313     1326      +13     
  Partials      157      157              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b0aa0df and 8d399c9.

📒 Files selected for processing (5)
  • internal/interpreter/batch_balances_query.go (3 hunks)
  • internal/interpreter/funds_queue.go (1 hunks)
  • internal/interpreter/funds_queue_test.go (3 hunks)
  • internal/interpreter/funds_stack.go (0 hunks)
  • internal/interpreter/interpreter.go (19 hunks)
💤 Files with no reviewable changes (1)
  • internal/interpreter/funds_stack.go
🧰 Additional context used
🧬 Code graph analysis (2)
internal/interpreter/funds_queue_test.go (1)
internal/interpreter/funds_queue.go (1)
  • Sender (9-13)
internal/interpreter/interpreter.go (5)
internal/interpreter/funds_queue.go (1)
  • Sender (9-13)
internal/parser/ast.go (20)
  • Source (122-125)
  • Destination (189-192)
  • SentValueLiteral (278-281)
  • SentValueLiteral (287-287)
  • ValueExpr (8-11)
  • SourceAccount (130-130)
  • SourceAccount (135-138)
  • SourceOverdraft (132-132)
  • SourceOverdraft (167-172)
  • SourceInorder (127-127)
  • SourceInorder (140-143)
  • SourceCapped (131-131)
  • SourceCapped (161-165)
  • DestinationAccount (194-194)
  • DestinationAccount (200-202)
  • KeptOrDestination (234-236)
  • DestinationKept (238-238)
  • DestinationKept (242-244)
  • DestinationTo (239-239)
  • DestinationTo (246-248)
internal/interpreter/value.go (4)
  • Asset (18-18)
  • Asset (32-32)
  • Monetary (22-25)
  • Monetary (30-30)
internal/interpreter/interpreter_error.go (2)
  • NegativeAmountErr (125-128)
  • MissingFundsErr (10-15)
internal/utils/utils.go (1)
  • NonNeg (36-38)

Comment on lines +114 to +118
func (s fundsQueue) Clone() fundsQueue {
return fundsQueue{
senders: slices.Clone(s.senders),
asset: s.asset,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Deep-clone sender amounts in Clone()

Clone() only copies the slice, so every cloned Sender.Amount still points to the same *big.Int. When cloneState() (interpreter.go Line 604) restores fundsQueue, subsequent mutations done after the clone leak back into the “restored” queue, breaking backtracking (e.g. oneof sources will see already-depleted amounts). Please deep-copy each amount.

 func (s fundsQueue) Clone() fundsQueue {
-	return fundsQueue{
-		senders: slices.Clone(s.senders),
-		asset:   s.asset,
-	}
+	cloned := make([]Sender, len(s.senders))
+	for i, sender := range s.senders {
+		cloned[i] = Sender{
+			Name:   sender.Name,
+			Color:  sender.Color,
+			Amount: new(big.Int).Set(sender.Amount),
+		}
+	}
+	return fundsQueue{
+		senders: cloned,
+		asset:   s.asset,
+	}
 }
📝 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.

Suggested change
func (s fundsQueue) Clone() fundsQueue {
return fundsQueue{
senders: slices.Clone(s.senders),
asset: s.asset,
}
func (s fundsQueue) Clone() fundsQueue {
cloned := make([]Sender, len(s.senders))
for i, sender := range s.senders {
cloned[i] = Sender{
Name: sender.Name,
Color: sender.Color,
Amount: new(big.Int).Set(sender.Amount),
}
}
return fundsQueue{
senders: cloned,
asset: s.asset,
}
}
🤖 Prompt for AI Agents
In internal/interpreter/funds_queue.go around lines 114 to 118, Clone()
currently shallow-copies the senders slice so each Sender.Amount still points to
the same *big.Int; change Clone() to deep-copy each Sender and its Amount by
creating a new slice of senders, copying each Sender struct and, for each
non-nil Amount, allocating a new big.Int and calling Set(oldAmount) (or using
new(big.Int).Set) so the cloned fundsQueue has independent amount values and
subsequent mutations do not affect the original.

Copy link
Contributor

@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: 0

♻️ Duplicate comments (1)
internal/interpreter/funds_queue.go (1)

122-126: Deep-clone sender amounts in Clone()

This issue was already flagged in previous reviews: Clone() shallow-copies the senders slice, so each cloned Sender.Amount still points to the same *big.Int. When the interpreter backtracks (e.g., oneof branches), mutations to Amount values will leak between the cloned and original queues.

Apply the suggested fix from the previous review to deep-copy each Sender and its Amount.

🧹 Nitpick comments (1)
internal/interpreter/funds_queue.go (1)

77-77: Consider addressing the TODO for performance.

The TODO suggests preallocating the output queue for performance. This could be beneficial in hot paths where Pull is called frequently.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8d399c9 and a24050d.

📒 Files selected for processing (1)
  • internal/interpreter/funds_queue.go (1 hunks)
🔇 Additional comments (3)
internal/interpreter/funds_queue.go (3)

37-51: LGTM! Merge logic is correct.

The merge logic correctly leverages pointer semantics: when last.Amount.Add(last.Amount, sender.Amount) is called, it mutates the *big.Int that both the local last variable and the slice element point to, making the change visible in the queue. The zero-amount early return is also a good optimization.


72-119: Pull logic is sound with proper offset handling.

The offset-based iteration correctly handles:

  • Skipping non-matching colors by incrementing offset
  • Removing matched elements without adjusting offset (elements shift left naturally)
  • Cloning maxAmount for safe mutation
  • Splitting senders when partially satisfying the pull

The logic has been traced through multiple scenarios and appears correct.


20-27: Asset field initialization is handled by callers in interpreter.go (lines 424, 436) and batch_balances_query.go (42); no changes needed.

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.

1 participant