package state import ( "ripple/bug" "ripple/config" "ripple/errmsgs" "ripple/types" ) type User struct { SecretKey [32]byte } type Payment struct { Amount uint64 Incoming types.UserIdentifier Outgoing types.UserIdentifier Counterpart types.UserIdentifier Cancel bool Timeout int64 } type Sync struct { TurnBit byte TurnCounter uint32 LastValidated types.Instruction } type Account struct { Creditline int64 Pending map[[32]byte]struct{} TrustlineIn uint64 TrustlineOut uint64 Sync } type Receipt struct { Identifier [32]byte Counterpart types.UserIdentifier Amount int64 Timestamp int64 } type Storage struct { User User Accounts map[types.UserIdentifier]Account Payments map[[32]byte]Payment Receipts [config.BufferSize]Receipt } func (s *Storage) MustGetAccount(id types.UserIdentifier) Account { acc, ok := s.Accounts[id] if !ok { panic(bug.BugStateViolated) } return acc } func (s *Storage) AccountExists(id types.UserIdentifier) bool { _, ok := s.Accounts[id] return ok } func (s *Storage) AddAccount(id types.UserIdentifier, turnBit byte) error { if s.AccountExists(id) { panic(bug.BugStateViolated) } if len(s.Accounts) >= config.BufferSize { return errmsgs.ErrBufferFull } s.Accounts[id] = Account{ Sync: Sync{ TurnBit: turnBit, }, Pending: make(map[[32]byte]struct{}), } return nil } func (s *Storage) RemoveAccount(id types.UserIdentifier) { if !s.AccountExists(id) { panic(bug.BugStateViolated) } delete(s.Accounts, id) } func (s *Storage) MustGetPayment(paymentID [32]byte) Payment { payment, ok := s.Payments[paymentID] if !ok { panic(bug.BugStateViolated) } return payment } func (s *Storage) GetBandwidthOut(id types.UserIdentifier) int64 { acc := s.MustGetAccount(id) bandwidthOut := int64(acc.TrustlineIn) + acc.Creditline for paymentID := range acc.Pending { payment := s.MustGetPayment(paymentID) if payment.Outgoing == id { bandwidthOut -= int64(payment.Amount) } } return bandwidthOut } func (s *Storage) GetBandwidthIn(id types.UserIdentifier) int64 { acc := s.MustGetAccount(id) bandwidthIn := int64(acc.TrustlineOut) - acc.Creditline for paymentID := range acc.Pending { payment := s.MustGetPayment(paymentID) if payment.Incoming == id { bandwidthIn -= int64(payment.Amount) } } return bandwidthIn } func (s *Storage) AddReceipt(r Receipt) { copy(s.Receipts[1:], s.Receipts[:]) s.Receipts[0] = r }