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