func (c *offlineRouting) PutValue(ctx context.Context, key key.Key, val []byte) error { rec, err := record.MakePutRecord(c.sk, key, val, false) if err != nil { return err } data, err := proto.Marshal(rec) if err != nil { return err } return c.datastore.Put(key.DsKey(), data) }
// GetValue searches for the value corresponding to given Key. func (dht *IpfsDHT) GetValue(ctx context.Context, key key.Key) ([]byte, error) { ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() vals, err := dht.GetValues(ctx, key, 16) if err != nil { return nil, err } var recs [][]byte for _, v := range vals { recs = append(recs, v.Val) } i, err := dht.Selector.BestRecord(key, recs) if err != nil { return nil, err } best := recs[i] log.Debugf("GetValue %v %v", key, best) if best == nil { log.Errorf("GetValue yielded correct record with nil value.") return nil, routing.ErrNotFound } fixupRec, err := record.MakePutRecord(dht.peerstore.PrivKey(dht.self), key, best, true) if err != nil { // probably shouldnt actually 'error' here as we have found a value we like, // but this call failing probably isnt something we want to ignore return nil, err } for _, v := range vals { // if someone sent us a different 'less-valid' record, lets correct them if !bytes.Equal(v.Val, best) { go func(v routing.RecvdVal) { ctx, cancel := context.WithTimeout(dht.Context(), time.Second*30) defer cancel() err := dht.putValueToPeer(ctx, v.From, key, fixupRec) if err != nil { log.Error("Error correcting DHT entry: ", err) } }(v) } } return best, nil }
// PutValue adds value corresponding to given Key. // This is the top level "Store" operation of the DHT func (dht *IpfsDHT) PutValue(ctx context.Context, key key.Key, value []byte) error { log.Debugf("PutValue %s", key) sk, err := dht.getOwnPrivateKey() if err != nil { return err } sign, err := dht.Validator.IsSigned(key) if err != nil { return err } rec, err := record.MakePutRecord(sk, key, value, sign) if err != nil { log.Debug("Creation of record failed!") return err } err = dht.putLocal(key, rec) if err != nil { return err } pchan, err := dht.GetClosestPeers(ctx, key) if err != nil { return err } wg := sync.WaitGroup{} for p := range pchan { wg.Add(1) go func(p peer.ID) { ctx, cancel := context.WithCancel(ctx) defer cancel() defer wg.Done() notif.PublishQueryEvent(ctx, ¬if.QueryEvent{ Type: notif.Value, ID: p, }) err := dht.putValueToPeer(ctx, p, key, rec) if err != nil { log.Debugf("failed putting value to peer: %s", err) } }(p) } wg.Wait() return nil }