package market import ( "bytes" cborrpc "github.com/filecoin-project/go-cbor-util" "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/namespace" dsq "github.com/ipfs/go-datastore/query" "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/node/modules/dtypes" ) const dsKeyAddr = "Addr" type Store struct { ds datastore.Batching } func newStore(ds dtypes.MetadataDS) *Store { ds = namespace.Wrap(ds, datastore.NewKey("/fundmgr/")) return &Store{ ds: ds, } } // save the state to the datastore func (ps *Store) save(state *FundedAddressState) error { k := dskeyForAddr(state.Addr) b, err := cborrpc.Dump(state) if err != nil { return err } return ps.ds.Put(k, b) } // get the state for the given address func (ps *Store) get(addr address.Address) (*FundedAddressState, error) { k := dskeyForAddr(addr) data, err := ps.ds.Get(k) if err != nil { return nil, err } var state FundedAddressState err = cborrpc.ReadCborRPC(bytes.NewReader(data), &state) if err != nil { return nil, err } return &state, nil } // forEach calls iter with each address in the datastore func (ps *Store) forEach(iter func(*FundedAddressState)) error { res, err := ps.ds.Query(dsq.Query{Prefix: dsKeyAddr}) if err != nil { return err } defer res.Close() //nolint:errcheck for { res, ok := res.NextSync() if !ok { break } if res.Error != nil { return err } var stored FundedAddressState if err := stored.UnmarshalCBOR(bytes.NewReader(res.Value)); err != nil { return err } iter(&stored) } return nil } // The datastore key used to identify the address state func dskeyForAddr(addr address.Address) datastore.Key { return datastore.KeyWithNamespaces([]string{dsKeyAddr, addr.String()}) }