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  }