Skip to content

Add solution for Challenge 7 by livingpool#1882

Merged
github-actions[bot] merged 1 commit into
RezaSi:mainfrom
livingpool:challenge-7-livingpool
Jul 11, 2026
Merged

Add solution for Challenge 7 by livingpool#1882
github-actions[bot] merged 1 commit into
RezaSi:mainfrom
livingpool:challenge-7-livingpool

Conversation

@livingpool

Copy link
Copy Markdown
Contributor

Challenge 7 Solution

Submitted by: @livingpool
Challenge: Challenge 7

Description

This PR contains my solution for Challenge 7.

Changes

  • Added solution file to challenge-7/submissions/livingpool/solution-template.go

Testing

  • Solution passes all test cases
  • Code follows Go best practices

Thank you for reviewing my submission! 🚀

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Added a complete Challenge 7 Go bank-account implementation with custom errors, constructor validation, transaction limits, mutex-protected deposits and withdrawals, and account transfers.

Changes

Bank account operations

Layer / File(s) Summary
Account contracts and error types
challenge-7/submissions/livingpool/solution-template.go
Defines BankAccount, MaxTransactionAmount, and custom error types for account validation and operation failures.
Construction and single-account operations
challenge-7/submissions/livingpool/solution-template.go
Adds validated account construction plus deposit and withdrawal operations with balance checks and mutex locking.
Account transfer operation
challenge-7/submissions/livingpool/solution-template.go
Adds transfer validation and updates source and target balances while locking the source account.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Poem

A rabbit deposits carrots with care,
Withdraws only what’s safely there.
Locks guard balances, errors speak,
Transfers hop from peak to peak.
Challenge seven now wears proud ears! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding a Challenge 7 solution for livingpool.
Description check ✅ Passed The description matches the changeset and summarizes the Challenge 7 submission.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eead8216-ccb1-440c-a58c-89c15b2c0103

📥 Commits

Reviewing files that changed from the base of the PR and between 0a82968 and bc23707.

📒 Files selected for processing (1)
  • challenge-7/submissions/livingpool/solution-template.go

Comment on lines +42 to +65
func (e *InsufficientFundsError) Error() string {
// Implement error message
return ""
}

// NegativeAmountError occurs when an amount for deposit, withdrawal, or transfer is negative.
type NegativeAmountError struct {
// Implement this error type
}

func (e *NegativeAmountError) Error() string {
// Implement error message
return ""
}

// ExceedsLimitError occurs when a deposit or withdrawal amount exceeds the defined limit.
type ExceedsLimitError struct {
// Implement this error type
}

