github.com/janotchain/janota@v0.0.0-20220824112012-93ea4c5dee78/swarm/storage/netstore.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 "fmt" 21 "path/filepath" 22 "time" 23 24 "github.com/ethereum/go-ethereum/log" 25 ) 26 27 /* 28 NetStore is a cloud storage access abstaction layer for swarm 29 it contains the shared logic of network served chunk store/retrieval requests 30 both local (coming from DPA api) and remote (coming from peers via bzz protocol) 31 it implements the ChunkStore interface and embeds LocalStore 32 33 It is called by the bzz protocol instances via Depo (the store/retrieve request handler) 34 a protocol instance is running on each peer, so this is heavily parallelised. 35 NetStore falls back to a backend (CloudStorage interface) 36 implemented by bzz/network/forwarder. forwarder or IPFS or IPΞS 37 */ 38 type NetStore struct { 39 hashfunc SwarmHasher 40 localStore *LocalStore 41 cloud CloudStore 42 } 43 44 // backend engine for cloud store 45 // It can be aggregate dispatching to several parallel implementations: 46 // bzz/network/forwarder. forwarder or IPFS or IPΞS 47 type CloudStore interface { 48 Store(*Chunk) 49 Deliver(*Chunk) 50 Retrieve(*Chunk) 51 } 52 53 type StoreParams struct { 54 ChunkDbPath string 55 DbCapacity uint64 56 CacheCapacity uint 57 Radius int 58 } 59 60 func NewStoreParams(path string) (self *StoreParams) { 61 return &StoreParams{ 62 ChunkDbPath: filepath.Join(path, "chunks"), 63 DbCapacity: defaultDbCapacity, 64 CacheCapacity: defaultCacheCapacity, 65 Radius: defaultRadius, 66 } 67 } 68 69 // netstore contructor, takes path argument that is used to initialise dbStore, 70 // the persistent (disk) storage component of LocalStore 71 // the second argument is the hive, the connection/logistics manager for the node 72 func NewNetStore(hash SwarmHasher, lstore *LocalStore, cloud CloudStore, params *StoreParams) *NetStore { 73 return &NetStore{ 74 hashfunc: hash, 75 localStore: lstore, 76 cloud: cloud, 77 } 78 } 79 80 const ( 81 // maximum number of peers that a retrieved message is delivered to 82 requesterCount = 3 83 ) 84 85 var ( 86 // timeout interval before retrieval is timed out 87 searchTimeout = 3 * time.Second 88 ) 89 90 // store logic common to local and network chunk store requests 91 // ~ unsafe put in localdb no check if exists no extra copy no hash validation 92 // the chunk is forced to propagate (Cloud.Store) even if locally found! 93 // caller needs to make sure if that is wanted 94 func (self *NetStore) Put(entry *Chunk) { 95 self.localStore.Put(entry) 96 97 // handle deliveries 98 if entry.Req != nil { 99 log.Trace(fmt.Sprintf("NetStore.Put: localStore.Put %v hit existing request...delivering", entry.Key.Log())) 100 // closing C signals to other routines (local requests) 101 // that the chunk is has been retrieved 102 close(entry.Req.C) 103 // deliver the chunk to requesters upstream 104 go self.cloud.Deliver(entry) 105 } else { 106 log.Trace(fmt.Sprintf("NetStore.Put: localStore.Put %v stored locally", entry.Key.Log())) 107 // handle propagating store requests 108 // go self.cloud.Store(entry) 109 go self.cloud.Store(entry) 110 } 111 } 112 113 // retrieve logic common for local and network chunk retrieval requests 114 func (self *NetStore) Get(key Key) (*Chunk, error) { 115 var err error 116 chunk, err := self.localStore.Get(key) 117 if err == nil { 118 if chunk.Req == nil { 119 log.Trace(fmt.Sprintf("NetStore.Get: %v found locally", key)) 120 } else { 121 log.Trace(fmt.Sprintf("NetStore.Get: %v hit on an existing request", key)) 122 // no need to launch again 123 } 124 return chunk, err 125 } 126 // no data and no request status 127 log.Trace(fmt.Sprintf("NetStore.Get: %v not found locally. open new request", key)) 128 chunk = NewChunk(key, newRequestStatus(key)) 129 self.localStore.memStore.Put(chunk) 130 go self.cloud.Retrieve(chunk) 131 return chunk, nil 132 } 133 134 // Close netstore 135 func (self *NetStore) Close() {}