github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/types.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:45</date> 10 //</624450121458782208> 11 12 13 package storage 14 15 import ( 16 "bytes" 17 "context" 18 "crypto" 19 "crypto/rand" 20 "encoding/binary" 21 "fmt" 22 "io" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/swarm/bmt" 26 ch "github.com/ethereum/go-ethereum/swarm/chunk" 27 "golang.org/x/crypto/sha3" 28 ) 29 30 const MaxPO = 16 31 const AddressLength = 32 32 33 type SwarmHasher func() SwarmHash 34 35 type Address []byte 36 37 //接近(x,y)返回x和y之间的最高位距离的接近顺序。 38 // 39 //两个等长字节序列x和y的距离度量msb(x,y)是 40 //x^y的二进制整数转换值,即x和y位xor-ed。 41 //二进制转换是big-endian:最高有效位优先(=msb)。 42 // 43 //邻近度(x,y)是最大有效位距离的离散对数标度。 44 //它被定义为基2整数部分的倒序。 45 //距离的对数。 46 //它是通过计算(msb)中公共前导零的数目来计算的。 47 //x^y的二进制表示。 48 // 49 //(最远0个,最近255个,自己256个) 50 func Proximity(one, other []byte) (ret int) { 51 b := (MaxPO-1)/8 + 1 52 if b > len(one) { 53 b = len(one) 54 } 55 m := 8 56 for i := 0; i < b; i++ { 57 oxo := one[i] ^ other[i] 58 for j := 0; j < m; j++ { 59 if (oxo>>uint8(7-j))&0x01 != 0 { 60 return i*8 + j 61 } 62 } 63 } 64 return MaxPO 65 } 66 67 var ZeroAddr = Address(common.Hash{}.Bytes()) 68 69 func MakeHashFunc(hash string) SwarmHasher { 70 switch hash { 71 case "SHA256": 72 return func() SwarmHash { return &HashWithLength{crypto.SHA256.New()} } 73 case "SHA3": 74 return func() SwarmHash { return &HashWithLength{sha3.NewLegacyKeccak256()} } 75 case "BMT": 76 return func() SwarmHash { 77 hasher := sha3.NewLegacyKeccak256 78 hasherSize := hasher().Size() 79 segmentCount := ch.DefaultSize / hasherSize 80 pool := bmt.NewTreePool(hasher, segmentCount, bmt.PoolSize) 81 return bmt.New(pool) 82 } 83 } 84 return nil 85 } 86 87 func (a Address) Hex() string { 88 return fmt.Sprintf("%064x", []byte(a[:])) 89 } 90 91 func (a Address) Log() string { 92 if len(a[:]) < 8 { 93 return fmt.Sprintf("%x", []byte(a[:])) 94 } 95 return fmt.Sprintf("%016x", []byte(a[:8])) 96 } 97 98 func (a Address) String() string { 99 return fmt.Sprintf("%064x", []byte(a)) 100 } 101 102 func (a Address) MarshalJSON() (out []byte, err error) { 103 return []byte(`"` + a.String() + `"`), nil 104 } 105 106 func (a *Address) UnmarshalJSON(value []byte) error { 107 s := string(value) 108 *a = make([]byte, 32) 109 h := common.Hex2Bytes(s[1 : len(s)-1]) 110 copy(*a, h) 111 return nil 112 } 113 114 type AddressCollection []Address 115 116 func NewAddressCollection(l int) AddressCollection { 117 return make(AddressCollection, l) 118 } 119 120 func (c AddressCollection) Len() int { 121 return len(c) 122 } 123 124 func (c AddressCollection) Less(i, j int) bool { 125 return bytes.Compare(c[i], c[j]) == -1 126 } 127 128 func (c AddressCollection) Swap(i, j int) { 129 c[i], c[j] = c[j], c[i] 130 } 131 132 //由context.context和数据块实现的块接口 133 type Chunk interface { 134 Address() Address 135 Data() []byte 136 } 137 138 type chunk struct { 139 addr Address 140 sdata []byte 141 span int64 142 } 143 144 func NewChunk(addr Address, data []byte) *chunk { 145 return &chunk{ 146 addr: addr, 147 sdata: data, 148 span: -1, 149 } 150 } 151 152 func (c *chunk) Address() Address { 153 return c.addr 154 } 155 156 func (c *chunk) Data() []byte { 157 return c.sdata 158 } 159 160 //字符串()用于漂亮打印 161 func (self *chunk) String() string { 162 return fmt.Sprintf("Address: %v TreeSize: %v Chunksize: %v", self.addr.Log(), self.span, len(self.sdata)) 163 } 164 165 func GenerateRandomChunk(dataSize int64) Chunk { 166 hasher := MakeHashFunc(DefaultHash)() 167 sdata := make([]byte, dataSize+8) 168 rand.Read(sdata[8:]) 169 binary.LittleEndian.PutUint64(sdata[:8], uint64(dataSize)) 170 hasher.ResetWithLength(sdata[:8]) 171 hasher.Write(sdata[8:]) 172 return NewChunk(hasher.Sum(nil), sdata) 173 } 174 175 func GenerateRandomChunks(dataSize int64, count int) (chunks []Chunk) { 176 for i := 0; i < count; i++ { 177 ch := GenerateRandomChunk(dataSize) 178 chunks = append(chunks, ch) 179 } 180 return chunks 181 } 182 183 //大小、查找、读取、读取 184 type LazySectionReader interface { 185 Context() context.Context 186 Size(context.Context, chan bool) (int64, error) 187 io.Seeker 188 io.Reader 189 io.ReaderAt 190 } 191 192 type LazyTestSectionReader struct { 193 *io.SectionReader 194 } 195 196 func (r *LazyTestSectionReader) Size(context.Context, chan bool) (int64, error) { 197 return r.SectionReader.Size(), nil 198 } 199 200 func (r *LazyTestSectionReader) Context() context.Context { 201 return context.TODO() 202 } 203 204 type StoreParams struct { 205 Hash SwarmHasher `toml:"-"` 206 DbCapacity uint64 207 CacheCapacity uint 208 BaseKey []byte 209 } 210 211 func NewDefaultStoreParams() *StoreParams { 212 return NewStoreParams(defaultLDBCapacity, defaultCacheCapacity, nil, nil) 213 } 214 215 func NewStoreParams(ldbCap uint64, cacheCap uint, hash SwarmHasher, basekey []byte) *StoreParams { 216 if basekey == nil { 217 basekey = make([]byte, 32) 218 } 219 if hash == nil { 220 hash = MakeHashFunc(DefaultHash) 221 } 222 return &StoreParams{ 223 Hash: hash, 224 DbCapacity: ldbCap, 225 CacheCapacity: cacheCap, 226 BaseKey: basekey, 227 } 228 } 229 230 type ChunkData []byte 231 232 type Reference []byte 233 234 //推杆负责存储数据并为其创建参考。 235 type Putter interface { 236 Put(context.Context, ChunkData) (Reference, error) 237 //refsize返回此推杆创建的参考长度 238 RefSize() int64 239 //CLOSE是指在这个推杆上不再放置数据块。 240 Close() 241 //如果所有数据都已存储并调用了close(),则wait返回。 242 Wait(context.Context) error 243 } 244 245 //getter是一个通过引用来检索块数据的接口。 246 type Getter interface { 247 Get(context.Context, Reference) (ChunkData, error) 248 } 249 250 //注意:如果块被加密,这将返回无效数据。 251 func (c ChunkData) Size() uint64 { 252 return binary.LittleEndian.Uint64(c[:8]) 253 } 254 255 type ChunkValidator interface { 256 Validate(chunk Chunk) bool 257 } 258 259 //提供对内容地址进行块验证的方法 260 //保留相应的哈希值以创建地址 261 type ContentAddressValidator struct { 262 Hasher SwarmHasher 263 } 264 265 //构造函数 266 func NewContentAddressValidator(hasher SwarmHasher) *ContentAddressValidator { 267 return &ContentAddressValidator{ 268 Hasher: hasher, 269 } 270 } 271 272 //验证给定密钥是否为给定数据的有效内容地址 273 func (v *ContentAddressValidator) Validate(chunk Chunk) bool { 274 data := chunk.Data() 275 if l := len(data); l < 9 || l > ch.DefaultSize+8 { 276 //log.error(“块大小无效”,“块”,addr.hex(),“大小”,l) 277 return false 278 } 279 280 hasher := v.Hasher() 281 hasher.ResetWithLength(data[:8]) 282 hasher.Write(data[8:]) 283 hash := hasher.Sum(nil) 284 285 return bytes.Equal(hash, chunk.Address()) 286 } 287 288 type ChunkStore interface { 289 Put(ctx context.Context, ch Chunk) (err error) 290 Get(rctx context.Context, ref Address) (ch Chunk, err error) 291 Close() 292 } 293 294 //SyncChunkStore是支持同步的ChunkStore 295 type SyncChunkStore interface { 296 ChunkStore 297 BinIndex(po uint8) uint64 298 Iterator(from uint64, to uint64, po uint8, f func(Address, uint64) bool) error 299 FetchFunc(ctx context.Context, ref Address) func(context.Context) error 300 } 301 302 //FakeChunkStore不存储任何内容,只实现ChunkStore接口 303 //如果您不想实际存储数据,可以使用它来注入哈希存储,只需执行 304 //哈希 305 type FakeChunkStore struct { 306 } 307 308 //Put不存储任何东西它只是在这里实现chunkstore 309 func (f *FakeChunkStore) Put(_ context.Context, ch Chunk) error { 310 return nil 311 } 312 313 //gut不存储任何东西,它只是在这里实现chunkstore 314 func (f *FakeChunkStore) Get(_ context.Context, ref Address) (Chunk, error) { 315 panic("FakeChunkStore doesn't support Get") 316 } 317 318 //close不存储任何内容,它只是在这里实现chunkstore 319 func (f *FakeChunkStore) Close() { 320 } 321