Skip to content
MediumStateful DesignPython 3

Idempotent Ledger

Apply in-memory account mutations once per successful request ID while preserving the original retry result.

30m3 sample tests5 hidden tests

Implement a small account ledger that applies deposits and withdrawals exactly once per request ID. means a retry returns the first successful result without repeating its mutation, even when the account balance changes afterward.

Requirements

  • Define Ledger.
  • apply(request_id, account_id, amount) applies amount to the account and returns the resulting balance.
  • Positive amounts are deposits. Negative amounts are withdrawals.
  • Amounts are integer units. A zero amount is a successful request and must also be recorded.
  • Request IDs are global to the ledger (not scoped per account).
  • A duplicate request_id returns the same result as the first successful application, not the account's current balance, and must not apply twice.
  • On a duplicate request_id, ignore the retry payload (account_id / amount) and return the stored result.
  • Only successful applications are recorded for idempotency. Failed overdrafts are not recorded, so a later retry with the same id may still succeed after the balance changes.
  • Withdrawals that would make the balance negative raise ValueError.
  • balance(account_id) returns the current account balance, defaulting to zero.

Example

python
ledger = Ledger()
assert ledger.apply("d1", "acct", 100) == 100
assert ledger.apply("d1", "acct", 100) == 100
assert ledger.apply("w1", "acct", -30) == 70
assert ledger.apply("d1", "other-acct", -999) == 100  # original receipt, despite changed payload
assert ledger.balance("acct") == 70
assert ledger.balance("other-acct") == 0

Constraints

  • Use standard-library Python only.
  • Keep all state in memory.
  • Calls are sequential, and idempotency lasts for this ledger instance's lifetime. Restart recovery and concurrency are follow-ups.
  • For the Java version, assume amounts and resulting balances fit signed 32-bit integers.

Editor