github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/swarm/storage/mru/lookup.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package mru 18 19 import ( 20 "encoding/binary" 21 "hash" 22 23 "github.com/FusionFoundation/efsn/swarm/storage" 24 ) 25 26 // LookupParams is used to specify constraints when performing an update lookup 27 // Limit defines whether or not the lookup should be limited 28 // If Limit is set to true then Max defines the amount of hops that can be performed 29 type LookupParams struct { 30 UpdateLookup 31 Limit uint32 32 } 33 34 // RootAddr returns the metadata chunk address 35 func (r *LookupParams) RootAddr() storage.Address { 36 return r.rootAddr 37 } 38 39 func NewLookupParams(rootAddr storage.Address, period, version uint32, limit uint32) *LookupParams { 40 return &LookupParams{ 41 UpdateLookup: UpdateLookup{ 42 period: period, 43 version: version, 44 rootAddr: rootAddr, 45 }, 46 Limit: limit, 47 } 48 } 49 50 // LookupLatest generates lookup parameters that look for the latest version of a resource 51 func LookupLatest(rootAddr storage.Address) *LookupParams { 52 return NewLookupParams(rootAddr, 0, 0, 0) 53 } 54 55 // LookupLatestVersionInPeriod generates lookup parameters that look for the latest version of a resource in a given period 56 func LookupLatestVersionInPeriod(rootAddr storage.Address, period uint32) *LookupParams { 57 return NewLookupParams(rootAddr, period, 0, 0) 58 } 59 60 // LookupVersion generates lookup parameters that look for a specific version of a resource 61 func LookupVersion(rootAddr storage.Address, period, version uint32) *LookupParams { 62 return NewLookupParams(rootAddr, period, version, 0) 63 } 64 65 // UpdateLookup represents the components of a resource update search key 66 type UpdateLookup struct { 67 period uint32 68 version uint32 69 rootAddr storage.Address 70 } 71 72 // 4 bytes period 73 // 4 bytes version 74 // storage.Keylength for rootAddr 75 const updateLookupLength = 4 + 4 + storage.AddressLength 76 77 // UpdateAddr calculates the resource update chunk address corresponding to this lookup key 78 func (u *UpdateLookup) UpdateAddr() (updateAddr storage.Address) { 79 serializedData := make([]byte, updateLookupLength) 80 u.binaryPut(serializedData) 81 hasher := hashPool.Get().(hash.Hash) 82 defer hashPool.Put(hasher) 83 hasher.Reset() 84 hasher.Write(serializedData) 85 return hasher.Sum(nil) 86 } 87 88 // binaryPut serializes this UpdateLookup instance into the provided slice 89 func (u *UpdateLookup) binaryPut(serializedData []byte) error { 90 if len(serializedData) != updateLookupLength { 91 return NewErrorf(ErrInvalidValue, "Incorrect slice size to serialize UpdateLookup. Expected %d, got %d", updateLookupLength, len(serializedData)) 92 } 93 if len(u.rootAddr) != storage.AddressLength { 94 return NewError(ErrInvalidValue, "UpdateLookup.binaryPut called without rootAddr set") 95 } 96 binary.LittleEndian.PutUint32(serializedData[:4], u.period) 97 binary.LittleEndian.PutUint32(serializedData[4:8], u.version) 98 copy(serializedData[8:], u.rootAddr[:]) 99 return nil 100 } 101 102 // binaryLength returns the expected size of this structure when serialized 103 func (u *UpdateLookup) binaryLength() int { 104 return updateLookupLength 105 } 106 107 // binaryGet restores the current instance from the information contained in the passed slice 108 func (u *UpdateLookup) binaryGet(serializedData []byte) error { 109 if len(serializedData) != updateLookupLength { 110 return NewErrorf(ErrInvalidValue, "Incorrect slice size to read UpdateLookup. Expected %d, got %d", updateLookupLength, len(serializedData)) 111 } 112 u.period = binary.LittleEndian.Uint32(serializedData[:4]) 113 u.version = binary.LittleEndian.Uint32(serializedData[4:8]) 114 u.rootAddr = storage.Address(make([]byte, storage.AddressLength)) 115 copy(u.rootAddr[:], serializedData[8:]) 116 return nil 117 }