github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/swarm/storage/types.go (about) 1 // Copyright 2016 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 storage 18 19 import ( 20 "bytes" 21 "context" 22 "crypto" 23 "crypto/rand" 24 "encoding/binary" 25 "io" 26 27 "github.com/ethereum/go-ethereum/swarm/bmt" 28 "github.com/ethereum/go-ethereum/swarm/chunk" 29 "golang.org/x/crypto/sha3" 30 ) 31 32 // MaxPO is the same as chunk.MaxPO for backward compatibility. 33 const MaxPO = chunk.MaxPO 34 35 // AddressLength is the same as chunk.AddressLength for backward compatibility. 36 const AddressLength = chunk.AddressLength 37 38 type SwarmHasher func() SwarmHash 39 40 // Address is an alias for chunk.Address for backward compatibility. 41 type Address = chunk.Address 42 43 // Proximity is the same as chunk.Proximity for backward compatibility. 44 var Proximity = chunk.Proximity 45 46 // ZeroAddr is the same as chunk.ZeroAddr for backward compatibility. 47 var ZeroAddr = chunk.ZeroAddr 48 49 func MakeHashFunc(hash string) SwarmHasher { 50 switch hash { 51 case "SHA256": 52 return func() SwarmHash { return &HashWithLength{crypto.SHA256.New()} } 53 case "SHA3": 54 return func() SwarmHash { return &HashWithLength{sha3.NewLegacyKeccak256()} } 55 case "BMT": 56 return func() SwarmHash { 57 hasher := sha3.NewLegacyKeccak256 58 hasherSize := hasher().Size() 59 segmentCount := chunk.DefaultSize / hasherSize 60 pool := bmt.NewTreePool(hasher, segmentCount, bmt.PoolSize) 61 return bmt.New(pool) 62 } 63 } 64 return nil 65 } 66 67 type AddressCollection []Address 68 69 func NewAddressCollection(l int) AddressCollection { 70 return make(AddressCollection, l) 71 } 72 73 func (c AddressCollection) Len() int { 74 return len(c) 75 } 76 77 func (c AddressCollection) Less(i, j int) bool { 78 return bytes.Compare(c[i], c[j]) == -1 79 } 80 81 func (c AddressCollection) Swap(i, j int) { 82 c[i], c[j] = c[j], c[i] 83 } 84 85 // Chunk is an alias for chunk.Chunk for backward compatibility. 86 type Chunk = chunk.Chunk 87 88 // NewChunk is the same as chunk.NewChunk for backward compatibility. 89 var NewChunk = chunk.NewChunk 90 91 func GenerateRandomChunk(dataSize int64) Chunk { 92 hasher := MakeHashFunc(DefaultHash)() 93 sdata := make([]byte, dataSize+8) 94 rand.Read(sdata[8:]) 95 binary.LittleEndian.PutUint64(sdata[:8], uint64(dataSize)) 96 hasher.ResetWithLength(sdata[:8]) 97 hasher.Write(sdata[8:]) 98 return NewChunk(hasher.Sum(nil), sdata) 99 } 100 101 func GenerateRandomChunks(dataSize int64, count int) (chunks []Chunk) { 102 for i := 0; i < count; i++ { 103 ch := GenerateRandomChunk(dataSize) 104 chunks = append(chunks, ch) 105 } 106 return chunks 107 } 108 109 // Size, Seek, Read, ReadAt 110 type LazySectionReader interface { 111 Context() context.Context 112 Size(context.Context, chan bool) (int64, error) 113 io.Seeker 114 io.Reader 115 io.ReaderAt 116 } 117 118 type LazyTestSectionReader struct { 119 *io.SectionReader 120 } 121 122 func (r *LazyTestSectionReader) Size(context.Context, chan bool) (int64, error) { 123 return r.SectionReader.Size(), nil 124 } 125 126 func (r *LazyTestSectionReader) Context() context.Context { 127 return context.TODO() 128 } 129 130 type StoreParams struct { 131 Hash SwarmHasher `toml:"-"` 132 DbCapacity uint64 133 CacheCapacity uint 134 BaseKey []byte 135 } 136 137 func NewDefaultStoreParams() *StoreParams { 138 return NewStoreParams(defaultLDBCapacity, defaultCacheCapacity, nil, nil) 139 } 140 141 func NewStoreParams(ldbCap uint64, cacheCap uint, hash SwarmHasher, basekey []byte) *StoreParams { 142 if basekey == nil { 143 basekey = make([]byte, 32) 144 } 145 if hash == nil { 146 hash = MakeHashFunc(DefaultHash) 147 } 148 return &StoreParams{ 149 Hash: hash, 150 DbCapacity: ldbCap, 151 CacheCapacity: cacheCap, 152 BaseKey: basekey, 153 } 154 } 155 156 type ChunkData []byte 157 158 type Reference []byte 159 160 // Putter is responsible to store data and create a reference for it 161 type Putter interface { 162 Put(context.Context, ChunkData) (Reference, error) 163 // RefSize returns the length of the Reference created by this Putter 164 RefSize() int64 165 // Close is to indicate that no more chunk data will be Put on this Putter 166 Close() 167 // Wait returns if all data has been store and the Close() was called. 168 Wait(context.Context) error 169 } 170 171 // Getter is an interface to retrieve a chunk's data by its reference 172 type Getter interface { 173 Get(context.Context, Reference) (ChunkData, error) 174 } 175 176 // NOTE: this returns invalid data if chunk is encrypted 177 func (c ChunkData) Size() uint64 { 178 return binary.LittleEndian.Uint64(c[:8]) 179 } 180 181 type ChunkValidator interface { 182 Validate(chunk Chunk) bool 183 } 184 185 // Provides method for validation of content address in chunks 186 // Holds the corresponding hasher to create the address 187 type ContentAddressValidator struct { 188 Hasher SwarmHasher 189 } 190 191 // Constructor 192 func NewContentAddressValidator(hasher SwarmHasher) *ContentAddressValidator { 193 return &ContentAddressValidator{ 194 Hasher: hasher, 195 } 196 } 197 198 // Validate that the given key is a valid content address for the given data 199 func (v *ContentAddressValidator) Validate(ch Chunk) bool { 200 data := ch.Data() 201 if l := len(data); l < 9 || l > chunk.DefaultSize+8 { 202 // log.Error("invalid chunk size", "chunk", addr.Hex(), "size", l) 203 return false 204 } 205 206 hasher := v.Hasher() 207 hasher.ResetWithLength(data[:8]) 208 hasher.Write(data[8:]) 209 hash := hasher.Sum(nil) 210 211 return bytes.Equal(hash, ch.Address()) 212 } 213 214 type ChunkStore interface { 215 Put(ctx context.Context, ch Chunk) (err error) 216 Get(rctx context.Context, ref Address) (ch Chunk, err error) 217 Has(rctx context.Context, ref Address) bool 218 Close() 219 } 220 221 // SyncChunkStore is a ChunkStore which supports syncing 222 type SyncChunkStore interface { 223 ChunkStore 224 BinIndex(po uint8) uint64 225 Iterator(from uint64, to uint64, po uint8, f func(Address, uint64) bool) error 226 FetchFunc(ctx context.Context, ref Address) func(context.Context) error 227 } 228 229 // FakeChunkStore doesn't store anything, just implements the ChunkStore interface 230 // It can be used to inject into a hasherStore if you don't want to actually store data just do the 231 // hashing 232 type FakeChunkStore struct { 233 } 234 235 // Put doesn't store anything it is just here to implement ChunkStore 236 func (f *FakeChunkStore) Put(_ context.Context, ch Chunk) error { 237 return nil 238 } 239 240 // Has doesn't do anything it is just here to implement ChunkStore 241 func (f *FakeChunkStore) Has(_ context.Context, ref Address) bool { 242 panic("FakeChunkStore doesn't support HasChunk") 243 } 244 245 // Get doesn't store anything it is just here to implement ChunkStore 246 func (f *FakeChunkStore) Get(_ context.Context, ref Address) (Chunk, error) { 247 panic("FakeChunkStore doesn't support Get") 248 } 249 250 // Close doesn't store anything it is just here to implement ChunkStore 251 func (f *FakeChunkStore) Close() { 252 }