package state import ( "encoding/gob" "os" "ripple/types" ) const errSaveFailed = "save failed" type State struct { Storage Storage Memory Memory } func newState() *State { return &State{ Memory: Memory{ Commit: make(map[types.UserIdentifier]map[[32]byte]struct{}), Pathfinding: make(map[[32]byte]Pathfinding), TaxBuffer: make(map[types.UserIdentifier]uint64), }, } } func (s *State) MustSave() { if err := s.Save(); err != nil { panic(errSaveFailed) } } func (s *State) Save() error { filePath, err := storagePath() if err != nil { return err } f, err := os.Create(filePath) if err != nil { return err } defer f.Close() enc := gob.NewEncoder(f) return enc.Encode(s.Storage) } func Load() (*State, error) { filePath, err := storagePath() if err != nil { return nil, err } f, err := os.Open(filePath) if err != nil { return nil, err } defer f.Close() dec := gob.NewDecoder(f) st := newState() if err := dec.Decode(&st.Storage); err != nil { return nil, err } return st, nil } func (s *State) AddAccount(id types.UserIdentifier, port int, secretKey [32]byte) error { if err := s.Storage.AddAccount(id, port, secretKey); err != nil { return err } s.Memory.AddAccount(id) return s.Save() } func (s *State) RemoveAccount(id types.UserIdentifier) error { s.Memory.RemoveAccount(id) s.Storage.RemoveAccount(id) return s.Save() } func (s *State) MustFinalizeIncoming(userID types.UserIdentifier, paymentID [32]byte, amount uint64, taxrate float32) { negToPos := s.Storage.MustFinalizeIncoming(userID, paymentID, amount, taxrate) if negToPos { s.Memory.TaxBuffer[userID] = 0 } }