diff options
Diffstat (limited to 'swarm/chunk/chunk.go')
-rw-r--r-- | swarm/chunk/chunk.go | 154 |
1 files changed, 153 insertions, 1 deletions
diff --git a/swarm/chunk/chunk.go b/swarm/chunk/chunk.go index 7540af8ce..c44292bb9 100644 --- a/swarm/chunk/chunk.go +++ b/swarm/chunk/chunk.go @@ -1,6 +1,23 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + package chunk import ( + "context" "errors" "fmt" @@ -28,7 +45,7 @@ type chunk struct { sdata []byte } -func NewChunk(addr Address, data []byte) *chunk { +func NewChunk(addr Address, data []byte) Chunk { return &chunk{ addr: addr, sdata: data, @@ -107,3 +124,138 @@ func Proximity(one, other []byte) (ret int) { } return MaxPO } + +// ModeGet enumerates different Getter modes. +type ModeGet int + +func (m ModeGet) String() string { + switch m { + case ModeGetRequest: + return "Request" + case ModeGetSync: + return "Sync" + case ModeGetLookup: + return "Lookup" + default: + return "Unknown" + } +} + +// Getter modes. +const ( + // ModeGetRequest: when accessed for retrieval + ModeGetRequest ModeGet = iota + // ModeGetSync: when accessed for syncing or proof of custody request + ModeGetSync + // ModeGetLookup: when accessed to lookup a a chunk in feeds or other places + ModeGetLookup +) + +// ModePut enumerates different Putter modes. +type ModePut int + +func (m ModePut) String() string { + switch m { + case ModePutRequest: + return "Request" + case ModePutSync: + return "Sync" + case ModePutUpload: + return "Upload" + default: + return "Unknown" + } +} + +// Putter modes. +const ( + // ModePutRequest: when a chunk is received as a result of retrieve request and delivery + ModePutRequest ModePut = iota + // ModePutSync: when a chunk is received via syncing + ModePutSync + // ModePutUpload: when a chunk is created by local upload + ModePutUpload +) + +// ModeSet enumerates different Setter modes. +type ModeSet int + +func (m ModeSet) String() string { + switch m { + case ModeSetAccess: + return "Access" + case ModeSetSync: + return "Sync" + case ModeSetRemove: + return "Remove" + default: + return "Unknown" + } +} + +// Setter modes. +const ( + // ModeSetAccess: when an update request is received for a chunk or chunk is retrieved for delivery + ModeSetAccess ModeSet = iota + // ModeSetSync: when a chunk is added to a pull sync batch or when a push sync receipt is received + ModeSetSync + // ModeSetRemove: when a chunk is removed + ModeSetRemove +) + +// Descriptor holds information required for Pull syncing. This struct +// is provided by subscribing to pull index. +type Descriptor struct { + Address Address + BinID uint64 +} + +func (d *Descriptor) String() string { + if d == nil { + return "" + } + return fmt.Sprintf("%s bin id %v", d.Address.Hex(), d.BinID) +} + +type Store interface { + Get(ctx context.Context, mode ModeGet, addr Address) (ch Chunk, err error) + Put(ctx context.Context, mode ModePut, ch Chunk) (exists bool, err error) + Has(ctx context.Context, addr Address) (yes bool, err error) + Set(ctx context.Context, mode ModeSet, addr Address) (err error) + LastPullSubscriptionBinID(bin uint8) (id uint64, err error) + SubscribePull(ctx context.Context, bin uint8, since, until uint64) (c <-chan Descriptor, stop func()) + Close() (err error) +} + +// Validator validates a chunk. +type Validator interface { + Validate(ch Chunk) bool +} + +// ValidatorStore encapsulates Store by decorting the Put method +// with validators check. +type ValidatorStore struct { + Store + validators []Validator +} + +// NewValidatorStore returns a new ValidatorStore which uses +// provided validators to validate chunks on Put. +func NewValidatorStore(store Store, validators ...Validator) (s *ValidatorStore) { + return &ValidatorStore{ + Store: store, + validators: validators, + } +} + +// Put overrides Store put method with validators check. If one of the validators +// return true, the chunk is considered valid and Store Put method is called. +// If all validators return false, ErrChunkInvalid is returned. +func (s *ValidatorStore) Put(ctx context.Context, mode ModePut, ch Chunk) (exists bool, err error) { + for _, v := range s.validators { + if v.Validate(ch) { + return s.Store.Put(ctx, mode, ch) + } + } + return false, ErrChunkInvalid +} |