MCPcopy Create free account
hub / github.com/devaccuracy/ledgerforge / GetBalanceAtTime

Method GetBalanceAtTime

database/balance.go:1606–1689  ·  view source on GitHub ↗

GetBalanceAtTime retrieves the balance state at a specific point in time. It finds the most recent snapshot before the target time and applies any subsequent transactions to calculate the exact balance state. If fromSource is true, it skips using snapshots and calculates directly from all transactio

(ctx context.Context, balanceID string, targetTime time.Time, fromSource bool)

Source from the content-addressed store, hash-verified

1604// - *Balance: The calculated balance state at the target time
1605// - error: An APIError if any issues occur during the operation
1606func (d Datasource) GetBalanceAtTime(ctx context.Context, balanceID string, targetTime time.Time, fromSource bool) (*model.Balance, error) {
1607 // Add context timeout
1608 ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
1609 defer cancel()
1610
1611 // Validate inputs
1612 if err := validateBalanceTimeParams(balanceID, targetTime); err != nil {
1613 return nil, err
1614 }
1615
1616 // Start transaction
1617 tx, err := d.Conn.BeginTx(ctx, &sql.TxOptions{
1618 ReadOnly: true,
1619 Isolation: sql.LevelRepeatableRead,
1620 })
1621 if err != nil {
1622 return nil, apierror.NewAPIError(apierror.ErrInternalServer, "Failed to start transaction", err)
1623 }
1624 defer func() {
1625 if err != nil {
1626 if rollbackErr := tx.Rollback(); rollbackErr != nil {
1627 logrus.WithError(rollbackErr).WithField("original_error", err.Error()).Error("GetBalanceAtTime: failed to rollback transaction")
1628 }
1629 }
1630 }()
1631
1632 // Get basic balance information
1633 currency, balanceCreatedAt, err := d.getBalanceInfo(ctx, tx, balanceID)
1634 if err != nil {
1635 return nil, err
1636 }
1637
1638 var creditBalance, debitBalance *big.Int
1639 var startTime time.Time
1640
1641 if fromSource {
1642 // Skip snapshots and start from zero
1643 logrus.WithField("balance_id", balanceID).Debug("skipping snapshots, calculating from genesis")
1644 creditBalance = new(big.Int).SetInt64(0)
1645 debitBalance = new(big.Int).SetInt64(0)
1646 startTime = time.Time{} // Use zero time to get all transactions
1647 } else {
1648 // Try to find the most recent snapshot
1649 creditBalance, debitBalance, startTime, err = d.getMostRecentSnapshot(ctx, tx, balanceID, targetTime)
1650 if err != nil {
1651 return nil, err
1652 }
1653 }
1654
1655 // Calculate the balance by applying transactions since the snapshot (or from genesis)
1656 creditBalance, debitBalance, err = d.calculateBalanceFromTransactions(
1657 ctx, tx, balanceID, startTime, targetTime, creditBalance, debitBalance)
1658 if err != nil {
1659 return nil, err
1660 }
1661
1662 // Calculate final balance
1663 balance := new(big.Int).Sub(creditBalance, debitBalance)

Calls 7

getBalanceInfoMethod · 0.95
getMostRecentSnapshotMethod · 0.95
NewAPIErrorFunction · 0.92
ErrorMethod · 0.45
DebugMethod · 0.45