func (e *ExceedsLimitError) Error() string {
// Implement error message
return ""
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Empty Error() strings defeat the purpose of the error interface.

InsufficientFundsError, NegativeAmountError, and ExceedsLimitError all return "", so logging or wrapping these errors yields no diagnostic text. The tests only inspect the concrete type via %T, which masks this, but any real caller printing the error gets a blank message. Give each a meaningful message (following the AccountError pattern).

♻️ Example implementation
 func (e *InsufficientFundsError) Error() string {
-	// Implement error message
-	return ""
+	return "insufficient funds: withdrawal would bring balance below minimum"
 }
 func (e *NegativeAmountError) Error() string {
-	// Implement error message
-	return ""
+	return "amount must not be negative"
 }
 func (e *ExceedsLimitError) Error() string {
-	// Implement error message
-	return ""
+	return fmt.Sprintf("amount exceeds transaction limit of %.2f", MaxTransactionAmount)
 }
📝 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 (e *InsufficientFundsError) Error() string {
// Implement error message
return ""
}
// NegativeAmountError occurs when an amount for deposit, withdrawal, or transfer is negative.
type NegativeAmountError struct {
// Implement this error type
}
func (e *NegativeAmountError) Error() string {
// Implement error message
return ""
}
// ExceedsLimitError occurs when a deposit or withdrawal amount exceeds the defined limit.
type ExceedsLimitError struct {
// Implement this error type
}
func (e *ExceedsLimitError) Error() string {
// Implement error message
return ""
}
func (e *InsufficientFundsError) Error() string {
return "insufficient funds: withdrawal would bring balance below minimum"
}
// NegativeAmountError occurs when an amount for deposit, withdrawal, or transfer is negative.
type NegativeAmountError struct {
// Implement this error type
}
func (e *NegativeAmountError) Error() string {
return "amount must not be negative"
}
// ExceedsLimitError occurs when a deposit or withdrawal amount exceeds the defined limit.
type ExceedsLimitError struct {
// Implement this error type
}
func (e *ExceedsLimitError) Error() string {
return fmt.Sprintf("amount exceeds transaction limit of %.2f", MaxTransactionAmount)
}

Comment on lines +110 to +116
if a.Balance-amount < a.MinBalance {
return &InsufficientFundsError{}
}
a.mu.Lock()
a.Balance -= amount
a.mu.Unlock()
return nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

TOCTOU race: balance check is outside the mutex.

Line 110 reads a.Balance without holding a.mu, then the update at 113–115 takes the lock. This is a data race against concurrent writers (flagged by go test -race), and the check-then-act gap allows two concurrent withdrawals to both pass the MinBalance guard and overdraw. Hold the lock across the check and the mutation.

🔒 Proposed fix
 	if amount > MaxTransactionAmount {
 		return &ExceedsLimitError{}
 	}
-	if a.Balance-amount < a.MinBalance {
-		return &InsufficientFundsError{}
-	}
-	a.mu.Lock()
-	a.Balance -= amount
-	a.mu.Unlock()
+	a.mu.Lock()
+	defer a.mu.Unlock()
+	if a.Balance-amount < a.MinBalance {
+		return &InsufficientFundsError{}
+	}
+	a.Balance -= amount
 	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.

Suggested change
if a.Balance-amount < a.MinBalance {
return &InsufficientFundsError{}
}
a.mu.Lock()
a.Balance -= amount
a.mu.Unlock()
return nil
if amount > MaxTransactionAmount {
return &ExceedsLimitError{}
}
a.mu.Lock()
defer a.mu.Unlock()
if a.Balance-amount < a.MinBalance {
return &InsufficientFundsError{}
}
a.Balance -= amount
return nil

Comment on lines +122 to +137
func (a *BankAccount) Transfer(amount float64, target *BankAccount) error {
// Implement transfer functionality with proper error handling
if amount < 0 {
return &NegativeAmountError{}
}
if amount > MaxTransactionAmount {
return &ExceedsLimitError{}
}
if a.Balance-amount < a.MinBalance {
return &InsufficientFundsError{}
}
a.mu.Lock()
a.Balance -= amount
target.Balance += amount
a.mu.Unlock()
return nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,260p' challenge-7/submissions/livingpool/solution-template.go

Repository: RezaSi/go-interview-practice

Length of output: 4049


🏁 Script executed:

rg -n --hidden --glob '!**/.git/**' -e 'Transfer' -e 'MinBalance' -e 'deadlock' -e 'concurr' challenge-7 .

Repository: RezaSi/go-interview-practice

Length of output: 50385


🏁 Script executed:

sed -n '250,430p' challenge-7/solution-template_test.go && printf '\n--- README ---\n' && sed -n '1,120p' challenge-7/README.md && printf '\n--- learning ---\n' && sed -n '110,150p' challenge-7/learning.md

Repository: RezaSi/go-interview-practice

Length of output: 8909


Transfer should lock both accounts and guard nil targets. target can panic when nil, target.Balance is updated without target.mu, and the minimum-balance check runs outside the lock. Lock both accounts in a stable order before checking and updating.

@github-actions
github-actions Bot merged commit 6c17be9 into RezaSi:main Jul 11, 2026
5 checks passed
@github-actions

Copy link
Copy Markdown

🎉 Auto-merged!

This PR was automatically merged after 2 days with all checks passing.

Thank you for your contribution, @livingpool!

📊 Scoreboards and badges will be updated shortly.

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