github.com/alexdevranger/node-1.8.27@v0.0.0-20221128213301-aa5841e41d2d/swarm/storage/feed/id.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-dubxcoin library. 3 // 4 // The go-dubxcoin library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-dubxcoin library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-dubxcoin library. If not, see <http://www.gnu.org/licenses/>. 16 17 package feed 18 19 import ( 20 "fmt" 21 "hash" 22 "strconv" 23 24 "github.com/alexdevranger/node-1.8.27/common" 25 "github.com/alexdevranger/node-1.8.27/swarm/storage/feed/lookup" 26 27 "github.com/alexdevranger/node-1.8.27/swarm/storage" 28 ) 29 30 // ID uniquely identifies an update on the network. 31 type ID struct { 32 Feed `json:"feed"` 33 lookup.Epoch `json:"epoch"` 34 } 35 36 // ID layout: 37 // Feed feedLength bytes 38 // Epoch EpochLength 39 const idLength = feedLength + lookup.EpochLength 40 41 // Addr calculates the feed update chunk address corresponding to this ID 42 func (u *ID) Addr() (updateAddr storage.Address) { 43 serializedData := make([]byte, idLength) 44 var cursor int 45 u.Feed.binaryPut(serializedData[cursor : cursor+feedLength]) 46 cursor += feedLength 47 48 eid := u.Epoch.ID() 49 copy(serializedData[cursor:cursor+lookup.EpochLength], eid[:]) 50 51 hasher := hashPool.Get().(hash.Hash) 52 defer hashPool.Put(hasher) 53 hasher.Reset() 54 hasher.Write(serializedData) 55 return hasher.Sum(nil) 56 } 57 58 // binaryPut serializes this instance into the provided slice 59 func (u *ID) binaryPut(serializedData []byte) error { 60 if len(serializedData) != idLength { 61 return NewErrorf(ErrInvalidValue, "Incorrect slice size to serialize ID. Expected %d, got %d", idLength, len(serializedData)) 62 } 63 var cursor int 64 if err := u.Feed.binaryPut(serializedData[cursor : cursor+feedLength]); err != nil { 65 return err 66 } 67 cursor += feedLength 68 69 epochBytes, err := u.Epoch.MarshalBinary() 70 if err != nil { 71 return err 72 } 73 copy(serializedData[cursor:cursor+lookup.EpochLength], epochBytes[:]) 74 cursor += lookup.EpochLength 75 76 return nil 77 } 78 79 // binaryLength returns the expected size of this structure when serialized 80 func (u *ID) binaryLength() int { 81 return idLength 82 } 83 84 // binaryGet restores the current instance from the information contained in the passed slice 85 func (u *ID) binaryGet(serializedData []byte) error { 86 if len(serializedData) != idLength { 87 return NewErrorf(ErrInvalidValue, "Incorrect slice size to read ID. Expected %d, got %d", idLength, len(serializedData)) 88 } 89 90 var cursor int 91 if err := u.Feed.binaryGet(serializedData[cursor : cursor+feedLength]); err != nil { 92 return err 93 } 94 cursor += feedLength 95 96 if err := u.Epoch.UnmarshalBinary(serializedData[cursor : cursor+lookup.EpochLength]); err != nil { 97 return err 98 } 99 cursor += lookup.EpochLength 100 101 return nil 102 } 103 104 // FromValues deserializes this instance from a string key-value store 105 // useful to parse query strings 106 func (u *ID) FromValues(values Values) error { 107 level, _ := strconv.ParseUint(values.Get("level"), 10, 32) 108 u.Epoch.Level = uint8(level) 109 u.Epoch.Time, _ = strconv.ParseUint(values.Get("time"), 10, 64) 110 111 if u.Feed.User == (common.Address{}) { 112 return u.Feed.FromValues(values) 113 } 114 return nil 115 } 116 117 // AppendValues serializes this structure into the provided string key-value store 118 // useful to build query strings 119 func (u *ID) AppendValues(values Values) { 120 values.Set("level", fmt.Sprintf("%d", u.Epoch.Level)) 121 values.Set("time", fmt.Sprintf("%d", u.Epoch.Time)) 122 u.Feed.AppendValues(values) 123 }