github.com/ethersphere/bee/v2@v2.2.0/pkg/feeds/getter.go (about) 1 // Copyright 2021 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package feeds 6 7 import ( 8 "context" 9 "encoding/binary" 10 "errors" 11 "fmt" 12 "time" 13 14 "github.com/ethersphere/bee/v2/pkg/soc" 15 storage "github.com/ethersphere/bee/v2/pkg/storage" 16 "github.com/ethersphere/bee/v2/pkg/swarm" 17 ) 18 19 // Lookup is the interface for time based feed lookup 20 type Lookup interface { 21 At(ctx context.Context, at int64, after uint64) (chunk swarm.Chunk, currentIndex, nextIndex Index, err error) 22 } 23 24 // Getter encapsulates a chunk Getter getter and a feed and provides non-concurrent lookup methods 25 type Getter struct { 26 getter storage.Getter 27 *Feed 28 } 29 30 // NewGetter constructs a feed Getter 31 func NewGetter(getter storage.Getter, feed *Feed) *Getter { 32 return &Getter{getter, feed} 33 } 34 35 // Latest looks up the latest update of the feed 36 // after is a unix time hint of the latest known update 37 func Latest(ctx context.Context, l Lookup, after uint64) (swarm.Chunk, error) { 38 c, _, _, err := l.At(ctx, time.Now().Unix(), after) 39 return c, err 40 } 41 42 // Get creates an update of the underlying feed at the given epoch 43 // and looks it up in the chunk Getter based on its address 44 func (f *Getter) Get(ctx context.Context, i Index) (swarm.Chunk, error) { 45 addr, err := f.Feed.Update(i).Address() 46 if err != nil { 47 return nil, err 48 } 49 return f.getter.Get(ctx, addr) 50 } 51 52 // FromChunk parses out the timestamp and the payload 53 func FromChunk(ch swarm.Chunk) (uint64, []byte, error) { 54 s, err := soc.FromChunk(ch) 55 if err != nil { 56 return 0, nil, err 57 } 58 cac := s.WrappedChunk() 59 if len(cac.Data()) < 16 { 60 return 0, nil, errors.New("feed update payload too short") 61 } 62 payload := cac.Data()[16:] 63 at := binary.BigEndian.Uint64(cac.Data()[8:16]) 64 return at, payload, nil 65 } 66 67 // UpdatedAt extracts the time of feed other than update 68 func UpdatedAt(ch swarm.Chunk) (uint64, error) { 69 d := ch.Data() 70 if len(d) < 113 { 71 return 0, fmt.Errorf("too short: %d", len(d)) 72 } 73 // a soc chunk with time information in the wrapped content addressed chunk 74 // 0-32 index, 75 // 65-97 signature, 76 // 98-105 span of wrapped chunk 77 // 105-113 timestamp 78 return binary.BigEndian.Uint64(d[105:113]), nil 79 }